From 84b733a31fb380b4499591f57c174396355120e7 Mon Sep 17 00:00:00 2001 From: CsyDesign <50761900+CsyDesign@users.noreply.github.com> Date: Sun, 12 Jul 2020 00:32:11 +0800 Subject: [PATCH 01/17] [ISSUE#3300] Optimize the default "minIdle"" of HikariPool set by naocs (#3304) --- .../datasource/ExternalDataSourceProperties.java | 2 +- .../ExternalDataSourcePropertiesTest.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java index a9915de54..8f55d169f 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java @@ -45,7 +45,7 @@ public class ExternalDataSourceProperties { public static final int DEFAULT_MAX_POOL_SIZE = 20; - public static final int DEFAULT_MINIMUM_IDLE = 50; + public static final int DEFAULT_MINIMUM_IDLE = 20; private Integer num; diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java index 1ef05b061..e7ad61363 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourcePropertiesTest.java @@ -97,6 +97,20 @@ public class ExternalDataSourcePropertiesTest { })); Assert.assertEquals(dataSources.size(), 2); } + + @Test + public void externalDatasourceToAssertMinIdle() { + MockEnvironment environment = new MockEnvironment(); + environment.setProperty("db.num", "1"); + environment.setProperty("db.user", USERNAME); + environment.setProperty("db.password", PASSWORD); + environment.setProperty("db.url.0", JDBC_URL); + List dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> { + dataSource.validate(); + Assert.assertEquals(dataSource.getMinimumIdle(), ExternalDataSourceProperties.DEFAULT_MINIMUM_IDLE); + })); + Assert.assertEquals(dataSources.size(), 1); + } @Test(expected = IllegalArgumentException.class) public void externalDatasourceFailureWithLarkInfo() { From d8e1d2aebc07fdd934971ab378401984086a5873 Mon Sep 17 00:00:00 2001 From: zongtanghu Date: Sun, 12 Jul 2020 11:28:54 +0800 Subject: [PATCH 02/17] [ISSUE#3179]Replace the NotifyCenter with new refactor in the config and test module. --- .../server/controller/ConfigOpsController.java | 2 +- .../nacos/config/server/filter/CurcuitFilter.java | 15 ++++++++------- .../server/model/event/ConfigDumpEvent.java | 4 ++-- .../server/model/event/DerbyImportEvent.java | 4 ++-- .../config/server/model/event/DerbyLoadEvent.java | 4 ++-- .../server/model/event/RaftDbErrorEvent.java | 4 ++-- .../model/event/RaftDbErrorRecoverEvent.java | 4 ++-- .../server/service/dump/DumpConfigHandler.java | 6 +++--- .../embedded/DerbySnapshotOperation.java | 2 +- .../embedded/DistributedDatabaseOperateImpl.java | 12 ++++++------ .../EmbeddedStoragePersistServiceImpl.java | 2 +- .../test/config/ConfigDerbyRaft_DITCase.java | 10 +++++----- .../alibaba/nacos/test/core/BaseClusterTest.java | 8 ++++---- 13 files changed, 39 insertions(+), 38 deletions(-) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java index ec0900f7b..584a67162 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java @@ -30,7 +30,7 @@ import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.core.auth.ActionTypes; import com.alibaba.nacos.core.auth.Secured; -import com.alibaba.nacos.core.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.WebUtils; import org.apache.commons.lang3.StringUtils; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java b/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java index c26f408ed..dcba2fd82 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java @@ -26,9 +26,9 @@ import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.MemberMetaDataConstants; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.code.ControllerMethodsCache; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.SmartSubscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.SmartSubscriber; import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.PostConstruct; @@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.security.AccessControlException; +import java.util.Arrays; import java.util.List; /** @@ -119,8 +120,8 @@ public class CurcuitFilter implements Filter { } private void registerSubscribe() { - NotifyCenter.registerSubscribe(new SmartSubscribe() { - + NotifyCenter.registerSubscriber(new SmartSubscriber() { + @Override public void onEvent(Event event) { // @JustForTest @@ -135,8 +136,8 @@ public class CurcuitFilter implements Filter { } @Override - public boolean canNotify(Event event) { - return (event instanceof RaftDbErrorEvent) || (event instanceof RaftDbErrorRecoverEvent); + public List> subscribeTypes() { + return Arrays.asList(RaftDbErrorRecoverEvent.class, RaftDbErrorEvent.class); } }); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java index c0d94f5d5..76cbbb7e5 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java @@ -16,14 +16,14 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.core.notify.Event; +import com.alibaba.nacos.common.notify.Event; /** * ConfigDumpEvent. * * @author liaochuntao */ -public class ConfigDumpEvent implements Event { +public class ConfigDumpEvent extends Event { private static final long serialVersionUID = -8776888606458370294L; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyImportEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyImportEvent.java index 5b467868a..4311fb559 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyImportEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyImportEvent.java @@ -16,14 +16,14 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.core.notify.SlowEvent; +import com.alibaba.nacos.common.notify.SlowEvent; /** * Data import event. * * @author liaochuntao */ -public class DerbyImportEvent implements SlowEvent { +public class DerbyImportEvent extends SlowEvent { private static final long serialVersionUID = 3299565864352399053L; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyLoadEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyLoadEvent.java index 988ea4184..6a54625b2 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyLoadEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/DerbyLoadEvent.java @@ -16,14 +16,14 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.core.notify.SlowEvent; +import com.alibaba.nacos.common.notify.SlowEvent; /** * DerbyLoadEvent. * * @author liaochuntao */ -public class DerbyLoadEvent implements SlowEvent { +public class DerbyLoadEvent extends SlowEvent { public static final DerbyLoadEvent INSTANCE = new DerbyLoadEvent(); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorEvent.java index 6d3a8bd43..3d2e9035d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorEvent.java @@ -16,14 +16,14 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.core.notify.SlowEvent; +import com.alibaba.nacos.common.notify.SlowEvent; /** * RaftDBErrorEvent. * * @author liaochuntao */ -public class RaftDbErrorEvent implements SlowEvent { +public class RaftDbErrorEvent extends SlowEvent { private static final long serialVersionUID = 101591819161802336L; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorRecoverEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorRecoverEvent.java index 047664b5b..457e17994 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorRecoverEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/RaftDbErrorRecoverEvent.java @@ -17,7 +17,7 @@ package com.alibaba.nacos.config.server.model.event; import com.alibaba.nacos.common.JustForTest; -import com.alibaba.nacos.core.notify.Event; +import com.alibaba.nacos.common.notify.Event; /** * RaftDBErrorRecoverEvent. @@ -25,6 +25,6 @@ import com.alibaba.nacos.core.notify.Event; * @author liaochuntao */ @JustForTest -public class RaftDbErrorRecoverEvent implements Event { +public class RaftDbErrorRecoverEvent extends Event { } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java index 758b22150..c70f496ca 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java @@ -23,15 +23,15 @@ import com.alibaba.nacos.config.server.service.ClientIpWhiteList; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.SwitchService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.listener.Subscriber; /** * Dump config subscriber. * * @author liaochuntao */ -public class DumpConfigHandler implements Subscribe { +public class DumpConfigHandler extends Subscriber { /** * trigger config dump event. diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java index da15f6644..c9f45411a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java @@ -27,7 +27,7 @@ import com.alibaba.nacos.consistency.snapshot.SnapshotOperation; import com.alibaba.nacos.consistency.snapshot.Writer; import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor; import com.alibaba.nacos.core.utils.DiskUtils; -import com.alibaba.nacos.core.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.TimerContext; import com.alipay.sofa.jraft.util.CRC64; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java index a2fa0e95f..de23641a4 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java @@ -21,6 +21,7 @@ import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; import com.alibaba.nacos.common.JustForTest; import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.LoggerUtils; @@ -53,9 +54,8 @@ import com.alibaba.nacos.consistency.exception.ConsistencyException; import com.alibaba.nacos.consistency.snapshot.SnapshotOperation; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.distributed.ProtocolManager; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ClassUtils; import com.alibaba.nacos.core.utils.DiskUtils; import com.alibaba.nacos.core.utils.GenericType; @@ -190,7 +190,7 @@ public class DistributedDatabaseOperateImpl extends LogProcessor4CP implements B // Register the snapshot load event NotifyCenter.registerToSharePublisher(DerbyLoadEvent.class); - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(RaftDbErrorEvent event) { dataSourceService.setHealthStatus("DOWN"); @@ -202,8 +202,8 @@ public class DistributedDatabaseOperateImpl extends LogProcessor4CP implements B } }); - NotifyCenter.registerToPublisher(ConfigDumpEvent.class, NotifyCenter.RING_BUFFER_SIZE); - NotifyCenter.registerSubscribe(new DumpConfigHandler()); + NotifyCenter.registerToPublisher(ConfigDumpEvent.class, NotifyCenter.ringBufferSize); + NotifyCenter.registerSubscriber(new DumpConfigHandler()); this.protocol.addLogProcessors(Collections.singletonList(this)); LogUtil.DEFAULT_LOG.info("use DistributedTransactionServicesImpl"); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java index efb2b5f29..b7a596b15 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java @@ -48,7 +48,7 @@ import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.ParamUtils; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; -import com.alibaba.nacos.core.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java index 1c8974c07..1ceaa0d58 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java @@ -27,9 +27,9 @@ import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.consistency.cp.CPProtocol; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.core.distributed.raft.utils.JRaftConstants; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.GenericType; import com.alibaba.nacos.core.utils.InetUtils; import com.alibaba.nacos.common.utils.ThreadUtils; @@ -299,7 +299,7 @@ public class ConfigDerbyRaft_DITCase NotifyCenter.registerToPublisher(RaftDbErrorRecoverEvent.class, 8); CountDownLatch latch1 = new CountDownLatch(1); - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(RaftDbErrorEvent event) { latch1.countDown(); @@ -318,7 +318,7 @@ public class ConfigDerbyRaft_DITCase Assert.assertFalse(result); CountDownLatch latch2 = new CountDownLatch(1); - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(RaftDbErrorRecoverEvent event) { diff --git a/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java b/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java index 404ce52e2..0aaa2a29a 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java @@ -27,9 +27,9 @@ import com.alibaba.nacos.config.server.model.event.RaftDbErrorEvent; import com.alibaba.nacos.config.server.service.repository.embedded.DistributedDatabaseOperateImpl; import com.alibaba.nacos.consistency.cp.CPProtocol; import com.alibaba.nacos.consistency.cp.MetadataKey; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.InetUtils; import com.alibaba.nacos.test.base.HttpClient4Test; @@ -84,7 +84,7 @@ public class BaseClusterTest extends HttpClient4Test { clusterInfo = "nacos.member.list=" + ip + ":8847," + ip + ":8848," + ip + ":8849"; - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(RaftDbErrorEvent event) { System.out.print(event.getEx()); From 34fd36b1159ae89d2b1e1a89666d43aa1c37bb5a Mon Sep 17 00:00:00 2001 From: zongtanghu Date: Sun, 12 Jul 2020 13:52:29 +0800 Subject: [PATCH 03/17] [ISSUE#3179]fix import formate issue. --- .../controller/ConfigOpsController.java | 2 +- .../config/server/filter/CurcuitFilter.java | 8 +- .../server/model/event/ConfigDumpEvent.java | 2 +- .../service/dump/DumpConfigHandler.java | 7 +- .../embedded/DerbySnapshotOperation.java | 2 +- .../DistributedDatabaseOperateImpl.java | 4 +- .../EmbeddedStoragePersistServiceImpl.java | 2 +- .../test/config/ConfigDerbyRaft_DITCase.java | 709 +++++++++--------- .../nacos/test/core/BaseClusterTest.java | 354 +++++---- 9 files changed, 538 insertions(+), 552 deletions(-) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java index 584a67162..cb7728c06 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigOpsController.java @@ -19,6 +19,7 @@ package com.alibaba.nacos.config.server.controller; import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils; import com.alibaba.nacos.common.utils.Objects; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.event.DerbyImportEvent; import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource; @@ -30,7 +31,6 @@ import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.core.auth.ActionTypes; import com.alibaba.nacos.core.auth.Secured; -import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.WebUtils; import org.apache.commons.lang3.StringUtils; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java b/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java index dcba2fd82..4c71d4012 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/filter/CurcuitFilter.java @@ -17,6 +17,9 @@ package com.alibaba.nacos.config.server.filter; import com.alibaba.nacos.common.utils.ExceptionUtil; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.SmartSubscriber; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.event.RaftDbErrorEvent; import com.alibaba.nacos.config.server.model.event.RaftDbErrorRecoverEvent; @@ -26,9 +29,6 @@ import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.MemberMetaDataConstants; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.code.ControllerMethodsCache; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.NotifyCenter; -import com.alibaba.nacos.common.notify.listener.SmartSubscriber; import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.PostConstruct; @@ -121,7 +121,7 @@ public class CurcuitFilter implements Filter { private void registerSubscribe() { NotifyCenter.registerSubscriber(new SmartSubscriber() { - + @Override public void onEvent(Event event) { // @JustForTest diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java index 76cbbb7e5..ae046ef8a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java @@ -222,7 +222,7 @@ public class ConfigDumpEvent extends Event { this.lastModifiedTs = lastModifiedTs; return this; } - + /** * Build a configDumpEvent. * diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java index c70f496ca..97e205f82 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java @@ -17,14 +17,14 @@ package com.alibaba.nacos.config.server.service.dump; import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent; import com.alibaba.nacos.config.server.service.AggrWhitelist; import com.alibaba.nacos.config.server.service.ClientIpWhiteList; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.SwitchService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.listener.Subscriber; /** * Dump config subscriber. @@ -37,8 +37,7 @@ public class DumpConfigHandler extends Subscriber { * trigger config dump event. * * @param event {@link ConfigDumpEvent} - * @return {@code true} if the config dump task success , else - * {@code false} + * @return {@code true} if the config dump task success , else {@code false} */ public static boolean configDump(ConfigDumpEvent event) { final String dataId = event.getDataId(); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java index c9f45411a..8fa6c7b10 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DerbySnapshotOperation.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.repository.embedded; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.model.event.DerbyLoadEvent; import com.alibaba.nacos.config.server.service.datasource.DataSourceService; import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource; @@ -27,7 +28,6 @@ import com.alibaba.nacos.consistency.snapshot.SnapshotOperation; import com.alibaba.nacos.consistency.snapshot.Writer; import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor; import com.alibaba.nacos.core.utils.DiskUtils; -import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.TimerContext; import com.alipay.sofa.jraft.util.CRC64; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java index de23641a4..081a7e5dd 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DistributedDatabaseOperateImpl.java @@ -21,6 +21,8 @@ import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; import com.alibaba.nacos.common.JustForTest; import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.JacksonUtils; @@ -54,8 +56,6 @@ import com.alibaba.nacos.consistency.exception.ConsistencyException; import com.alibaba.nacos.consistency.snapshot.SnapshotOperation; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.distributed.ProtocolManager; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ClassUtils; import com.alibaba.nacos.core.utils.DiskUtils; import com.alibaba.nacos.core.utils.GenericType; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java index b7a596b15..e510740bd 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java @@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.repository.embedded; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.enums.FileTypeEnum; @@ -48,7 +49,6 @@ import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.ParamUtils; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; -import com.alibaba.nacos.common.notify.NotifyCenter; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java index 1ceaa0d58..be489522c 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigDerbyRaft_DITCase.java @@ -17,6 +17,10 @@ package com.alibaba.nacos.test.config; import com.alibaba.nacos.api.config.listener.AbstractListener; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; +import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RestResult; @@ -27,13 +31,10 @@ import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.consistency.cp.CPProtocol; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.core.distributed.raft.utils.JRaftConstants; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.NotifyCenter; -import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.GenericType; import com.alibaba.nacos.core.utils.InetUtils; -import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.test.core.BaseClusterTest; + import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Ignore; @@ -55,360 +56,348 @@ import java.util.concurrent.atomic.AtomicReference; @SuppressWarnings("all") @Ignore @FixMethodOrder(value = MethodSorters.NAME_ASCENDING) -public class ConfigDerbyRaft_DITCase - extends BaseClusterTest { - - @Test - public void test_a_publish_config() throws Exception { - boolean result = iconfig7.publishConfig("raft_test", "cluster_test_1", - "this.is.raft_cluster=lessspring_7"); - Assert.assertTrue(result); - - ThreadUtils.sleep(5000); - - ConfigurableApplicationContext context7 = applications.get("8847"); - ConfigurableApplicationContext context8 = applications.get("8848"); - ConfigurableApplicationContext context9 = applications.get("8849"); - - PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); - - String s7 = operate7.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - String s8 = operate8.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - String s9 = operate9.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - - Assert.assertArrayEquals("The three nodes must have consistent data", - new String[] { s7, s8, s9 }, - new String[] { "this.is.raft_cluster=lessspring_7", - "this.is.raft_cluster=lessspring_7", - "this.is.raft_cluster=lessspring_7" }); - } - - @Test - public void test_b_publish_config() throws Exception { - ThreadUtils.sleep(5000); - - boolean result = iconfig8.publishConfig("raft_test", "cluster_test_2", - "this.is.raft_cluster=lessspring_8"); - Assert.assertTrue(result); - - ThreadUtils.sleep(5000); - - ConfigurableApplicationContext context7 = applications.get("8847"); - ConfigurableApplicationContext context8 = applications.get("8848"); - ConfigurableApplicationContext context9 = applications.get("8849"); - - PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); - - String s7 = operate7.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - String s8 = operate8.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - String s9 = operate9.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - - Assert.assertArrayEquals("The three nodes must have consistent data", - new String[] { s7, s8, s9 }, - new String[] { "this.is.raft_cluster=lessspring_8", - "this.is.raft_cluster=lessspring_8", - "this.is.raft_cluster=lessspring_8" }); - } - - @Test - public void test_c_publish_config() throws Exception { - ThreadUtils.sleep(5000); - boolean result = iconfig9.publishConfig("raft_test", "cluster_test_2", - "this.is.raft_cluster=lessspring_9"); - Assert.assertTrue(result); - - ThreadUtils.sleep(5000); - - ConfigurableApplicationContext context7 = applications.get("8847"); - ConfigurableApplicationContext context8 = applications.get("8848"); - ConfigurableApplicationContext context9 = applications.get("8849"); - - PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); - - String s7 = operate7.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - String s8 = operate8.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - String s9 = operate9.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); - - Assert.assertArrayEquals("The three nodes must have consistent data", - new String[] { s7, s8, s9 }, - new String[] { "this.is.raft_cluster=lessspring_9", - "this.is.raft_cluster=lessspring_9", - "this.is.raft_cluster=lessspring_9" }); - } - - @Test - public void test_d_modify_config() throws Exception { - boolean result = iconfig7.publishConfig("raft_test", "cluster_test_1", - "this.is.raft_cluster=lessspring_7_it_is_for_modify"); - Assert.assertTrue(result); - - ThreadUtils.sleep(5000); - - ConfigurableApplicationContext context7 = applications.get("8847"); - ConfigurableApplicationContext context8 = applications.get("8848"); - ConfigurableApplicationContext context9 = applications.get("8849"); - - PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); - PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); - - String s7 = operate7.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - String s8 = operate8.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - String s9 = operate9.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); - - Assert.assertArrayEquals("The three nodes must have consistent data", - new String[] { s7, s8, s9 }, - new String[] { "this.is.raft_cluster=lessspring_7_it_is_for_modify", - "this.is.raft_cluster=lessspring_7_it_is_for_modify", - "this.is.raft_cluster=lessspring_7_it_is_for_modify" }); - } - - @Test - public void test_l_client_operation() throws Exception { - final String dataId = "test_l_client_operation"; - final String groupId = "test_l_client_operation"; - String content = "test_l_client_operation" + System.currentTimeMillis(); - - // publish by 8847 - boolean result = iconfig7.publishConfig(dataId, groupId, content); - Assert.assertTrue(result); - ThreadUtils.sleep(5000); - - String v1_7 = iconfig7.getConfig(dataId, groupId, 5000L); - String v1_8 = iconfig8.getConfig(dataId, groupId, 5000L); - String v1_9 = iconfig9.getConfig(dataId, groupId, 5000L); - - Assert.assertEquals(content, v1_7); - Assert.assertEquals(content, v1_8); - Assert.assertEquals(content, v1_9); - - // publish by 8848 - content = "test_l_client_operation" + System.currentTimeMillis(); - result = iconfig8.publishConfig(dataId, groupId, content); - Assert.assertTrue(result); - ThreadUtils.sleep(5000); - - String v2_7 = iconfig7.getConfig(dataId, groupId, 5000L); - String v2_8 = iconfig8.getConfig(dataId, groupId, 5000L); - String v2_9 = iconfig9.getConfig(dataId, groupId, 5000L); - - Assert.assertEquals(content, v2_7); - Assert.assertEquals(content, v2_8); - Assert.assertEquals(content, v2_9); - - // publish by 8849 - content = "test_l_client_operation" + System.currentTimeMillis(); - result = iconfig9.publishConfig(dataId, groupId, content); - Assert.assertTrue(result); - ThreadUtils.sleep(5000); - - String v3_7 = iconfig7.getConfig(dataId, groupId, 5000L); - String v3_8 = iconfig8.getConfig(dataId, groupId, 5000L); - String v3_9 = iconfig9.getConfig(dataId, groupId, 5000L); - - Assert.assertEquals(content, v3_7); - Assert.assertEquals(content, v3_8); - Assert.assertEquals(content, v3_9); - - // delete by 8849 - result = iconfig9.removeConfig(dataId, groupId); - Assert.assertTrue(result); - ThreadUtils.sleep(5000); - - String v4_7 = iconfig7.getConfig(dataId, groupId, 5000L); - String v4_8 = iconfig8.getConfig(dataId, groupId, 5000L); - String v4_9 = iconfig9.getConfig(dataId, groupId, 5000L); - - Assert.assertNull(v4_7); - Assert.assertNull(v4_8); - Assert.assertNull(v4_9); - } - - @Test - public void test_k_config_listener() throws Exception { - String dataId = "test_h_config_listener"; - String group = "test_h_config_listener"; - String content = "test_h_config_listener"; - CountDownLatch[] latch = new CountDownLatch[]{new CountDownLatch(1), new CountDownLatch(0)}; - AtomicReference r = new AtomicReference<>(); - AtomicInteger i = new AtomicInteger(0); - iconfig7.addListener(dataId, group, new AbstractListener() { - @Override - public void receiveConfigInfo(String configInfo) { - System.out.println(configInfo); - r.set(configInfo); - latch[i.getAndIncrement()].countDown(); - } - }); - - iconfig7.publishConfig(dataId, group, content); - - ThreadUtils.sleep(10_000L); - latch[0].await(10_000L, TimeUnit.MILLISECONDS); - Assert.assertEquals(content, r.get()); - Assert.assertEquals(content, iconfig7.getConfig(dataId, group, 2_000L)); - - content = content + System.currentTimeMillis(); - iconfig7.publishConfig(dataId, group, content); - - ThreadUtils.sleep(10_000L); - latch[1].await(10_000L, TimeUnit.MILLISECONDS); - Assert.assertEquals(content, r.get()); - Assert.assertEquals(content, iconfig7.getConfig(dataId, group, 2_000L)); - } - - @Test - public void test_e_derby_ops() throws Exception { - String url = "http://127.0.0.1:8848/nacos/v1/cs/ops/derby"; - Query query = Query.newInstance() - .addParam("sql", "select * from users"); - RestResult>> result = httpClient.get(url, Header.EMPTY, query, new GenericType>>>(){}.getType()); - System.out.println(result.getData()); - Assert.assertTrue(result.ok()); - List> list = result.getData(); - Assert.assertEquals(1, list.size()); - Assert.assertEquals("nacos", list.get(0).get("USERNAME")); - } - - @Test - public void test_g_derby_ops_no_select() throws Exception { - String url = "http://127.0.0.1:8848/nacos/v1/cs/ops/derby"; - Query query = Query.newInstance() - .addParam("sql", "update users set username='nacos'"); - RestResult result = httpClient.get(url, Header.EMPTY, query, new GenericType>(){}.getType()); - System.out.println(result); - Assert.assertFalse(result.ok()); - Assert.assertEquals("Only query statements are allowed to be executed", result.getMessage()); - } - - @Test - public void test_h_derby_has_error() throws Exception { - - ThreadUtils.sleep(5000); - - boolean result = iconfig7.publishConfig("raft_test_raft_error", "cluster_test_1", - "this.is.raft_cluster=lessspring_7"); - Assert.assertTrue(result); - - NotifyCenter.registerToPublisher(RaftDbErrorRecoverEvent.class, 8); - - CountDownLatch latch1 = new CountDownLatch(1); - NotifyCenter.registerSubscriber(new Subscriber() { - @Override - public void onEvent(RaftDbErrorEvent event) { - latch1.countDown(); - } - - @Override - public Class subscribeType() { - return RaftDbErrorEvent.class; - } - }); - NotifyCenter.publishEvent(new RaftDbErrorEvent()); - latch1.await(10_000L, TimeUnit.MILLISECONDS); - - result = iconfig7.publishConfig("raft_test_raft_error", "cluster_test_1", - "this.is.raft_cluster=lessspring_7"); - Assert.assertFalse(result); - - CountDownLatch latch2 = new CountDownLatch(1); - NotifyCenter.registerSubscriber(new Subscriber() { - - @Override - public void onEvent(RaftDbErrorRecoverEvent event) { - latch2.countDown(); - } - - @Override - public Class subscribeType() { - return RaftDbErrorRecoverEvent.class; - } - }); - NotifyCenter.publishEvent(new RaftDbErrorRecoverEvent()); - latch2.await(10_000L, TimeUnit.MILLISECONDS); - - result = iconfig7.publishConfig("raft_test_raft_error", "cluster_test_1", - "this.is.raft_cluster=lessspring_7"); - Assert.assertTrue(result); - } - - @Test - public void test_f_id_generator_leader_transfer() throws Exception { - ConfigurableApplicationContext context7 = applications.get("8847"); - ConfigurableApplicationContext context8 = applications.get("8848"); - ConfigurableApplicationContext context9 = applications.get("8849"); - IdGeneratorManager manager7 = context7.getBean(IdGeneratorManager.class); - IdGeneratorManager manager8 = context8.getBean(IdGeneratorManager.class); - IdGeneratorManager manager9 = context9.getBean(IdGeneratorManager.class); - - CPProtocol protocol7 = context7.getBean(CPProtocol.class); - CPProtocol protocol8 = context8.getBean(CPProtocol.class); - CPProtocol protocol9 = context9.getBean(CPProtocol.class); - - final String configGroup = com.alibaba.nacos.config.server.constant.Constants.CONFIG_MODEL_RAFT_GROUP; - long preId = -1L; - long currentId = -1L; - - if (protocol7.isLeader(configGroup)) { - preId = manager7.nextId(CONFIG_INFO_ID); - } - if (protocol8.isLeader(configGroup)) { - preId = manager8.nextId(CONFIG_INFO_ID); - } - if (protocol9.isLeader(configGroup)) { - preId = manager9.nextId(CONFIG_INFO_ID); - } - - // transfer leader to ip:8807 - - Map transfer = new HashMap<>(); - transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9847"); - RestResult result = protocol7.execute(transfer); - System.out.println(result); - Assert.assertTrue(result.ok()); - - TimeUnit.SECONDS.sleep(2); - - Assert.assertTrue(protocol7.isLeader(configGroup)); - currentId = manager7.nextId(CONFIG_INFO_ID); - Assert.assertNotEquals(preId, currentId); - preId = currentId; - - // transfer leader to ip:8808 - - transfer = new HashMap<>(); - transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9848"); - result = protocol8.execute(transfer); - System.out.println(result); - Assert.assertTrue(result.ok()); - - TimeUnit.SECONDS.sleep(2); - - Assert.assertTrue(protocol8.isLeader(configGroup)); - currentId = manager8.nextId(CONFIG_INFO_ID); - Assert.assertNotEquals(preId, currentId); - preId = currentId; - - // transfer leader to ip:8809 - - transfer = new HashMap<>(); - transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9849"); - result = protocol9.execute(transfer); - System.out.println(result); - Assert.assertTrue(result.ok()); - - TimeUnit.SECONDS.sleep(2); - - Assert.assertTrue(protocol9.isLeader(configGroup)); - currentId = manager9.nextId(CONFIG_INFO_ID); - Assert.assertNotEquals(preId, currentId); - - } - +public class ConfigDerbyRaft_DITCase extends BaseClusterTest { + + @Test + public void test_a_publish_config() throws Exception { + boolean result = iconfig7.publishConfig("raft_test", "cluster_test_1", "this.is.raft_cluster=lessspring_7"); + Assert.assertTrue(result); + + ThreadUtils.sleep(5000); + + ConfigurableApplicationContext context7 = applications.get("8847"); + ConfigurableApplicationContext context8 = applications.get("8848"); + ConfigurableApplicationContext context9 = applications.get("8849"); + + PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); + + String s7 = operate7.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + String s8 = operate8.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + String s9 = operate9.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + + Assert.assertArrayEquals("The three nodes must have consistent data", new String[] {s7, s8, s9}, + new String[] {"this.is.raft_cluster=lessspring_7", "this.is.raft_cluster=lessspring_7", + "this.is.raft_cluster=lessspring_7"}); + } + + @Test + public void test_b_publish_config() throws Exception { + ThreadUtils.sleep(5000); + + boolean result = iconfig8.publishConfig("raft_test", "cluster_test_2", "this.is.raft_cluster=lessspring_8"); + Assert.assertTrue(result); + + ThreadUtils.sleep(5000); + + ConfigurableApplicationContext context7 = applications.get("8847"); + ConfigurableApplicationContext context8 = applications.get("8848"); + ConfigurableApplicationContext context9 = applications.get("8849"); + + PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); + + String s7 = operate7.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + String s8 = operate8.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + String s9 = operate9.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + + Assert.assertArrayEquals("The three nodes must have consistent data", new String[] {s7, s8, s9}, + new String[] {"this.is.raft_cluster=lessspring_8", "this.is.raft_cluster=lessspring_8", + "this.is.raft_cluster=lessspring_8"}); + } + + @Test + public void test_c_publish_config() throws Exception { + ThreadUtils.sleep(5000); + boolean result = iconfig9.publishConfig("raft_test", "cluster_test_2", "this.is.raft_cluster=lessspring_9"); + Assert.assertTrue(result); + + ThreadUtils.sleep(5000); + + ConfigurableApplicationContext context7 = applications.get("8847"); + ConfigurableApplicationContext context8 = applications.get("8848"); + ConfigurableApplicationContext context9 = applications.get("8849"); + + PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); + + String s7 = operate7.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + String s8 = operate8.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + String s9 = operate9.findConfigInfo("raft_test", "cluster_test_2", "").getContent(); + + Assert.assertArrayEquals("The three nodes must have consistent data", new String[] {s7, s8, s9}, + new String[] {"this.is.raft_cluster=lessspring_9", "this.is.raft_cluster=lessspring_9", + "this.is.raft_cluster=lessspring_9"}); + } + + @Test + public void test_d_modify_config() throws Exception { + boolean result = iconfig7 + .publishConfig("raft_test", "cluster_test_1", "this.is.raft_cluster=lessspring_7_it_is_for_modify"); + Assert.assertTrue(result); + + ThreadUtils.sleep(5000); + + ConfigurableApplicationContext context7 = applications.get("8847"); + ConfigurableApplicationContext context8 = applications.get("8848"); + ConfigurableApplicationContext context9 = applications.get("8849"); + + PersistService operate7 = context7.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate8 = context8.getBean(EmbeddedStoragePersistServiceImpl.class); + PersistService operate9 = context9.getBean(EmbeddedStoragePersistServiceImpl.class); + + String s7 = operate7.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + String s8 = operate8.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + String s9 = operate9.findConfigInfo("raft_test", "cluster_test_1", "").getContent(); + + Assert.assertArrayEquals("The three nodes must have consistent data", new String[] {s7, s8, s9}, + new String[] {"this.is.raft_cluster=lessspring_7_it_is_for_modify", + "this.is.raft_cluster=lessspring_7_it_is_for_modify", + "this.is.raft_cluster=lessspring_7_it_is_for_modify"}); + } + + @Test + public void test_l_client_operation() throws Exception { + final String dataId = "test_l_client_operation"; + final String groupId = "test_l_client_operation"; + String content = "test_l_client_operation" + System.currentTimeMillis(); + + // publish by 8847 + boolean result = iconfig7.publishConfig(dataId, groupId, content); + Assert.assertTrue(result); + ThreadUtils.sleep(5000); + + String v1_7 = iconfig7.getConfig(dataId, groupId, 5000L); + String v1_8 = iconfig8.getConfig(dataId, groupId, 5000L); + String v1_9 = iconfig9.getConfig(dataId, groupId, 5000L); + + Assert.assertEquals(content, v1_7); + Assert.assertEquals(content, v1_8); + Assert.assertEquals(content, v1_9); + + // publish by 8848 + content = "test_l_client_operation" + System.currentTimeMillis(); + result = iconfig8.publishConfig(dataId, groupId, content); + Assert.assertTrue(result); + ThreadUtils.sleep(5000); + + String v2_7 = iconfig7.getConfig(dataId, groupId, 5000L); + String v2_8 = iconfig8.getConfig(dataId, groupId, 5000L); + String v2_9 = iconfig9.getConfig(dataId, groupId, 5000L); + + Assert.assertEquals(content, v2_7); + Assert.assertEquals(content, v2_8); + Assert.assertEquals(content, v2_9); + + // publish by 8849 + content = "test_l_client_operation" + System.currentTimeMillis(); + result = iconfig9.publishConfig(dataId, groupId, content); + Assert.assertTrue(result); + ThreadUtils.sleep(5000); + + String v3_7 = iconfig7.getConfig(dataId, groupId, 5000L); + String v3_8 = iconfig8.getConfig(dataId, groupId, 5000L); + String v3_9 = iconfig9.getConfig(dataId, groupId, 5000L); + + Assert.assertEquals(content, v3_7); + Assert.assertEquals(content, v3_8); + Assert.assertEquals(content, v3_9); + + // delete by 8849 + result = iconfig9.removeConfig(dataId, groupId); + Assert.assertTrue(result); + ThreadUtils.sleep(5000); + + String v4_7 = iconfig7.getConfig(dataId, groupId, 5000L); + String v4_8 = iconfig8.getConfig(dataId, groupId, 5000L); + String v4_9 = iconfig9.getConfig(dataId, groupId, 5000L); + + Assert.assertNull(v4_7); + Assert.assertNull(v4_8); + Assert.assertNull(v4_9); + } + + @Test + public void test_k_config_listener() throws Exception { + String dataId = "test_h_config_listener"; + String group = "test_h_config_listener"; + String content = "test_h_config_listener"; + CountDownLatch[] latch = new CountDownLatch[] {new CountDownLatch(1), new CountDownLatch(0)}; + AtomicReference r = new AtomicReference<>(); + AtomicInteger i = new AtomicInteger(0); + iconfig7.addListener(dataId, group, new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + System.out.println(configInfo); + r.set(configInfo); + latch[i.getAndIncrement()].countDown(); + } + }); + + iconfig7.publishConfig(dataId, group, content); + + ThreadUtils.sleep(10_000L); + latch[0].await(10_000L, TimeUnit.MILLISECONDS); + Assert.assertEquals(content, r.get()); + Assert.assertEquals(content, iconfig7.getConfig(dataId, group, 2_000L)); + + content = content + System.currentTimeMillis(); + iconfig7.publishConfig(dataId, group, content); + + ThreadUtils.sleep(10_000L); + latch[1].await(10_000L, TimeUnit.MILLISECONDS); + Assert.assertEquals(content, r.get()); + Assert.assertEquals(content, iconfig7.getConfig(dataId, group, 2_000L)); + } + + @Test + public void test_e_derby_ops() throws Exception { + String url = "http://127.0.0.1:8848/nacos/v1/cs/ops/derby"; + Query query = Query.newInstance().addParam("sql", "select * from users"); + RestResult>> result = httpClient + .get(url, Header.EMPTY, query, new GenericType>>>() { + }.getType()); + System.out.println(result.getData()); + Assert.assertTrue(result.ok()); + List> list = result.getData(); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("nacos", list.get(0).get("USERNAME")); + } + + @Test + public void test_g_derby_ops_no_select() throws Exception { + String url = "http://127.0.0.1:8848/nacos/v1/cs/ops/derby"; + Query query = Query.newInstance().addParam("sql", "update users set username='nacos'"); + RestResult result = httpClient.get(url, Header.EMPTY, query, new GenericType>() { + }.getType()); + System.out.println(result); + Assert.assertFalse(result.ok()); + Assert.assertEquals("Only query statements are allowed to be executed", result.getMessage()); + } + + @Test + public void test_h_derby_has_error() throws Exception { + + ThreadUtils.sleep(5000); + + boolean result = iconfig7 + .publishConfig("raft_test_raft_error", "cluster_test_1", "this.is.raft_cluster=lessspring_7"); + Assert.assertTrue(result); + + NotifyCenter.registerToPublisher(RaftDbErrorRecoverEvent.class, 8); + + CountDownLatch latch1 = new CountDownLatch(1); + NotifyCenter.registerSubscriber(new Subscriber() { + @Override + public void onEvent(RaftDbErrorEvent event) { + latch1.countDown(); + } + + @Override + public Class subscribeType() { + return RaftDbErrorEvent.class; + } + }); + NotifyCenter.publishEvent(new RaftDbErrorEvent()); + latch1.await(10_000L, TimeUnit.MILLISECONDS); + + result = iconfig7.publishConfig("raft_test_raft_error", "cluster_test_1", "this.is.raft_cluster=lessspring_7"); + Assert.assertFalse(result); + + CountDownLatch latch2 = new CountDownLatch(1); + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(RaftDbErrorRecoverEvent event) { + latch2.countDown(); + } + + @Override + public Class subscribeType() { + return RaftDbErrorRecoverEvent.class; + } + }); + NotifyCenter.publishEvent(new RaftDbErrorRecoverEvent()); + latch2.await(10_000L, TimeUnit.MILLISECONDS); + + result = iconfig7.publishConfig("raft_test_raft_error", "cluster_test_1", "this.is.raft_cluster=lessspring_7"); + Assert.assertTrue(result); + } + + @Test + public void test_f_id_generator_leader_transfer() throws Exception { + ConfigurableApplicationContext context7 = applications.get("8847"); + ConfigurableApplicationContext context8 = applications.get("8848"); + ConfigurableApplicationContext context9 = applications.get("8849"); + IdGeneratorManager manager7 = context7.getBean(IdGeneratorManager.class); + IdGeneratorManager manager8 = context8.getBean(IdGeneratorManager.class); + IdGeneratorManager manager9 = context9.getBean(IdGeneratorManager.class); + + CPProtocol protocol7 = context7.getBean(CPProtocol.class); + CPProtocol protocol8 = context8.getBean(CPProtocol.class); + CPProtocol protocol9 = context9.getBean(CPProtocol.class); + + final String configGroup = com.alibaba.nacos.config.server.constant.Constants.CONFIG_MODEL_RAFT_GROUP; + long preId = -1L; + long currentId = -1L; + + if (protocol7.isLeader(configGroup)) { + preId = manager7.nextId(CONFIG_INFO_ID); + } + if (protocol8.isLeader(configGroup)) { + preId = manager8.nextId(CONFIG_INFO_ID); + } + if (protocol9.isLeader(configGroup)) { + preId = manager9.nextId(CONFIG_INFO_ID); + } + + // transfer leader to ip:8807 + + Map transfer = new HashMap<>(); + transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9847"); + RestResult result = protocol7.execute(transfer); + System.out.println(result); + Assert.assertTrue(result.ok()); + + TimeUnit.SECONDS.sleep(2); + + Assert.assertTrue(protocol7.isLeader(configGroup)); + currentId = manager7.nextId(CONFIG_INFO_ID); + Assert.assertNotEquals(preId, currentId); + preId = currentId; + + // transfer leader to ip:8808 + + transfer = new HashMap<>(); + transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9848"); + result = protocol8.execute(transfer); + System.out.println(result); + Assert.assertTrue(result.ok()); + + TimeUnit.SECONDS.sleep(2); + + Assert.assertTrue(protocol8.isLeader(configGroup)); + currentId = manager8.nextId(CONFIG_INFO_ID); + Assert.assertNotEquals(preId, currentId); + preId = currentId; + + // transfer leader to ip:8809 + + transfer = new HashMap<>(); + transfer.put(JRaftConstants.TRANSFER_LEADER, InetUtils.getSelfIp() + ":9849"); + result = protocol9.execute(transfer); + System.out.println(result); + Assert.assertTrue(result.ok()); + + TimeUnit.SECONDS.sleep(2); + + Assert.assertTrue(protocol9.isLeader(configGroup)); + currentId = manager9.nextId(CONFIG_INFO_ID); + Assert.assertNotEquals(preId, currentId); + + } + } diff --git a/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java b/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java index 0aaa2a29a..c6d308462 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/BaseClusterTest.java @@ -22,17 +22,18 @@ import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.common.http.HttpClientManager; import com.alibaba.nacos.common.http.NSyncHttpClient; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.DiskUtils; import com.alibaba.nacos.config.server.model.event.RaftDbErrorEvent; import com.alibaba.nacos.config.server.service.repository.embedded.DistributedDatabaseOperateImpl; import com.alibaba.nacos.consistency.cp.CPProtocol; import com.alibaba.nacos.consistency.cp.MetadataKey; -import com.alibaba.nacos.common.notify.Event; -import com.alibaba.nacos.common.notify.NotifyCenter; -import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.InetUtils; import com.alibaba.nacos.test.base.HttpClient4Test; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.springframework.boot.SpringApplication; @@ -58,186 +59,183 @@ import java.util.concurrent.atomic.AtomicBoolean; * @author liaochuntao */ public class BaseClusterTest extends HttpClient4Test { - - protected static final String CONFIG_INFO_ID = "config-info-id"; - - protected static ConfigService iconfig7; - protected static ConfigService iconfig8; - protected static ConfigService iconfig9; - - protected static NamingService inaming7; - protected static NamingService inaming8; - protected static NamingService inaming9; - - protected static final NSyncHttpClient httpClient = HttpClientManager.getSyncHttpClient(); - - protected static final AtomicBoolean[] finished = new AtomicBoolean[]{new AtomicBoolean(false), new AtomicBoolean(false), new AtomicBoolean(false)}; - - protected static Map applications = new HashMap<>(); - - protected static String clusterInfo; - - static { - System.getProperties().setProperty("nacos.core.auth.enabled", "false"); - System.getProperties().setProperty("embeddedStorage", "true"); - String ip = InetUtils.getSelfIp(); - clusterInfo = "nacos.member.list=" + ip + ":8847," + ip - + ":8848," + ip + ":8849"; - - NotifyCenter.registerSubscriber(new Subscriber() { - @Override - public void onEvent(RaftDbErrorEvent event) { - System.out.print(event.getEx()); - } - - @Override - public Class subscribeType() { - return RaftDbErrorEvent.class; - } - }); - } - - @BeforeClass - public static void before() throws Exception { - - CountDownLatch latch = new CountDownLatch(3); - - Runnable runnable = () -> { - for (int i = 0; i < 3; i++) { - try { - URL runnerUrl = new File("../console/target/classes").toURI().toURL(); - URL[] urls = new URL[] { runnerUrl }; - URLClassLoader cl = new URLClassLoader(urls); - Class runnerClass = cl.loadClass("com.alibaba.nacos.Nacos"); - run(i, latch, runnerClass); - } catch (Exception e) { - latch.countDown(); - } - } - }; - - new Thread(runnable).start(); - - latch.await(); - - System.out.println("The cluster node initialization is complete"); - - Properties setting7 = new Properties(); - String serverIp7 = "127.0.0.1:8847"; - setting7.put(PropertyKeyConst.SERVER_ADDR, serverIp7); - setting7.put(PropertyKeyConst.USERNAME, "nacos"); - setting7.put(PropertyKeyConst.PASSWORD, "nacos"); - iconfig7 = NacosFactory.createConfigService(setting7); - inaming7 = NacosFactory.createNamingService(setting7); - - Properties setting8 = new Properties(); - String serverIp8 = "127.0.0.1:8848"; - setting8.put(PropertyKeyConst.SERVER_ADDR, serverIp8); - setting8.put(PropertyKeyConst.USERNAME, "nacos"); - setting8.put(PropertyKeyConst.PASSWORD, "nacos"); - iconfig8 = NacosFactory.createConfigService(setting8); - inaming8 = NacosFactory.createNamingService(setting7); - - Properties setting9 = new Properties(); - String serverIp9 = "127.0.0.1:8849"; - setting9.put(PropertyKeyConst.SERVER_ADDR, serverIp9); - setting9.put(PropertyKeyConst.USERNAME, "nacos"); - setting9.put(PropertyKeyConst.PASSWORD, "nacos"); - iconfig9 = NacosFactory.createConfigService(setting9); - inaming9 = NacosFactory.createNamingService(setting7); - - TimeUnit.SECONDS.sleep(20L); - } - - @AfterClass - public static void after() throws Exception { - CountDownLatch latch = new CountDownLatch(applications.size()); - for (ConfigurableApplicationContext context : applications.values()) { - new Thread(() -> { - try { - System.out.println("start close : " + context); - context.close(); + + protected static final String CONFIG_INFO_ID = "config-info-id"; + + protected static ConfigService iconfig7; + + protected static ConfigService iconfig8; + + protected static ConfigService iconfig9; + + protected static NamingService inaming7; + + protected static NamingService inaming8; + + protected static NamingService inaming9; + + protected static final NSyncHttpClient httpClient = HttpClientManager.getSyncHttpClient(); + + protected static final AtomicBoolean[] finished = new AtomicBoolean[] {new AtomicBoolean(false), + new AtomicBoolean(false), new AtomicBoolean(false)}; + + protected static Map applications = new HashMap<>(); + + protected static String clusterInfo; + + static { + System.getProperties().setProperty("nacos.core.auth.enabled", "false"); + System.getProperties().setProperty("embeddedStorage", "true"); + String ip = InetUtils.getSelfIp(); + clusterInfo = "nacos.member.list=" + ip + ":8847," + ip + ":8848," + ip + ":8849"; + + NotifyCenter.registerSubscriber(new Subscriber() { + @Override + public void onEvent(RaftDbErrorEvent event) { + System.out.print(event.getEx()); + } + + @Override + public Class subscribeType() { + return RaftDbErrorEvent.class; + } + }); + } + + @BeforeClass + public static void before() throws Exception { + + CountDownLatch latch = new CountDownLatch(3); + + Runnable runnable = () -> { + for (int i = 0; i < 3; i++) { + try { + URL runnerUrl = new File("../console/target/classes").toURI().toURL(); + URL[] urls = new URL[] {runnerUrl}; + URLClassLoader cl = new URLClassLoader(urls); + Class runnerClass = cl.loadClass("com.alibaba.nacos.Nacos"); + run(i, latch, runnerClass); + } catch (Exception e) { + latch.countDown(); + } + } + }; + + new Thread(runnable).start(); + + latch.await(); + + System.out.println("The cluster node initialization is complete"); + + Properties setting7 = new Properties(); + String serverIp7 = "127.0.0.1:8847"; + setting7.put(PropertyKeyConst.SERVER_ADDR, serverIp7); + setting7.put(PropertyKeyConst.USERNAME, "nacos"); + setting7.put(PropertyKeyConst.PASSWORD, "nacos"); + iconfig7 = NacosFactory.createConfigService(setting7); + inaming7 = NacosFactory.createNamingService(setting7); + + Properties setting8 = new Properties(); + String serverIp8 = "127.0.0.1:8848"; + setting8.put(PropertyKeyConst.SERVER_ADDR, serverIp8); + setting8.put(PropertyKeyConst.USERNAME, "nacos"); + setting8.put(PropertyKeyConst.PASSWORD, "nacos"); + iconfig8 = NacosFactory.createConfigService(setting8); + inaming8 = NacosFactory.createNamingService(setting7); + + Properties setting9 = new Properties(); + String serverIp9 = "127.0.0.1:8849"; + setting9.put(PropertyKeyConst.SERVER_ADDR, serverIp9); + setting9.put(PropertyKeyConst.USERNAME, "nacos"); + setting9.put(PropertyKeyConst.PASSWORD, "nacos"); + iconfig9 = NacosFactory.createConfigService(setting9); + inaming9 = NacosFactory.createNamingService(setting7); + + TimeUnit.SECONDS.sleep(20L); + } + + @AfterClass + public static void after() throws Exception { + CountDownLatch latch = new CountDownLatch(applications.size()); + for (ConfigurableApplicationContext context : applications.values()) { + new Thread(() -> { + try { + System.out.println("start close : " + context); + context.close(); iconfig7.shutDown(); iconfig8.shutDown(); iconfig9.shutDown(); - + inaming7.shutDown(); inaming8.shutDown(); inaming9.shutDown(); } catch (Exception ignore) { - } finally { - System.out.println("finished close : " + context); - latch.countDown(); - } - }).start(); - } - latch.await(); - } - - private static void run(final int index, final CountDownLatch latch, final Class cls) { - Runnable runnable = () -> { - try { - ApplicationUtils.setIsStandalone(false); - - final String path = Paths - .get(System.getProperty("user.home"), "/nacos-" + index + "/").toString(); - DiskUtils.deleteDirectory(path); - - System.setProperty("nacos.home", path); - System.out.println("nacos.home is : [" + path + "]"); - - Map properties = new HashMap<>(); - properties.put("server.port", "884" + (7 + index)); - properties.put("nacos.home", path); - properties.put("nacos.logs.path", - Paths.get(System.getProperty("user.home"), "nacos-" + index, "/logs/").toString()); - properties.put("spring.jmx.enabled", false); - properties.put("nacos.core.snowflake.worker-id", index + 1); - MapPropertySource propertySource = new MapPropertySource( - "nacos_cluster_test", properties); - ConfigurableEnvironment environment = new StandardServletEnvironment(); - environment.getPropertySources().addFirst(propertySource); - SpringApplication cluster = new SpringApplicationBuilder(cls).web( - WebApplicationType.SERVLET).environment(environment) - .properties(clusterInfo).properties("embeddedStorage=true") - .build(); - - ConfigurableApplicationContext context = cluster.run(); - - DistributedDatabaseOperateImpl operate = context.getBean(DistributedDatabaseOperateImpl.class); - CPProtocol protocol = context.getBean(CPProtocol.class); - - protocol.protocolMetaData() - .subscribe(operate.group(), MetadataKey.LEADER_META_DATA, - (o, arg) -> { - System.out.println("node : 884" + (7 + index) + "-> select leader is : " + arg); - if (finished[index].compareAndSet(false, true)) { - latch.countDown(); - } - }); - - new Thread(() -> { - try { - Thread.sleep(5000L); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (finished[index].compareAndSet(false, true)) { - latch.countDown(); - } - } - }); - - applications.put(String.valueOf(properties.get("server.port")), context); - } - catch (Throwable e) { - e.printStackTrace(); - } finally { - latch.countDown(); - } - }; - - runnable.run(); - } - + } finally { + System.out.println("finished close : " + context); + latch.countDown(); + } + }).start(); + } + latch.await(); + } + + private static void run(final int index, final CountDownLatch latch, final Class cls) { + Runnable runnable = () -> { + try { + ApplicationUtils.setIsStandalone(false); + + final String path = Paths.get(System.getProperty("user.home"), "/nacos-" + index + "/").toString(); + DiskUtils.deleteDirectory(path); + + System.setProperty("nacos.home", path); + System.out.println("nacos.home is : [" + path + "]"); + + Map properties = new HashMap<>(); + properties.put("server.port", "884" + (7 + index)); + properties.put("nacos.home", path); + properties.put("nacos.logs.path", + Paths.get(System.getProperty("user.home"), "nacos-" + index, "/logs/").toString()); + properties.put("spring.jmx.enabled", false); + properties.put("nacos.core.snowflake.worker-id", index + 1); + MapPropertySource propertySource = new MapPropertySource("nacos_cluster_test", properties); + ConfigurableEnvironment environment = new StandardServletEnvironment(); + environment.getPropertySources().addFirst(propertySource); + SpringApplication cluster = new SpringApplicationBuilder(cls).web(WebApplicationType.SERVLET) + .environment(environment).properties(clusterInfo).properties("embeddedStorage=true").build(); + + ConfigurableApplicationContext context = cluster.run(); + + DistributedDatabaseOperateImpl operate = context.getBean(DistributedDatabaseOperateImpl.class); + CPProtocol protocol = context.getBean(CPProtocol.class); + + protocol.protocolMetaData().subscribe(operate.group(), MetadataKey.LEADER_META_DATA, (o, arg) -> { + System.out.println("node : 884" + (7 + index) + "-> select leader is : " + arg); + if (finished[index].compareAndSet(false, true)) { + latch.countDown(); + } + }); + + new Thread(() -> { + try { + Thread.sleep(5000L); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (finished[index].compareAndSet(false, true)) { + latch.countDown(); + } + } + }); + + applications.put(String.valueOf(properties.get("server.port")), context); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + latch.countDown(); + } + }; + + runnable.run(); + } + } From eca82bff6fa9d08dcf472742e2eaa5e2e4654ef7 Mon Sep 17 00:00:00 2001 From: Joe <1060287354@qq.com> Date: Mon, 13 Jul 2020 10:39:59 +0800 Subject: [PATCH 04/17] Update BeatReactor.java (#3299) update `asInt()` to `asLong()` --- .../java/com/alibaba/nacos/client/naming/beat/BeatReactor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java index 8e6582290..3d405151d 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java @@ -165,7 +165,7 @@ public class BeatReactor implements Closeable { long nextTime = beatInfo.getPeriod(); try { JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled); - long interval = result.get("clientBeatInterval").asInt(); + long interval = result.get("clientBeatInterval").asLong(); boolean lightBeatEnabled = false; if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) { lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean(); From 092a08971fa4da6cf673e2fab52d2c4d7d048ca2 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Mon, 13 Jul 2020 11:34:00 +0800 Subject: [PATCH 05/17] [ISSUE #3210] Enhanced nacos resttemplate response handler (#3212) * Enhanced nacos resttemplate response handler * Enhanced nacos resttemplate response handler * Add license * [#3212] Modify some class name and comment * [#3212] Modify some class name and comment * [#3212] Modify some class name and comment * [#3212] change the name of property * Fix code style issue --- .../nacos/api/exception/NacosException.java | 6 ++ .../common/constant/ResponseHandlerType.java | 32 ++++++++ .../nacos/common/http/HttpRestResult.java | 4 +- .../client/AbstractNacosRestTemplate.java | 76 +++++++++++++++++++ .../http/client/AbstractResponseHandler.java | 64 ++++++++++++++++ .../http/client/AsyncHttpClientRequest.java | 7 +- .../http/client/BeanResponseHandler.java | 41 ++++++++++ .../client/DefaultAsyncHttpClientRequest.java | 6 +- .../http/client/NacosAsyncRestTemplate.java | 9 ++- .../common/http/client/NacosRestTemplate.java | 8 +- .../common/http/client/ResponseHandler.java | 47 ++++++++++++ .../client/RestResultResponseHandler.java | 53 +++++++++++++ .../http/client/StringResponseHandler.java | 38 ++++++++++ .../common/http/handler/ResponseHandler.java | 64 ---------------- .../nacos/common/utils/JacksonUtils.java | 11 +++ .../test/common/NacosRestTemplate_ITCase.java | 8 +- 16 files changed, 393 insertions(+), 81 deletions(-) create mode 100644 common/src/main/java/com/alibaba/nacos/common/constant/ResponseHandlerType.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/AbstractResponseHandler.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/BeanResponseHandler.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/ResponseHandler.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/RestResultResponseHandler.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/StringResponseHandler.java diff --git a/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java b/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java index be9b6af2c..28f0276ef 100644 --- a/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java +++ b/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java @@ -154,4 +154,10 @@ public class NacosException extends Exception { public static final int OVER_THRESHOLD = 503; public static final int RESOURCE_NOT_FOUND = -404; + + /** + * http client error code, + * ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate. + */ + public static final int HTTP_CLIENT_ERROR_CODE = -500; } diff --git a/common/src/main/java/com/alibaba/nacos/common/constant/ResponseHandlerType.java b/common/src/main/java/com/alibaba/nacos/common/constant/ResponseHandlerType.java new file mode 100644 index 000000000..e46a9b881 --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/constant/ResponseHandlerType.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.common.constant; + +/** + * Response Handler Type. + * + * @author mai.jh + */ +public final class ResponseHandlerType { + + public static final String STRING_TYPE = "java.lang.String"; + + public static final String RESTRESULT_TYPE = "com.alibaba.nacos.common.model.RestResult"; + + public static final String DEFAULT_BEAN_TYPE = "default_bean_handler"; + +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpRestResult.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpRestResult.java index 6e2ec75a1..2cf88e114 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/HttpRestResult.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpRestResult.java @@ -33,8 +33,8 @@ public class HttpRestResult extends RestResult { public HttpRestResult() { } - public HttpRestResult(Header header, int code, T data) { - super(code, data); + public HttpRestResult(Header header, int code, T data, String message) { + super(code, message, data); this.header = header; } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java new file mode 100644 index 000000000..5c91f8742 --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java @@ -0,0 +1,76 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.constant.ResponseHandlerType; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.databind.JavaType; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * For NacosRestTemplate and NacosAsyncRestTemplate, provide initialization and register of response converter. + * + * @author mai.jh + */ +public abstract class AbstractNacosRestTemplate { + + private final Map responseHandlerMap = new HashMap(); + + public AbstractNacosRestTemplate() { + // init response handler + responseHandlerMap.put(ResponseHandlerType.STRING_TYPE, new StringResponseHandler()); + responseHandlerMap.put(ResponseHandlerType.RESTRESULT_TYPE, new RestResultResponseHandler()); + responseHandlerMap.put(ResponseHandlerType.DEFAULT_BEAN_TYPE, new BeanResponseHandler()); + } + + /** + * register customization Response Handler. + * + * @param responseHandler {@link ResponseHandler} + */ + public void registerResponseHandler(String responseHandlerType, ResponseHandler responseHandler) { + responseHandlerMap.put(responseHandlerType, responseHandler); + } + + /** + * Select a response handler by responseType. + * + * @param responseType responseType + * @return ResponseHandler + */ + protected ResponseHandler selectResponseHandler(Type responseType) { + ResponseHandler responseHandler = null; + if (responseType == null) { + responseHandler = responseHandlerMap.get(ResponseHandlerType.STRING_TYPE); + } + if (responseHandler == null) { + JavaType javaType = JacksonUtils.constructJavaType(responseType); + String name = javaType.getRawClass().getName(); + responseHandler = responseHandlerMap.get(name); + } + // When the corresponding type of response handler cannot be obtained, + // the default bean response handler is used + if (responseHandler == null) { + responseHandler = responseHandlerMap.get(ResponseHandlerType.DEFAULT_BEAN_TYPE); + } + responseHandler.setResponseType(responseType); + return responseHandler; + } +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractResponseHandler.java new file mode 100644 index 000000000..698ddb915 --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractResponseHandler.java @@ -0,0 +1,64 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.utils.IoUtils; +import org.apache.http.HttpStatus; + +import java.lang.reflect.Type; + +/** + * Abstract response handler. + * + * @author mai.jh + */ +public abstract class AbstractResponseHandler implements ResponseHandler { + + private Type responseType; + + @Override + public final void setResponseType(Type responseType) { + this.responseType = responseType; + } + + @Override + public final HttpRestResult handle(HttpClientResponse response) throws Exception { + if (HttpStatus.SC_OK != response.getStatusCode()) { + return handleError(response); + } + return convertResult(response, this.responseType); + } + + private HttpRestResult handleError(HttpClientResponse response) throws Exception { + Header headers = response.getHeaders(); + String message = IoUtils.toString(response.getBody(), headers.getCharset()); + return new HttpRestResult(headers, response.getStatusCode(), null, message); + } + + /** + * Abstract convertResult method, Different types of converters for expansion. + * + * @param response http client response + * @param responseType responseType + * @return HttpRestResult + * @throws Exception ex + */ + public abstract HttpRestResult convertResult(HttpClientResponse response, Type responseType) throws Exception; + +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/AsyncHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/AsyncHttpClientRequest.java index 4355f5656..3d2b4d93b 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/AsyncHttpClientRequest.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/AsyncHttpClientRequest.java @@ -20,7 +20,6 @@ import com.alibaba.nacos.common.http.Callback; import com.alibaba.nacos.common.model.RequestHttpEntity; import java.io.Closeable; -import java.lang.reflect.Type; import java.net.URI; /** @@ -37,10 +36,10 @@ public interface AsyncHttpClientRequest extends Closeable { * @param uri http url * @param httpMethod http request method * @param requestHttpEntity http request entity - * @param responseType http response type + * @param responseHandler http response handler * @param callback http response callback * @throws Exception ex */ - void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType, - final Callback callback) throws Exception; + void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, + final ResponseHandler responseHandler, final Callback callback) throws Exception; } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/BeanResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/client/BeanResponseHandler.java new file mode 100644 index 000000000..4a667e57d --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/BeanResponseHandler.java @@ -0,0 +1,41 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.utils.JacksonUtils; + +import java.io.InputStream; +import java.lang.reflect.Type; + +/** + * bean response handler, + * Mainly converter response type as bean type. + * + * @author mai.jh + */ +public class BeanResponseHandler extends AbstractResponseHandler { + + @Override + public HttpRestResult convertResult(HttpClientResponse response, Type responseType) throws Exception { + final Header headers = response.getHeaders(); + InputStream body = response.getBody(); + T extractBody = JacksonUtils.toObj(body, responseType); + return new HttpRestResult(headers, response.getStatusCode(), extractBody, null); + } +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultAsyncHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultAsyncHttpClientRequest.java index acae4c1ef..7b5d2f5ed 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultAsyncHttpClientRequest.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultAsyncHttpClientRequest.java @@ -18,7 +18,6 @@ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.http.Callback; import com.alibaba.nacos.common.http.HttpRestResult; -import com.alibaba.nacos.common.http.handler.ResponseHandler; import com.alibaba.nacos.common.model.RequestHttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpRequestBase; @@ -26,7 +25,6 @@ import org.apache.http.concurrent.FutureCallback; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import java.io.IOException; -import java.lang.reflect.Type; import java.net.URI; /** @@ -46,7 +44,7 @@ public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest { } @Override - public void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType, + public void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final ResponseHandler responseHandler, final Callback callback) throws Exception { HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity); asyncClient.execute(httpRequestBase, new FutureCallback() { @@ -54,7 +52,7 @@ public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest { public void completed(HttpResponse result) { DefaultClientHttpResponse response = new DefaultClientHttpResponse(result); try { - HttpRestResult httpRestResult = ResponseHandler.responseEntityExtractor(response, responseType); + HttpRestResult httpRestResult = responseHandler.handle(response); callback.onReceive(httpRestResult); } catch (Exception e) { callback.onError(e); diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java index 38566fac0..3c317f3ce 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java @@ -37,13 +37,14 @@ import java.util.Map; * @see AsyncHttpClientRequest * @see HttpClientResponse */ -public class NacosAsyncRestTemplate { +public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate { private static final Logger LOGGER = LoggerFactory.getLogger(NacosAsyncRestTemplate.class); private AsyncHttpClientRequest clientRequest; public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) { + super(); this.clientRequest = clientRequest; } @@ -330,13 +331,15 @@ public class NacosAsyncRestTemplate { } - private void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType, + @SuppressWarnings("unchecked") + private void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type, Callback callback) throws Exception { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("HTTP " + httpMethod + " " + url); } - clientRequest.execute(uri, httpMethod, requestEntity, responseType, callback); + ResponseHandler responseHandler = super.selectResponseHandler(type); + clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback); } /** diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java index 85b0ffc07..b455050c6 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java @@ -18,7 +18,6 @@ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.HttpUtils; -import com.alibaba.nacos.common.http.handler.ResponseHandler; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.http.param.Query; @@ -38,13 +37,14 @@ import java.util.Map; * @see HttpClientRequest * @see HttpClientResponse */ -public class NacosRestTemplate { +public class NacosRestTemplate extends AbstractNacosRestTemplate { private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class); private HttpClientRequest requestClient; public NacosRestTemplate(HttpClientRequest requestClient) { + super(); this.requestClient = requestClient; } @@ -319,16 +319,18 @@ public class NacosRestTemplate { return execute(url, httpMethod, requestHttpEntity, responseType); } + @SuppressWarnings("unchecked") private HttpRestResult execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType) throws Exception { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("HTTP " + httpMethod + " " + url); } + ResponseHandler responseHandler = super.selectResponseHandler(responseType); HttpClientResponse response = null; try { response = requestClient.execute(uri, httpMethod, requestEntity); - return ResponseHandler.responseEntityExtractor(response, responseType); + return responseHandler.handle(response); } finally { if (response != null) { response.close(); diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/ResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/client/ResponseHandler.java new file mode 100644 index 000000000..8508d1d8c --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/ResponseHandler.java @@ -0,0 +1,47 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.http.HttpRestResult; + +import java.lang.reflect.Type; + +/** + * Response Handler abstract interface, + * the actual processing of the response conversion is done by a concrete implementation class. + * + * @author mai.jh + */ +public interface ResponseHandler { + + /** + * set response type. + * + * @param responseType responseType + */ + void setResponseType(Type responseType); + + /** + * handle response convert to HttpRestResult. + * + * @param response http response + * @return HttpRestResult {@link HttpRestResult} + * @throws Exception ex + */ + HttpRestResult handle(HttpClientResponse response) throws Exception; + +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/RestResultResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/client/RestResultResponseHandler.java new file mode 100644 index 000000000..bb9da540b --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/RestResultResponseHandler.java @@ -0,0 +1,53 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.common.utils.JacksonUtils; + +import java.io.InputStream; +import java.lang.reflect.Type; + +/** + * RestResult response handler, Mainly converter response type as {@link RestResult} type. + * + * @author mai.jh + */ +public class RestResultResponseHandler extends AbstractResponseHandler { + + @Override + @SuppressWarnings("unchecked") + public HttpRestResult convertResult(HttpClientResponse response, Type responseType) throws Exception { + final Header headers = response.getHeaders(); + InputStream body = response.getBody(); + T extractBody = JacksonUtils.toObj(body, responseType); + HttpRestResult httpRestResult = convert((RestResult) extractBody); + httpRestResult.setHeader(headers); + return httpRestResult; + } + + private static HttpRestResult convert(RestResult restResult) { + HttpRestResult httpRestResult = new HttpRestResult(); + httpRestResult.setCode(restResult.getCode()); + httpRestResult.setData(restResult.getData()); + httpRestResult.setMessage(restResult.getMessage()); + return httpRestResult; + } + +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/StringResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/client/StringResponseHandler.java new file mode 100644 index 000000000..ba1020d5a --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/StringResponseHandler.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.common.http.client; + +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.utils.IoUtils; + +import java.lang.reflect.Type; + +/** + * string response handler, Mainly converter response type as string type. + * + * @author mai.jh + */ +public class StringResponseHandler extends AbstractResponseHandler { + + @Override + public HttpRestResult convertResult(HttpClientResponse response, Type responseType) throws Exception { + final Header headers = response.getHeaders(); + String extractBody = IoUtils.toString(response.getBody(), headers.getCharset()); + return new HttpRestResult(headers, response.getStatusCode(), extractBody, null); + } +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/handler/ResponseHandler.java b/common/src/main/java/com/alibaba/nacos/common/http/handler/ResponseHandler.java index 57ad28c4e..2c9a77419 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/handler/ResponseHandler.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/handler/ResponseHandler.java @@ -16,18 +16,7 @@ package com.alibaba.nacos.common.http.handler; -import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException; -import com.alibaba.nacos.common.constant.HttpHeaderConsts; -import com.alibaba.nacos.common.http.HttpRestResult; -import com.alibaba.nacos.common.http.client.HttpClientResponse; -import com.alibaba.nacos.common.http.param.Header; -import com.alibaba.nacos.common.http.param.MediaType; -import com.alibaba.nacos.common.model.RestResult; -import com.alibaba.nacos.common.utils.IoUtils; import com.alibaba.nacos.common.utils.JacksonUtils; -import org.apache.http.HttpStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.InputStream; import java.lang.reflect.Type; @@ -39,8 +28,6 @@ import java.lang.reflect.Type; */ public final class ResponseHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(ResponseHandler.class); - public static T convert(String s, Class cls) throws Exception { return JacksonUtils.toObj(s, cls); } @@ -52,55 +39,4 @@ public final class ResponseHandler { public static T convert(InputStream inputStream, Type type) throws Exception { return JacksonUtils.toObj(inputStream, type); } - - private static HttpRestResult convert(RestResult restResult) { - HttpRestResult httpRestResult = new HttpRestResult(); - httpRestResult.setCode(restResult.getCode()); - httpRestResult.setData(restResult.getData()); - httpRestResult.setMessage(restResult.getMessage()); - return httpRestResult; - } - - /** - * Extract response entity to {@link HttpRestResult}. - * - * @param response response - * @param type type - * @param general type - * @return {@link HttpRestResult} - * @throws Exception exception - */ - @SuppressWarnings({"unchecked", "rawtypes", "resource"}) - public static HttpRestResult responseEntityExtractor(HttpClientResponse response, Type type) - throws Exception { - Header headers = response.getHeaders(); - String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE); - InputStream body = response.getBody(); - T extractBody = null; - final boolean typeToStr = String.class.toString().equals(type.toString()); - if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON) && HttpStatus.SC_OK == response - .getStatusCode()) { - // When the type is string type and the response contentType is [application/json], - // then it should be serialized as string - if (typeToStr) { - extractBody = (T) IoUtils.toString(body, headers.getCharset()); - } else { - extractBody = convert(body, type); - } - } - if (extractBody == null) { - if (!typeToStr) { - LOGGER.error( - "if the response contentType is not [application/json]," + " only support to java.lang.String"); - throw new NacosDeserializationException(type); - } - extractBody = (T) IoUtils.toString(body, headers.getCharset()); - } - if (extractBody instanceof RestResult) { - HttpRestResult httpRestResult = convert((RestResult) extractBody); - httpRestResult.setHeader(headers); - return httpRestResult; - } - return new HttpRestResult(response.getHeaders(), response.getStatusCode(), extractBody); - } } diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java index 845241527..31a3f15bc 100644 --- a/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java +++ b/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.NamedType; @@ -264,4 +265,14 @@ public final class JacksonUtils { public static JsonNode transferToJsonNode(Object obj) { return mapper.valueToTree(obj); } + + /** + * construct java type -> Jackson Java Type. + * + * @param type java type + * @return JavaType {@link JavaType} + */ + public static JavaType constructJavaType(Type type) { + return mapper.constructType(type); + } } 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 296220f3b..72475b8a3 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 @@ -17,12 +17,18 @@ package com.alibaba.nacos.test.common; import com.alibaba.nacos.Nacos; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.config.http.ServerHttpAgent; import com.alibaba.nacos.common.http.HttpClientBeanHolder; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.client.NacosRestTemplate; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.config.server.model.ConfigInfo4Beta; +import com.alibaba.nacos.config.server.utils.JSONUtils; +import com.alibaba.nacos.core.utils.GenericType; +import com.fasterxml.jackson.core.type.TypeReference; import org.junit.Assert; import org.junit.Before; import org.junit.FixMethodOrder; @@ -79,7 +85,7 @@ public class NacosRestTemplate_ITCase { public void test_url_get_return_restResult() throws Exception{ String url = IP + CONFIG_PATH + "/configs"; Query query = Query.newInstance().addParam("beta", true).addParam("dataId","test-1").addParam("group", "DEFAULT_GROUP"); - HttpRestResult restResult = nacosRestTemplate.get(url, Header.newInstance(), query, RestResult.class); + HttpRestResult restResult = nacosRestTemplate.get(url, Header.newInstance(), query, new TypeReference>(){}.getType()); Assert.assertTrue(restResult.ok()); System.out.println(restResult.getData()); System.out.println(restResult.getHeader()); From c1515b6940c0c8277818d46e6b00384635df7d31 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Mon, 13 Jul 2020 13:55:27 +0800 Subject: [PATCH 06/17] [ISSUE #3197] NacosRestTemplate enhance (#3198) * enhance nacosRestTemplate * enhance nacosRestTemplate * supplement throw exception * Modify the iterate method of the interceptor and modify some method name * Adjust the way to get HttpClientRequest implement in NacosRestTempalte * Fix code style issue * Fix code style issue * Fix code style issue * Fix code style issue * Log output change --- .../http/client/DefaultHttpClientRequest.java | 21 ++- .../client/HttpClientRequestInterceptor.java | 47 ++++++ .../client/InterceptingHttpClientRequest.java | 58 ++++++++ .../common/http/client/NacosRestTemplate.java | 138 +++++++++++++++++- .../nacos/common/model/RequestHttpEntity.java | 19 ++- .../common/NacosAsyncRestTemplate_ITCase.java | 1 - .../test/common/NacosRestTemplate_ITCase.java | 1 - ...NacosRestTemplate_Interceptors_ITCase.java | 123 ++++++++++++++++ 8 files changed, 401 insertions(+), 7 deletions(-) create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientRequestInterceptor.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/InterceptingHttpClientRequest.java create mode 100644 test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java index 496167c9c..c31cd5cae 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java @@ -18,9 +18,11 @@ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.constant.HttpHeaderConsts; import com.alibaba.nacos.common.http.BaseHttpMethod; +import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.model.RequestHttpEntity; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; @@ -69,7 +71,24 @@ public class DefaultHttpClientRequest implements HttpClientRequest { } else { httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE)); } - return httpMethod.getRequestBase(); + HttpRequestBase requestBase = httpMethod.getRequestBase(); + replaceDefaultConfig(requestBase, requestHttpEntity.getHttpClientConfig()); + return requestBase; + } + + /** + * Replace the HTTP config created by default with the HTTP config specified in the request. + * + * @param requestBase requestBase + * @param httpClientConfig http config + */ + private static void replaceDefaultConfig(HttpRequestBase requestBase, HttpClientConfig httpClientConfig) { + if (httpClientConfig == null) { + return; + } + requestBase.setConfig(RequestConfig.custom() + .setConnectTimeout(httpClientConfig.getConTimeOutMillis()) + .setSocketTimeout(httpClientConfig.getReadTimeOutMillis()).build()); } @Override diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientRequestInterceptor.java b/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientRequestInterceptor.java new file mode 100644 index 000000000..442221bff --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientRequestInterceptor.java @@ -0,0 +1,47 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.model.RequestHttpEntity; + +import java.net.URI; + +/** + * Intercepts client-side HTTP requests. Implementations of this interface can be. + * + * @author mai.jh + */ +public interface HttpClientRequestInterceptor { + + /** + * is intercept. + * + * @param uri uri + * @param httpMethod http method + * @param requestHttpEntity request entity + * @return boolean + */ + boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity); + + /** + * if isIntercept method is true Intercept the given request, and return a response Otherwise, + * the {@link HttpClientRequest} will be used for execution. + * + * @return HttpClientResponse + */ + HttpClientResponse intercept(); +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/InterceptingHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/InterceptingHttpClientRequest.java new file mode 100644 index 000000000..e612cc2e6 --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/InterceptingHttpClientRequest.java @@ -0,0 +1,58 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.model.RequestHttpEntity; + +import java.io.IOException; +import java.net.URI; +import java.util.Iterator; + +/** + * Wrap http client request and perform corresponding interception. + * + * @author mai.jh + */ +public class InterceptingHttpClientRequest implements HttpClientRequest { + + private final HttpClientRequest httpClientRequest; + + private final Iterator interceptors; + + public InterceptingHttpClientRequest(HttpClientRequest httpClientRequest, + Iterator interceptors) { + this.httpClientRequest = httpClientRequest; + this.interceptors = interceptors; + } + + @Override + public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) + throws Exception { + while (interceptors.hasNext()) { + HttpClientRequestInterceptor nextInterceptor = interceptors.next(); + if (nextInterceptor.isIntercept(uri, httpMethod, requestHttpEntity)) { + return nextInterceptor.intercept(); + } + } + return httpClientRequest.execute(uri, httpMethod, requestHttpEntity); + } + + @Override + public void close() throws IOException { + httpClientRequest.close(); + } +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java index b455050c6..d710eecd0 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java @@ -16,18 +16,22 @@ package com.alibaba.nacos.common.http.client; +import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.HttpUtils; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RequestHttpEntity; +import com.alibaba.nacos.common.utils.CollectionUtils; import com.alibaba.nacos.common.utils.HttpMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Type; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import java.util.Map; /** @@ -41,7 +45,9 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class); - private HttpClientRequest requestClient; + private final HttpClientRequest requestClient; + + private final List interceptors = new ArrayList(); public NacosRestTemplate(HttpClientRequest requestClient) { super(); @@ -83,6 +89,28 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { return execute(url, HttpMethod.GET, requestHttpEntity, responseType); } + /** + * http get URL request params are expanded using the given query {@link Query}. + * + *

{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. + * + *

{@code config} Specify the request config via {@link HttpClientConfig} + * + * @param url url + * @param config http config + * @param header headers + * @param paramValues paramValues + * @param responseType return type + * @return {@link HttpRestResult} + * @throws Exception ex + */ + public HttpRestResult get(String url, HttpClientConfig config, Header header, + Map paramValues, Type responseType) throws Exception { + RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header, + Query.newInstance().initParams(paramValues)); + return execute(url, HttpMethod.GET, requestHttpEntity, responseType); + } + /** * get request, may be pulling a lot of data URL request params are expanded using the given query {@link Query}, * More request parameters can be set via body. @@ -118,6 +146,27 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType); } + /** + * http delete URL request params are expanded using the given query {@link Query}. + * + *

{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. + * + *

{@code config} Specify the request config via {@link HttpClientConfig} + * + * @param url url + * @param config http config + * @param header http header param + * @param paramValues http query param + * @param responseType return type + * @return {@link HttpRestResult} + * @throws Exception ex + */ + public HttpRestResult delete(String url, HttpClientConfig config, Header header, + Map paramValues, Type responseType) throws Exception { + return execute(url, HttpMethod.DELETE, + new RequestHttpEntity(config, header, Query.newInstance().initParams(paramValues)), responseType); + } + /** * http put Create a new resource by PUTting the given body to http request. * @@ -208,6 +257,33 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } + /** + * http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header + * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. + * + *

URL request params are expanded using the given map {@code paramValues}. + * + *

{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. + * + *

{@code config} Specify the request config via {@link HttpClientConfig} + * + * @param url url + * @param config http config + * @param header http header param + * @param paramValues http query param + * @param bodyValues http body param + * @param responseType return type + * @return {@link HttpRestResult} + * @throws Exception ex + */ + public HttpRestResult putForm(String url, HttpClientConfig config, Header header, + Map paramValues, Map bodyValues, Type responseType) throws Exception { + RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, + header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), + Query.newInstance().initParams(paramValues), bodyValues); + return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); + } + /** * http post Create a new resource by POSTing the given object to the http request. * @@ -298,6 +374,33 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } + /** + * http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header + * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. + * + *

URL request params are expanded using the given map {@code paramValues}. + * + *

{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. + * + *

{@code config} Specify the request config via {@link HttpClientConfig} + * + * @param url url + * @param config http config + * @param header http header param + * @param paramValues http query param + * @param bodyValues http body param + * @param responseType return type + * @return {@link HttpRestResult} + * @throws Exception ex + */ + public HttpRestResult postForm(String url, HttpClientConfig config, Header header, + Map paramValues, Map bodyValues, Type responseType) throws Exception { + RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, + header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), + Query.newInstance().initParams(paramValues), bodyValues); + return execute(url, HttpMethod.POST, requestHttpEntity, responseType); + } + /** * Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns * the response as {@link HttpRestResult}. @@ -319,6 +422,27 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { return execute(url, httpMethod, requestHttpEntity, responseType); } + /** + * Set the request interceptors that this accessor should use. + * + * @param interceptors {@link HttpClientRequestInterceptor} + */ + public void setInterceptors(List interceptors) { + if (this.interceptors != interceptors) { + this.interceptors.clear(); + this.interceptors.addAll(interceptors); + } + } + + /** + * Return the request interceptors that this accessor uses. + * + *

The returned {@link List} is active and may get appended to. + */ + public List getInterceptors() { + return interceptors; + } + @SuppressWarnings("unchecked") private HttpRestResult execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType) throws Exception { @@ -329,7 +453,7 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { ResponseHandler responseHandler = super.selectResponseHandler(responseType); HttpClientResponse response = null; try { - response = requestClient.execute(uri, httpMethod, requestEntity); + response = this.requestClient().execute(uri, httpMethod, requestEntity); return responseHandler.handle(response); } finally { if (response != null) { @@ -338,6 +462,16 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { } } + private HttpClientRequest requestClient() { + if (CollectionUtils.isNotEmpty(interceptors)) { + if (LOGGER.isDebugEnabled()) { + LOGGER.info("Execute via interceptors :{}", interceptors); + } + return new InterceptingHttpClientRequest(requestClient, interceptors.iterator()); + } + return requestClient; + } + /** * close request client. */ diff --git a/common/src/main/java/com/alibaba/nacos/common/model/RequestHttpEntity.java b/common/src/main/java/com/alibaba/nacos/common/model/RequestHttpEntity.java index 94c9c2617..a403694f5 100644 --- a/common/src/main/java/com/alibaba/nacos/common/model/RequestHttpEntity.java +++ b/common/src/main/java/com/alibaba/nacos/common/model/RequestHttpEntity.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.model; +import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; @@ -31,17 +32,27 @@ public class RequestHttpEntity { private final Header headers = Header.newInstance(); + private final HttpClientConfig httpClientConfig; + private final Query query; private Object body; public RequestHttpEntity(Header header, Query query) { - handleHeader(header); - this.query = query; + this(null, header, query); + } + + public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query) { + this(httpClientConfig, header, query, null); } public RequestHttpEntity(Header header, Query query, Object body) { + this(null, header, query, body); + } + + public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query, Object body) { handleHeader(header); + this.httpClientConfig = httpClientConfig; this.query = query; this.body = body; } @@ -65,6 +76,10 @@ public class RequestHttpEntity { return body; } + public HttpClientConfig getHttpClientConfig() { + return httpClientConfig; + } + public boolean isEmptyBody() { return body == null; } 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 307927e6d..2e301ef6c 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 @@ -41,7 +41,6 @@ import java.util.Map; * NacosAsyncRestTemplate_ITCase * * @author mai.jh - * @date 2020/5/29 */ @SuppressWarnings("all") @FixMethodOrder(MethodSorters.JVM) 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 72475b8a3..2c7720fcc 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 @@ -46,7 +46,6 @@ import java.util.Map; * NacosRestTemplate_ITCase * * @author mai.jh - * @date 2020/5/30 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, 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 new file mode 100644 index 000000000..14a96dccf --- /dev/null +++ b/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java @@ -0,0 +1,123 @@ +/* + * 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.common; + +import com.alibaba.nacos.Nacos; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.common.http.HttpClientBeanHolder; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.HttpClientRequestInterceptor; +import com.alibaba.nacos.common.http.client.HttpClientResponse; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.http.param.Query; +import com.alibaba.nacos.common.model.RequestHttpEntity; +import org.junit.Assert; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * NacosRestTemplate_Interceptors_ITCase + * + * @author mai.jh + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@FixMethodOrder(MethodSorters.JVM) +public class NacosRestTemplate_Interceptors_ITCase { + + @LocalServerPort + private int port; + + private NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder.getNacosRestTemplate(); + + private final String CONFIG_PATH = "/nacos/v1/cs"; + private String IP = null; + + private class TerminationInterceptor implements HttpClientRequestInterceptor { + + @Override + public HttpClientResponse intercept() { + return new HttpClientResponse() { + @Override + public Header getHeaders() { + return Header.EMPTY; + } + + @Override + public InputStream getBody() throws IOException { + return new ByteArrayInputStream("Stop request".getBytes()); + } + + @Override + public int getStatusCode() { + return NacosException.SERVER_ERROR; + } + + @Override + public String getStatusText() { + return null; + } + + @Override + public void close() throws IOException { + + } + }; + } + + @Override + public boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) { + return true; + } + + } + + @Before + public void init() throws NacosException { + nacosRestTemplate.setInterceptors(Arrays.asList(new TerminationInterceptor())); + IP = String.format("http://localhost:%d", port); + } + + @Test + public void test_url_post_config() throws Exception { + String url = IP + CONFIG_PATH + "/configs"; + Map param = new HashMap<>(); + param.put("dataId", "test-1"); + param.put("group", "DEFAULT_GROUP"); + param.put("content", "aaa=b"); + HttpRestResult restResult = nacosRestTemplate.postForm(url, Header.newInstance(), Query.EMPTY, param, String.class); + Assert.assertEquals(500, restResult.getCode()); + Assert.assertEquals("Stop request", restResult.getData()); + System.out.println(restResult.getData()); + System.out.println(restResult.getHeader()); + } +} From 665d9d7aaf41c5653e6926a71c02e90f684b172e Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Mon, 13 Jul 2020 13:59:25 +0800 Subject: [PATCH 07/17] [ISSUE#3179]Replace the NotifyCenter with new refactor in the core and test module. (#3309) * [ISSUE#3179]Replace the NotifyCenter with new refactor in the core and test module. * [ISSUE#3179]Replace package in the nacos-logback.xml. * [ISSUE#3179]code reformat. --- .../nacos/common/notify/NotifyCenter.java | 4 +--- .../nacos/core/cluster/MemberChangeListener.java | 11 ++++++----- .../nacos/core/cluster/MembersChangeEvent.java | 16 +++------------- .../nacos/core/cluster/ServerMemberManager.java | 8 ++++---- .../StartingSpringApplicationRunListener.java | 2 +- .../nacos/core/distributed/ProtocolManager.java | 6 +++--- .../core/distributed/raft/JRaftProtocol.java | 8 ++++---- .../core/distributed/raft/NacosStateMachine.java | 2 +- .../core/distributed/raft/RaftErrorEvent.java | 4 ++-- .../nacos/core/distributed/raft/RaftEvent.java | 4 ++-- .../com/alibaba/nacos/core/utils/InetUtils.java | 6 +++--- .../main/resources/META-INF/logback/nacos.xml | 2 +- distribution/conf/nacos-logback.xml | 2 +- .../nacos/naming/cluster/ServerListManager.java | 6 +++--- .../consistency/persistent/raft/RaftPeerSet.java | 6 +++--- .../alibaba/nacos/naming/core/DistroMapper.java | 6 +++--- .../nacos/test/core/InetUtils_ITCase.java | 10 +++++----- .../core/cluster/ServerMemberManager_ITCase.java | 10 +++++----- 18 files changed, 51 insertions(+), 62 deletions(-) diff --git a/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java b/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java index b3b58bc6a..1798203cf 100644 --- a/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java +++ b/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java @@ -16,7 +16,6 @@ package com.alibaba.nacos.common.notify; -import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; import com.alibaba.nacos.common.JustForTest; import com.alibaba.nacos.common.notify.listener.Subscriber; @@ -310,8 +309,7 @@ public class NotifyCenter { * @param eventType class Instances type of the event type. * @param queueMaxSize the publisher's queue max size. */ - public static EventPublisher registerToPublisher(final Class eventType, final int queueMaxSize) - throws NacosException { + public static EventPublisher registerToPublisher(final Class eventType, final int queueMaxSize) { if (ClassUtils.isAssignableFrom(SlowEvent.class, eventType)) { return INSTANCE.sharePublisher; } diff --git a/core/src/main/java/com/alibaba/nacos/core/cluster/MemberChangeListener.java b/core/src/main/java/com/alibaba/nacos/core/cluster/MemberChangeListener.java index 46b114d82..25b7192ca 100644 --- a/core/src/main/java/com/alibaba/nacos/core/cluster/MemberChangeListener.java +++ b/core/src/main/java/com/alibaba/nacos/core/cluster/MemberChangeListener.java @@ -16,15 +16,16 @@ package com.alibaba.nacos.core.cluster; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.listener.Subscriber; /** * Node change listeners. * * @author liaochuntao */ -public interface MemberChangeListener extends Subscribe { +@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") +public abstract class MemberChangeListener extends Subscriber { /** * return NodeChangeEvent.class info. @@ -32,7 +33,7 @@ public interface MemberChangeListener extends Subscribe { * @return {@link MembersChangeEvent#getClass()} */ @Override - default Class subscribeType() { + public Class subscribeType() { return MembersChangeEvent.class; } @@ -42,7 +43,7 @@ public interface MemberChangeListener extends Subscribe { * @return default value is {@link Boolean#TRUE} */ @Override - default boolean ignoreExpireEvent() { + public boolean ignoreExpireEvent() { return true; } } diff --git a/core/src/main/java/com/alibaba/nacos/core/cluster/MembersChangeEvent.java b/core/src/main/java/com/alibaba/nacos/core/cluster/MembersChangeEvent.java index ffc0d69e8..7d8ac4d47 100644 --- a/core/src/main/java/com/alibaba/nacos/core/cluster/MembersChangeEvent.java +++ b/core/src/main/java/com/alibaba/nacos/core/cluster/MembersChangeEvent.java @@ -16,10 +16,9 @@ package com.alibaba.nacos.core.cluster; -import com.alibaba.nacos.core.notify.Event; +import com.alibaba.nacos.common.notify.Event; import java.util.Collection; -import java.util.concurrent.atomic.AtomicLong; /** * Publish this event when the node list changes,All interested in the node list change event can listen to this event. @@ -32,16 +31,12 @@ import java.util.concurrent.atomic.AtomicLong; * * @author liaochuntao */ -public class MembersChangeEvent implements Event { - - private static final AtomicLong SEQUENCE = new AtomicLong(0); +public class MembersChangeEvent extends Event { private static final long serialVersionUID = 7308126651076668976L; private Collection members; - private long no = SEQUENCE.getAndIncrement(); - public static MemberChangeEventBuilder builder() { return new MemberChangeEventBuilder(); } @@ -54,14 +49,9 @@ public class MembersChangeEvent implements Event { this.members = members; } - @Override - public long sequence() { - return no; - } - @Override public String toString() { - return "MembersChangeEvent{" + "members=" + members + ", no=" + no + '}'; + return "MembersChangeEvent{" + "members=" + members + ", no=" + sequence() + '}'; } public static final class MemberChangeEventBuilder { 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 de6d8e443..f77c0a8b3 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 @@ -25,13 +25,13 @@ import com.alibaba.nacos.common.http.NAsyncHttpClient; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.ConcurrentHashSet; import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.VersionUtils; import com.alibaba.nacos.core.cluster.lookup.LookupFactory; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.Commons; import com.alibaba.nacos.core.utils.Constants; @@ -166,7 +166,7 @@ public class ServerMemberManager implements ApplicationListener() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(InetUtils.IPChangeEvent event) { String newAddress = event.getNewIp() + ":" + port; diff --git a/core/src/main/java/com/alibaba/nacos/core/code/StartingSpringApplicationRunListener.java b/core/src/main/java/com/alibaba/nacos/core/code/StartingSpringApplicationRunListener.java index 19a30dd73..0b8c69777 100644 --- a/core/src/main/java/com/alibaba/nacos/core/code/StartingSpringApplicationRunListener.java +++ b/core/src/main/java/com/alibaba/nacos/core/code/StartingSpringApplicationRunListener.java @@ -20,8 +20,8 @@ import com.alibaba.nacos.common.executor.ExecutorFactory; import com.alibaba.nacos.common.executor.NameThreadFactory; import com.alibaba.nacos.common.executor.ThreadPoolManager; import com.alibaba.nacos.common.http.HttpClientManager; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.file.WatchFileCenter; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.DiskUtils; import com.alibaba.nacos.core.utils.InetUtils; diff --git a/core/src/main/java/com/alibaba/nacos/core/distributed/ProtocolManager.java b/core/src/main/java/com/alibaba/nacos/core/distributed/ProtocolManager.java index 0469abacf..bf2729027 100644 --- a/core/src/main/java/com/alibaba/nacos/core/distributed/ProtocolManager.java +++ b/core/src/main/java/com/alibaba/nacos/core/distributed/ProtocolManager.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.core.distributed; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.consistency.Config; import com.alibaba.nacos.consistency.ap.APProtocol; import com.alibaba.nacos.consistency.cp.CPProtocol; @@ -25,7 +26,6 @@ import com.alibaba.nacos.core.cluster.MemberChangeListener; import com.alibaba.nacos.core.cluster.MemberMetaDataConstants; import com.alibaba.nacos.core.cluster.MemberUtils; import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.ClassUtils; import org.springframework.beans.factory.DisposableBean; @@ -49,7 +49,7 @@ import java.util.Set; @SuppressWarnings("all") @Component(value = "ProtocolManager") @DependsOn("serverMemberManager") -public class ProtocolManager implements ApplicationListener, DisposableBean, MemberChangeListener { +public class ProtocolManager extends MemberChangeListener implements ApplicationListener, DisposableBean { private CPProtocol cpProtocol; @@ -85,7 +85,7 @@ public class ProtocolManager implements ApplicationListener @PostConstruct public void init() { this.memberManager = memberManager; - NotifyCenter.registerSubscribe(this); + NotifyCenter.registerSubscriber(this); } public CPProtocol getCpProtocol() { diff --git a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/JRaftProtocol.java b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/JRaftProtocol.java index bc02daa03..b137b3473 100644 --- a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/JRaftProtocol.java +++ b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/JRaftProtocol.java @@ -17,6 +17,9 @@ package com.alibaba.nacos.core.distributed.raft; import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; +import com.alibaba.nacos.common.notify.Event; import com.alibaba.nacos.common.utils.MapUtils; import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.consistency.ProtocolMetaData; @@ -32,9 +35,6 @@ import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.distributed.AbstractConsistencyProtocol; import com.alibaba.nacos.core.distributed.raft.exception.NoSuchRaftGroupException; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; import com.alibaba.nacos.core.utils.Loggers; import com.alipay.sofa.jraft.Node; @@ -123,7 +123,7 @@ public class JRaftProtocol extends AbstractConsistencyProtocol() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(RaftEvent event) { Loggers.RAFT.info("This Raft event changes : {}", event); diff --git a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/NacosStateMachine.java b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/NacosStateMachine.java index 2651b7597..5ced1dbe8 100644 --- a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/NacosStateMachine.java +++ b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/NacosStateMachine.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.core.distributed.raft; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.LoggerUtils; @@ -30,7 +31,6 @@ import com.alibaba.nacos.consistency.snapshot.Reader; import com.alibaba.nacos.consistency.snapshot.SnapshotOperation; import com.alibaba.nacos.consistency.snapshot.Writer; import com.alibaba.nacos.core.distributed.raft.utils.JRaftUtils; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.Loggers; import com.alipay.sofa.jraft.Closure; import com.alipay.sofa.jraft.Iterator; diff --git a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftErrorEvent.java b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftErrorEvent.java index 40cfbf94a..ba6bbc693 100644 --- a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftErrorEvent.java +++ b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftErrorEvent.java @@ -16,7 +16,7 @@ package com.alibaba.nacos.core.distributed.raft; -import com.alibaba.nacos.core.notify.Event; +import com.alibaba.nacos.common.notify.Event; /** * The RAFT protocol runs an exception event. If this event is published, it means that the current raft Group cannot @@ -24,7 +24,7 @@ import com.alibaba.nacos.core.notify.Event; * * @author liaochuntao */ -public class RaftErrorEvent implements Event { +public class RaftErrorEvent extends Event { private static final long serialVersionUID = 3016514657754158167L; diff --git a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftEvent.java b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftEvent.java index b2fcc3b41..5281ef87b 100644 --- a/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftEvent.java +++ b/core/src/main/java/com/alibaba/nacos/core/distributed/raft/RaftEvent.java @@ -16,7 +16,7 @@ package com.alibaba.nacos.core.distributed.raft; -import com.alibaba.nacos.core.notify.SlowEvent; +import com.alibaba.nacos.common.notify.SlowEvent; import java.util.Collections; import java.util.List; @@ -27,7 +27,7 @@ import java.util.List; * @author liaochuntao */ @SuppressWarnings("all") -public class RaftEvent implements SlowEvent { +public class RaftEvent extends SlowEvent { private static final long serialVersionUID = -4304258594602886451L; diff --git a/core/src/main/java/com/alibaba/nacos/core/utils/InetUtils.java b/core/src/main/java/com/alibaba/nacos/core/utils/InetUtils.java index fa4bccd1c..06574caac 100644 --- a/core/src/main/java/com/alibaba/nacos/core/utils/InetUtils.java +++ b/core/src/main/java/com/alibaba/nacos/core/utils/InetUtils.java @@ -16,8 +16,8 @@ package com.alibaba.nacos.core.utils; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.SlowEvent; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.SlowEvent; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -229,7 +229,7 @@ public class InetUtils { * {@link com.alibaba.nacos.core.cluster.ServerMemberManager} is listener. */ @SuppressWarnings({"PMD.ClassNamingShouldBeCamelRule", "checkstyle:AbbreviationAsWordInName"}) - public static class IPChangeEvent implements SlowEvent { + public static class IPChangeEvent extends SlowEvent { private String oldIp; diff --git a/core/src/main/resources/META-INF/logback/nacos.xml b/core/src/main/resources/META-INF/logback/nacos.xml index 9ccd4b68d..9bbbf7aec 100644 --- a/core/src/main/resources/META-INF/logback/nacos.xml +++ b/core/src/main/resources/META-INF/logback/nacos.xml @@ -200,7 +200,7 @@ - + diff --git a/distribution/conf/nacos-logback.xml b/distribution/conf/nacos-logback.xml index b3b4fa772..3779fbc66 100644 --- a/distribution/conf/nacos-logback.xml +++ b/distribution/conf/nacos-logback.xml @@ -619,7 +619,7 @@ - + diff --git a/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerListManager.java b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerListManager.java index 86731038c..5fe4fe38c 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerListManager.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerListManager.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.naming.cluster; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.MembersChangeEvent; @@ -23,7 +24,6 @@ import com.alibaba.nacos.core.cluster.MemberChangeListener; import com.alibaba.nacos.core.cluster.MemberMetaDataConstants; import com.alibaba.nacos.core.cluster.NodeState; import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer; import com.alibaba.nacos.naming.misc.GlobalExecutor; @@ -54,7 +54,7 @@ import java.util.Optional; * @deprecated 1.3.0 This object will be deleted sometime after version 1.3.0 */ @Component("serverListManager") -public class ServerListManager implements MemberChangeListener { +public class ServerListManager extends MemberChangeListener { private static final String LOCALHOST_SITE = UtilsAndCommons.UNKNOWN_SITE; @@ -69,7 +69,7 @@ public class ServerListManager implements MemberChangeListener { public ServerListManager(final SwitchDomain switchDomain, final ServerMemberManager memberManager) { this.switchDomain = switchDomain; this.memberManager = memberManager; - NotifyCenter.registerSubscribe(this); + NotifyCenter.registerSubscriber(this); this.servers = new ArrayList<>(memberManager.allMembers()); } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftPeerSet.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftPeerSet.java index b32eaee7e..68c4b7945 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftPeerSet.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftPeerSet.java @@ -16,12 +16,12 @@ package com.alibaba.nacos.naming.consistency.persistent.raft; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.MemberChangeListener; import com.alibaba.nacos.core.cluster.MembersChangeEvent; import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.naming.misc.HttpClient; import com.alibaba.nacos.naming.misc.Loggers; @@ -53,7 +53,7 @@ import java.util.concurrent.atomic.AtomicLong; */ @Component @DependsOn("ProtocolManager") -public class RaftPeerSet implements MemberChangeListener { +public class RaftPeerSet extends MemberChangeListener { private final ServerMemberManager memberManager; @@ -75,7 +75,7 @@ public class RaftPeerSet implements MemberChangeListener { @PostConstruct public void init() { - NotifyCenter.registerSubscribe(this); + NotifyCenter.registerSubscriber(this); changePeers(memberManager.allMembers()); } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/core/DistroMapper.java b/naming/src/main/java/com/alibaba/nacos/naming/core/DistroMapper.java index 68cf7f05d..b5ec07095 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/core/DistroMapper.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/core/DistroMapper.java @@ -16,12 +16,12 @@ package com.alibaba.nacos.naming.core; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.core.cluster.MemberChangeListener; import com.alibaba.nacos.core.cluster.MemberUtils; import com.alibaba.nacos.core.cluster.MembersChangeEvent; import com.alibaba.nacos.core.cluster.NodeState; import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.core.notify.NotifyCenter; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.SwitchDomain; @@ -40,7 +40,7 @@ import java.util.List; * @author nkorange */ @Component("distroMapper") -public class DistroMapper implements MemberChangeListener { +public class DistroMapper extends MemberChangeListener { /** * List of service nodes, you must ensure that the order of healthyList is the same for all nodes. @@ -65,7 +65,7 @@ public class DistroMapper implements MemberChangeListener { */ @PostConstruct public void init() { - NotifyCenter.registerSubscribe(this); + NotifyCenter.registerSubscriber(this); this.healthyList = MemberUtils.simpleMembers(memberManager.allMembers()); } diff --git a/test/src/test/java/com/alibaba/nacos/test/core/InetUtils_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/InetUtils_ITCase.java index 48eeab2e6..1b219072b 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/InetUtils_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/InetUtils_ITCase.java @@ -16,9 +16,9 @@ package com.alibaba.nacos.test.core; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.utils.InetUtils; import org.junit.Assert; import org.junit.Test; @@ -49,7 +49,7 @@ public class InetUtils_ITCase { AtomicReference reference = new AtomicReference<>(null); - Subscribe subscribe = new Subscribe() { + Subscriber subscribe = new Subscriber() { @Override public void onEvent(InetUtils.IPChangeEvent event) { if (Objects.nonNull(event.getOldIp())) { @@ -69,7 +69,7 @@ public class InetUtils_ITCase { } }; - NotifyCenter.registerSubscribe(subscribe); + NotifyCenter.registerSubscriber(subscribe); latch.await(10_000L, TimeUnit.MILLISECONDS); Assert.assertEquals(testIp, reference.get()); diff --git a/test/src/test/java/com/alibaba/nacos/test/core/cluster/ServerMemberManager_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/cluster/ServerMemberManager_ITCase.java index b84fd6ce5..9579c742e 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/cluster/ServerMemberManager_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/cluster/ServerMemberManager_ITCase.java @@ -16,14 +16,14 @@ package com.alibaba.nacos.test.core.cluster; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.MembersChangeEvent; import com.alibaba.nacos.core.cluster.MemberUtils; import com.alibaba.nacos.core.cluster.NodeState; import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.core.notify.Event; -import com.alibaba.nacos.core.notify.NotifyCenter; -import com.alibaba.nacos.core.notify.listener.Subscribe; import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.Constants; import org.junit.After; @@ -108,7 +108,7 @@ public class ServerMemberManager_ITCase { AtomicInteger integer = new AtomicInteger(0); CountDownLatch latch = new CountDownLatch(1); - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(MembersChangeEvent event) { integer.incrementAndGet(); @@ -141,7 +141,7 @@ public class ServerMemberManager_ITCase { AtomicReference> healthMembers = new AtomicReference<>(); CountDownLatch first = new CountDownLatch(1); CountDownLatch second = new CountDownLatch(1); - NotifyCenter.registerSubscribe(new Subscribe() { + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(MembersChangeEvent event) { System.out.println(event); From 3a4e21b60ea4e2008b3244e88715513b87523800 Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Mon, 13 Jul 2020 17:30:50 +0800 Subject: [PATCH 08/17] [ISSUE#3179]Remove original NotifyCenter codes in the core module. (#3310) --- .../nacos/core/notify/DefaultPublisher.java | 211 ------------- .../com/alibaba/nacos/core/notify/Event.java | 37 --- .../nacos/core/notify/EventPublisher.java | 86 ------ .../nacos/core/notify/NotifyCenter.java | 280 ------------------ .../alibaba/nacos/core/notify/SlowEvent.java | 26 -- .../core/notify/listener/SmartSubscribe.java | 46 --- .../nacos/core/notify/listener/Subscribe.java | 62 ---- 7 files changed, 748 deletions(-) delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/DefaultPublisher.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/Event.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/EventPublisher.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/NotifyCenter.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/SlowEvent.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/listener/SmartSubscribe.java delete mode 100644 core/src/main/java/com/alibaba/nacos/core/notify/listener/Subscribe.java diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/DefaultPublisher.java b/core/src/main/java/com/alibaba/nacos/core/notify/DefaultPublisher.java deleted file mode 100644 index 66e3bea29..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/DefaultPublisher.java +++ /dev/null @@ -1,211 +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.core.notify; - -import com.alibaba.nacos.common.utils.ConcurrentHashSet; -import com.alibaba.nacos.common.utils.ThreadUtils; -import com.alibaba.nacos.core.notify.listener.SmartSubscribe; -import com.alibaba.nacos.core.notify.listener.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Objects; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -import static com.alibaba.nacos.core.notify.NotifyCenter.RING_BUFFER_SIZE; - -/** - * The default event publisher implementation. Internally, use {@link ArrayBlockingQueue} as a message staging queue - * - * @author liaochuntao - */ -public class DefaultPublisher extends Thread implements EventPublisher { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotifyCenter.class); - - private final ConcurrentHashSet subscribes = new ConcurrentHashSet<>(); - - private final AtomicReferenceFieldUpdater updater = AtomicReferenceFieldUpdater - .newUpdater(DefaultPublisher.class, Long.class, "lastEventSequence"); - - private volatile boolean initialized = false; - - private volatile boolean canOpen = false; - - private volatile boolean shutdown = false; - - private Class eventType; - - private int queueMaxSize = -1; - - private BlockingQueue queue; - - private volatile Long lastEventSequence = -1L; - - @Override - public void init(Class type, int bufferSize) { - setDaemon(true); - setName("nacos.publisher-" + type.getName()); - this.eventType = type; - this.queueMaxSize = bufferSize; - this.queue = new ArrayBlockingQueue<>(bufferSize); - start(); - } - - public ConcurrentHashSet getSubscribes() { - return subscribes; - } - - @Override - public synchronized void start() { - super.start(); - if (!initialized) { - if (queueMaxSize == -1) { - queueMaxSize = RING_BUFFER_SIZE; - } - initialized = true; - } - } - - @Override - public long currentEventSize() { - return queue.size(); - } - - @Override - public void run() { - openEventHandler(); - } - - void openEventHandler() { - try { - int waitTimes = 60; - // To ensure that messages are not lost, enable EventHandler when - // waiting for the first Subscriber to register - for (; ; ) { - if (shutdown || canOpen || waitTimes <= 0) { - break; - } - ThreadUtils.sleep(1_000L); - waitTimes--; - } - - for (; ; ) { - if (shutdown) { - break; - } - final Event event = queue.take(); - receiveEvent(event); - updater.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence())); - } - } catch (Throwable ex) { - LOGGER.error("Event listener exception : {}", ex); - } - } - - @Override - public void addSubscribe(Subscribe subscribe) { - subscribes.add(subscribe); - canOpen = true; - } - - @Override - public void unSubscribe(Subscribe subscribe) { - subscribes.remove(subscribe); - } - - @Override - public boolean publish(Event event) { - checkIsStart(); - boolean success = this.queue.offer(event); - if (!success) { - LOGGER.warn("Unable to plug in due to interruption, synchronize sending time, event : {}", event); - receiveEvent(event); - return true; - } - return true; - } - - void checkIsStart() { - if (!initialized) { - throw new IllegalStateException("Publisher does not start"); - } - } - - @Override - public void shutdown() { - this.shutdown = true; - this.queue.clear(); - } - - public boolean isInitialized() { - return initialized; - } - - void receiveEvent(Event event) { - final long currentEventSequence = event.sequence(); - final String sourceName = event.getClass().getName(); - - // Notification single event listener - for (Subscribe subscribe : subscribes) { - // Whether to ignore expiration events - if (subscribe.ignoreExpireEvent() && lastEventSequence > currentEventSequence) { - LOGGER.debug("[NotifyCenter] the {} is unacceptable to this subscriber, because had expire", - event.getClass()); - continue; - } - - final String targetName = subscribe.subscribeType().getName(); - if (!Objects.equals(sourceName, targetName)) { - continue; - } - - notifySubscriber(subscribe, event); - } - - // Notification multi-event event listener - for (SmartSubscribe subscribe : SMART_SUBSCRIBES) { - // If you are a multi-event listener, you need to make additional logical judgments - if (!subscribe.canNotify(event)) { - LOGGER.debug("[NotifyCenter] the {} is unacceptable to this multi-event subscriber", event.getClass()); - continue; - } - notifySubscriber(subscribe, event); - } - } - - @Override - public void notifySubscriber(final Subscribe subscribe, final Event event) { - - LOGGER.debug("[NotifyCenter] the {} will received by {}", event, subscribe); - - final Runnable job = () -> subscribe.onEvent(event); - final Executor executor = subscribe.executor(); - if (Objects.nonNull(executor)) { - executor.execute(job); - } else { - try { - job.run(); - } catch (Throwable e) { - LOGGER.error("Event callback exception : {}", e); - } - } - } -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/Event.java b/core/src/main/java/com/alibaba/nacos/core/notify/Event.java deleted file mode 100644 index 53ada3634..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/Event.java +++ /dev/null @@ -1,37 +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.core.notify; - -import java.io.Serializable; - -/** - * event. - * - * @author liaochuntao - */ -public interface Event extends Serializable { - - /** - * Event sequence number, which can be used to handle the sequence of events. - * - * @return sequence num, It's best to make sure it's monotone - */ - default long sequence() { - return System.currentTimeMillis(); - } - -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/EventPublisher.java b/core/src/main/java/com/alibaba/nacos/core/notify/EventPublisher.java deleted file mode 100644 index 7b181c1c0..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/EventPublisher.java +++ /dev/null @@ -1,86 +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.core.notify; - -import com.alibaba.nacos.common.utils.ConcurrentHashSet; -import com.alibaba.nacos.core.notify.listener.SmartSubscribe; -import com.alibaba.nacos.core.notify.listener.Subscribe; - -import java.util.Set; - -/** - * Event publisher. - * - * @author liaochuntao - */ -public interface EventPublisher { - - /** - * Multi-event listener collection list. - */ - Set SMART_SUBSCRIBES = new ConcurrentHashSet<>(); - - /** - * Initializes the event publisher. - * - * @param type {@link Class} - * @param bufferSize Message staging queue size - */ - void init(Class type, int bufferSize); - - /** - * The number of currently staged events. - * - * @return event size - */ - long currentEventSize(); - - /** - * Add listener. - * - * @param subscribe {@link Subscribe} - */ - void addSubscribe(Subscribe subscribe); - - /** - * Remove listener. - * - * @param subscribe {@link Subscribe} - */ - void unSubscribe(Subscribe subscribe); - - /** - * publish event. - * - * @param event {@link Event} - * @return publish event is success - */ - boolean publish(Event event); - - /** - * Notify listener. - * - * @param subscribe {@link Subscribe} - * @param event {@link Event} - */ - void notifySubscriber(Subscribe subscribe, Event event); - - /** - * shutdown this publisher. - */ - void shutdown(); -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/NotifyCenter.java b/core/src/main/java/com/alibaba/nacos/core/notify/NotifyCenter.java deleted file mode 100644 index 2ca5a2c24..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/NotifyCenter.java +++ /dev/null @@ -1,280 +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.core.notify; - -import com.alibaba.nacos.common.JustForTest; -import com.alibaba.nacos.common.utils.ConcurrentHashSet; -import com.alibaba.nacos.common.utils.ThreadUtils; -import com.alibaba.nacos.core.notify.listener.SmartSubscribe; -import com.alibaba.nacos.core.notify.listener.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; - -/** - * notify center. - * - * @author liaochuntao - */ -@SuppressWarnings("all") -public class NotifyCenter { - - private static final Logger LOGGER = LoggerFactory.getLogger(NotifyCenter.class); - - private static final AtomicBoolean CLOSED = new AtomicBoolean(false); - - private static final NotifyCenter INSTANCE = new NotifyCenter(); - - private static final AtomicBoolean closed = new AtomicBoolean(false); - - public static int RING_BUFFER_SIZE = 16384; - - public static int SHATE_BUFFER_SIZE = 1024; - - private static BiFunction, Integer, EventPublisher> BUILD_FACTORY = null; - - static { - // Internal ArrayBlockingQueue buffer size. For applications with high write throughput, - // this value needs to be increased appropriately. default value is 16384 - String ringBufferSizeProperty = "nacos.core.notify.ring-buffer-size"; - RING_BUFFER_SIZE = Integer.getInteger(ringBufferSizeProperty, 16384); - - // The size of the public publisher's message staging queue buffer - String shareBufferSizeProperty = "nacos.core.notify.share-buffer-size"; - SHATE_BUFFER_SIZE = Integer.getInteger(shareBufferSizeProperty, 1024); - - ServiceLoader loader = ServiceLoader.load(EventPublisher.class); - Iterator iterator = loader.iterator(); - - if (iterator.hasNext()) { - BUILD_FACTORY = (cls, buffer) -> { - loader.reload(); - EventPublisher publisher = ServiceLoader.load(EventPublisher.class).iterator().next(); - publisher.init(cls, buffer); - return publisher; - }; - } else { - BUILD_FACTORY = (cls, buffer) -> { - EventPublisher publisher = new DefaultPublisher(); - publisher.init(cls, buffer); - return publisher; - }; - } - - INSTANCE.sharePublisher = BUILD_FACTORY.apply(SlowEvent.class, SHATE_BUFFER_SIZE); - ThreadUtils.addShutdownHook(new Thread(() -> { - shutdown(); - })); - - } - - /** - * Publisher management container - */ - private final Map publisherMap = new ConcurrentHashMap<>(16); - - /** - * Multi-event listening list - */ - private final Set smartSubscribes = new ConcurrentHashSet<>(); - - private EventPublisher sharePublisher; - - @JustForTest - public static Map getPublisherMap() { - return INSTANCE.publisherMap; - } - - @JustForTest - public static EventPublisher getPublisher(Class topic) { - if (SlowEvent.class.isAssignableFrom(topic)) { - return INSTANCE.sharePublisher; - } - return INSTANCE.publisherMap.get(topic.getCanonicalName()); - } - - @JustForTest - public static Set getSmartSubscribes() { - return EventPublisher.SMART_SUBSCRIBES; - } - - @JustForTest - public static EventPublisher getSharePublisher() { - return INSTANCE.sharePublisher; - } - - public static void shutdown() { - if (!closed.compareAndSet(false, true)) { - return; - } - LOGGER.warn("[NotifyCenter] Start destroying Publisher"); - try { - INSTANCE.publisherMap.forEach(new BiConsumer() { - @Override - public void accept(String s, EventPublisher publisher) { - publisher.shutdown(); - } - }); - - INSTANCE.sharePublisher.shutdown(); - } catch (Throwable e) { - LOGGER.error("NotifyCenter shutdown has error : {}", e); - } - LOGGER.warn("[NotifyCenter] Destruction of the end"); - } - - /** - * Register a Subscriber. If the Publisher concerned by the Subscriber does not exist, then PublihserMap will - * preempt a placeholder Publisher first. not call {@link Publisher#start()} - * - * @param eventType Types of events that Subscriber cares about - * @param consumer subscriber - * @param event type - */ - public static void registerSubscribe(final Subscribe consumer) { - final Class cls = consumer.subscribeType(); - // If you want to listen to multiple events, you do it separately, - // without automatically registering the appropriate publisher - if (consumer instanceof SmartSubscribe) { - EventPublisher.SMART_SUBSCRIBES.add((SmartSubscribe) consumer); - return; - } - // If the event does not require additional queue resources, - // go to share-publisher to reduce resource waste - if (SlowEvent.class.isAssignableFrom(cls)) { - INSTANCE.sharePublisher.addSubscribe(consumer); - return; - } - final String topic = consumer.subscribeType().getCanonicalName(); - INSTANCE.publisherMap.computeIfAbsent(topic, s -> BUILD_FACTORY.apply(cls, RING_BUFFER_SIZE)); - EventPublisher publisher = INSTANCE.publisherMap.get(topic); - publisher.addSubscribe(consumer); - } - - /** - * deregister subscriber - * - * @param consumer subscriber - * @param - */ - public static void deregisterSubscribe(final Subscribe consumer) { - final Class cls = consumer.subscribeType(); - if (consumer instanceof SmartSubscribe) { - EventPublisher.SMART_SUBSCRIBES.remove((SmartSubscribe) consumer); - return; - } - if (SlowEvent.class.isAssignableFrom(cls)) { - INSTANCE.sharePublisher.unSubscribe(consumer); - return; - } - final String topic = consumer.subscribeType().getCanonicalName(); - if (INSTANCE.publisherMap.containsKey(topic)) { - EventPublisher publisher = INSTANCE.publisherMap.get(topic); - publisher.unSubscribe(consumer); - return; - } - throw new NoSuchElementException("The subcriber has no event publisher"); - } - - /** - * request publisher publish event Publishers load lazily, calling publisher. Start () only when the event is - * actually published - * - * @param event - */ - public static boolean publishEvent(final Event event) { - try { - return publishEvent(event.getClass(), event); - } catch (Throwable ex) { - LOGGER.error("There was an exception to the message publishing : {}", ex); - return false; - } - } - - /** - * request publisher publish event Publishers load lazily, calling publisher. Start () only when the event is - * actually published - * - * @param eventType - * @param event - */ - private static boolean publishEvent(final Class eventType, final Event event) { - final String topic = eventType.getCanonicalName(); - if (SlowEvent.class.isAssignableFrom(eventType)) { - return INSTANCE.sharePublisher.publish(event); - } - - if (INSTANCE.publisherMap.containsKey(topic)) { - EventPublisher publisher = INSTANCE.publisherMap.get(topic); - return publisher.publish(event); - } - throw new NoSuchElementException("There are no [" + topic + "] publishers for this event, please register"); - } - - /** - * register to share-publisher - * - * @param supplier - * @param eventType - * @return - */ - public static EventPublisher registerToSharePublisher(final Class eventType) { - return INSTANCE.sharePublisher; - } - - /** - * register publisher - * - * @param supplier - * @param eventType - * @param queueMaxSize - * @return - */ - public static EventPublisher registerToPublisher(final Class eventType, final int queueMaxSize) { - - if (SlowEvent.class.isAssignableFrom(eventType)) { - return INSTANCE.sharePublisher; - } - - final String topic = eventType.getCanonicalName(); - INSTANCE.publisherMap.computeIfAbsent(topic, s -> BUILD_FACTORY.apply(eventType, queueMaxSize)); - EventPublisher publisher = INSTANCE.publisherMap.get(topic); - return publisher; - } - - /** - * deregister publisher - * - * @param eventType - * @return - */ - public static void deregisterPublisher(final Class eventType) { - final String topic = eventType.getCanonicalName(); - EventPublisher publisher = INSTANCE.publisherMap.remove(topic); - publisher.shutdown(); - } - -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/SlowEvent.java b/core/src/main/java/com/alibaba/nacos/core/notify/SlowEvent.java deleted file mode 100644 index f105b68b8..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/SlowEvent.java +++ /dev/null @@ -1,26 +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.core.notify; - -/** - * this event share one event-queue. - * - * @author liaochuntao - */ -public interface SlowEvent extends Event { - -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/listener/SmartSubscribe.java b/core/src/main/java/com/alibaba/nacos/core/notify/listener/SmartSubscribe.java deleted file mode 100644 index 074cfa557..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/listener/SmartSubscribe.java +++ /dev/null @@ -1,46 +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.core.notify.listener; - -import com.alibaba.nacos.core.notify.Event; - -/** - * Subscribers to multiple events can be listened to. - * - * @author liaochuntao - */ -@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") -public abstract class SmartSubscribe implements Subscribe { - - /** - * Determines if the processing message is acceptable. - * - * @param event {@link Event} - * @return Determines if the processing message is acceptable - */ - public abstract boolean canNotify(Event event); - - @Override - public final Class subscribeType() { - return null; - } - - @Override - public final boolean ignoreExpireEvent() { - return false; - } -} diff --git a/core/src/main/java/com/alibaba/nacos/core/notify/listener/Subscribe.java b/core/src/main/java/com/alibaba/nacos/core/notify/listener/Subscribe.java deleted file mode 100644 index 0f28f5f39..000000000 --- a/core/src/main/java/com/alibaba/nacos/core/notify/listener/Subscribe.java +++ /dev/null @@ -1,62 +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.core.notify.listener; - -import com.alibaba.nacos.core.notify.Event; - -import java.util.concurrent.Executor; - -/** - * subscriber. - * - * @author liaochuntao - */ -public interface Subscribe { - - /** - * Event callback. - * - * @param event {@link Event} - */ - void onEvent(T event); - - /** - * Type of this subscriber's subscription. - * - * @return Class which extends {@link Event} - */ - Class subscribeType(); - - /** - * It is up to the listener to determine whether the callback is asynchronous or synchronous. - * - * @return {@link Executor} - */ - default Executor executor() { - return null; - } - - /** - * Whether to ignore expired events. - * - * @return default value is {@link Boolean#FALSE} - */ - default boolean ignoreExpireEvent() { - return false; - } - -} From 891c1f3ba57f667ab8689fe390f6e41112a0f5c3 Mon Sep 17 00:00:00 2001 From: Gagharv Date: Mon, 13 Jul 2020 17:33:25 +0800 Subject: [PATCH 09/17] [ISSUE #2856]Adjust the use of thread pools (config module) (#3206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ISSUE #2856]Adjust the use of thread pools (config、cmdb module) * add CmdbExecutor class --- .../nacos/cmdb/memory/CmdbProvider.java | 16 ++-- .../nacos/cmdb/utils/CmdbExecutor.java | 43 +++++++++ .../nacos/cmdb/utils/UtilsAndCommons.java | 19 ---- .../common/executor/ExecutorFactory.java | 59 ------------ .../config/server/monitor/MemoryMonitor.java | 11 ++- .../monitor/NotifyTaskQueueMonitorTask.java | 5 +- .../server/service/ConfigSubService.java | 45 +++------ .../server/service/LongPollingService.java | 53 ++++------- .../service/capacity/CapacityService.java | 95 ++++++++----------- .../ExternalDataSourceServiceImpl.java | 8 +- .../server/service/dump/DumpService.java | 25 ++--- .../service/notify/AsyncNotifyService.java | 28 +----- .../service/notify/NotifySingleService.java | 24 +---- .../config/server/utils/ConfigExecutor.java | 66 +++++++++++-- .../config/server/utils/SimpleFlowData.java | 22 ++--- .../config/server/utils/SimpleIpFlowData.java | 22 ++--- 16 files changed, 232 insertions(+), 309 deletions(-) create mode 100644 cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/CmdbExecutor.java diff --git a/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java b/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java index 52fb40373..c2390e5a6 100644 --- a/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java +++ b/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java @@ -24,8 +24,8 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.cmdb.core.SwitchAndOptions; import com.alibaba.nacos.cmdb.service.CmdbReader; import com.alibaba.nacos.cmdb.service.CmdbWriter; +import com.alibaba.nacos.cmdb.utils.CmdbExecutor; import com.alibaba.nacos.cmdb.utils.Loggers; -import com.alibaba.nacos.cmdb.utils.UtilsAndCommons; import com.alibaba.nacos.common.utils.JacksonUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -117,11 +117,9 @@ public class CmdbProvider implements CmdbReader, CmdbWriter { initCmdbService(); load(); - UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS); - UtilsAndCommons.GLOBAL_EXECUTOR - .schedule(new CmdbLabelTask(), switches.getLabelTaskInterval(), TimeUnit.SECONDS); - UtilsAndCommons.GLOBAL_EXECUTOR - .schedule(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(new CmdbLabelTask(), switches.getLabelTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS); } @Override @@ -205,7 +203,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter { } catch (Exception e) { Loggers.MAIN.error("CMDB-LABEL-TASK {}", "dump failed!", e); } finally { - UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getLabelTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(this, switches.getLabelTaskInterval(), TimeUnit.SECONDS); } } } @@ -227,7 +225,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter { } catch (Exception e) { Loggers.MAIN.error("DUMP-TASK {}", "dump failed!", e); } finally { - UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS); } } } @@ -271,7 +269,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter { } catch (Exception e) { Loggers.MAIN.error("CMDB-EVENT {}", "event task failed!", e); } finally { - UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getEventTaskInterval(), TimeUnit.SECONDS); + CmdbExecutor.scheduleCmdbTask(this, switches.getEventTaskInterval(), TimeUnit.SECONDS); } } } diff --git a/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/CmdbExecutor.java b/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/CmdbExecutor.java new file mode 100644 index 000000000..56dbac99b --- /dev/null +++ b/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/CmdbExecutor.java @@ -0,0 +1,43 @@ +/* + * 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.cmdb.utils; + +import com.alibaba.nacos.cmdb.CmdbApp; +import com.alibaba.nacos.common.executor.ExecutorFactory; +import com.alibaba.nacos.common.executor.NameThreadFactory; +import com.alibaba.nacos.core.utils.ClassUtils; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * Cmdb executor. + * + * @author wangweizZZ + * @date 2020/7/13 1:54 PM + */ +public class CmdbExecutor { + + private static final ScheduledExecutorService GLOBAL_EXECUTOR = ExecutorFactory.Managed + .newScheduledExecutorService(ClassUtils.getCanonicalName(CmdbApp.class), + Runtime.getRuntime().availableProcessors(), + new NameThreadFactory("com.alibaba.nacos.cmdb.global.executor")); + + public static void scheduleCmdbTask(Runnable runnable, long delay, TimeUnit unit) { + GLOBAL_EXECUTOR.schedule(runnable, delay, unit); + } +} diff --git a/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/UtilsAndCommons.java b/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/UtilsAndCommons.java index 564d99a84..befcda118 100644 --- a/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/UtilsAndCommons.java +++ b/cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/UtilsAndCommons.java @@ -16,10 +16,6 @@ package com.alibaba.nacos.cmdb.utils; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; - /** * Utils and constants. * @@ -32,19 +28,4 @@ public class UtilsAndCommons { public static final String NACOS_CMDB_CONTEXT = NACOS_SERVER_VERSION + "/cmdb"; - public static final ScheduledExecutorService GLOBAL_EXECUTOR; - - static { - - GLOBAL_EXECUTOR = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), - new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("nacos.cmdb.global.executor"); - t.setDaemon(true); - return t; - } - }); - } } diff --git a/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java b/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java index ba4f8458c..c5419ec0e 100644 --- a/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java +++ b/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java @@ -38,10 +38,6 @@ import java.util.concurrent.TimeUnit; "checkstyle:missingjavadocmethod"}) public final class ExecutorFactory { - private static final String DEFAULT_NAMESPACE = "nacos"; - - private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance(); - public static ExecutorService newSingleExecutorService() { return Executors.newFixedThreadPool(1); } @@ -73,61 +69,6 @@ public final class ExecutorFactory { new LinkedBlockingQueue(), threadFactory); } - //TODO remove Deprecated function after replace all module - @Deprecated - public static ExecutorService newSingleExecutorService(final String group) { - ExecutorService executorService = Executors.newFixedThreadPool(1); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ExecutorService newSingleExecutorService(final String group, final ThreadFactory threadFactory) { - ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ExecutorService newFixedExecutorService(final String group, final int nThreads) { - ExecutorService executorService = Executors.newFixedThreadPool(nThreads); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ExecutorService newFixedExecutorService(final String group, final int nThreads, - final ThreadFactory threadFactory) { - ExecutorService executorService = Executors.newFixedThreadPool(nThreads, threadFactory); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ScheduledExecutorService newSingleScheduledExecutorService(final String group, - final ThreadFactory threadFactory) { - ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, threadFactory); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ScheduledExecutorService newScheduledExecutorService(final String group, final int nThreads, - final ThreadFactory threadFactory) { - ScheduledExecutorService executorService = Executors.newScheduledThreadPool(nThreads, threadFactory); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService); - return executorService; - } - - @Deprecated - public static ThreadPoolExecutor newCustomerThreadExecutor(final String group, final int coreThreads, - final int maxThreads, final long keepAliveTimeMs, final ThreadFactory threadFactory) { - ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads, keepAliveTimeMs, - TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), threadFactory); - THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor); - return executor; - } - public static final class Managed { private static final String DEFAULT_NAMESPACE = "nacos"; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/monitor/MemoryMonitor.java b/config/src/main/java/com/alibaba/nacos/config/server/monitor/MemoryMonitor.java index e29b1f04a..44c0a8825 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/monitor/MemoryMonitor.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/monitor/MemoryMonitor.java @@ -35,13 +35,14 @@ public class MemoryMonitor { @Autowired public MemoryMonitor(AsyncNotifyService notifySingleService) { - ConfigExecutor.scheduleWithFixedDelay(new PrintMemoryTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS); + ConfigExecutor.scheduleConfigTask(new PrintMemoryTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS); - ConfigExecutor.scheduleWithFixedDelay(new PrintGetConfigResponeTask(), DELAY_SECONDS, DELAY_SECONDS, - TimeUnit.SECONDS); + ConfigExecutor + .scheduleConfigTask(new PrintGetConfigResponeTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS); - ConfigExecutor.scheduleWithFixedDelay(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS, - DELAY_SECONDS, TimeUnit.SECONDS); + ConfigExecutor + .scheduleConfigTask(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS, DELAY_SECONDS, + TimeUnit.SECONDS); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/monitor/NotifyTaskQueueMonitorTask.java b/config/src/main/java/com/alibaba/nacos/config/server/monitor/NotifyTaskQueueMonitorTask.java index 287ffbd14..c0ba1eb18 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/monitor/NotifyTaskQueueMonitorTask.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/monitor/NotifyTaskQueueMonitorTask.java @@ -17,8 +17,7 @@ package com.alibaba.nacos.config.server.monitor; import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService; - -import java.util.concurrent.ScheduledThreadPoolExecutor; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG; @@ -37,7 +36,7 @@ public class NotifyTaskQueueMonitorTask implements Runnable { @Override public void run() { - int size = ((ScheduledThreadPoolExecutor) notifySingleService.getExecutor()).getQueue().size(); + int size = ConfigExecutor.asyncNotifyQueueSize(); MEMORY_LOG.info("toNotifyTaskSize = {}", size); MetricsMonitor.getNotifyTaskMonitor().set(size); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java index e29a902cd..892e21f82 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java @@ -16,17 +16,17 @@ package com.alibaba.nacos.config.server.service; -import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.SampleResult; import com.alibaba.nacos.config.server.service.notify.NotifyService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.JSONUtils; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.utils.ApplicationUtils; -import org.apache.commons.lang3.StringUtils; import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -37,18 +37,15 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.CompletionService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.Future; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.Callable; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * Config sub service. @@ -58,24 +55,12 @@ import java.util.concurrent.ExecutorCompletionService; @Service public class ConfigSubService { - private ScheduledExecutorService scheduler; - private ServerMemberManager memberManager; @Autowired @SuppressWarnings("PMD.ThreadPoolCreationRule") public ConfigSubService(ServerMemberManager memberManager) { this.memberManager = memberManager; - - scheduler = Executors.newScheduledThreadPool(ThreadUtils.getSuitableThreadCount(), new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - t.setName("com.alibaba.nacos.ConfigSubService"); - return t; - } - }); } protected ConfigSubService() { @@ -140,7 +125,7 @@ public class ConfigSubService { * Merge SampleResult. * * @param sampleCollectResult sampleCollectResult. - * @param sampleResults sampleResults. + * @param sampleResults sampleResults. * @return SampleResult. */ public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List sampleResults) { @@ -195,7 +180,7 @@ public class ConfigSubService { String urlAll = getUrl(ip, url) + "?" + paramUrl; com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult result = NotifyService .invokeURL(urlAll, null, Constants.ENCODE); - + // Http code 200 if (result.code == HttpURLConnection.HTTP_OK) { String json = result.content; @@ -227,8 +212,8 @@ public class ConfigSubService { } BlockingQueue> queue = new LinkedBlockingDeque>( memberManager.getServerList().size()); - CompletionService completionService = new ExecutorCompletionService(scheduler, - queue); + CompletionService completionService = new ExecutorCompletionService( + ConfigExecutor.getConfigSubServiceExecutor(), queue); SampleResult sampleCollectResult = new SampleResult(); for (int i = 0; i < sampleTime; i++) { @@ -247,8 +232,8 @@ public class ConfigSubService { params.put("ip", ip); BlockingQueue> queue = new LinkedBlockingDeque>( memberManager.getServerList().size()); - CompletionService completionService = new ExecutorCompletionService(scheduler, - queue); + CompletionService completionService = new ExecutorCompletionService( + ConfigExecutor.getConfigSubServiceExecutor(), queue); SampleResult sampleCollectResult = new SampleResult(); for (int i = 0; i < sampleTime; i++) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java index f6035356c..2a92f5d41 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java @@ -21,6 +21,7 @@ import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.config.server.model.SampleResult; import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent; import com.alibaba.nacos.config.server.monitor.MetricsMonitor; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.MD5Util; @@ -33,24 +34,20 @@ import org.springframework.stereotype.Service; import javax.servlet.AsyncContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.Iterator; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.Future; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.Arrays; import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG; import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG; @@ -126,8 +123,8 @@ public class LongPollingService extends AbstractEventListener { } /** - * Aggregate the sampling IP and monitoring configuration information in the sampling results. - * There is no problem for the merging strategy to cover the previous one with the latter. + * Aggregate the sampling IP and monitoring configuration information in the sampling results. There is no problem + * for the merging strategy to cover the previous one with the latter. * * @param sampleResults sample Results. * @return Results. @@ -147,6 +144,7 @@ public class LongPollingService extends AbstractEventListener { /** * Collect application subscribe configinfos. + * * @return configinfos results. */ public Map> collectApplicationSubscribeConfigInfos() { @@ -232,9 +230,9 @@ public class LongPollingService extends AbstractEventListener { /** * Add LongPollingClient. * - * @param req HttpServletRequest. - * @param rsp HttpServletResponse. - * @param clientMd5Map clientMd5Map. + * @param req HttpServletRequest. + * @param rsp HttpServletResponse. + * @param clientMd5Map clientMd5Map. * @param probeRequestSize probeRequestSize. */ public void addLongPollingClient(HttpServletRequest req, HttpServletResponse rsp, Map clientMd5Map, @@ -245,7 +243,7 @@ public class LongPollingService extends AbstractEventListener { String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER); String tag = req.getHeader("Vipserver-Tag"); int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500); - + // Add delay time for LoadBalance, and one response is returned 500 ms in advance to avoid client timeout. long timeout = Math.max(10000, Long.parseLong(str) - delayTime); if (isFixedPolling()) { @@ -275,7 +273,7 @@ public class LongPollingService extends AbstractEventListener { // AsyncContext.setTimeout() is incorrect, Control by oneself asyncContext.setTimeout(0L); - scheduler.execute( + ConfigExecutor.executeLongPolling( new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag)); } @@ -293,7 +291,7 @@ public class LongPollingService extends AbstractEventListener { } else { if (event instanceof LocalDataChangeEvent) { LocalDataChangeEvent evt = (LocalDataChangeEvent) event; - scheduler.execute(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); + ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); } } } @@ -306,24 +304,13 @@ public class LongPollingService extends AbstractEventListener { public LongPollingService() { allSubs = new ConcurrentLinkedQueue(); - scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - t.setName("com.alibaba.nacos.LongPolling"); - return t; - } - }); - scheduler.scheduleWithFixedDelay(new StatTask(), 0L, 10L, TimeUnit.SECONDS); + ConfigExecutor.scheduleLongPolling(new StatTask(), 0L, 10L, TimeUnit.SECONDS); } public static final String LONG_POLLING_HEADER = "Long-Pulling-Timeout"; public static final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup"; - final ScheduledExecutorService scheduler; - /** * ClientLongPolling subscibers. */ @@ -398,12 +385,12 @@ public class LongPollingService extends AbstractEventListener { @Override public void run() { - asyncTimeoutFuture = scheduler.schedule(new Runnable() { + asyncTimeoutFuture = ConfigExecutor.scheduleLongPolling(new Runnable() { @Override public void run() { try { getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis()); - + // Delete subsciber's relations. allSubs.remove(ClientLongPolling.this); @@ -439,7 +426,7 @@ public class LongPollingService extends AbstractEventListener { } void sendResponse(List changedGroups) { - + // Cancel time out task. if (null != asyncTimeoutFuture) { asyncTimeoutFuture.cancel(false); @@ -449,7 +436,7 @@ public class LongPollingService extends AbstractEventListener { void generateResponse(List changedGroups) { if (null == changedGroups) { - + // Tell web container to send http response. asyncContext.complete(); return; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/capacity/CapacityService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/capacity/CapacityService.java index 4bbde95f0..515dd849c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/capacity/CapacityService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/capacity/CapacityService.java @@ -21,11 +21,11 @@ import com.alibaba.nacos.config.server.model.capacity.Capacity; import com.alibaba.nacos.config.server.model.capacity.GroupCapacity; import com.alibaba.nacos.config.server.model.capacity.TenantCapacity; import com.alibaba.nacos.config.server.service.repository.PersistService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.config.server.utils.TimeUtils; import com.google.common.base.Stopwatch; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,12 +34,8 @@ import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.sql.Timestamp; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; /** @@ -66,8 +62,6 @@ public class CapacityService { @Autowired private PersistService persistService; - private ScheduledExecutorService scheduledExecutorService; - /** * Init. */ @@ -75,10 +69,7 @@ public class CapacityService { @SuppressWarnings("PMD.ThreadPoolCreationRule") public void init() { // All servers have jobs that modify usage, idempotent. - ThreadFactory threadFactory = new ThreadFactoryBuilder() - .setNameFormat("com.alibaba.nacos.CapacityManagement-%d").setDaemon(true).build(); - scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(threadFactory); - scheduledExecutorService.scheduleWithFixedDelay(new Runnable() { + ConfigExecutor.scheduleCorrectUsageTask(new Runnable() { @Override public void run() { LOGGER.info("[capacityManagement] start correct usage"); @@ -90,11 +81,6 @@ public class CapacityService { }, PropertyUtil.getCorrectUsageDelay(), PropertyUtil.getCorrectUsageDelay(), TimeUnit.SECONDS); } - @PreDestroy - public void destroy() { - scheduledExecutorService.shutdown(); - } - public void correctUsage() { correctGroupUsage(); correctTenantUsage(); @@ -192,11 +178,10 @@ public class CapacityService { } /** - * To Cluster. - * 1.If the capacity information does not exist, initialize the capacity information. - * 2.Update capacity usage, plus or minus one. + * To Cluster. 1.If the capacity information does not exist, initialize the capacity information. 2.Update capacity + * usage, plus or minus one. * - * @param counterMode increase or decrease mode. + * @param counterMode increase or decrease mode. * @param ignoreQuotaLimit ignoreQuotaLimit flag. * @return */ @@ -215,12 +200,11 @@ public class CapacityService { } /** - * It is used for counting when the limit check function of capacity management is turned off. - * 1.If the capacity information does not exist, initialize the capacity information. - * 2.Update capacity usage, plus or minus one. + * It is used for counting when the limit check function of capacity management is turned off. 1.If the capacity + * information does not exist, initialize the capacity information. 2.Update capacity usage, plus or minus one. * - * @param counterMode increase or decrease mode. - * @param group tenant string value. + * @param counterMode increase or decrease mode. + * @param group tenant string value. * @param ignoreQuotaLimit ignoreQuotaLimit flag. * @return operate successfully or not. */ @@ -260,8 +244,8 @@ public class CapacityService { } /** - * Initialize the capacity information of the group. - * If the quota is reached, the capacity will be automatically expanded to reduce the operation and maintenance cost. + * Initialize the capacity information of the group. If the quota is reached, the capacity will be automatically + * expanded to reduce the operation and maintenance cost. * * @param group group string value. * @return init result. @@ -271,14 +255,14 @@ public class CapacityService { } /** - * Initialize the capacity information of the group. If the quota is reached, - * the capacity will be automatically expanded to reduce the operation and maintenance cost. + * Initialize the capacity information of the group. If the quota is reached, the capacity will be automatically + * expanded to reduce the operation and maintenance cost. * - * @param group group string value. - * @param quota quota int value. - * @param maxSize maxSize int value. + * @param group group string value. + * @param quota quota int value. + * @param maxSize maxSize int value. * @param maxAggrCount maxAggrCount int value. - * @param maxAggrSize maxAggrSize int value. + * @param maxAggrSize maxAggrSize int value. * @return init result. */ private boolean initGroupCapacity(String group, Integer quota, Integer maxSize, Integer maxAggrCount, @@ -290,11 +274,11 @@ public class CapacityService { autoExpansion(group, null); return insertSuccess; } - + /** * Expand capacity automatically. * - * @param group group string value. + * @param group group string value. * @param tenant tenant string value. */ private void autoExpansion(String group, String tenant) { @@ -377,7 +361,7 @@ public class CapacityService { /** * Init capacity. * - * @param group group string value. + * @param group group string value. * @param tenant tenant string value. * @return init result. */ @@ -423,12 +407,11 @@ public class CapacityService { } /** - * It is used for counting when the limit check function of capacity management is turned off. - * 1.If the capacity information does not exist, initialize the capacity information. - * 2.Update capacity usage, plus or minus one. + * It is used for counting when the limit check function of capacity management is turned off. 1.If the capacity + * information does not exist, initialize the capacity information. 2.Update capacity usage, plus or minus one. * - * @param counterMode increase or decrease mode. - * @param tenant tenant string value. + * @param counterMode increase or decrease mode. + * @param tenant tenant string value. * @param ignoreQuotaLimit ignoreQuotaLimit flag. * @return operate successfully or not. */ @@ -464,8 +447,8 @@ public class CapacityService { } /** - * Initialize the capacity information of the tenant. If the quota is reached, - * the capacity will be automatically expanded to reduce the operation and maintenance cos. + * Initialize the capacity information of the tenant. If the quota is reached, the capacity will be automatically + * expanded to reduce the operation and maintenance cos. * * @param tenant tenant string value. * @return init result. @@ -475,14 +458,14 @@ public class CapacityService { } /** - * Initialize the capacity information of the tenant. If the quota is reached, - * the capacity will be automatically expanded to reduce the operation and maintenance cost + * Initialize the capacity information of the tenant. If the quota is reached, the capacity will be automatically + * expanded to reduce the operation and maintenance cost * - * @param tenant tenant string value. - * @param quota quota int value. - * @param maxSize maxSize int value. + * @param tenant tenant string value. + * @param quota quota int value. + * @param maxSize maxSize int value. * @param maxAggrCount maxAggrCount int value. - * @param maxAggrSize maxAggrSize int value. + * @param maxAggrSize maxAggrSize int value. * @return */ public boolean initTenantCapacity(String tenant, Integer quota, Integer maxSize, Integer maxAggrCount, @@ -530,15 +513,15 @@ public class CapacityService { } /** - * Support for API interface, Tenant: initialize if the record does not exist, - * and update the capacity quota or content size directly if it exists. + * Support for API interface, Tenant: initialize if the record does not exist, and update the capacity quota or + * content size directly if it exists. * - * @param group group string value. - * @param tenant tenant string value. - * @param quota quota int value. - * @param maxSize maxSize int value. + * @param group group string value. + * @param tenant tenant string value. + * @param quota quota int value. + * @param maxSize maxSize int value. * @param maxAggrCount maxAggrCount int value. - * @param maxAggrSize maxAggrSize int value. + * @param maxAggrSize maxAggrSize int value. * @return operate successfully or not. */ public boolean insertOrUpdateCapacity(String group, String tenant, Integer quota, Integer maxSize, diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java index de3cf59b4..725101282 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceServiceImpl.java @@ -101,13 +101,13 @@ public class ExternalDataSourceServiceImpl implements DataSourceService { testMasterWritableJT.setQueryTimeout(1); // Database health check - + testJtList = new ArrayList(); isHealthList = new ArrayList(); tm = new DataSourceTransactionManager(); tjt = new TransactionTemplate(tm); - + // Transaction timeout needs to be distinguished from ordinary operations. tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT); if (PropertyUtil.isUseExternalDB()) { @@ -118,8 +118,8 @@ public class ExternalDataSourceServiceImpl implements DataSourceService { throw new RuntimeException(DB_LOAD_ERROR_MSG); } - ConfigExecutor.scheduleWithFixedDelay(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS); - ConfigExecutor.scheduleWithFixedDelay(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS); + ConfigExecutor.scheduleConfigTask(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS); + ConfigExecutor.scheduleConfigTask(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java index 06c072ecd..0143feffa 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java @@ -152,7 +152,8 @@ public abstract class DumpService { if (totalCount > 0) { int pageSize = 1000; int removeTime = (totalCount + pageSize - 1) / pageSize; - LOGGER.warn("clearConfigHistory, getBeforeStamp:{}, totalCount:{}, pageSize:{}, removeTime:{}", + LOGGER.warn( + "clearConfigHistory, getBeforeStamp:{}, totalCount:{}, pageSize:{}, removeTime:{}", startTime, totalCount, pageSize, removeTime); while (removeTime > 0) { // delete paging to avoid reporting errors in batches @@ -212,22 +213,21 @@ public abstract class DumpService { } }; - ConfigExecutor.scheduleWithFixedDelay(heartbeat, 0, 10, TimeUnit.SECONDS); + ConfigExecutor.scheduleConfigTask(heartbeat, 0, 10, TimeUnit.SECONDS); long initialDelay = new Random().nextInt(INITIAL_DELAY_IN_MINUTE) + 10; LogUtil.DEFAULT_LOG.warn("initialDelay:{}", initialDelay); + ConfigExecutor.scheduleConfigTask(dumpAll, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); + ConfigExecutor - .scheduleWithFixedDelay(dumpAll, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); + .scheduleConfigTask(dumpAllBeta, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); - ConfigExecutor.scheduleWithFixedDelay(dumpAllBeta, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, - TimeUnit.MINUTES); - - ConfigExecutor.scheduleWithFixedDelay(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, - TimeUnit.MINUTES); + ConfigExecutor + .scheduleConfigTask(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); } - ConfigExecutor.scheduleWithFixedDelay(clearConfigHistory, 10, 10, TimeUnit.MINUTES); + ConfigExecutor.scheduleConfigTask(clearConfigHistory, 10, 10, TimeUnit.MINUTES); } finally { TimerContext.end(LogUtil.DUMP_LOG); } @@ -276,7 +276,7 @@ public abstract class DumpService { } LogUtil.DEFAULT_LOG.error("end checkMd5Task"); }; - ConfigExecutor.scheduleWithFixedDelay(checkMd5Task, 0, 12, TimeUnit.HOURS); + ConfigExecutor.scheduleConfigTask(checkMd5Task, 0, 12, TimeUnit.HOURS); } } catch (IOException e) { LogUtil.FATAL_LOG.error("dump config fail" + e.getMessage()); @@ -420,8 +420,9 @@ public abstract class DumpService { } else { // remove config info persistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIp(), null); - LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" - + group); + LOGGER.warn( + "[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + + group); } } catch (Throwable e) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java index d53febead..1a5a82aac 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java @@ -17,9 +17,10 @@ package com.alibaba.nacos.config.server.service.notify; import com.alibaba.nacos.config.server.constant.Constants; -import com.alibaba.nacos.config.server.monitor.MetricsMonitor; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; +import com.alibaba.nacos.config.server.monitor.MetricsMonitor; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener; @@ -50,10 +51,6 @@ import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Queue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; /** @@ -90,7 +87,7 @@ public class AsyncNotifyService extends AbstractEventListener { for (Member member : ipList) { queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(), evt.isBeta)); } - EXECUTOR.execute(new AsyncTask(httpclient, queue)); + ConfigExecutor.executeAsyncNotify(new AsyncTask(httpclient, queue)); } } @@ -100,13 +97,6 @@ public class AsyncNotifyService extends AbstractEventListener { httpclient.start(); } - public Executor getExecutor() { - return EXECUTOR; - } - - @SuppressWarnings("PMD.ThreadPoolCreationRule") - private static final Executor EXECUTOR = Executors.newScheduledThreadPool(100, new NotifyThreadFactory()); - private RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(PropertyUtil.getNotifyConnectTimeout()) .setSocketTimeout(PropertyUtil.getNotifySocketTimeout()).build(); @@ -169,7 +159,7 @@ public class AsyncNotifyService extends AbstractEventListener { Queue queue = new LinkedList(); queue.add(task); AsyncTask asyncTask = new AsyncTask(httpclient, queue); - ((ScheduledThreadPoolExecutor) EXECUTOR).schedule(asyncTask, delay, TimeUnit.MILLISECONDS); + ConfigExecutor.scheduleAsyncNotify(asyncTask, delay, TimeUnit.MILLISECONDS); } class AsyncNotifyCallBack implements FutureCallback { @@ -310,16 +300,6 @@ public class AsyncNotifyService extends AbstractEventListener { } - static class NotifyThreadFactory implements ThreadFactory { - - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "com.alibaba.nacos.AsyncNotifyServiceThread"); - thread.setDaemon(true); - return thread; - } - } - /** * get delayTime and also set failCount to task; The failure time index increases, so as not to retry invalid tasks * in the offline scene, which affects the normal synchronization. diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/NotifySingleService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/NotifySingleService.java index 698ac7c16..4ea54f06e 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/NotifySingleService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/NotifySingleService.java @@ -16,6 +16,8 @@ package com.alibaba.nacos.config.server.service.notify; +import com.alibaba.nacos.common.executor.ExecutorFactory; +import com.alibaba.nacos.common.executor.NameThreadFactory; import com.alibaba.nacos.config.server.manager.AbstractTask; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; @@ -28,9 +30,7 @@ import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -102,22 +102,6 @@ public class NotifySingleService { } } - static class NotifyThreadFactory implements ThreadFactory { - - private final String notifyTarget; - - NotifyThreadFactory(String notifyTarget) { - this.notifyTarget = notifyTarget; - } - - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "com.alibaba.nacos.NotifySingleServiceThread-" + notifyTarget); - thread.setDaemon(true); - return thread; - } - } - @Autowired public NotifySingleService(ServerMemberManager memberManager) { this.memberManager = memberManager; @@ -141,8 +125,8 @@ public class NotifySingleService { * there will be no continuous task accumulation, * there is occasional instantaneous pressure) */ - @SuppressWarnings("PMD.ThreadPoolCreationRule") Executor executor = Executors - .newScheduledThreadPool(1, new NotifyThreadFactory(address)); + Executor executor = ExecutorFactory.newSingleScheduledExecutorService( + new NameThreadFactory("com.alibaba.nacos.config.NotifySingleServiceThread-" + address)); if (null == executors.putIfAbsent(address, executor)) { LOGGER.warn("[notify-thread-pool] setup thread target ip {} ok.", address); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExecutor.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExecutor.java index 4f12d79c1..9a60da02d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExecutor.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExecutor.java @@ -18,10 +18,14 @@ package com.alibaba.nacos.config.server.utils; import com.alibaba.nacos.common.executor.ExecutorFactory; import com.alibaba.nacos.common.executor.NameThreadFactory; +import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.config.server.Config; +import com.alibaba.nacos.core.utils.ClassUtils; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** @@ -31,15 +35,32 @@ import java.util.concurrent.TimeUnit; */ public final class ConfigExecutor { - private static final Executor DUMP_EXECUTOR = ExecutorFactory - .newFixedExecutorService(Config.class.getCanonicalName(), 1, - new NameThreadFactory("nacos.config.embedded.dump")); + private static final Executor DUMP_EXECUTOR = ExecutorFactory.Managed + .newSingleExecutorService(ClassUtils.getCanonicalName(Config.class), + new NameThreadFactory("com.alibaba.nacos.config.embedded.dump")); - private static final ScheduledExecutorService TIMER_EXECUTOR = ExecutorFactory - .newScheduledExecutorService(Config.class.getCanonicalName(), 10, - new NameThreadFactory("com.alibaba.nacos.server.Timer")); + private static final ScheduledExecutorService TIMER_EXECUTOR = ExecutorFactory.Managed + .newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), 10, + new NameThreadFactory("com.alibaba.nacos.config.server.timer")); - public static void scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + private static final ScheduledExecutorService CAPACITY_MANAGEMENT_EXECUTOR = ExecutorFactory.Managed + .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), + new NameThreadFactory("com.alibaba.nacos.config.CapacityManagement")); + + private static final ScheduledExecutorService ASYNC_NOTIFY_EXECUTOR = ExecutorFactory.Managed + .newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), 100, + new NameThreadFactory("com.alibaba.nacos.config.AsyncNotifyService")); + + private static final ScheduledExecutorService CONFIG_SUB_SERVICE_EXECUTOR = ExecutorFactory.Managed + .newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), + ThreadUtils.getSuitableThreadCount(), + new NameThreadFactory("com.alibaba.nacos.config.ConfigSubService")); + + private static final ScheduledExecutorService LONG_POLLING_EXECUTOR = ExecutorFactory.Managed + .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), + new NameThreadFactory("com.alibaba.nacos.config.LongPolling")); + + public static void scheduleConfigTask(Runnable command, long initialDelay, long delay, TimeUnit unit) { TIMER_EXECUTOR.scheduleWithFixedDelay(command, initialDelay, delay, unit); } @@ -47,4 +68,35 @@ public final class ConfigExecutor { DUMP_EXECUTOR.execute(runnable); } + public static void scheduleCorrectUsageTask(Runnable runnable, long initialDelay, long delay, TimeUnit unit) { + CAPACITY_MANAGEMENT_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, delay, unit); + } + + public static void executeAsyncNotify(Runnable runnable) { + ASYNC_NOTIFY_EXECUTOR.execute(runnable); + } + + public static void scheduleAsyncNotify(Runnable command, long delay, TimeUnit unit) { + ASYNC_NOTIFY_EXECUTOR.schedule(command, delay, unit); + } + + public static int asyncNotifyQueueSize() { + return ((ScheduledThreadPoolExecutor) ASYNC_NOTIFY_EXECUTOR).getQueue().size(); + } + + public static ScheduledExecutorService getConfigSubServiceExecutor() { + return CONFIG_SUB_SERVICE_EXECUTOR; + } + + public static void scheduleLongPolling(Runnable runnable, long initialDelay, long period, TimeUnit unit) { + LONG_POLLING_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, period, unit); + } + + public static ScheduledFuture scheduleLongPolling(Runnable runnable, long period, TimeUnit unit) { + return LONG_POLLING_EXECUTOR.schedule(runnable, period, unit); + } + + public static void executeLongPolling(Runnable runnable) { + LONG_POLLING_EXECUTOR.execute(runnable); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleFlowData.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleFlowData.java index 5b9540751..82c2baefb 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleFlowData.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleFlowData.java @@ -16,9 +16,12 @@ package com.alibaba.nacos.config.server.utils; -import java.util.concurrent.Executors; +import com.alibaba.nacos.common.executor.ExecutorFactory; +import com.alibaba.nacos.common.executor.NameThreadFactory; +import com.alibaba.nacos.config.server.Config; +import com.alibaba.nacos.core.utils.ClassUtils; + import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -37,18 +40,9 @@ public class SimpleFlowData { private int slotCount; - @SuppressWarnings("PMD.ThreadPoolCreationRule") - private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("nacos flow control thread"); - t.setDaemon(true); - return t; - } - - }); + private ScheduledExecutorService timer = ExecutorFactory.Managed + .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), + new NameThreadFactory("com.alibaba.nacos.config.flow.control")); public SimpleFlowData(int slotCount, int interval) { this.slotCount = slotCount; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleIpFlowData.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleIpFlowData.java index 45f4ffd3b..3b9919fc7 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleIpFlowData.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/SimpleIpFlowData.java @@ -16,9 +16,12 @@ package com.alibaba.nacos.config.server.utils; -import java.util.concurrent.Executors; +import com.alibaba.nacos.common.executor.ExecutorFactory; +import com.alibaba.nacos.common.executor.NameThreadFactory; +import com.alibaba.nacos.config.server.Config; +import com.alibaba.nacos.core.utils.ClassUtils; + import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -35,18 +38,9 @@ public class SimpleIpFlowData { private int averageCount; - @SuppressWarnings("PMD.ThreadPoolCreationRule") - private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("nacos ip flow control thread"); - t.setDaemon(true); - return t; - } - - }); + private ScheduledExecutorService timer = ExecutorFactory.Managed + .newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), + new NameThreadFactory("com.alibaba.nacos.config.flow.control.ip")); class DefaultIpFlowDataManagerTask implements Runnable { From 511ef88ccc9c6be5527cf2472aef5e8b440a82ec Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Mon, 13 Jul 2020 18:54:06 +0800 Subject: [PATCH 10/17] fix:#3311 Add specified Logger when constructing nacos resttemplate (#3312) --- .../naming/net/NamingHttpClientManager.java | 7 ++ .../http/AbstractHttpClientFactory.java | 12 ++- .../common/http/DefaultHttpClientFactory.java | 13 ++++ .../common/http/HttpClientBeanHolder.java | 8 +- .../client/AbstractNacosRestTemplate.java | 11 ++- .../http/client/DefaultHttpClientRequest.java | 7 -- .../http/client/NacosAsyncRestTemplate.java | 13 ++-- .../common/http/client/NacosRestTemplate.java | 16 ++-- .../common/NacosAsyncRestTemplate_ITCase.java | 61 ++++++++------- .../test/common/NacosRestTemplate_ITCase.java | 75 +++++++++++-------- ...NacosRestTemplate_Interceptors_ITCase.java | 37 +++++---- 11 files changed, 152 insertions(+), 108 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java index 0ff5f2c5d..a900c2b8c 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java @@ -16,11 +16,13 @@ package com.alibaba.nacos.client.naming.net; +import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.common.http.AbstractHttpClientFactory; import com.alibaba.nacos.common.http.HttpClientBeanHolder; import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpClientFactory; import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import org.slf4j.Logger; /** * http Manager. @@ -58,5 +60,10 @@ public class NamingHttpClientManager { return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS) .setReadTimeOutMillis(READ_TIME_OUT_MILLIS).setMaxRedirects(MAX_REDIRECTS).build(); } + + @Override + protected Logger assignLogger() { + return LogUtils.NAMING_LOGGER; + } } } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java b/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java index afe9b742b..b3ed2568d 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java @@ -23,6 +23,7 @@ import com.alibaba.nacos.common.http.client.NacosRestTemplate; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.nio.client.HttpAsyncClients; +import org.slf4j.Logger; /** * AbstractHttpClientFactory Let the creator only specify the http client config. @@ -34,14 +35,14 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory { @Override public final NacosRestTemplate createNacosRestTemplate() { RequestConfig requestConfig = getRequestConfig(); - return new NacosRestTemplate( + return new NacosRestTemplate(assignLogger(), new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(requestConfig).build())); } @Override public final NacosAsyncRestTemplate createNacosAsyncRestTemplate() { RequestConfig requestConfig = getRequestConfig(); - return new NacosAsyncRestTemplate(new DefaultAsyncHttpClientRequest( + return new NacosAsyncRestTemplate(assignLogger(), new DefaultAsyncHttpClientRequest( HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig).build())); } @@ -58,4 +59,11 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory { * @return HttpClientConfig */ protected abstract HttpClientConfig buildHttpClientConfig(); + + /** + * assign Logger. + * + * @return Logger + */ + protected abstract Logger assignLogger(); } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/DefaultHttpClientFactory.java b/common/src/main/java/com/alibaba/nacos/common/http/DefaultHttpClientFactory.java index 383271af4..c8440c23c 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/DefaultHttpClientFactory.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/DefaultHttpClientFactory.java @@ -16,6 +16,8 @@ package com.alibaba.nacos.common.http; +import org.slf4j.Logger; + /** * default http client factory. * @@ -25,8 +27,19 @@ public class DefaultHttpClientFactory extends AbstractHttpClientFactory { private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000); + private final Logger logger; + + public DefaultHttpClientFactory(Logger logger) { + this.logger = logger; + } + @Override protected HttpClientConfig buildHttpClientConfig() { return HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build(); } + + @Override + protected Logger assignLogger() { + return logger; + } } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java index 18d28a725..0e264985d 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java @@ -52,8 +52,8 @@ public final class HttpClientBeanHolder { }); } - public static NacosRestTemplate getNacosRestTemplate() { - return getNacosRestTemplate(new DefaultHttpClientFactory()); + public static NacosRestTemplate getNacosRestTemplate(Logger logger) { + return getNacosRestTemplate(new DefaultHttpClientFactory(logger)); } public static NacosRestTemplate getNacosRestTemplate(HttpClientFactory httpClientFactory) { @@ -75,8 +75,8 @@ public final class HttpClientBeanHolder { return nacosRestTemplate; } - public static NacosAsyncRestTemplate getNacosAsyncRestTemplate() { - return getNacosAsyncRestTemplate(new DefaultHttpClientFactory()); + public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(Logger logger) { + return getNacosAsyncRestTemplate(new DefaultHttpClientFactory(logger)); } public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(HttpClientFactory httpClientFactory) { diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java index 5c91f8742..7edd64e6e 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/AbstractNacosRestTemplate.java @@ -19,6 +19,7 @@ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.constant.ResponseHandlerType; import com.alibaba.nacos.common.utils.JacksonUtils; import com.fasterxml.jackson.databind.JavaType; +import org.slf4j.Logger; import java.lang.reflect.Type; import java.util.HashMap; @@ -29,11 +30,19 @@ import java.util.Map; * * @author mai.jh */ +@SuppressWarnings("all") public abstract class AbstractNacosRestTemplate { private final Map responseHandlerMap = new HashMap(); - public AbstractNacosRestTemplate() { + protected final Logger logger; + + public AbstractNacosRestTemplate(Logger logger) { + this.logger = logger; + initDefaultResponseHandler(); + } + + private void initDefaultResponseHandler() { // init response handler responseHandlerMap.put(ResponseHandlerType.STRING_TYPE, new StringResponseHandler()); responseHandlerMap.put(ResponseHandlerType.RESTRESULT_TYPE, new RestResultResponseHandler()); diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java index c31cd5cae..459211bb0 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/DefaultHttpClientRequest.java @@ -26,8 +26,6 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; @@ -41,8 +39,6 @@ import java.util.Map; @SuppressWarnings({"unchecked", "resource"}) public class DefaultHttpClientRequest implements HttpClientRequest { - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHttpClientRequest.class); - private final CloseableHttpClient client; public DefaultHttpClientRequest(CloseableHttpClient client) { @@ -54,9 +50,6 @@ public class DefaultHttpClientRequest implements HttpClientRequest { throws Exception { HttpRequestBase request = build(uri, httpMethod, requestHttpEntity); CloseableHttpResponse response = client.execute(request); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Request from server: " + request.getURI().toString()); - } return new DefaultClientHttpResponse(response); } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java index 3c317f3ce..f894c3a6d 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosAsyncRestTemplate.java @@ -24,7 +24,6 @@ import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RequestHttpEntity; import com.alibaba.nacos.common.utils.HttpMethod; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.lang.reflect.Type; import java.net.URI; @@ -39,12 +38,10 @@ import java.util.Map; */ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate { - private static final Logger LOGGER = LoggerFactory.getLogger(NacosAsyncRestTemplate.class); + private final AsyncHttpClientRequest clientRequest; - private AsyncHttpClientRequest clientRequest; - - public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) { - super(); + public NacosAsyncRestTemplate(Logger logger, AsyncHttpClientRequest clientRequest) { + super(logger); this.clientRequest = clientRequest; } @@ -335,8 +332,8 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate { private void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type, Callback callback) throws Exception { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("HTTP " + httpMethod + " " + url); + if (logger.isDebugEnabled()) { + logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody()); } ResponseHandler responseHandler = super.selectResponseHandler(type); clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback); diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java index d710eecd0..38d9ce2d8 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/NacosRestTemplate.java @@ -26,7 +26,6 @@ import com.alibaba.nacos.common.model.RequestHttpEntity; import com.alibaba.nacos.common.utils.CollectionUtils; import com.alibaba.nacos.common.utils.HttpMethod; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.lang.reflect.Type; import java.net.URI; @@ -43,14 +42,12 @@ import java.util.Map; */ public class NacosRestTemplate extends AbstractNacosRestTemplate { - private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class); - private final HttpClientRequest requestClient; private final List interceptors = new ArrayList(); - public NacosRestTemplate(HttpClientRequest requestClient) { - super(); + public NacosRestTemplate(Logger logger, HttpClientRequest requestClient) { + super(logger); this.requestClient = requestClient; } @@ -447,9 +444,10 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { private HttpRestResult execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType) throws Exception { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("HTTP " + httpMethod + " " + url); + if (logger.isDebugEnabled()) { + logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody()); } + ResponseHandler responseHandler = super.selectResponseHandler(responseType); HttpClientResponse response = null; try { @@ -464,8 +462,8 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate { private HttpClientRequest requestClient() { if (CollectionUtils.isNotEmpty(interceptors)) { - if (LOGGER.isDebugEnabled()) { - LOGGER.info("Execute via interceptors :{}", interceptors); + if (logger.isDebugEnabled()) { + logger.debug("Execute via interceptors :{}", interceptors); } return new InterceptingHttpClientRequest(requestClient, interceptors.iterator()); } 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 2e301ef6c..381264165 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 @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.test.common; import com.alibaba.nacos.Nacos; @@ -30,6 +31,7 @@ import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; @@ -45,49 +47,52 @@ import java.util.Map; @SuppressWarnings("all") @FixMethodOrder(MethodSorters.JVM) @RunWith(SpringRunner.class) -@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = Nacos.class, properties = { + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class NacosAsyncRestTemplate_ITCase { - + @LocalServerPort private int port; - - private NacosAsyncRestTemplate nacosRestTemplate = HttpClientBeanHolder.getNacosAsyncRestTemplate(); - + + private NacosAsyncRestTemplate nacosRestTemplate = HttpClientBeanHolder + .getNacosAsyncRestTemplate(LoggerFactory.getLogger(NacosAsyncRestTemplate_ITCase.class)); + private final String CONFIG_INSTANCE_PATH = "/nacos/v1/ns"; + private String IP = null; - + @Before public void init() throws NacosException { IP = String.format("http://localhost:%d", port); } - + private class CallbackMap implements Callback { - + private HttpRestResult restResult; + private Throwable throwable; - + @Override public void onReceive(RestResult result) { restResult = (HttpRestResult) result; } - + @Override public void onError(Throwable throwable) { throwable = throwable; } - + public HttpRestResult getRestResult() { return restResult; } - + public Throwable getThrowable() { return throwable; } } - + @Test - public void test_url_post_form() throws Exception{ + public void test_url_post_form() throws Exception { String url = IP + CONFIG_INSTANCE_PATH + "/instance"; Map param = new HashMap<>(); param.put("serviceName", "app-test"); @@ -101,9 +106,9 @@ public class NacosAsyncRestTemplate_ITCase { System.out.println(restResult.getHeader()); Assert.assertTrue(restResult.ok()); } - + @Test - public void test_url_put_form() throws Exception{ + public void test_url_put_form() throws Exception { String url = IP + CONFIG_INSTANCE_PATH + "/instance"; Map param = new HashMap<>(); param.put("serviceName", "app-test-change"); @@ -117,8 +122,8 @@ public class NacosAsyncRestTemplate_ITCase { System.out.println(restResult.getHeader()); Assert.assertTrue(restResult.ok()); } - - + + @Test public void test_url_get() throws Exception { String url = IP + CONFIG_INSTANCE_PATH + "/instance/list"; @@ -132,9 +137,9 @@ public class NacosAsyncRestTemplate_ITCase { Assert.assertTrue(restResult.ok()); Assert.assertEquals(restResult.getData().get("dom"), "app-test"); } - + @Test - public void test_url_by_map() throws Exception{ + public void test_url_by_map() throws Exception { String url = IP + CONFIG_INSTANCE_PATH + "/instance/list"; Map param = new HashMap<>(); param.put("serviceName", "app-test"); @@ -147,21 +152,19 @@ public class NacosAsyncRestTemplate_ITCase { Assert.assertTrue(restResult.ok()); Assert.assertEquals(restResult.getData().get("dom"), "app-test"); } - + @Test - public void test_url_delete() throws Exception{ + public void test_url_delete() throws Exception { String url = IP + CONFIG_INSTANCE_PATH + "/instance"; - Query query = Query.newInstance() - .addParam("ip", "11.11.11.11") - .addParam("port", "8080") - .addParam("serviceName", "app-test"); + Query query = Query.newInstance().addParam("ip", "11.11.11.11").addParam("port", "8080") + .addParam("serviceName", "app-test"); CallbackMap callbackMap = new CallbackMap<>(); - nacosRestTemplate.delete(url, Header.newInstance(), query, String.class, callbackMap); + nacosRestTemplate.delete(url, Header.newInstance(), query, String.class, callbackMap); Thread.sleep(2000); HttpRestResult restResult = callbackMap.getRestResult(); System.out.println(restResult.getData()); System.out.println(restResult.getHeader()); Assert.assertTrue(restResult.ok()); } - + } 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 2c7720fcc..801089b85 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 @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.test.common; import com.alibaba.nacos.Nacos; @@ -28,13 +29,16 @@ import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.config.server.model.ConfigInfo4Beta; import com.alibaba.nacos.config.server.utils.JSONUtils; import com.alibaba.nacos.core.utils.GenericType; +import com.alibaba.nacos.test.smoke.nacosSmoke_ITCase; import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.log4j.Logger; import org.junit.Assert; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; @@ -43,78 +47,87 @@ import java.util.HashMap; import java.util.Map; /** - * NacosRestTemplate_ITCase + * NacosRestTemplate_ITCase * * @author mai.jh */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = Nacos.class, properties = { + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @FixMethodOrder(MethodSorters.JVM) public class NacosRestTemplate_ITCase { - + @LocalServerPort private int port; - - private NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder.getNacosRestTemplate(); - + + private NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder + .getNacosRestTemplate(LoggerFactory.getLogger(NacosRestTemplate_ITCase.class)); + private final String INSTANCE_PATH = "/nacos/v1/ns"; + private final String CONFIG_PATH = "/nacos/v1/cs"; + private String IP = null; - + @Before public void init() throws NacosException { IP = String.format("http://localhost:%d", port); } - + @Test - public void test_url_post_config() throws Exception { + public void test_url_post_config() throws Exception { String url = IP + CONFIG_PATH + "/configs"; Map param = new HashMap<>(); param.put("dataId", "test-1"); param.put("group", "DEFAULT_GROUP"); param.put("content", "aaa=b"); - HttpRestResult restResult = nacosRestTemplate.postForm(url, Header.newInstance(), Query.EMPTY, param, String.class); + HttpRestResult restResult = nacosRestTemplate + .postForm(url, Header.newInstance(), Query.EMPTY, param, String.class); Assert.assertTrue(restResult.ok()); System.out.println(restResult.getData()); System.out.println(restResult.getHeader()); } - + @Test - public void test_url_get_return_restResult() throws Exception{ + public void test_url_get_return_restResult() throws Exception { String url = IP + CONFIG_PATH + "/configs"; - Query query = Query.newInstance().addParam("beta", true).addParam("dataId","test-1").addParam("group", "DEFAULT_GROUP"); - HttpRestResult restResult = nacosRestTemplate.get(url, Header.newInstance(), query, new TypeReference>(){}.getType()); + Query query = Query.newInstance().addParam("beta", true).addParam("dataId", "test-1") + .addParam("group", "DEFAULT_GROUP"); + HttpRestResult restResult = nacosRestTemplate + .get(url, Header.newInstance(), query, new TypeReference>() { + }.getType()); Assert.assertTrue(restResult.ok()); System.out.println(restResult.getData()); System.out.println(restResult.getHeader()); } - - + + @Test - public void test_url_post_form() throws Exception{ + public void test_url_post_form() throws Exception { String url = IP + INSTANCE_PATH + "/instance"; Map param = new HashMap<>(); param.put("serviceName", "app-test"); param.put("port", "8080"); param.put("ip", "11.11.11.11"); - HttpRestResult restResult = nacosRestTemplate.postForm(url, Header.newInstance(), Query.newInstance(), param, String.class); + HttpRestResult restResult = nacosRestTemplate + .postForm(url, Header.newInstance(), Query.newInstance(), param, String.class); Assert.assertTrue(restResult.ok()); System.out.println(restResult.getData()); } - + @Test - public void test_url_put_from() throws Exception{ + public void test_url_put_from() throws Exception { String url = IP + INSTANCE_PATH + "/instance"; Map param = new HashMap<>(); param.put("serviceName", "app-test-change"); param.put("port", "8080"); param.put("ip", "11.11.11.11"); - HttpRestResult restResult = nacosRestTemplate.putForm(url, Header.newInstance(), Query.newInstance(), param, String.class); + HttpRestResult restResult = nacosRestTemplate + .putForm(url, Header.newInstance(), Query.newInstance(), param, String.class); Assert.assertTrue(restResult.ok()); System.out.println(restResult.getData()); } - + @Test public void test_url_get() throws Exception { String url = IP + INSTANCE_PATH + "/instance/list"; @@ -124,7 +137,7 @@ public class NacosRestTemplate_ITCase { Assert.assertEquals(restResult.getData().get("dom"), "app-test"); System.out.println(restResult.getData()); } - + @Test public void test_url_get_by_map() throws Exception { String url = IP + INSTANCE_PATH + "/instance/list"; @@ -135,17 +148,15 @@ public class NacosRestTemplate_ITCase { Assert.assertEquals(restResult.getData().get("dom"), "app-test"); System.out.println(restResult.getData()); } - + @Test - public void test_url_delete() throws Exception{ + public void test_url_delete() throws Exception { String url = IP + INSTANCE_PATH + "/instance"; - Query query = Query.newInstance() - .addParam("ip", "11.11.11.11") - .addParam("port", "8080") - .addParam("serviceName", "app-test"); - HttpRestResult restResult = nacosRestTemplate.delete(url, Header.newInstance(), query, String.class); + Query query = Query.newInstance().addParam("ip", "11.11.11.11").addParam("port", "8080") + .addParam("serviceName", "app-test"); + HttpRestResult restResult = nacosRestTemplate.delete(url, Header.newInstance(), query, String.class); Assert.assertTrue(restResult.ok()); System.out.println(restResult); } - + } 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 14a96dccf..de36a71df 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 @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.test.common; import com.alibaba.nacos.Nacos; @@ -31,6 +32,7 @@ import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; @@ -44,26 +46,28 @@ import java.util.HashMap; import java.util.Map; /** - * NacosRestTemplate_Interceptors_ITCase + * NacosRestTemplate_Interceptors_ITCase * * @author mai.jh */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = Nacos.class, properties = { + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @FixMethodOrder(MethodSorters.JVM) public class NacosRestTemplate_Interceptors_ITCase { - + @LocalServerPort private int port; - - private NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder.getNacosRestTemplate(); - + + private NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder + .getNacosRestTemplate(LoggerFactory.getLogger(NacosRestTemplate_Interceptors_ITCase.class)); + private final String CONFIG_PATH = "/nacos/v1/cs"; + private String IP = null; private class TerminationInterceptor implements HttpClientRequestInterceptor { - + @Override public HttpClientResponse intercept() { return new HttpClientResponse() { @@ -71,36 +75,36 @@ public class NacosRestTemplate_Interceptors_ITCase { public Header getHeaders() { return Header.EMPTY; } - + @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("Stop request".getBytes()); } - + @Override public int getStatusCode() { return NacosException.SERVER_ERROR; } - + @Override public String getStatusText() { return null; } - + @Override public void close() throws IOException { } }; } - + @Override public boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) { return true; } } - + @Before public void init() throws NacosException { nacosRestTemplate.setInterceptors(Arrays.asList(new TerminationInterceptor())); @@ -108,13 +112,14 @@ public class NacosRestTemplate_Interceptors_ITCase { } @Test - public void test_url_post_config() throws Exception { + public void test_url_post_config() throws Exception { String url = IP + CONFIG_PATH + "/configs"; Map param = new HashMap<>(); param.put("dataId", "test-1"); param.put("group", "DEFAULT_GROUP"); param.put("content", "aaa=b"); - HttpRestResult restResult = nacosRestTemplate.postForm(url, Header.newInstance(), Query.EMPTY, param, String.class); + HttpRestResult restResult = nacosRestTemplate + .postForm(url, Header.newInstance(), Query.EMPTY, param, String.class); Assert.assertEquals(500, restResult.getCode()); Assert.assertEquals("Stop request", restResult.getData()); System.out.println(restResult.getData()); From fee6cf4dc947a347f33f6191d3451e1bf8d48015 Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Tue, 14 Jul 2020 15:10:25 +0800 Subject: [PATCH 11/17] Replace original EventDispatcher with NotifyCenter in the config module. (#3313) * [ISSUE##2859]Replace some usage of EventDispatcher for ConfigCacheService and LongPollingService. * [ISSUE##2859]Replace some usage of EventDispatcher for AsyncNotifyService and ConfigChangePublisher. * [ISSUE#3179]fix typo. * [ISSUE#3179]fix typo. * [ISSUE#3179]fix typo. --- .../model/event/ConfigDataChangeEvent.java | 4 +- .../model/event/LocalDataChangeEvent.java | 4 +- .../server/service/ConfigCacheService.java | 89 ++++++++++--------- .../server/service/ConfigChangePublisher.java | 5 +- .../server/service/LongPollingService.java | 52 ++++++----- .../service/merge/MergeTaskProcessor.java | 19 ++-- .../service/notify/AsyncNotifyService.java | 73 +++++++-------- .../service/ConfigChangePublisherTest.java | 27 +++--- 8 files changed, 145 insertions(+), 128 deletions(-) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java index 66be77ffe..3d816932a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java @@ -16,7 +16,7 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event; +import com.alibaba.nacos.common.notify.Event; import org.apache.commons.lang3.StringUtils; /** @@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils; * * @author Nacos */ -public class ConfigDataChangeEvent implements Event { +public class ConfigDataChangeEvent extends Event { public final boolean isBeta; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java index 493783ff6..9a99c4e5d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java @@ -16,7 +16,7 @@ package com.alibaba.nacos.config.server.model.event; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event; +import com.alibaba.nacos.common.notify.Event; import java.util.List; @@ -25,7 +25,7 @@ import java.util.List; * * @author Nacos */ -public class LocalDataChangeEvent implements Event { +public class LocalDataChangeEvent extends Event { public final String groupKey; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java index 40983c036..0a525b285 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.CacheItem; @@ -26,7 +27,6 @@ import com.alibaba.nacos.config.server.utils.DiskUtil; import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.PropertyUtil; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,12 +67,12 @@ public class ConfigCacheService { /** * Save config file and update md5 value in cache. * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @param content content string value. + * @param dataId dataId string value. + * @param group group string value. + * @param tenant tenant string value. + * @param content content string value. * @param lastModifiedTs lastModifiedTs. - * @param type file type. + * @param type file type. * @return dumpChange success or not. */ public static boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs, @@ -120,12 +120,12 @@ public class ConfigCacheService { /** * Save config file and update md5 value in cache. * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @param content content string value. + * @param dataId dataId string value. + * @param group group string value. + * @param tenant tenant string value. + * @param content content string value. * @param lastModifiedTs lastModifiedTs. - * @param betaIps betaIps string value. + * @param betaIps betaIps string value. * @return dumpChange success or not. */ public static boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs, @@ -165,12 +165,12 @@ public class ConfigCacheService { /** * Save config file and update md5 value in cache. * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @param content content string value. + * @param dataId dataId string value. + * @param group group string value. + * @param tenant tenant string value. + * @param content content string value. * @param lastModifiedTs lastModifiedTs. - * @param tag tag string value. + * @param tag tag string value. * @return dumpChange success or not. */ public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content, @@ -209,10 +209,10 @@ public class ConfigCacheService { /** * Save config file and update md5 value in cache. * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @param content content string value. + * @param dataId dataId string value. + * @param group group string value. + * @param tenant tenant string value. + * @param content content string value. * @param lastModifiedTs lastModifiedTs. * @return dumpChange success or not. */ @@ -313,6 +313,7 @@ public class ConfigCacheService { /** * Check md5. + * * @return return diff result list. */ public static List checkMd5() { @@ -343,20 +344,20 @@ public class ConfigCacheService { * Delete config file, and delete cache. * * @param dataId dataId string value. - * @param group group string value. + * @param group group string value. * @param tenant tenant string value. * @return remove success or not. */ public static boolean remove(String dataId, String group, String tenant) { final String groupKey = GroupKey2.getKey(dataId, group, tenant); final int lockResult = tryWriteLock(groupKey); - + // If data is non-existent. if (0 == lockResult) { DUMP_LOG.info("[remove-ok] {} not exist.", groupKey); return true; } - + // try to lock failed if (lockResult < 0) { DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey); @@ -368,7 +369,7 @@ public class ConfigCacheService { DiskUtil.removeConfigInfo(dataId, group, tenant); } CACHE.remove(groupKey); - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); return true; } finally { @@ -380,7 +381,7 @@ public class ConfigCacheService { * Delete beta config file, and delete cache. * * @param dataId dataId string value. - * @param group group string value. + * @param group group string value. * @param tenant tenant string value. * @return remove success or not. */ @@ -393,7 +394,7 @@ public class ConfigCacheService { DUMP_LOG.info("[remove-ok] {} not exist.", groupKey); return true; } - + // try to lock failed if (lockResult < 0) { DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey); @@ -404,7 +405,7 @@ public class ConfigCacheService { if (!PropertyUtil.isDirectRead()) { DiskUtil.removeConfigInfo4Beta(dataId, group, tenant); } - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta())); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta())); CACHE.get(groupKey).setBeta(false); CACHE.get(groupKey).setIps4Beta(null); CACHE.get(groupKey).setMd54Beta(Constants.NULL); @@ -418,21 +419,21 @@ public class ConfigCacheService { * Delete tag config file, and delete cache. * * @param dataId dataId string value. - * @param group group string value. + * @param group group string value. * @param tenant tenant string value. - * @param tag tag string value. + * @param tag tag string value. * @return remove success or not. */ public static boolean removeTag(String dataId, String group, String tenant, String tag) { final String groupKey = GroupKey2.getKey(dataId, group, tenant); final int lockResult = tryWriteLock(groupKey); - + // If data is non-existent. if (0 == lockResult) { DUMP_LOG.info("[remove-ok] {} not exist.", groupKey); return true; } - + // try to lock failed if (lockResult < 0) { DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey); @@ -447,7 +448,7 @@ public class ConfigCacheService { CacheItem ci = CACHE.get(groupKey); ci.tagMd5.remove(tag); ci.tagLastModifiedTs.remove(tag); - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); return true; } finally { releaseWriteLock(groupKey); @@ -457,8 +458,8 @@ public class ConfigCacheService { /** * Update md5 value. * - * @param groupKey groupKey string value. - * @param md5 md5 string value. + * @param groupKey groupKey string value. + * @param md5 md5 string value. * @param lastModifiedTs lastModifiedTs long value. */ public static void updateMd5(String groupKey, String md5, long lastModifiedTs) { @@ -466,16 +467,16 @@ public class ConfigCacheService { if (cache.md5 == null || !cache.md5.equals(md5)) { cache.md5 = md5; cache.lastModifiedTs = lastModifiedTs; - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); } } /** * Update Beta md5 value. * - * @param groupKey groupKey string value. - * @param md5 md5 string value. - * @param ips4Beta ips4Beta List. + * @param groupKey groupKey string value. + * @param md5 md5 string value. + * @param ips4Beta ips4Beta List. * @param lastModifiedTs lastModifiedTs long value. */ public static void updateBetaMd5(String groupKey, String md5, List ips4Beta, long lastModifiedTs) { @@ -485,16 +486,16 @@ public class ConfigCacheService { cache.md54Beta = md5; cache.lastModifiedTs4Beta = lastModifiedTs; cache.ips4Beta = ips4Beta; - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta)); } } /** * Update tag md5 value. * - * @param groupKey groupKey string value. - * @param tag tag string value. - * @param md5 md5 string value. + * @param groupKey groupKey string value. + * @param tag tag string value. + * @param md5 md5 string value. * @param lastModifiedTs lastModifiedTs long value. */ public static void updateTagMd5(String groupKey, String tag, String md5, long lastModifiedTs) { @@ -510,13 +511,13 @@ public class ConfigCacheService { } else { cache.tagLastModifiedTs.put(tag, lastModifiedTs); } - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); return; } if (cache.tagMd5.get(tag) == null || !cache.tagMd5.get(tag).equals(md5)) { cache.tagMd5.put(tag, md5); cache.tagLastModifiedTs.put(tag, lastModifiedTs); - EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag)); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigChangePublisher.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigChangePublisher.java index d9279218d..99fdeaf0b 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigChangePublisher.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigChangePublisher.java @@ -16,9 +16,9 @@ package com.alibaba.nacos.config.server.service; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.utils.PropertyUtil; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher; import com.alibaba.nacos.core.utils.ApplicationUtils; /** @@ -30,13 +30,14 @@ public class ConfigChangePublisher { /** * Notify ConfigChange. + * * @param event ConfigDataChangeEvent instance. */ public static void notifyConfigChange(ConfigDataChangeEvent event) { if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) { return; } - EventDispatcher.fireEvent(event); + NotifyCenter.publishEvent(event); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java index 2a92f5d41..a6a20bdda 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java @@ -16,6 +16,9 @@ package com.alibaba.nacos.config.server.service; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.CollectionUtils; import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.config.server.model.SampleResult; @@ -26,8 +29,7 @@ import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.MD5Util; import com.alibaba.nacos.config.server.utils.RequestUtil; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event; + import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -58,7 +60,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG; * @author Nacos */ @Service -public class LongPollingService extends AbstractEventListener { +public class LongPollingService { private static final int FIXED_POLLING_INTERVAL_MS = 10000; @@ -277,25 +279,6 @@ public class LongPollingService extends AbstractEventListener { new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag)); } - @Override - public List> interest() { - List> eventTypes = new ArrayList>(); - eventTypes.add(LocalDataChangeEvent.class); - return eventTypes; - } - - @Override - public void onEvent(Event event) { - if (isFixedPolling()) { - // Ignore. - } else { - if (event instanceof LocalDataChangeEvent) { - LocalDataChangeEvent evt = (LocalDataChangeEvent) event; - ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); - } - } - } - public static boolean isSupportLongPolling(HttpServletRequest req) { return null != req.getHeader(LONG_POLLING_HEADER); } @@ -305,6 +288,31 @@ public class LongPollingService extends AbstractEventListener { allSubs = new ConcurrentLinkedQueue(); ConfigExecutor.scheduleLongPolling(new StatTask(), 0L, 10L, TimeUnit.SECONDS); + + // Register LocalDataChangeEvent to NotifyCenter. + NotifyCenter.registerToPublisher(LocalDataChangeEvent.class, NotifyCenter.ringBufferSize); + + // Register A Subscriber to subscribe LocalDataChangeEvent. + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(Event event) { + if (isFixedPolling()) { + // Ignore. + } else { + if (event instanceof LocalDataChangeEvent) { + LocalDataChangeEvent evt = (LocalDataChangeEvent) event; + ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); + } + } + } + + @Override + public Class subscribeType() { + return LocalDataChangeEvent.class; + } + }); + } public static final String LONG_POLLING_HEADER = "Long-Pulling-Timeout"; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessor.java b/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessor.java index 1e9f4fe6d..0ec866715 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessor.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessor.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.merge; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.manager.AbstractTask; import com.alibaba.nacos.config.server.manager.TaskProcessor; @@ -27,7 +28,6 @@ import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.utils.ContentUtils; import com.alibaba.nacos.config.server.utils.TimeUtils; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher; import com.alibaba.nacos.core.utils.InetUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -79,8 +79,9 @@ public class MergeTaskProcessor implements TaskProcessor { persistService.insertOrUpdate(null, null, cf, time, null); - LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, datumList.size(), - cf.getContent().length(), cf.getMd5(), ContentUtils.truncateContent(cf.getContent())); + LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, + datumList.size(), cf.getContent().length(), cf.getMd5(), + ContentUtils.truncateContent(cf.getContent())); ConfigTraceService .logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(), @@ -93,14 +94,14 @@ public class MergeTaskProcessor implements TaskProcessor { persistService.removeConfigInfoTag(dataId, group, tenant, tag, clientIp, null); } - LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + group); + LOGGER.warn( + "[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + group); ConfigTraceService .logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(), ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null); } - - EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime())); + NotifyCenter.publishEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime())); } catch (Exception e) { mergeService.addMergeTask(dataId, group, tenant, mergeTask.getClientIp()); @@ -113,9 +114,9 @@ public class MergeTaskProcessor implements TaskProcessor { /** * merge datumList {@link ConfigInfoAggr}. * - * @param dataId data id - * @param group group - * @param tenant tenant + * @param dataId data id + * @param group group + * @param tenant tenant * @param datumList datumList * @return {@link ConfigInfo} */ diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java index 1a5a82aac..c78247294 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java @@ -16,6 +16,9 @@ package com.alibaba.nacos.config.server.service.notify; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.monitor.MetricsMonitor; @@ -23,8 +26,6 @@ import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event; import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.utils.ApplicationUtils; @@ -46,10 +47,8 @@ import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.MessageFormat; -import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; -import java.util.List; import java.util.Queue; import java.util.concurrent.TimeUnit; @@ -59,42 +58,46 @@ import java.util.concurrent.TimeUnit; * @author Nacos */ @Service -public class AsyncNotifyService extends AbstractEventListener { - - @Override - public List> interest() { - List> types = new ArrayList>(); - // Trigger configuration change synchronization notification - types.add(ConfigDataChangeEvent.class); - return types; - } - - @Override - public void onEvent(Event event) { - - // Generate ConfigDataChangeEvent concurrently - if (event instanceof ConfigDataChangeEvent) { - ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; - long dumpTs = evt.lastModifiedTs; - String dataId = evt.dataId; - String group = evt.group; - String tenant = evt.tenant; - String tag = evt.tag; - Collection ipList = memberManager.allMembers(); - - // In fact, any type of queue here can be - Queue queue = new LinkedList(); - for (Member member : ipList) { - queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(), evt.isBeta)); - } - ConfigExecutor.executeAsyncNotify(new AsyncTask(httpclient, queue)); - } - } +public class AsyncNotifyService { @Autowired public AsyncNotifyService(ServerMemberManager memberManager) { this.memberManager = memberManager; httpclient.start(); + + // Register ConfigDataChangeEvent to NotifyCenter. + NotifyCenter.registerToPublisher(ConfigDataChangeEvent.class, NotifyCenter.ringBufferSize); + + // Register A Subscriber to subscribe ConfigDataChangeEvent. + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(Event event) { + // Generate ConfigDataChangeEvent concurrently + if (event instanceof ConfigDataChangeEvent) { + ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; + long dumpTs = evt.lastModifiedTs; + String dataId = evt.dataId; + String group = evt.group; + String tenant = evt.tenant; + String tag = evt.tag; + Collection ipList = memberManager.allMembers(); + + // In fact, any type of queue here can be + Queue queue = new LinkedList(); + for (Member member : ipList) { + queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(), + evt.isBeta)); + } + ConfigExecutor.executeAsyncNotify(new AsyncTask(httpclient, queue)); + } + } + + @Override + public Class subscribeType() { + return ConfigDataChangeEvent.class; + } + }); } private RequestConfig requestConfig = RequestConfig.custom() diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigChangePublisherTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigChangePublisherTest.java index a6e97ab74..224e1e6fa 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigChangePublisherTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigChangePublisherTest.java @@ -16,33 +16,35 @@ package com.alibaba.nacos.config.server.service; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.utils.PropertyUtil; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher; import com.alibaba.nacos.core.utils.ApplicationUtils; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; -import java.util.List; import java.util.concurrent.atomic.AtomicReference; public class ConfigChangePublisherTest { @Test - public void testConfigChangeNotify() { + public void testConfigChangeNotify() throws InterruptedException { AtomicReference reference = new AtomicReference<>(); - EventDispatcher.addEventListener(new EventDispatcher.AbstractEventListener() { + NotifyCenter.registerToPublisher(ConfigDataChangeEvent.class, NotifyCenter.ringBufferSize); + NotifyCenter.registerSubscriber(new Subscriber() { + @Override - public List> interest() { - return Collections.singletonList(ConfigDataChangeEvent.class); + public void onEvent(Event event) { + reference.set((ConfigDataChangeEvent) event); } @Override - public void onEvent(EventDispatcher.Event event) { - reference.set((ConfigDataChangeEvent) event); + public Class subscribeType() { + return ConfigDataChangeEvent.class; } }); @@ -52,33 +54,34 @@ public class ConfigChangePublisherTest { ConfigChangePublisher .notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis())); + Thread.sleep(2000); Assert.assertNotNull(reference.get()); reference.set(null); // nacos is standalone mode and use external storage ApplicationUtils.setIsStandalone(true); PropertyUtil.setEmbeddedStorage(false); - ConfigChangePublisher .notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis())); + Thread.sleep(2000); Assert.assertNotNull(reference.get()); reference.set(null); // nacos is cluster mode and use embedded storage ApplicationUtils.setIsStandalone(false); PropertyUtil.setEmbeddedStorage(true); - ConfigChangePublisher .notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis())); + Thread.sleep(2000); Assert.assertNull(reference.get()); reference.set(null); // nacos is cluster mode and use external storage ApplicationUtils.setIsStandalone(false); PropertyUtil.setEmbeddedStorage(false); - ConfigChangePublisher .notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis())); + Thread.sleep(2000); Assert.assertNotNull(reference.get()); reference.set(null); } From 132adb48996704776f452f4a25c4ce9e3d998a66 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Tue, 14 Jul 2020 19:37:37 +0800 Subject: [PATCH 12/17] [ISSUE##3317]Change the http client implementation that nacos resttemplate depends on from apache to JDk (#3322) * fix:#3317 change the http client implementation that nacos resttemplate depends on from apache to JDk * Use the IoUtils.closeQuietly() method to close the InputStream * change HttpClientBeanHolder logger output object --- .../http/AbstractHttpClientFactory.java | 8 +- .../common/http/HttpClientBeanHolder.java | 2 +- .../http/client/HttpClientResponse.java | 6 +- .../http/client/JdkHttpClientRequest.java | 100 ++++++++++++++++++ .../http/client/JdkHttpClientResponse.java | 78 ++++++++++++++ 5 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientRequest.java create mode 100644 common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java diff --git a/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java b/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java index b3ed2568d..e09a29b21 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/AbstractHttpClientFactory.java @@ -17,11 +17,10 @@ package com.alibaba.nacos.common.http; import com.alibaba.nacos.common.http.client.DefaultAsyncHttpClientRequest; -import com.alibaba.nacos.common.http.client.DefaultHttpClientRequest; +import com.alibaba.nacos.common.http.client.JdkHttpClientRequest; import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate; import com.alibaba.nacos.common.http.client.NacosRestTemplate; import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.slf4j.Logger; @@ -34,9 +33,8 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory { @Override public final NacosRestTemplate createNacosRestTemplate() { - RequestConfig requestConfig = getRequestConfig(); - return new NacosRestTemplate(assignLogger(), - new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(requestConfig).build())); + HttpClientConfig httpClientConfig = buildHttpClientConfig(); + return new NacosRestTemplate(assignLogger(), new JdkHttpClientRequest(httpClientConfig)); } @Override diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java index 0e264985d..ce6f8ca37 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java @@ -35,7 +35,7 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public final class HttpClientBeanHolder { - private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class); + private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientBeanHolder.class); private static final Map SINGLETON_REST = new HashMap(10); diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientResponse.java b/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientResponse.java index 0aaac2f38..e11a26f28 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientResponse.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/HttpClientResponse.java @@ -48,15 +48,17 @@ public interface HttpClientResponse extends Closeable { * Return the HTTP status code. * * @return the HTTP status as an integer + * @throws IOException IOException */ - int getStatusCode(); + int getStatusCode() throws IOException; /** * Return the HTTP status text of the response. * * @return the HTTP status text + * @throws IOException IOException */ - String getStatusText(); + String getStatusText() throws IOException; /** * close response InputStream. diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientRequest.java b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientRequest.java new file mode 100644 index 000000000..538dd061a --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientRequest.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.common.http.client; + +import com.alibaba.nacos.common.constant.HttpHeaderConsts; +import com.alibaba.nacos.common.http.HttpClientConfig; +import com.alibaba.nacos.common.http.HttpUtils; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.http.param.MediaType; +import com.alibaba.nacos.common.model.RequestHttpEntity; +import com.alibaba.nacos.common.utils.JacksonUtils; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +/** + * JDK http client request implement. + * + * @author mai.jh + */ +public class JdkHttpClientRequest implements HttpClientRequest { + + private HttpClientConfig httpClientConfig; + + public JdkHttpClientRequest(HttpClientConfig httpClientConfig) { + this.httpClientConfig = httpClientConfig; + } + + @Override + public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) + throws Exception { + final Object body = requestHttpEntity.getBody(); + final Header headers = requestHttpEntity.getHeaders(); + replaceDefaultConfig(requestHttpEntity.getHttpClientConfig()); + + HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection(); + Map headerMap = headers.getHeader(); + if (headerMap != null && headerMap.size() > 0) { + for (Map.Entry entry : headerMap.entrySet()) { + conn.setRequestProperty(entry.getKey(), entry.getValue()); + } + } + + conn.setConnectTimeout(this.httpClientConfig.getConTimeOutMillis()); + conn.setReadTimeout(this.httpClientConfig.getReadTimeOutMillis()); + conn.setRequestMethod(httpMethod); + if (body != null) { + String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE); + String bodyStr = JacksonUtils.toJson(body); + if (MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) { + Map map = JacksonUtils.toObj(bodyStr, HashMap.class); + bodyStr = HttpUtils.encodingParams(map, headers.getCharset()); + } + if (bodyStr != null) { + conn.setDoOutput(true); + byte[] b = bodyStr.getBytes(); + conn.setRequestProperty("Content-Length", String.valueOf(b.length)); + conn.getOutputStream().write(b, 0, b.length); + conn.getOutputStream().flush(); + conn.getOutputStream().close(); + } + } + conn.connect(); + return new JdkHttpClientResponse(conn); + } + + /** + * Replace the HTTP config created by default with the HTTP config specified in the request. + * + * @param replaceConfig http config + */ + private void replaceDefaultConfig(HttpClientConfig replaceConfig) { + if (replaceConfig == null) { + return; + } + this.httpClientConfig = replaceConfig; + } + + @Override + public void close() throws IOException { + + } +} diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java new file mode 100644 index 000000000..6ca7650e6 --- /dev/null +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java @@ -0,0 +1,78 @@ +/* + * 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.common.http.client; + +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.utils.IoUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.List; +import java.util.Map; + +/** + * JDk http client response implement. + * + * @author mai.jh + */ +public class JdkHttpClientResponse implements HttpClientResponse { + + private final HttpURLConnection conn; + + private InputStream responseStream; + + private Header responseHeader; + + public JdkHttpClientResponse(HttpURLConnection conn) { + this.conn = conn; + } + + @Override + public Header getHeaders() { + if (this.responseHeader == null) { + this.responseHeader = Header.newInstance(); + } + + for (Map.Entry> entry : conn.getHeaderFields().entrySet()) { + this.responseHeader.addParam(entry.getKey(), entry.getValue().get(0)); + } + return this.responseHeader; + } + + @Override + public InputStream getBody() throws IOException { + InputStream errorStream = this.conn.getErrorStream(); + this.responseStream = (errorStream != null ? errorStream : this.conn.getInputStream()); + return this.responseStream; + } + + @Override + public int getStatusCode() throws IOException { + return this.conn.getResponseCode(); + } + + @Override + public String getStatusText() throws IOException { + return this.conn.getResponseMessage(); + } + + @Override + public void close() { + IoUtils.closeQuietly(this.responseStream); + } +} From 52d9cf9cf9bdd537ec4417996e70776fd03a93dc Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Tue, 14 Jul 2020 19:38:08 +0800 Subject: [PATCH 13/17] [ISSUE##2859]Remove original EventDispatcher in the config module. (#3319) --- .../server/utils/event/EventDispatcher.java | 143 ------------------ .../utils/event/EventDispatcherTest.java | 98 ------------ 2 files changed, 241 deletions(-) delete mode 100644 config/src/main/java/com/alibaba/nacos/config/server/utils/event/EventDispatcher.java delete mode 100755 config/src/test/java/com/alibaba/nacos/config/server/utils/event/EventDispatcherTest.java diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/event/EventDispatcher.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/event/EventDispatcher.java deleted file mode 100644 index ca0318741..000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/event/EventDispatcher.java +++ /dev/null @@ -1,143 +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.config.server.utils.event; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * Event dispatcher. - * - * @author Nacos - */ -public class EventDispatcher { - - /** - * add event listener. - */ - public static void addEventListener(AbstractEventListener listener) { - for (Class type : listener.interest()) { - getEntry(type).listeners.addIfAbsent(listener); - } - } - - /** - * fire event, notify listeners. - */ - public static void fireEvent(Event event) { - if (null == event) { - throw new IllegalArgumentException("event is null"); - } - - for (AbstractEventListener listener : getEntry(event.getClass()).listeners) { - try { - listener.onEvent(event); - } catch (Exception e) { - LOGGER.error(e.toString(), e); - } - } - } - - /** - * For only test purpose. - */ - public static void clear() { - LISTENER_HUB.clear(); - } - - /** - * Get event listener for eventType. Add Entry if not exist. - */ - static Entry getEntry(Class eventType) { - for (; ; ) { - for (Entry entry : LISTENER_HUB) { - if (entry.eventType == eventType) { - return entry; - } - } - - Entry tmp = new Entry(eventType); - // false means already exists - if (LISTENER_HUB.addIfAbsent(tmp)) { - return tmp; - } - } - } - - private static class Entry { - - final Class eventType; - - final CopyOnWriteArrayList listeners; - - Entry(Class type) { - eventType = type; - listeners = new CopyOnWriteArrayList(); - } - - @Override - public boolean equals(Object obj) { - if (null == obj || obj.getClass() != getClass()) { - return false; - } - if (this == obj) { - return true; - } - return eventType == ((Entry) obj).eventType; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - } - - private static final Logger LOGGER = LoggerFactory.getLogger(EventDispatcher.class); - - static final CopyOnWriteArrayList LISTENER_HUB = new CopyOnWriteArrayList(); - - public interface Event { - - } - - public abstract static class AbstractEventListener { - - public AbstractEventListener() { - // automatic register - EventDispatcher.addEventListener(this); - } - - /** - * List of events of interest. - * - * @return event list - */ - public abstract List> interest(); - - /** - * Handle events. - * - * @param event event - */ - public abstract void onEvent(Event event); - } - -} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/utils/event/EventDispatcherTest.java b/config/src/test/java/com/alibaba/nacos/config/server/utils/event/EventDispatcherTest.java deleted file mode 100755 index cdfe9d0dc..000000000 --- a/config/src/test/java/com/alibaba/nacos/config/server/utils/event/EventDispatcherTest.java +++ /dev/null @@ -1,98 +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.config.server.utils.event; - -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener; -import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event; -import org.junit.After; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -public class EventDispatcherTest { - - @After - public void after() { - EventDispatcher.clear(); - } - - @Ignore - @Test - public void testAddListener() throws Exception { - final AbstractEventListener listener = new MockListener(); - - int vusers = 1000; - final CountDownLatch latch = new CountDownLatch(vusers); - - for (int i = 0; i < vusers; ++i) { - new Thread(new Runnable() { - public void run() { - latch.countDown(); - EventDispatcher.addEventListener(listener); - } - }).start(); - } - - latch.await(); - assertEquals(1, EventDispatcher.LISTENER_HUB.size()); - } - - @Test - public void testFireEvent() { - EventDispatcher.fireEvent(new MockEvent()); - assertEquals(0, MockListener.count); - - EventDispatcher.addEventListener(new MockListener()); - - EventDispatcher.fireEvent(new MockEvent()); - assertEquals(1, MockListener.count); - - EventDispatcher.fireEvent(new MockEvent()); - assertEquals(2, MockListener.count); - } - - private static class MockEvent implements Event { - - } - - private static class MockListener extends AbstractEventListener { - - static int count = 0; - - @Override - public List> interest() { - List> types = new ArrayList>(); - types.add(MockEvent.class); - return types; - } - - @Override - public void onEvent(Event event) { - ++count; - } - } -} From 0163d2d0c707c8c791f972f53d322adbb9e68c20 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Wed, 15 Jul 2020 14:12:44 +0800 Subject: [PATCH 14/17] fix: #3324, Move http client close method to NamingProxy.shutdown() (#3333) --- .../naming/net/NamingHttpClientManager.java | 35 +++++++-- .../nacos/client/naming/net/NamingProxy.java | 5 +- .../nacos/client/security/SecurityProxy.java | 2 +- .../common/http/HttpClientBeanHolder.java | 78 ++++++++----------- .../alibaba/nacos/test/naming/NamingBase.java | 2 +- 5 files changed, 66 insertions(+), 56 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java index a900c2b8c..b66ee09e1 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingHttpClientManager.java @@ -16,20 +16,24 @@ package com.alibaba.nacos.client.naming.net; -import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.common.http.AbstractHttpClientFactory; import com.alibaba.nacos.common.http.HttpClientBeanHolder; import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpClientFactory; import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.lifecycle.Closeable; +import com.alibaba.nacos.common.utils.ExceptionUtil; import org.slf4j.Logger; +import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; + /** * http Manager. * * @author mai.jh */ -public class NamingHttpClientManager { +public class NamingHttpClientManager implements Closeable { private static final int READ_TIME_OUT_MILLIS = Integer .getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000); @@ -42,17 +46,38 @@ public class NamingHttpClientManager { private static final HttpClientFactory HTTP_CLIENT_FACTORY = new NamingHttpClientFactory(); - public static String getPrefix() { + private static class NamingHttpClientManagerInstance { + + private static final NamingHttpClientManager INSTANCE = new NamingHttpClientManager(); + } + + public static NamingHttpClientManager getInstance() { + return NamingHttpClientManagerInstance.INSTANCE; + } + + public String getPrefix() { if (ENABLE_HTTPS) { return "https://"; } return "http://"; } - public static NacosRestTemplate getNacosRestTemplate() { + public NacosRestTemplate getNacosRestTemplate() { return HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY); } + @Override + public void shutdown() throws NacosException { + NAMING_LOGGER.warn("[NamingHttpClientManager] Start destroying NacosRestTemplate"); + try { + HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName()); + } catch (Exception ex) { + NAMING_LOGGER.error("[NamingHttpClientManager] An exception occurred when the HTTP client was closed : {}", + ExceptionUtil.getStackTrace(ex)); + } + NAMING_LOGGER.warn("[NamingHttpClientManager] Destruction of the end"); + } + private static class NamingHttpClientFactory extends AbstractHttpClientFactory { @Override @@ -63,7 +88,7 @@ public class NamingHttpClientManager { @Override protected Logger assignLogger() { - return LogUtils.NAMING_LOGGER; + return NAMING_LOGGER; } } } diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java index f9f685e45..ba85bde72 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java @@ -79,7 +79,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; */ public class NamingProxy implements Closeable { - private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate(); + private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate(); private static final int DEFAULT_SERVER_PORT = 8848; @@ -591,7 +591,7 @@ public class NamingProxy implements Closeable { if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) { curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort; } - url = NamingHttpClientManager.getPrefix() + curServer + api; + url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api; } try { @@ -714,6 +714,7 @@ public class NamingProxy implements Closeable { String className = this.getClass().getName(); NAMING_LOGGER.info("{} do shutdown begin", className); ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER); + NamingHttpClientManager.getInstance().shutdown(); NAMING_LOGGER.info("{} do shutdown stop", className); } } diff --git a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java index a1f1df5f1..44b6a5f6d 100644 --- a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java @@ -46,7 +46,7 @@ public class SecurityProxy { private static final String LOGIN_URL = "/v1/auth/users/login"; - private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate(); + private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate(); private String contextPath; diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java index ce6f8ca37..6008662d4 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpClientBeanHolder.java @@ -18,15 +18,10 @@ package com.alibaba.nacos.common.http; import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate; import com.alibaba.nacos.common.http.client.NacosRestTemplate; -import com.alibaba.nacos.common.utils.ExceptionUtil; -import com.alibaba.nacos.common.utils.ThreadUtils; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; /** * Create a rest template to ensure that each custom client config and rest template are in one-to-one correspondence. @@ -35,22 +30,10 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public final class HttpClientBeanHolder { - private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientBeanHolder.class); - private static final Map SINGLETON_REST = new HashMap(10); - private static final Map SINGLETON_ASYNC_REST = new HashMap(10); - - private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false); - - static { - ThreadUtils.addShutdownHook(new Runnable() { - @Override - public void run() { - shutdown(); - } - }); - } + private static final Map SINGLETON_ASYNC_REST = new HashMap( + 10); public static NacosRestTemplate getNacosRestTemplate(Logger logger) { return getNacosRestTemplate(new DefaultHttpClientFactory(logger)); @@ -99,40 +82,41 @@ public final class HttpClientBeanHolder { } /** - * Shutdown http client holder and close all template. + * Shutdown http client holder and close remove template. + * + * @param className HttpClientFactory implement class name + * @throws Exception ex */ - public static void shutdown() { - if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) { - return; - } - LOGGER.warn("[HttpClientBeanFactory] Start destroying NacosRestTemplate"); - try { - nacostRestTemplateShutdown(); - nacosAsyncRestTemplateShutdown(); - } catch (Exception ex) { - LOGGER.error("[HttpClientBeanFactory] An exception occurred when the HTTP client was closed : {}", - ExceptionUtil.getStackTrace(ex)); - } - LOGGER.warn("[HttpClientBeanFactory] Destruction of the end"); + public static void shutdown(String className) throws Exception { + shutdownNacostSyncRest(className); + shutdownNacosAsyncRest(className); } - private static void nacostRestTemplateShutdown() throws Exception { - if (!SINGLETON_REST.isEmpty()) { - Collection nacosRestTemplates = SINGLETON_REST.values(); - for (NacosRestTemplate nacosRestTemplate : nacosRestTemplates) { - nacosRestTemplate.close(); - } - SINGLETON_REST.clear(); + /** + * Shutdown sync http client holder and remove template. + * + * @param className HttpClientFactory implement class name + * @throws Exception ex + */ + public static void shutdownNacostSyncRest(String className) throws Exception { + final NacosRestTemplate nacosRestTemplate = SINGLETON_REST.get(className); + if (nacosRestTemplate != null) { + nacosRestTemplate.close(); + SINGLETON_REST.remove(className); } } - private static void nacosAsyncRestTemplateShutdown() throws Exception { - if (!SINGLETON_ASYNC_REST.isEmpty()) { - Collection nacosAsyncRestTemplates = SINGLETON_ASYNC_REST.values(); - for (NacosAsyncRestTemplate nacosAsyncRestTemplate : nacosAsyncRestTemplates) { - nacosAsyncRestTemplate.close(); - } - SINGLETON_ASYNC_REST.clear(); + /** + * Shutdown async http client holder and remove template. + * + * @param className HttpClientFactory implement class name + * @throws Exception ex + */ + public static void shutdownNacosAsyncRest(String className) throws Exception { + final NacosAsyncRestTemplate nacosAsyncRestTemplate = SINGLETON_ASYNC_REST.get(className); + if (nacosAsyncRestTemplate != null) { + nacosAsyncRestTemplate.close(); + SINGLETON_ASYNC_REST.remove(className); } } } diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/NamingBase.java b/test/src/test/java/com/alibaba/nacos/test/naming/NamingBase.java index c06ccb8aa..df7bd20e6 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/NamingBase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/NamingBase.java @@ -33,7 +33,7 @@ import java.util.*; */ public class NamingBase extends HttpClient4Test { - private static final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate(); + private static final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate(); public static final String TEST_DOM_1 = "nacos.test.1"; public static final String TEST_IP_4_DOM_1 = "127.0.0.1"; From ff929b75ad8f2d11316c4be8310b56a19828a299 Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Fri, 17 Jul 2020 16:12:08 +0800 Subject: [PATCH 15/17] [ISSUE#3356]fix no throw exception when publish event but no subsciber. (#3363) --- .../nacos/common/notify/NotifyCenter.java | 4 +- .../nacos/common/notify/NotifyCenterTest.java | 39 ++++++++++++++----- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java b/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java index 1798203cf..059fee9fb 100644 --- a/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java +++ b/common/src/main/java/com/alibaba/nacos/common/notify/NotifyCenter.java @@ -290,7 +290,9 @@ public class NotifyCenter { EventPublisher publisher = INSTANCE.publisherMap.get(topic); return publisher.publish(event); } - throw new NoSuchElementException("There are no [" + topic + "] publishers for this event, please register"); + + LOGGER.warn("There are no [{}] publishers for this event, please register", topic); + return false; } /** diff --git a/common/src/test/java/com/alibaba/nacos/common/notify/NotifyCenterTest.java b/common/src/test/java/com/alibaba/nacos/common/notify/NotifyCenterTest.java index 6bf98fa98..a7163938d 100644 --- a/common/src/test/java/com/alibaba/nacos/common/notify/NotifyCenterTest.java +++ b/common/src/test/java/com/alibaba/nacos/common/notify/NotifyCenterTest.java @@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicLong; public class NotifyCenterTest { private static class TestSlowEvent extends SlowEvent { + } private static class TestEvent extends Event { @@ -330,9 +331,11 @@ public class NotifyCenterTest { } private static class TestSlowEvent1 extends SlowEvent { + } private static class TestSlowEvent2 extends SlowEvent { + } @Test @@ -343,10 +346,10 @@ public class NotifyCenterTest { final AtomicInteger count1 = new AtomicInteger(0); final AtomicInteger count2 = new AtomicInteger(0); - + final CountDownLatch latch1 = new CountDownLatch(3); final CountDownLatch latch2 = new CountDownLatch(3); - + NotifyCenter.registerSubscriber(new Subscriber() { @Override public void onEvent(TestSlowEvent1 event) { @@ -365,7 +368,7 @@ public class NotifyCenterTest { public void onEvent(TestSlowEvent2 event) { count2.incrementAndGet(); latch2.countDown(); - + } @Override @@ -373,26 +376,28 @@ public class NotifyCenterTest { return TestSlowEvent2.class; } }); - + for (int i = 0; i < 3; i++) { Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent1())); Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent2())); } - + ThreadUtils.sleep(2000L); - + latch1.await(3000L, TimeUnit.MILLISECONDS); latch2.await(3000L, TimeUnit.MILLISECONDS); - + Assert.assertEquals(3, count1.get()); Assert.assertEquals(3, count2.get()); - + } private static class TestSlowEvent3 extends SlowEvent { + } private static class TestSlowEvent4 extends SlowEvent { + } @Test @@ -408,7 +413,7 @@ public class NotifyCenterTest { final CountDownLatch latch2 = new CountDownLatch(3); NotifyCenter.registerSubscriber(new SmartSubscriber() { - + @Override public void onEvent(Event event) { if (event instanceof TestSlowEvent3) { @@ -421,7 +426,7 @@ public class NotifyCenterTest { latch2.countDown(); } } - + @Override public List> subscribeTypes() { List> subTypes = new ArrayList>(); @@ -447,9 +452,11 @@ public class NotifyCenterTest { } private static class TestSlowEvent5 extends SlowEvent { + } private static class TestEvent6 extends Event { + } @Test @@ -502,4 +509,16 @@ public class NotifyCenterTest { Assert.assertEquals(3, count2.get()); } + + private static class TestEvent7 extends Event { + + } + + @Test + public void testPublishEventByNoSubscriber() { + + for (int i = 0; i < 3; i++) { + Assert.assertFalse(NotifyCenter.publishEvent(new TestEvent7())); + } + } } From 9f12f76d6c7ca08a3ebe3cc8d83ee5c9a203d60f Mon Sep 17 00:00:00 2001 From: Hu Zongtang Date: Fri, 17 Jul 2020 16:12:32 +0800 Subject: [PATCH 16/17] [ISSUE#2859]fix no throw exception when publish event but no subsciber. (#3364) --- .../client/config/impl/EventDispatcher.java | 128 ------------------ .../client/config/impl/ServerListManager.java | 5 +- .../config/impl/ServerlistChangeEvent.java | 27 ++++ 3 files changed, 30 insertions(+), 130 deletions(-) delete mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/EventDispatcher.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ServerlistChangeEvent.java diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/EventDispatcher.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/EventDispatcher.java deleted file mode 100644 index cbb6071c8..000000000 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/EventDispatcher.java +++ /dev/null @@ -1,128 +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.config.impl; - -import com.alibaba.nacos.client.utils.LogUtils; -import org.slf4j.Logger; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * Event subscription and publishing tools. - * - * @author Nacos - */ -public class EventDispatcher { - - private static final Logger LOGGER = LogUtils.logger(EventDispatcher.class); - - /** - * 添加事件监听器. - */ - public static void addEventListener(AbstractEventListener listener) { - for (Class type : listener.interest()) { - getListenerList(type).addIfAbsent(listener); - } - } - - /** - * 发布事件,首先发布该事件暗示的其他事件,最后通知所有对应的监听器. - */ - public static void fireEvent(AbstractEvent abstractEvent) { - if (null == abstractEvent) { - return; - } - - // 发布该事件暗示的其他事件 - for (AbstractEvent implyEvent : abstractEvent.implyEvents()) { - try { - // 避免死循环 - if (abstractEvent != implyEvent) { - fireEvent(implyEvent); - } - } catch (Exception e) { - LOGGER.warn(e.toString(), e); - } - } - - for (AbstractEventListener listener : getListenerList(abstractEvent.getClass())) { - try { - listener.onEvent(abstractEvent); - } catch (Exception e) { - LOGGER.warn(e.toString(), e); - } - } - } - - static synchronized CopyOnWriteArrayList getListenerList( - Class eventType) { - CopyOnWriteArrayList listeners = LISTENER_MAP.get(eventType); - if (null == listeners) { - listeners = new CopyOnWriteArrayList(); - LISTENER_MAP.put(eventType, listeners); - } - return listeners; - } - - @SuppressWarnings("checkstyle:linelength") - static final Map, CopyOnWriteArrayList> LISTENER_MAP = new HashMap, CopyOnWriteArrayList>(); - - /** - * Client事件. - */ - public abstract static class AbstractEvent { - - @SuppressWarnings("unchecked") - protected List implyEvents() { - return Collections.EMPTY_LIST; - } - } - - /** - * 事件监听器. - */ - public abstract static class AbstractEventListener { - - public AbstractEventListener() { - EventDispatcher.addEventListener(this); - } - - /** - * 感兴趣的事件列表. - * - * @return event list - */ - public abstract List> interest(); - - /** - * 处理事件. - * - * @param abstractEvent event to do - */ - public abstract void onEvent(AbstractEvent abstractEvent); - } - - /** - * serverList has changed. - */ - public static class ServerlistChangeEvent extends AbstractEvent { - } -} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java index 3e0a79afe..2c3b2119a 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java @@ -19,13 +19,13 @@ package com.alibaba.nacos.client.config.impl; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.SystemPropertyKeyConst; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEvent; import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.utils.EnvUtil; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.TemplateUtils; import com.alibaba.nacos.common.lifecycle.Closeable; +import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.IoUtils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.ThreadUtils; @@ -335,7 +335,8 @@ public class ServerListManager implements Closeable { iterator = iterator(); currentServerAddr = iterator.next(); - EventDispatcher.fireEvent(new ServerlistChangeEvent()); + // Using unified event processor, NotifyCenter + NotifyCenter.publishEvent(new ServerlistChangeEvent()); LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls); } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerlistChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerlistChangeEvent.java new file mode 100644 index 000000000..c30db33ce --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerlistChangeEvent.java @@ -0,0 +1,27 @@ +/* + * 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.config.impl; + +import com.alibaba.nacos.common.notify.SlowEvent; + +/** + * Server List Change Event. + * + * @author zongtanghu + */ +public class ServerlistChangeEvent extends SlowEvent { +} From 63a4e30ae637100902848999dc0c7219af1e8cd4 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Sat, 18 Jul 2020 14:42:02 +0800 Subject: [PATCH 17/17] [ISSUE #3224]nacos-client module http client replace (#3348) * nacos-client module http client replace * fix code style problem * add HashMap initialCapacity * fix code style problem * Modify the header object, keep the original response header to avoid modifying the original logic code * fix code style problem * naming http client request exception messages output change * Merge code --- .../client/config/NacosConfigService.java | 80 ++- .../nacos/client/config/http/HttpAgent.java | 23 +- .../client/config/http/MetricsHttpAgent.java | 28 +- .../client/config/http/ServerHttpAgent.java | 218 ++++---- .../client/config/impl/ClientWorker.java | 70 ++- .../config/impl/ConfigHttpClientManager.java | 171 +++++++ .../client/config/impl/HttpSimpleClient.java | 3 + .../client/config/impl/ServerListManager.java | 23 +- .../nacos/client/config/impl/SpasAdapter.java | 42 +- .../nacos/client/naming/net/NamingProxy.java | 4 +- .../nacos/client/security/SecurityProxy.java | 6 +- .../alibaba/nacos/client/utils/ParamUtil.java | 3 +- .../http/client/JdkHttpClientResponse.java | 7 +- .../nacos/common/http/param/Header.java | 29 ++ .../nacos/test/config/ConfigAPI_CITCase.java | 479 ++++++++++-------- .../ConfigExportAndImportAPI_CITCase.java | 55 +- 16 files changed, 730 insertions(+), 511 deletions(-) create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java index 80e3280d0..a0c614011 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java @@ -28,21 +28,20 @@ import com.alibaba.nacos.client.config.http.HttpAgent; import com.alibaba.nacos.client.config.http.MetricsHttpAgent; import com.alibaba.nacos.client.config.http.ServerHttpAgent; import com.alibaba.nacos.client.config.impl.ClientWorker; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor; import com.alibaba.nacos.client.config.utils.ContentUtils; import com.alibaba.nacos.client.config.utils.ParamUtils; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.ValidatorUtils; +import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.utils.StringUtils; import org.slf4j.Logger; -import java.io.IOException; import java.net.HttpURLConnection; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; /** @@ -179,37 +178,34 @@ public class NacosConfigService implements ConfigService { group = null2defaultGroup(group); ParamUtils.checkKeyParam(dataId, group); String url = Constants.CONFIG_CONTROLLER_PATH; - List params = new ArrayList(); - params.add("dataId"); - params.add(dataId); - params.add("group"); - params.add(group); + Map params = new HashMap(4); + params.put("dataId", dataId); + params.put("group", group); + if (StringUtils.isNotEmpty(tenant)) { - params.add("tenant"); - params.add(tenant); + params.put("tenant", tenant); } if (StringUtils.isNotEmpty(tag)) { - params.add("tag"); - params.add(tag); + params.put("tag", tag); } - HttpResult result = null; + HttpRestResult result = null; try { result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT); - } catch (IOException ioe) { - LOGGER.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString()); + } catch (Exception ex) { + LOGGER.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ex.toString()); return false; } - if (HttpURLConnection.HTTP_OK == result.code) { + if (result.ok()) { LOGGER.info("[{}] [remove] ok, dataId={}, group={}, tenant={}", agent.getName(), dataId, group, tenant); return true; - } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) { + } else if (HttpURLConnection.HTTP_FORBIDDEN == result.getCode()) { LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId, - group, tenant, result.code, result.content); - throw new NacosException(result.code, result.content); + group, tenant, result.getCode(), result.getMessage()); + throw new NacosException(result.getCode(), result.getMessage()); } else { LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId, - group, tenant, result.code, result.content); + group, tenant, result.getCode(), result.getMessage()); return false; } } @@ -228,52 +224,44 @@ public class NacosConfigService implements ConfigService { content = cr.getContent(); String url = Constants.CONFIG_CONTROLLER_PATH; - List params = new ArrayList(); - params.add("dataId"); - params.add(dataId); - params.add("group"); - params.add(group); - params.add("content"); - params.add(content); + Map params = new HashMap(6); + params.put("dataId", dataId); + params.put("group", group); + params.put("content", content); if (StringUtils.isNotEmpty(tenant)) { - params.add("tenant"); - params.add(tenant); + params.put("tenant", tenant); } if (StringUtils.isNotEmpty(appName)) { - params.add("appName"); - params.add(appName); + params.put("appName", appName); } if (StringUtils.isNotEmpty(tag)) { - params.add("tag"); - params.add(tag); + params.put("tag", tag); } - - List headers = new ArrayList(); + Map headers = new HashMap(1); if (StringUtils.isNotEmpty(betaIps)) { - headers.add("betaIps"); - headers.add(betaIps); + headers.put("betaIps", betaIps); } - HttpResult result = null; + HttpRestResult result = null; try { result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT); - } catch (IOException ioe) { + } catch (Exception ex) { LOGGER.warn("[{}] [publish-single] exception, dataId={}, group={}, msg={}", agent.getName(), dataId, group, - ioe.toString()); + ex.toString()); return false; } - if (HttpURLConnection.HTTP_OK == result.code) { + if (result.ok()) { LOGGER.info("[{}] [publish-single] ok, dataId={}, group={}, tenant={}, config={}", agent.getName(), dataId, group, tenant, ContentUtils.truncateContent(content)); return true; - } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) { + } else if (HttpURLConnection.HTTP_FORBIDDEN == result.getCode()) { LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), - dataId, group, tenant, result.code, result.content); - throw new NacosException(result.code, result.content); + dataId, group, tenant, result.getCode(), result.getMessage()); + throw new NacosException(result.getCode(), result.getMessage()); } else { LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), - dataId, group, tenant, result.code, result.content); + dataId, group, tenant, result.getCode(), result.getMessage()); return false; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java b/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java index da856cc9f..451b10dc7 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java @@ -17,11 +17,10 @@ package com.alibaba.nacos.client.config.http; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; +import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.lifecycle.Closeable; -import java.io.IOException; -import java.util.List; +import java.util.Map; /** * HttpAgent. @@ -46,11 +45,11 @@ public interface HttpAgent extends Closeable { * @param encoding http encode * @param readTimeoutMs http timeout * @return HttpResult http response - * @throws IOException If an input or output exception occurred + * @throws Exception If an input or output exception occurred */ - HttpResult httpGet(String path, List headers, List paramValues, String encoding, long readTimeoutMs) - throws IOException; + HttpRestResult httpGet(String path, Map headers, Map paramValues, + String encoding, long readTimeoutMs) throws Exception; /** * invoke http post method. @@ -61,10 +60,10 @@ public interface HttpAgent extends Closeable { * @param encoding http encode * @param readTimeoutMs http timeout * @return HttpResult http response - * @throws IOException If an input or output exception occurred + * @throws Exception If an input or output exception occurred */ - HttpResult httpPost(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException; + HttpRestResult httpPost(String path, Map headers, Map paramValues, + String encoding, long readTimeoutMs) throws Exception; /** * invoke http delete method. @@ -75,10 +74,10 @@ public interface HttpAgent extends Closeable { * @param encoding http encode * @param readTimeoutMs http timeout * @return HttpResult http response - * @throws IOException If an input or output exception occurred + * @throws Exception If an input or output exception occurred */ - HttpResult httpDelete(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException; + HttpRestResult httpDelete(String path, Map headers, Map paramValues, + String encoding, long readTimeoutMs) throws Exception; /** * get name. diff --git a/client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java b/client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java index ede4e830f..caac01e2b 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java @@ -17,12 +17,12 @@ package com.alibaba.nacos.client.config.http; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.monitor.MetricsMonitor; +import com.alibaba.nacos.common.http.HttpRestResult; import io.prometheus.client.Histogram; import java.io.IOException; -import java.util.List; +import java.util.Map; /** * MetricsHttpAgent. @@ -43,12 +43,12 @@ public class MetricsHttpAgent implements HttpAgent { } @Override - public HttpResult httpGet(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpGet(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA"); - HttpResult result; + HttpRestResult result; try { - result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs); + result = httpAgent.httpGet(path, headers, paramValues, encode, readTimeoutMs); } catch (IOException e) { throw e; } finally { @@ -60,12 +60,12 @@ public class MetricsHttpAgent implements HttpAgent { } @Override - public HttpResult httpPost(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpPost(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA"); - HttpResult result; + HttpRestResult result; try { - result = httpAgent.httpPost(path, headers, paramValues, encoding, readTimeoutMs); + result = httpAgent.httpPost(path, headers, paramValues, encode, readTimeoutMs); } catch (IOException e) { throw e; } finally { @@ -77,12 +77,12 @@ public class MetricsHttpAgent implements HttpAgent { } @Override - public HttpResult httpDelete(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpDelete(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA"); - HttpResult result; + HttpRestResult result; try { - result = httpAgent.httpDelete(path, headers, paramValues, encoding, readTimeoutMs); + result = httpAgent.httpDelete(path, headers, paramValues, encode, readTimeoutMs); } catch (IOException e) { throw e; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java index 81c0f155e..6d83577ac 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java @@ -19,8 +19,7 @@ package com.alibaba.nacos.client.config.http; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; +import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager; import com.alibaba.nacos.client.config.impl.ServerListManager; import com.alibaba.nacos.client.config.impl.SpasAdapter; import com.alibaba.nacos.client.identify.StsConfig; @@ -28,29 +27,36 @@ import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.TemplateUtils; +import com.alibaba.nacos.common.constant.HttpHeaderConsts; +import com.alibaba.nacos.common.http.HttpClientConfig; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.utils.ConvertUtils; -import com.alibaba.nacos.common.utils.IoUtils; +import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.ThreadUtils; +import com.alibaba.nacos.common.utils.UuidUtils; +import com.alibaba.nacos.common.utils.VersionUtils; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import org.slf4j.Logger; -import java.io.IOException; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; -import java.net.URL; -import java.util.ArrayList; import java.util.Date; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; -import java.util.concurrent.Callable; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.Callable; /** * Server Agent. @@ -61,6 +67,9 @@ public class ServerHttpAgent implements HttpAgent { private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class); + private static final NacosRestTemplate NACOS_RESTTEMPLATE = ConfigHttpClientManager.getInstance() + .getNacosRestTemplate(); + private SecurityProxy securityProxy; private String namespaceId; @@ -69,40 +78,28 @@ public class ServerHttpAgent implements HttpAgent { private ScheduledExecutorService executorService; - /** - * Invoke http get method. - * - * @param path 相对于web应用根,以/开头 - * @param headers headers - * @param paramValues parameters - * @param encoding encoding - * @param readTimeoutMs time out milliseconds - * @return http result - * @throws IOException io exception - */ @Override - public HttpResult httpGet(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpGet(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - final boolean isSsl = false; injectSecurityInfo(paramValues); String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; - + HttpClientConfig httpConfig = HttpClientConfig.builder() + .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) + .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build(); do { try { - List newHeaders = getSpasHeaders(paramValues); + Header newHeaders = getSpasHeaders(paramValues, encode); if (headers != null) { newHeaders.addAll(headers); } - HttpResult result = HttpSimpleClient - .httpGet(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs, - isSsl); - if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR - || result.code == HttpURLConnection.HTTP_BAD_GATEWAY - || result.code == HttpURLConnection.HTTP_UNAVAILABLE) { + + HttpRestResult result = NACOS_RESTTEMPLATE + .get(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class); + if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", - serverListMgr.getCurrentServerAddr(), result.code); + serverListMgr.getCurrentServerAddr(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); @@ -114,10 +111,10 @@ public class ServerHttpAgent implements HttpAgent { } catch (SocketTimeoutException socketTimeoutException) { LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage()); - } catch (IOException ioException) { - LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), - ioException); - throw ioException; + } catch (Exception ex) { + LOGGER.error("[NACOS Exception httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), + ex); + throw ex; } if (serverListMgr.getIterator().hasNext()) { @@ -138,30 +135,29 @@ public class ServerHttpAgent implements HttpAgent { } @Override - public HttpResult httpPost(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpPost(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - boolean isSsl = false; injectSecurityInfo(paramValues); String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; - + HttpClientConfig httpConfig = HttpClientConfig.builder() + .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) + .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(3000)).build(); do { try { - List newHeaders = getSpasHeaders(paramValues); + Header newHeaders = getSpasHeaders(paramValues, encode); if (headers != null) { newHeaders.addAll(headers); } + HttpRestResult result = NACOS_RESTTEMPLATE + .postForm(getUrl(currentServerAddr, path), httpConfig, newHeaders, + new HashMap(0), paramValues, String.class); - HttpResult result = HttpSimpleClient - .httpPost(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs, - isSsl); - if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR - || result.code == HttpURLConnection.HTTP_BAD_GATEWAY - || result.code == HttpURLConnection.HTTP_UNAVAILABLE) { + if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr, - result.code); + result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); @@ -173,9 +169,9 @@ public class ServerHttpAgent implements HttpAgent { } catch (SocketTimeoutException socketTimeoutException) { LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, socketTimeoutException.getMessage()); - } catch (IOException ioe) { - LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe); - throw ioe; + } catch (Exception ex) { + LOGGER.error("[NACOS Exception httpPost] currentServerAddr: " + currentServerAddr, ex); + throw ex; } if (serverListMgr.getIterator().hasNext()) { @@ -196,46 +192,42 @@ public class ServerHttpAgent implements HttpAgent { } @Override - public HttpResult httpDelete(String path, List headers, List paramValues, String encoding, - long readTimeoutMs) throws IOException { + public HttpRestResult httpDelete(String path, Map headers, Map paramValues, + String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - boolean isSsl = false; injectSecurityInfo(paramValues); String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; - + HttpClientConfig httpConfig = HttpClientConfig.builder() + .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) + .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build(); do { try { - List newHeaders = getSpasHeaders(paramValues); + Header newHeaders = getSpasHeaders(paramValues, encode); if (headers != null) { newHeaders.addAll(headers); } - HttpResult result = HttpSimpleClient - .httpDelete(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs, - isSsl); - if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR - || result.code == HttpURLConnection.HTTP_BAD_GATEWAY - || result.code == HttpURLConnection.HTTP_UNAVAILABLE) { + HttpRestResult result = NACOS_RESTTEMPLATE + .delete(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class); + if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", - serverListMgr.getCurrentServerAddr(), result.code); + serverListMgr.getCurrentServerAddr(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); return result; } } catch (ConnectException connectException) { - connectException.printStackTrace(); LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), connectException.getMessage()); + serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(connectException)); } catch (SocketTimeoutException stoe) { - stoe.printStackTrace(); LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), stoe.getMessage()); - } catch (IOException ioe) { + serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(stoe)); + } catch (Exception ex) { LOGGER.error( - "[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), - ioe); - throw ioe; + "[NACOS Exception httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), + ex); + throw ex; } if (serverListMgr.getIterator().hasNext()) { @@ -261,6 +253,12 @@ public class ServerHttpAgent implements HttpAgent { return serverAddr + contextPath + relativePath; } + private boolean isFail(HttpRestResult result) { + return result.getCode() == HttpURLConnection.HTTP_INTERNAL_ERROR + || result.getCode() == HttpURLConnection.HTTP_BAD_GATEWAY + || result.getCode() == HttpURLConnection.HTTP_UNAVAILABLE; + } + public static String getAppname() { return ParamUtil.getAppName(); } @@ -276,7 +274,7 @@ public class ServerHttpAgent implements HttpAgent { public ServerHttpAgent(Properties properties) throws NacosException { this.serverListMgr = new ServerListManager(properties); - this.securityProxy = new SecurityProxy(properties); + this.securityProxy = new SecurityProxy(properties, NACOS_RESTTEMPLATE); this.namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE); init(properties); this.securityProxy.login(this.serverListMgr.getServerUrls()); @@ -301,14 +299,12 @@ public class ServerHttpAgent implements HttpAgent { } - private void injectSecurityInfo(List params) { + private void injectSecurityInfo(Map params) { if (StringUtils.isNotBlank(securityProxy.getAccessToken())) { - params.add(Constants.ACCESS_TOKEN); - params.add(securityProxy.getAccessToken()); + params.put(Constants.ACCESS_TOKEN, securityProxy.getAccessToken()); } - if (StringUtils.isNotBlank(namespaceId) && !params.contains(SpasAdapter.TENANT_KEY)) { - params.add(SpasAdapter.TENANT_KEY); - params.add(namespaceId); + if (StringUtils.isNotBlank(namespaceId) && !params.containsKey(SpasAdapter.TENANT_KEY)) { + params.put(SpasAdapter.TENANT_KEY, namespaceId); } } @@ -358,29 +354,37 @@ public class ServerHttpAgent implements HttpAgent { serverListMgr.start(); } - private List getSpasHeaders(List paramValues) throws IOException { - List newHeaders = new ArrayList(); + private Header getSpasHeaders(Map paramValues, String encode) throws Exception { + Header header = Header.newInstance(); // STS 临时凭证鉴权的优先级高于 AK/SK 鉴权 if (StsConfig.getInstance().isStsOn()) { StsCredential stsCredential = getStsCredential(); accessKey = stsCredential.accessKeyId; secretKey = stsCredential.accessKeySecret; - newHeaders.add("Spas-SecurityToken"); - newHeaders.add(stsCredential.securityToken); + header.addParam("Spas-SecurityToken", stsCredential.securityToken); } if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) { - newHeaders.add("Spas-AccessKey"); - newHeaders.add(accessKey); - List signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey); + header.addParam("Spas-AccessKey", accessKey); + Map signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey); if (signHeaders != null) { - newHeaders.addAll(signHeaders); + header.addAll(signHeaders); } } - return newHeaders; + String ts = String.valueOf(System.currentTimeMillis()); + String token = MD5Utils.md5Hex(ts + ParamUtil.getAppKey(), Constants.ENCODE); + + header.addParam(Constants.CLIENT_APPNAME_HEADER, ParamUtil.getAppName()); + header.addParam(Constants.CLIENT_REQUEST_TS_HEADER, ts); + header.addParam(Constants.CLIENT_REQUEST_TOKEN_HEADER, token); + header.addParam(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version); + header.addParam("exConfigInfo", "true"); + header.addParam(HttpHeaderConsts.REQUEST_ID, UuidUtils.generateUuid()); + header.addParam(HttpHeaderConsts.ACCEPT_CHARSET, encode); + return header; } - private StsCredential getStsCredential() throws IOException { + private StsCredential getStsCredential() throws Exception { boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials(); if (cacheSecurityCredentials && stsCredential != null) { long currentTime = System.currentTimeMillis(); @@ -400,40 +404,29 @@ public class ServerHttpAgent implements HttpAgent { return stsCredential; } - private static String getStsResponse() throws IOException { + private static String getStsResponse() throws Exception { String securityCredentials = StsConfig.getInstance().getSecurityCredentials(); if (securityCredentials != null) { return securityCredentials; } String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl(); - HttpURLConnection conn = null; - int respCode; - String response; try { - conn = (HttpURLConnection) new URL(securityCredentialsUrl).openConnection(); - conn.setRequestMethod("GET"); - conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100); - conn.setReadTimeout(1000); - conn.connect(); - respCode = conn.getResponseCode(); - if (HttpURLConnection.HTTP_OK == respCode) { - response = IoUtils.toString(conn.getInputStream(), Constants.ENCODE); - } else { - response = IoUtils.toString(conn.getErrorStream(), Constants.ENCODE); + HttpRestResult result = NACOS_RESTTEMPLATE + .get(securityCredentialsUrl, Header.EMPTY, Query.EMPTY, String.class); + + if (!result.ok()) { + LOGGER.error( + "can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}", + securityCredentialsUrl, result.getCode(), result.getMessage()); + throw new NacosException(NacosException.SERVER_ERROR, + "can not get security credentials, responseCode: " + result.getCode() + ", response: " + result + .getMessage()); } - } catch (IOException e) { + return result.getData(); + } catch (Exception e) { LOGGER.error("can not get security credentials", e); throw e; - } finally { - IoUtils.closeQuietly(conn); } - if (HttpURLConnection.HTTP_OK == respCode) { - return response; - } - LOGGER.error("can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}", - securityCredentialsUrl, respCode, response); - throw new IOException( - "can not get security credentials, responseCode: " + respCode + ", response: " + response); } @Override @@ -461,6 +454,7 @@ public class ServerHttpAgent implements HttpAgent { String className = this.getClass().getName(); LOGGER.info("{} do shutdown begin", className); ThreadUtils.shutdownThreadPool(executorService, LOGGER); + ConfigHttpClientManager.getInstance().shutdown(); LOGGER.info("{} do shutdown stop", className); } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index d92976b45..93578dda9 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -24,13 +24,13 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.common.GroupKey; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.http.HttpAgent; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.utils.ContentUtils; import com.alibaba.nacos.client.monitor.MetricsMonitor; import com.alibaba.nacos.client.naming.utils.CollectionUtils; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.TenantUtil; +import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.lifecycle.Closeable; import com.alibaba.nacos.common.utils.ConvertUtils; import com.alibaba.nacos.common.utils.MD5Utils; @@ -43,7 +43,6 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URLDecoder; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -285,29 +284,32 @@ public class ClientWorker implements Closeable { group = Constants.DEFAULT_GROUP; } - HttpResult result = null; + HttpRestResult result = null; try { - List params = null; + Map params = new HashMap(3); if (StringUtils.isBlank(tenant)) { - params = new ArrayList(Arrays.asList("dataId", dataId, "group", group)); + params.put("dataId", dataId); + params.put("group", group); } else { - params = new ArrayList(Arrays.asList("dataId", dataId, "group", group, "tenant", tenant)); + params.put("dataId", dataId); + params.put("group", group); + params.put("tenant", tenant); } result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout); - } catch (IOException e) { + } catch (Exception ex) { String message = String .format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s", agent.getName(), dataId, group, tenant); - LOGGER.error(message, e); - throw new NacosException(NacosException.SERVER_ERROR, e); + LOGGER.error(message, ex); + throw new NacosException(NacosException.SERVER_ERROR, ex); } - switch (result.code) { + switch (result.getCode()) { case HttpURLConnection.HTTP_OK: - LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content); - ct[0] = result.content; - if (result.headers.containsKey(CONFIG_TYPE)) { - ct[1] = result.headers.get(CONFIG_TYPE).get(0); + LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.getData()); + ct[0] = result.getData(); + if (result.getHeader().getValue(CONFIG_TYPE) != null) { + ct[1] = result.getHeader().getValue(CONFIG_TYPE); } else { ct[1] = ConfigType.TEXT.getType(); } @@ -325,13 +327,13 @@ public class ClientWorker implements Closeable { case HttpURLConnection.HTTP_FORBIDDEN: { LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(), dataId, group, tenant); - throw new NacosException(result.code, result.content); + throw new NacosException(result.getCode(), result.getMessage()); } default: { LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", agent.getName(), - dataId, group, tenant, result.code); - throw new NacosException(result.code, - "http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + dataId, group, tenant, result.getCode()); + throw new NacosException(result.getCode(), + "http error, code=" + result.getCode() + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant); } } @@ -405,10 +407,9 @@ public class ClientWorker implements Closeable { * @param cacheDatas CacheDatas for config infomations. * @param inInitializingCacheList initial cache lists. * @return String include dataId and group (ps: it maybe null). - * @throws IOException Exception. + * @throws Exception Exception. */ - List checkUpdateDataIds(List cacheDatas, List inInitializingCacheList) - throws IOException { + List checkUpdateDataIds(List cacheDatas, List inInitializingCacheList) throws Exception { StringBuilder sb = new StringBuilder(); for (CacheData cacheData : cacheDatas) { if (!cacheData.isUseLocalConfigInfo()) { @@ -439,20 +440,16 @@ public class ClientWorker implements Closeable { * @return The updated dataId list(ps: it maybe null). * @throws IOException Exception. */ - List checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException { + List checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws Exception { - List params = new ArrayList(2); - params.add(Constants.PROBE_MODIFY_REQUEST); - params.add(probeUpdateString); - - List headers = new ArrayList(2); - headers.add("Long-Pulling-Timeout"); - headers.add("" + timeout); + Map params = new HashMap(2); + params.put(Constants.PROBE_MODIFY_REQUEST, probeUpdateString); + Map headers = new HashMap(2); + headers.put("Long-Pulling-Timeout", "" + timeout); // told server do not hang me up if new initializing cacheData added in if (isInitializingCacheList) { - headers.add("Long-Pulling-Timeout-No-Hangup"); - headers.add("true"); + headers.put("Long-Pulling-Timeout-No-Hangup", "true"); } if (StringUtils.isBlank(probeUpdateString)) { @@ -464,18 +461,19 @@ public class ClientWorker implements Closeable { // increase the client's read timeout to avoid this problem. long readTimeoutMs = timeout + (long) Math.round(timeout >> 1); - HttpResult result = agent + HttpRestResult result = agent .httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params, agent.getEncode(), readTimeoutMs); - if (HttpURLConnection.HTTP_OK == result.code) { + if (result.ok()) { setHealthServer(true); - return parseUpdateDataIdResponse(result.content); + return parseUpdateDataIdResponse(result.getData()); } else { setHealthServer(false); - LOGGER.error("[{}] [check-update] get changed dataId error, code: {}", agent.getName(), result.code); + LOGGER.error("[{}] [check-update] get changed dataId error, code: {}", agent.getName(), + result.getCode()); } - } catch (IOException e) { + } catch (Exception e) { setHealthServer(false); LOGGER.error("[" + agent.getName() + "] [check-update] get changed dataId exception", e); throw e; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java new file mode 100644 index 000000000..d28ef4b2b --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java @@ -0,0 +1,171 @@ +/* + * 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.config.impl; + +import com.alibaba.nacos.api.common.Constants; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.client.utils.ParamUtil; +import com.alibaba.nacos.common.http.AbstractHttpClientFactory; +import com.alibaba.nacos.common.http.HttpClientBeanHolder; +import com.alibaba.nacos.common.http.HttpClientConfig; +import com.alibaba.nacos.common.http.HttpClientFactory; +import com.alibaba.nacos.common.http.client.HttpClientRequestInterceptor; +import com.alibaba.nacos.common.http.client.HttpClientResponse; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.lifecycle.Closeable; +import com.alibaba.nacos.common.model.RequestHttpEntity; +import com.alibaba.nacos.common.utils.ExceptionUtil; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.common.utils.MD5Utils; +import org.slf4j.Logger; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; + +/** + * config http Manager. + * + * @author mai.jh + */ +public class ConfigHttpClientManager implements Closeable { + + private static final Logger LOGGER = LogUtils.logger(ConfigHttpClientManager.class); + + private static final HttpClientFactory HTTP_CLIENT_FACTORY = new ConfigHttpClientFactory(); + + private static final int CON_TIME_OUT_MILLIS = ParamUtil.getConnectTimeout(); + + private static final int READ_TIME_OUT_MILLIS = 3000; + + private static final NacosRestTemplate NACOS_REST_TEMPLATE; + + static { + NACOS_REST_TEMPLATE = HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY); + NACOS_REST_TEMPLATE.getInterceptors().add(new LimiterHttpClientRequestInterceptor()); + } + + private static class ConfigHttpClientManagerInstance { + + private static final ConfigHttpClientManager INSTANCE = new ConfigHttpClientManager(); + } + + public static ConfigHttpClientManager getInstance() { + return ConfigHttpClientManagerInstance.INSTANCE; + } + + @Override + public void shutdown() throws NacosException { + NAMING_LOGGER.warn("[ConfigHttpClientManager] Start destroying NacosRestTemplate"); + try { + HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName()); + } catch (Exception ex) { + NAMING_LOGGER.error("[ConfigHttpClientManager] An exception occurred when the HTTP client was closed : {}", + ExceptionUtil.getStackTrace(ex)); + } + NAMING_LOGGER.warn("[ConfigHttpClientManager] Destruction of the end"); + } + + /** + * get connectTimeout. + * + * @param connectTimeout connectTimeout + * @return int return max timeout + */ + public int getConnectTimeoutOrDefault(int connectTimeout) { + return Math.max(CON_TIME_OUT_MILLIS, connectTimeout); + } + + /** + * get NacosRestTemplate Instance. + * + * @return NacosRestTemplate + */ + public NacosRestTemplate getNacosRestTemplate() { + return NACOS_REST_TEMPLATE; + } + + /** + * ConfigHttpClientFactory. + */ + private static class ConfigHttpClientFactory extends AbstractHttpClientFactory { + + @Override + protected HttpClientConfig buildHttpClientConfig() { + return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS) + .setReadTimeOutMillis(READ_TIME_OUT_MILLIS).build(); + } + + @Override + protected Logger assignLogger() { + return LOGGER; + } + } + + /** + * config Limiter implement. + */ + private static class LimiterHttpClientRequestInterceptor implements HttpClientRequestInterceptor { + + @Override + public boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) { + final String body = requestHttpEntity.getBody() == null ? "" : JacksonUtils.toJson(requestHttpEntity.getBody()); + return Limiter.isLimit(MD5Utils.md5Hex(uri + body, Constants.ENCODE)); + } + + @Override + public HttpClientResponse intercept() { + return new LimitResponse(); + } + } + + /** + * Limit Interrupt response. + */ + private static class LimitResponse implements HttpClientResponse { + + @Override + public Header getHeaders() { + return Header.EMPTY; + } + + @Override + public InputStream getBody() throws IOException { + return new ByteArrayInputStream("More than client-side current limit threshold".getBytes()); + } + + @Override + public int getStatusCode() { + return NacosException.CLIENT_OVER_THRESHOLD; + } + + @Override + public String getStatusText() { + return null; + } + + @Override + public void close() throws IOException { + + } + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/HttpSimpleClient.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/HttpSimpleClient.java index f3861c146..67187378c 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/HttpSimpleClient.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/HttpSimpleClient.java @@ -20,6 +20,7 @@ import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.common.constant.HttpHeaderConsts; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; import com.alibaba.nacos.common.utils.IoUtils; import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.UuidUtils; @@ -39,7 +40,9 @@ import java.util.Map; * Http tool. * * @author Nacos + * @deprecated Use NacosRestTemplate{@link NacosRestTemplate} unified http client */ +@Deprecated public class HttpSimpleClient { /** diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java index 2c3b2119a..b666ad80d 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java @@ -19,11 +19,14 @@ package com.alibaba.nacos.client.config.impl; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.SystemPropertyKeyConst; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.utils.EnvUtil; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.client.utils.TemplateUtils; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.lifecycle.Closeable; import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.IoUtils; @@ -31,9 +34,7 @@ import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.ThreadUtils; import org.slf4j.Logger; -import java.io.IOException; import java.io.StringReader; -import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -59,6 +60,8 @@ public class ServerListManager implements Closeable { private static final String HTTP = "http://"; + private final NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate(); + private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { @@ -342,13 +345,13 @@ public class ServerListManager implements Closeable { private List getApacheServerList(String url, String name) { try { - HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000); - - if (HttpURLConnection.HTTP_OK == httpResult.code) { + HttpRestResult httpResult = nacosRestTemplate.get(url, Header.EMPTY, Query.EMPTY, String.class); + + if (httpResult.ok()) { if (DEFAULT_NAME.equals(name)) { - EnvUtil.setSelfEnv(httpResult.headers); + EnvUtil.setSelfEnv(httpResult.getHeader().getOriginalResponseHeader()); } - List lines = IoUtils.readLines(new StringReader(httpResult.content)); + List lines = IoUtils.readLines(new StringReader(httpResult.getData())); List result = new ArrayList(lines.size()); for (String serverAddr : lines) { if (StringUtils.isNotBlank(serverAddr)) { @@ -364,10 +367,10 @@ public class ServerListManager implements Closeable { return result; } else { LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl, - httpResult.code); + httpResult.getCode()); return null; } - } catch (IOException e) { + } catch (Exception e) { LOGGER.error("[check-serverlist] exception. url: " + url, e); return null; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/SpasAdapter.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/SpasAdapter.java index 210dbc6f7..418ef0866 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/SpasAdapter.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/SpasAdapter.java @@ -24,11 +24,7 @@ import com.alibaba.nacos.common.utils.StringUtils; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; /** @@ -37,44 +33,34 @@ import java.util.Map; * @author Nacos */ public class SpasAdapter { - - public static List getSignHeaders(String resource, String secretKey) { - List header = new ArrayList(); + + public static Map getSignHeaders(String resource, String secretKey) { + Map header = new HashMap(2); String timeStamp = String.valueOf(System.currentTimeMillis()); - header.add("Timestamp"); - header.add(timeStamp); + header.put("Timestamp", timeStamp); if (secretKey != null) { - header.add("Spas-Signature"); String signature = ""; if (StringUtils.isBlank(resource)) { signature = signWithHmacSha1Encrypt(timeStamp, secretKey); } else { signature = signWithHmacSha1Encrypt(resource + "+" + timeStamp, secretKey); } - header.add(signature); + header.put("Spas-Signature", signature); } return header; } - - public static List getSignHeaders(List paramValues, String secretKey) { + + public static Map getSignHeaders(Map paramValues, String secretKey) { if (null == paramValues) { return null; } - Map signMap = new HashMap(5); - for (Iterator iter = paramValues.iterator(); iter.hasNext(); ) { - String key = iter.next(); - if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) { - signMap.put(key, iter.next()); - } else { - iter.next(); - } - } + String resource = ""; - if (signMap.size() > 1) { - resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY); + if (paramValues.containsKey(TENANT_KEY) && paramValues.containsKey(GROUP_KEY)) { + resource = paramValues.get(TENANT_KEY) + "+" + paramValues.get(GROUP_KEY); } else { - if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) { - resource = signMap.get(GROUP_KEY); + if (!StringUtils.isBlank(paramValues.get(GROUP_KEY))) { + resource = paramValues.get(GROUP_KEY); } } return getSignHeaders(resource, secretKey); @@ -97,14 +83,14 @@ public class SpasAdapter { */ public static String signWithHmacSha1Encrypt(String encryptText, String encryptKey) { try { - byte[] data = encryptKey.getBytes(StandardCharsets.UTF_8); + byte[] data = encryptKey.getBytes(Constants.ENCODE); // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1"); // 生成一个指定 Mac 算法 的 Mac 对象 Mac mac = Mac.getInstance("HmacSHA1"); // 用给定密钥初始化 Mac 对象 mac.init(secretKey); - byte[] text = encryptText.getBytes(StandardCharsets.UTF_8); + byte[] text = encryptText.getBytes(Constants.ENCODE); byte[] textFinal = mac.doFinal(text); // 完成 Mac 操作, base64编码,将byte数组转换为字符串 return new String(Base64.encodeBase64(textFinal), Constants.ENCODE); diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java index ba85bde72..77a811a56 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java @@ -109,7 +109,7 @@ public class NamingProxy implements Closeable { public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) { - this.securityProxy = new SecurityProxy(properties); + this.securityProxy = new SecurityProxy(properties, nacosRestTemplate); this.properties = properties; this.setServerPort(DEFAULT_SERVER_PORT); this.namespaceId = namespaceId; @@ -608,7 +608,7 @@ public class NamingProxy implements Closeable { if (HttpStatus.SC_NOT_MODIFIED == restResult.getCode()) { return StringUtils.EMPTY; } - throw new NacosException(restResult.getCode(), restResult.getData()); + throw new NacosException(restResult.getCode(), restResult.getMessage()); } catch (Exception e) { NAMING_LOGGER.error("[NA] failed to request", e); throw new NacosException(NacosException.SERVER_ERROR, e); diff --git a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java index 44b6a5f6d..65d6e7610 100644 --- a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java @@ -18,7 +18,6 @@ package com.alibaba.nacos.client.security; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.common.Constants; -import com.alibaba.nacos.client.naming.net.NamingHttpClientManager; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.client.NacosRestTemplate; import com.alibaba.nacos.common.http.param.Header; @@ -46,7 +45,7 @@ public class SecurityProxy { private static final String LOGIN_URL = "/v1/auth/users/login"; - private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate(); + private final NacosRestTemplate nacosRestTemplate; private String contextPath; @@ -85,11 +84,12 @@ public class SecurityProxy { * * @param properties a bunch of properties to read */ - public SecurityProxy(Properties properties) { + public SecurityProxy(Properties properties, NacosRestTemplate nacosRestTemplate) { username = properties.getProperty(PropertyKeyConst.USERNAME, StringUtils.EMPTY); password = properties.getProperty(PropertyKeyConst.PASSWORD, StringUtils.EMPTY); contextPath = properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos"); contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath; + this.nacosRestTemplate = nacosRestTemplate; } /** diff --git a/client/src/main/java/com/alibaba/nacos/client/utils/ParamUtil.java b/client/src/main/java/com/alibaba/nacos/client/utils/ParamUtil.java index 1b7d726fc..bbab52593 100644 --- a/client/src/main/java/com/alibaba/nacos/client/utils/ParamUtil.java +++ b/client/src/main/java/com/alibaba/nacos/client/utils/ParamUtil.java @@ -19,7 +19,6 @@ package com.alibaba.nacos.client.utils; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.SystemPropertyKeyConst; import com.alibaba.nacos.api.common.Constants; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient; import com.alibaba.nacos.common.utils.StringUtils; import org.slf4j.Logger; @@ -82,7 +81,7 @@ public class ParamUtil { LOGGER.info("[settings] [http-client] connect timeout:{}", connectTimeout); try { - InputStream in = HttpSimpleClient.class.getClassLoader().getResourceAsStream("application.properties"); + InputStream in = ValidatorUtils.class.getClassLoader().getResourceAsStream("application.properties"); Properties props = new Properties(); props.load(in); String val = null; diff --git a/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java index 6ca7650e6..6332650d1 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/client/JdkHttpClientResponse.java @@ -22,8 +22,6 @@ import com.alibaba.nacos.common.utils.IoUtils; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.util.List; -import java.util.Map; /** * JDk http client response implement. @@ -47,10 +45,7 @@ public class JdkHttpClientResponse implements HttpClientResponse { if (this.responseHeader == null) { this.responseHeader = Header.newInstance(); } - - for (Map.Entry> entry : conn.getHeaderFields().entrySet()) { - this.responseHeader.addParam(entry.getKey(), entry.getValue().get(0)); - } + this.responseHeader.setOriginalResponseHeader(conn.getHeaderFields()); return this.responseHeader; } diff --git a/common/src/main/java/com/alibaba/nacos/common/http/param/Header.java b/common/src/main/java/com/alibaba/nacos/common/http/param/Header.java index 35dc8348b..277a8bbce 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/param/Header.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/param/Header.java @@ -37,8 +37,11 @@ public class Header { private final Map header; + private final Map> originalResponseHeader; + private Header() { header = new LinkedHashMap(); + originalResponseHeader = new LinkedHashMap>(); addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON); addParam(HttpHeaderConsts.ACCEPT_CHARSET, "UTF-8"); addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip"); @@ -120,6 +123,31 @@ public class Header { } } + /** + * set original format response header. + * + *

Currently only corresponds to the response header of JDK. + * + * @param headers original response header + */ + public void setOriginalResponseHeader(Map> headers) { + this.originalResponseHeader.putAll(headers); + for (Map.Entry> entry : this.originalResponseHeader.entrySet()) { + addParam(entry.getKey(), entry.getValue().get(0)); + } + } + + /** + * get original format response header. + * + *

Currently only corresponds to the response header of JDK. + * + * @return Map original response header + */ + public Map> getOriginalResponseHeader() { + return this.originalResponseHeader; + } + public String getCharset() { String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET); if (acceptCharset == null) { @@ -145,6 +173,7 @@ public class Header { public void clear() { header.clear(); + originalResponseHeader.clear(); } @Override diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_CITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_CITCase.java index b572e3d85..219a9fd51 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_CITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_CITCase.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.alibaba.nacos.test.config; import com.alibaba.nacos.Nacos; @@ -26,7 +27,7 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.http.HttpAgent; import com.alibaba.nacos.client.config.http.MetricsHttpAgent; import com.alibaba.nacos.client.config.http.ServerHttpAgent; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; +import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.ThreadUtils; import org.junit.After; @@ -41,8 +42,8 @@ import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; import java.net.HttpURLConnection; -import java.util.Arrays; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; @@ -52,41 +53,49 @@ import java.util.concurrent.atomic.AtomicInteger; * @author xiaochun.xxc */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"}, - webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", + "server.port=7001"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class ConfigAPI_CITCase { - + public static final long TIME_OUT = 5000; + static ConfigService iconfig = null; + static HttpAgent agent = null; - + static final String CONFIG_CONTROLLER_PATH = "/v1/cs/configs"; + String SPECIAL_CHARACTERS = "!@#$%^&*()_+-=_|/'?."; + String dataId = "yanlin"; + String group = "yanlin"; - + @LocalServerPort private int port; - + @Before public void setUp() throws Exception { Properties properties = new Properties(); - properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1"+":"+port); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port); properties.put(PropertyKeyConst.CONTEXT_PATH, "/nacos"); iconfig = NacosFactory.createConfigService(properties); agent = new MetricsHttpAgent(new ServerHttpAgent(properties)); agent.start(); } - + @After public void cleanup() throws Exception { - HttpResult result = null; + HttpRestResult result = null; try { - List params = Arrays.asList("dataId", dataId, "group", group, "beta", "true"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("beta", "true"); result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertTrue(JacksonUtils.toObj(result.content).get("data").booleanValue()); - Assert.assertTrue(JacksonUtils.toObj(result.content).get("data").booleanValue()); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("data").booleanValue()); + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("data").booleanValue()); } catch (Exception e) { e.printStackTrace(); Assert.fail(); @@ -98,13 +107,13 @@ public class ConfigAPI_CITCase { public static void cleanClientCache() throws Exception { ConfigCleanUtils.cleanClientCache(); } - + /** * @TCDescription : nacos_正常获取数据 * @TestStep : * @ExpectResult : */ - @Test(timeout = 3*TIME_OUT) + @Test(timeout = 3 * TIME_OUT) public void nacos_getconfig_1() throws Exception { final String content = "test"; boolean result = iconfig.publishConfig(dataId, group, content); @@ -119,22 +128,22 @@ public class ConfigAPI_CITCase { System.out.println(value); Assert.assertNull(value); } - + /** - * @TCDescription : nacos_服务端无配置时,获取配置 * @throws Exception + * @TCDescription : nacos_服务端无配置时,获取配置 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_getconfig_2() throws Exception { String content = iconfig.getConfig(dataId, "nacos", TIME_OUT); Assert.assertNull(content); } - + /** - * @TCDescription : nacos_获取配置时dataId为null * @throws Exception + * @TCDescription : nacos_获取配置时dataId为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_getconfig_3() throws Exception { try { String content = iconfig.getConfig(null, group, TIME_OUT); @@ -144,32 +153,32 @@ public class ConfigAPI_CITCase { } Assert.fail(); } - + /** - * @TCDescription : nacos_获取配置时group为null * @throws Exception + * @TCDescription : nacos_获取配置时group为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_getconfig_4() throws Exception { final String dataId = "nacos_getconfig_4"; final String content = "test"; boolean result = iconfig.publishConfig(dataId, null, content); Assert.assertTrue(result); Thread.sleep(TIME_OUT); - + String value = iconfig.getConfig(dataId, null, TIME_OUT); Assert.assertEquals(content, value); - + result = iconfig.removeConfig(dataId, null); Thread.sleep(TIME_OUT); Assert.assertTrue(result); } - + /** - * @TCDescription : nacos_服务端无该配置项时,正常创建配置 * @throws Exception + * @TCDescription : nacos_服务端无该配置项时,正常创建配置 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_1() throws Exception { final String content = "publishConfigTest"; boolean result = iconfig.publishConfig(dataId, group, content); @@ -178,45 +187,45 @@ public class ConfigAPI_CITCase { result = iconfig.removeConfig(dataId, group); Assert.assertTrue(result); } - + /** - * @TCDescription : nacos_服务端有该配置项时,正常修改配置 * @throws Exception + * @TCDescription : nacos_服务端有该配置项时,正常修改配置 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_2() throws Exception { final String content = "publishConfigTest"; boolean result = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(result); - + final String content1 = "test.abc"; result = iconfig.publishConfig(dataId, group, content1); Thread.sleep(TIME_OUT); String value = iconfig.getConfig(dataId, group, TIME_OUT); Assert.assertEquals(content1, value); } - + /** - * @TCDescription : nacos_发布配置时包含特殊字符 * @throws Exception + * @TCDescription : nacos_发布配置时包含特殊字符 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_3() throws Exception { String content = "test" + SPECIAL_CHARACTERS; boolean result = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(result); - + String value = iconfig.getConfig(dataId, group, TIME_OUT); Assert.assertEquals(content, value); } - + /** - * @TCDescription : nacos_发布配置时dataId为null * @throws Exception + * @TCDescription : nacos_发布配置时dataId为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_4() throws Exception { try { String content = "test"; @@ -229,29 +238,29 @@ public class ConfigAPI_CITCase { } Assert.fail(); } - + /** - * @TCDescription : nacos_发布配置时group为null * @throws Exception + * @TCDescription : nacos_发布配置时group为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_5() throws Exception { final String dataId = "nacos_publishConfig_5"; String content = "test"; boolean result = iconfig.publishConfig(dataId, null, content); Thread.sleep(TIME_OUT); Assert.assertTrue(result); - + String value = iconfig.getConfig(dataId, null, TIME_OUT); Assert.assertEquals(content, value); } - - + + /** - * @TCDescription : nacos_发布配置时配置内容为null * @throws Exception + * @TCDescription : nacos_发布配置时配置内容为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_6() throws Exception { String content = null; try { @@ -263,56 +272,56 @@ public class ConfigAPI_CITCase { } Assert.fail(); } - + /** - * @TCDescription : nacos_发布配置时配置内容包含中文字符 * @throws Exception + * @TCDescription : nacos_发布配置时配置内容包含中文字符 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_publishConfig_7() throws Exception { String content = "阿里abc"; boolean result = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(result); - String value = iconfig.getConfig(dataId, group, TIME_OUT); + String value = iconfig.getConfig(dataId, group, TIME_OUT); Assert.assertEquals(content, value); } - + /** - * @TCDescription : nacos_服务端有该配置项时,正常删除配置 * @throws Exception + * @TCDescription : nacos_服务端有该配置项时,正常删除配置 */ @Test public void nacos_removeConfig_1() throws Exception { String content = "test"; boolean result = iconfig.publishConfig(dataId, group, content); - + Assert.assertTrue(result); Thread.sleep(TIME_OUT); - + result = iconfig.removeConfig(dataId, group); Assert.assertTrue(result); Thread.sleep(TIME_OUT); String value = iconfig.getConfig(dataId, group, TIME_OUT); Assert.assertNull(value); } - + /** - * @TCDescription : nacos_服务端无该配置项时,配置删除失败 * @throws Exception + * @TCDescription : nacos_服务端无该配置项时,配置删除失败 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_removeConfig_2() throws Exception { group += "removeConfig2"; boolean result = iconfig.removeConfig(dataId, group); Assert.assertTrue(result); } - + /** - * @TCDescription : nacos_删除配置时dataId为null * @throws Exception + * @TCDescription : nacos_删除配置时dataId为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_removeConfig_3() throws Exception { try { boolean result = iconfig.removeConfig(null, group); @@ -323,28 +332,28 @@ public class ConfigAPI_CITCase { } Assert.fail(); } - + /** - * @TCDescription : nacos_删除配置时group为null * @throws Exception + * @TCDescription : nacos_删除配置时group为null */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_removeConfig_4() throws Exception { boolean result = iconfig.removeConfig(dataId, null); Assert.assertTrue(result); } - + /** - * @TCDescription : nacos_添加对dataId的监听,在服务端修改配置后,获取监听后的修改的配置 * @throws Exception + * @TCDescription : nacos_添加对dataId的监听,在服务端修改配置后,获取监听后的修改的配置 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_addListener_1() throws Exception { final AtomicInteger count = new AtomicInteger(0); final String content = "test-abc"; boolean result = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(result); - + Listener ml = new Listener() { @Override public void receiveConfigInfo(String configInfo) { @@ -352,7 +361,7 @@ public class ConfigAPI_CITCase { count.incrementAndGet(); Assert.assertEquals(content, configInfo); } - + @Override public Executor getExecutor() { return null; @@ -365,7 +374,7 @@ public class ConfigAPI_CITCase { Assert.assertTrue(count.get() >= 1); iconfig.removeListener(dataId, group, ml); } - + /** * @TCDescription : nacos_设置监听器为null,抛出异常信息 * @TestStep : @@ -377,8 +386,8 @@ public class ConfigAPI_CITCase { public void nacos_addListener_2() throws Exception { iconfig.addListener(dataId, group, null); } - - + + /** * @TCDescription : nacos_添加对dataId的监听,修改服务端配置,正常推送并只推送一次 * @TestStep : TODO Test steps @@ -398,7 +407,7 @@ public class ConfigAPI_CITCase { // Maximum assurance level notification has been performed ThreadUtils.sleep(5000); - + Listener ml = new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { @@ -416,7 +425,7 @@ public class ConfigAPI_CITCase { Assert.assertEquals(1, count.get()); iconfig.removeListener(dataId, group, ml); } - + /** * @TCDescription : nacos_服务端无配置时,添加对dataId的监听 * @TestStep : TODO Test steps @@ -424,13 +433,13 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_addListener_4() throws Exception { final AtomicInteger count = new AtomicInteger(0); - + iconfig.removeConfig(dataId, group); Thread.sleep(TIME_OUT); - + Listener ml = new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { @@ -442,14 +451,14 @@ public class ConfigAPI_CITCase { String content = "test-abc"; boolean result = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(result); - + while (count.get() == 0) { Thread.sleep(3000); } Assert.assertEquals(1, count.get()); iconfig.removeListener(dataId, group, ml); } - + /** * @TCDescription : nacos_在主动拉取配置后并注册Listener,在更新配置后才触发Listener监听事件(使用特定接口) * @TestStep : TODO Test steps @@ -466,9 +475,9 @@ public class ConfigAPI_CITCase { final String newContent = "new-test-def"; boolean result = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(result); - + Thread.sleep(2000); - + Listener ml = new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { @@ -476,20 +485,20 @@ public class ConfigAPI_CITCase { Assert.assertEquals(newContent, configInfo); } }; - + String receiveContent = iconfig.getConfigAndSignListener(dataId, group, 1000, ml); System.out.println(receiveContent); - + result = iconfig.publishConfig(dataId, group, newContent); Assert.assertTrue(result); - + Assert.assertEquals(content, receiveContent); Thread.sleep(2000); - + Assert.assertEquals(1, count.get()); iconfig.removeListener(dataId, group, ml); } - + /** * @TCDescription : nacos_在主动拉取配置后并注册Listener,在更新配置后才触发Listener监听事件(进行配置参数设置) * @TestStep : TODO Test steps @@ -499,22 +508,22 @@ public class ConfigAPI_CITCase { */ @Test public void nacos_addListener_6() throws InterruptedException, NacosException { - + Properties properties = new Properties(); - properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1"+":"+port); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port); properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG, "true"); ConfigService iconfig = NacosFactory.createConfigService(properties); - + final AtomicInteger count = new AtomicInteger(0); final String dataId = "nacos_addListener_6"; - final String group ="nacos_addListener_6"; + final String group = "nacos_addListener_6"; final String content = "test-abc"; final String newContent = "new-test-def"; boolean result = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(result); - + Thread.sleep(2000); - + Listener ml = new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { @@ -523,26 +532,26 @@ public class ConfigAPI_CITCase { Assert.assertEquals(newContent, configInfo); } }; - + iconfig.addListener(dataId, group, ml); - + String receiveContent = iconfig.getConfig(dataId, group, 1000); - + System.out.println(receiveContent); - + result = iconfig.publishConfig(dataId, group, newContent); Assert.assertTrue(result); - + Thread.sleep(2000); - + receiveContent = iconfig.getConfig(dataId, group, 1000); - + Assert.assertEquals(newContent, receiveContent); - + Assert.assertEquals(1, count.get()); iconfig.removeListener(dataId, group, ml); } - + /** * @TCDescription : nacos_正常移除监听器 * @TestStep : TODO Test steps @@ -550,7 +559,7 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_removeListener_1() throws Exception { iconfig.addListener(dataId, group, new AbstractListener() { @Override @@ -567,10 +576,10 @@ public class ConfigAPI_CITCase { } }); } catch (Exception e) { - + } } - + /** * @TCDescription : nacos_移除无该项dataId的监听器 * @TestStep : TODO Test steps @@ -585,14 +594,14 @@ public class ConfigAPI_CITCase { iconfig.removeListener(dataId, group, new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { - + } }); } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_存在多个监听器时,删除最后一个监听器 * @TestStep : TODO Test steps @@ -600,11 +609,11 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_removeListener_3() throws Exception { final String contentRemove = "test-abc-two"; final AtomicInteger count = new AtomicInteger(0); - + Listener ml = new AbstractListener() { @Override public void receiveConfigInfo(String configInfo) { @@ -621,20 +630,20 @@ public class ConfigAPI_CITCase { }; iconfig.addListener(dataId, group, ml); iconfig.addListener(dataId, group, ml1); - + iconfig.removeListener(dataId, group, ml); Thread.sleep(TIME_OUT); - + boolean result = iconfig.publishConfig(dataId, group, contentRemove); Thread.sleep(TIME_OUT); Assert.assertTrue(result); - + while (count.get() == 0) { Thread.sleep(3000); } Assert.assertNotEquals(0, count.get()); } - + /** * @TCDescription : nacos_监听器为null时 * @TestStep : TODO Test steps @@ -646,7 +655,7 @@ public class ConfigAPI_CITCase { public void nacos_removeListener_4() { iconfig.removeListener(dataId, group, null); } - + /** * @TCDescription : nacos_openAPI_配置具体信息 * @TestStep : @@ -654,26 +663,28 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 3*TIME_OUT) + @Test(timeout = 3 * TIME_OUT) public void nacos_openAPI_detailConfig_1() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test"; boolean ret = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(ret); - - List params = Arrays.asList("dataId", dataId, "group", group, "show", "all"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("show", "all"); result = agent.httpGet(CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - - Assert.assertEquals(content, JacksonUtils.toObj(result.content).get("content").textValue()); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + + Assert.assertEquals(content, JacksonUtils.toObj(result.getData()).get("content").textValue()); } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_catalog信息 * @TestStep : @@ -681,28 +692,29 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 3*TIME_OUT) + @Test(timeout = 3 * TIME_OUT) public void nacos_openAPI_catalog() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test"; boolean ret = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(ret); - - List params = Arrays.asList("dataId", dataId, "group", group); - result = agent.httpGet(CONFIG_CONTROLLER_PATH+"/catalog", null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - - System.out.println(result.content); - Assert.assertFalse(JacksonUtils.toObj(result.content).get("data").isNull()); - + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/catalog", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + + System.out.println(result.getData()); + Assert.assertFalse(JacksonUtils.toObj(result.getData()).get("data").isNull()); + } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_queryBeta信息 * @TestStep : @@ -710,177 +722,206 @@ public class ConfigAPI_CITCase { * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 3*TIME_OUT) + @Test(timeout = 3 * TIME_OUT) public void nacos_openAPI_queryBeta_1() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test-beta"; - List headers = Arrays.asList("betaIps", "127.0.0.1"); - List params1 = Arrays.asList("dataId", dataId, "group", group, "content", content); - result = agent.httpPost(CONFIG_CONTROLLER_PATH + "/", headers, params1, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertEquals("true", result.content); - - List params = Arrays.asList("dataId", dataId, "group", group, "beta", "true"); + Map headers = new HashMap<>(); + headers.put("betaIps", "127.0.0.1"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("content", content); + result = agent.httpPost(CONFIG_CONTROLLER_PATH + "/", headers, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertEquals("true", result.getData()); + params.clear(); + params.put("dataId", dataId); + params.put("group", group); + params.put("beta", "true"); result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertEquals(content, JacksonUtils.toObj(result.content).get("data").get("content").textValue()); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertEquals(content, JacksonUtils.toObj(result.getData()).get("data").get("content").textValue()); // delete data result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); } catch (Exception e) { + Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_queryBeta删除信息 - * @TestStep : 1. 发布配置 - * 2. 删除Beta配置信息 + * @TestStep : 1. 发布配置 2. 删除Beta配置信息 * @ExpectResult : * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 3*TIME_OUT) + @Test(timeout = 3 * TIME_OUT) public void nacos_openAPI_queryBeta_delete() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test-beta"; - List headers = Arrays.asList("betaIps", "127.0.0.1"); - List params1 = Arrays.asList("dataId", dataId, "group", group, "content", content); - result = agent.httpPost(CONFIG_CONTROLLER_PATH + "/", headers, params1, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertEquals("true", result.content); - - - List params = Arrays.asList("dataId", dataId, "group", group, "beta", "true"); + Map headers = new HashMap<>(); + headers.put("betaIps", "127.0.0.1"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("content", content); + result = agent.httpPost(CONFIG_CONTROLLER_PATH + "/", headers, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertEquals("true", result.getData()); + + params.clear(); + params.put("dataId", dataId); + params.put("group", group); + params.put("beta", "true"); result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertTrue(JacksonUtils.toObj(result.content).get("data").booleanValue()); + + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("data").booleanValue()); } catch (Exception e) { e.printStackTrace(); Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_模糊查询配置信息 - * @TestStep : 1. 发布配置 - * 2. 模糊查询 + * @TestStep : 1. 发布配置 2. 模糊查询 * @ExpectResult : 获取查询到配置 * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_openAPI_fuzzySearchConfig() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test123"; boolean ret = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(ret); - - List params = Arrays.asList("dataId", dataId, "group", group, "pageNo","1", "pageSize","10", "search", "blur"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("pageNo", "1"); + params.put("pageSize", "10"); + params.put("search", "blur"); result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - - Assert.assertTrue(JacksonUtils.toObj(result.content).get("totalCount").intValue() >= 1); - Assert.assertTrue(JacksonUtils.toObj(result.content).get("pageItems").get(0).get("content").textValue().startsWith(content)); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("totalCount").intValue() >= 1); + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("pageItems").get(0).get("content").textValue() + .startsWith(content)); } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_模糊查询配置信息 - * @TestStep : 1. 发布配置 - * 2. 查询配置信息 + * @TestStep : 1. 发布配置 2. 查询配置信息 * @ExpectResult : 获取查询到配置 * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_openAPI_fuzzySearchConfig_1() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test123"; boolean ret = iconfig.publishConfig(dataId, group, content); Thread.sleep(TIME_OUT); Assert.assertTrue(ret); - - List params = Arrays.asList("dataId", dataId+"*", "group", group+"*", "pageNo","1", "pageSize","10", "search", "blur"); + Map params = new HashMap<>(); + params.put("dataId", dataId + "*"); + params.put("group", group + "*"); + params.put("pageNo", "1"); + params.put("pageSize", "10"); + params.put("search", "blur"); result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertTrue(JacksonUtils.toObj(result.content).get("totalCount").intValue() >= 1); - Assert.assertEquals(content, JacksonUtils.toObj(result.content).get("pageItems").get(0).get("content").textValue()); - + + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertTrue(JacksonUtils.toObj(result.getData()).get("totalCount").intValue() >= 1); + Assert.assertEquals(content, + JacksonUtils.toObj(result.getData()).get("pageItems").get(0).get("content").textValue()); + } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_查询配置信息 - * @TestStep : 1. 发布配置 - * 2. 查询配置信息 + * @TestStep : 1. 发布配置 2. 查询配置信息 * @ExpectResult : 获取查询到配置 * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_openAPI_searchConfig() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test123"; boolean ret = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(ret); Thread.sleep(TIME_OUT); - - List params = Arrays.asList("dataId", dataId, "group", group, "pageNo","1", "pageSize","10", "search", "accurate"); + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("pageNo", "1"); + params.put("pageSize", "10"); + params.put("search", "accurate"); result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); - - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertEquals(1, JacksonUtils.toObj(result.content).get("totalCount").intValue()); - Assert.assertEquals(content, JacksonUtils.toObj(result.content).get("pageItems").get(0).get("content").textValue()); - + + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertEquals(1, JacksonUtils.toObj(result.getData()).get("totalCount").intValue()); + Assert.assertEquals(content, + JacksonUtils.toObj(result.getData()).get("pageItems").get(0).get("content").textValue()); + } catch (Exception e) { Assert.fail(); } } - + /** * @TCDescription : nacos_openAPI_查询配置信息,包含中文,utf-8 - * @TestStep : 1. 发布配置 - * 2. 查询配置信息 + * @TestStep : 1. 发布配置 2. 查询配置信息 * @ExpectResult : 获取查询到配置 * @author xiaochun.xxc * @since 3.6.8 */ - @Test(timeout = 5*TIME_OUT) + @Test(timeout = 5 * TIME_OUT) public void nacos_openAPI_searchConfig_2() { - HttpResult result = null; - + HttpRestResult result = null; + try { final String content = "test测试"; boolean ret = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(ret); Thread.sleep(TIME_OUT); - - List params = Arrays.asList("dataId", dataId, "group", group, "pageNo","1", "pageSize","10", "search", "accurate"); - result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, "utf-8", TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - Assert.assertEquals(1, JacksonUtils.toObj(result.content).get("totalCount").intValue()); - Assert.assertEquals(content, JacksonUtils.toObj(result.content).get("pageItems").get(0).get("content").textValue()); + + Map params = new HashMap<>(); + params.put("dataId", dataId); + params.put("group", group); + params.put("pageNo", "1"); + params.put("pageSize", "10"); + params.put("search", "accurate"); + result = agent.httpGet(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assert.assertEquals(1, JacksonUtils.toObj(result.getData()).get("totalCount").intValue()); + Assert.assertEquals(content, + JacksonUtils.toObj(result.getData()).get("pageItems").get(0).get("content").textValue()); } catch (Exception e) { Assert.fail(); } } - + } diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigExportAndImportAPI_CITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigExportAndImportAPI_CITCase.java index cd55ccaca..10ee4ddd7 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigExportAndImportAPI_CITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigExportAndImportAPI_CITCase.java @@ -20,7 +20,7 @@ import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.client.config.http.HttpAgent; import com.alibaba.nacos.client.config.http.MetricsHttpAgent; import com.alibaba.nacos.client.config.http.ServerHttpAgent; -import com.alibaba.nacos.client.config.impl.HttpSimpleClient; +import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.config.server.utils.ZipUtils; import com.fasterxml.jackson.databind.JsonNode; @@ -96,31 +96,44 @@ public class ConfigExportAndImportAPI_CITCase { @After public void cleanup() throws Exception{ - HttpSimpleClient.HttpResult result; + HttpRestResult result; try { - List params2 = Arrays.asList("dataId", "testNoAppname1.yml", "group", "EXPORT_IMPORT_TEST_GROUP", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params2, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + Map params = new HashMap<>(); + params.put("dataId", "testNoAppname1.yml"); + params.put("group", "EXPORT_IMPORT_TEST_GROUP"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); - List params3 = Arrays.asList("dataId", "testNoAppname2.txt", "group", "TEST1_GROUP", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params3, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + params.put("dataId", "testNoAppname2.txt"); + params.put("group", "TEST1_GROUP"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + + params.put("dataId", "testHasAppname1.properties"); + params.put("group", "EXPORT_IMPORT_TEST_GROUP"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); - List params4 = Arrays.asList("dataId", "testHasAppname1.properties", "group", "EXPORT_IMPORT_TEST_GROUP", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params4, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + params.put("dataId", "test1.yml"); + params.put("group", "TEST_IMPORT"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); - List params5 = Arrays.asList("dataId", "test1.yml", "group", "TEST_IMPORT", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params5, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + params.put("dataId", "test2.txt"); + params.put("group", "TEST_IMPORT"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); - List params6 = Arrays.asList("dataId", "test2.txt", "group", "TEST_IMPORT", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params6, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); - - List params7 = Arrays.asList("dataId", "test3.properties", "group", "TEST_IMPORT", "beta", "false"); - result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params7, agent.getEncode(), TIME_OUT); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code); + params.put("dataId", "test3.properties"); + params.put("group", "TEST_IMPORT"); + params.put("beta", "false"); + result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT); + Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); } catch (Exception e) { Assert.fail(); }