diff --git a/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClusterClientAbilities.java b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClusterClientAbilities.java new file mode 100644 index 000000000..76327a848 --- /dev/null +++ b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClusterClientAbilities.java @@ -0,0 +1,41 @@ +package com.alibaba.nacos.api.ability.register.impl; + +import com.alibaba.nacos.api.ability.constant.AbilityKey; +import com.alibaba.nacos.api.ability.register.AbstractAbilityRegistry; + +import java.util.Map; + +/** + * It is used to register cluster client abilities. + * + * @author Daydreamer + **/ +public class ClusterClientAbilities extends AbstractAbilityRegistry { + + private static final ClusterClientAbilities INSTANCE = new ClusterClientAbilities(); + + { + /* + * example: + * There is a function named "compression". + * The key is from

AbilityKey

, the value is whether turn on. + * + * You can add a new public field in

AbilityKey

like: + * DATA_COMPRESSION("compression", "description about this ability") + * + * And then you need to declare whether turn on in the ability table, you can: + * supportedAbilities.put(AbilityKey.DATA_COMPRESSION, true); means that current client support compression. + * + */ + // put ability here, which you want current client supports + } + + /** + * get static ability current cluster client supports. + * + * @return static ability + */ + public static Map getStaticAbilities() { + return INSTANCE.getSupportedAbilities(); + } +} diff --git a/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClientAbilities.java b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/SdkClientAbilities.java similarity index 89% rename from api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClientAbilities.java rename to api/src/main/java/com/alibaba/nacos/api/ability/register/impl/SdkClientAbilities.java index 669bd2ab3..cb306f11d 100644 --- a/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ClientAbilities.java +++ b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/SdkClientAbilities.java @@ -21,14 +21,15 @@ import com.alibaba.nacos.api.ability.register.AbstractAbilityRegistry; import java.util.Map; -/**. +/** + * It is used to register client abilities. + * * @author Daydreamer - * @description It is used to register client abilities. * @date 2022/8/31 12:32 **/ -public class ClientAbilities extends AbstractAbilityRegistry { +public class SdkClientAbilities extends AbstractAbilityRegistry { - private static final ClientAbilities INSTANCE = new ClientAbilities(); + private static final SdkClientAbilities INSTANCE = new SdkClientAbilities(); { /* diff --git a/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ServerAbilities.java b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ServerAbilities.java index 456b9f906..2fa8f9693 100644 --- a/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ServerAbilities.java +++ b/api/src/main/java/com/alibaba/nacos/api/ability/register/impl/ServerAbilities.java @@ -21,9 +21,10 @@ import com.alibaba.nacos.api.ability.register.AbstractAbilityRegistry; import java.util.Map; -/**. +/** + * It is used to register server abilities. + * * @author Daydreamer - * @description It is used to register server abilities. * @date 2022/8/31 12:32 **/ public class ServerAbilities extends AbstractAbilityRegistry { diff --git a/client/src/main/java/com/alibaba/nacos/client/ability/ClientAbilityControlManager.java b/client/src/main/java/com/alibaba/nacos/client/ability/ClientAbilityControlManager.java index a47b9b87e..cdbae28e3 100644 --- a/client/src/main/java/com/alibaba/nacos/client/ability/ClientAbilityControlManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/ability/ClientAbilityControlManager.java @@ -18,9 +18,10 @@ package com.alibaba.nacos.client.ability; import com.alibaba.nacos.api.ability.constant.AbilityKey; import com.alibaba.nacos.api.ability.constant.AbilityMode; -import com.alibaba.nacos.api.ability.register.impl.ClientAbilities; +import com.alibaba.nacos.api.ability.register.impl.SdkClientAbilities; import com.alibaba.nacos.common.ability.AbstractAbilityControlManager; +import java.util.HashMap; import java.util.Map; /**. @@ -34,13 +35,10 @@ public class ClientAbilityControlManager extends AbstractAbilityControlManager { } @Override - protected Map initCurrentNodeAbilities() { - return ClientAbilities.getStaticAbilities(); - } - - @Override - protected AbilityMode initializeMode() { - return AbilityMode.SDK_CLIENT; + protected Map> initCurrentNodeAbilities() { + Map> abilities = new HashMap<>(); + abilities.put(AbilityMode.SDK_CLIENT, SdkClientAbilities.getStaticAbilities()); + return abilities; } @Override diff --git a/common/src/main/java/com/alibaba/nacos/common/ability/AbstractAbilityControlManager.java b/common/src/main/java/com/alibaba/nacos/common/ability/AbstractAbilityControlManager.java index 447d214ef..1ef0f3d81 100644 --- a/common/src/main/java/com/alibaba/nacos/common/ability/AbstractAbilityControlManager.java +++ b/common/src/main/java/com/alibaba/nacos/common/ability/AbstractAbilityControlManager.java @@ -18,17 +18,18 @@ package com.alibaba.nacos.common.ability; import com.alibaba.nacos.api.ability.constant.AbilityKey; import com.alibaba.nacos.api.ability.constant.AbilityMode; +import com.alibaba.nacos.api.ability.constant.AbilityStatus; import com.alibaba.nacos.api.ability.initializer.AbilityPostProcessor; import com.alibaba.nacos.common.notify.Event; import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.spi.NacosServiceLoader; -import com.alibaba.nacos.common.utils.ThreadUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.Map; import java.util.Collection; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -40,16 +41,15 @@ import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractAbilityControlManager { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAbilityControlManager.class); - - /**. - * ability current node running + + /** + * current node support abilities. */ - protected final Map currentRunningAbility = new ConcurrentHashMap<>(); + protected final Map> currentNodeAbilities = new ConcurrentHashMap<>(); protected AbstractAbilityControlManager() { - ThreadUtils.addShutdownHook(this::destroy); NotifyCenter.registerToPublisher(AbilityUpdateEvent.class, 16384); - currentRunningAbility.putAll(getAbilityTable()); + initAbilityTable(); } /** @@ -57,16 +57,37 @@ public abstract class AbstractAbilityControlManager { * * @return abilities */ - private Map getAbilityTable() { + private void initAbilityTable() { + LOGGER.info("Ready to get current node abilities..."); // get processors - Collection processors = NacosServiceLoader.load(AbilityPostProcessor.class); - Map abilities = initCurrentNodeAbilities(); - AbilityMode mode = initializeMode(); + Map> abilities = initCurrentNodeAbilities(); // get abilities - for (AbilityPostProcessor processor : processors) { - processor.process(mode, abilities); + for (AbilityMode mode : AbilityMode.values()) { + Map abilitiesTable = abilities.get(mode); + if (abilitiesTable == null) { + continue; + } + // check whether exist error key + // check for developer + for (AbilityKey abilityKey : abilitiesTable.keySet()) { + if (!mode.equals(abilityKey.getMode())) { + LOGGER.error("You should not contain a other mode: {} in a specify mode: {} abilities set, error key: {}, please check again.", + abilityKey.getMode(), mode, abilityKey); + throw new IllegalStateException("Except mode: " + mode + " but " + abilityKey + " mode: " + abilityKey.getMode() + ", please check again."); + } + } + Collection processors = NacosServiceLoader.load(AbilityPostProcessor.class); + for (AbilityPostProcessor processor : processors) { + processor.process(mode, abilitiesTable); + } } - return AbilityKey.mapStr(abilities); + // init + Set abilityModes = abilities.keySet(); + LOGGER.info("Ready to initialize current node abilities, support modes: {}", abilityModes); + for (AbilityMode abilityMode : abilityModes) { + this.currentNodeAbilities.put(abilityMode, new ConcurrentHashMap<>(AbilityKey.mapStr(abilities.get(abilityMode)))); + } + LOGGER.info("Initialize current abilities finish..."); } /** @@ -75,14 +96,21 @@ public abstract class AbstractAbilityControlManager { * @param abilityKey ability key{@link AbilityKey} */ public void enableCurrentNodeAbility(AbilityKey abilityKey) { - doTurn(this.currentRunningAbility, abilityKey, true); + Map abilities = this.currentNodeAbilities.get(abilityKey.getMode()); + if (abilities != null) { + doTurn(abilities, abilityKey, true, abilityKey.getMode()); + } } - protected void doTurn(Map abilities, AbilityKey key, boolean turn) { + protected void doTurn(Map abilities, AbilityKey key, boolean turn, AbilityMode mode) { + if (!key.getMode().equals(mode)) { + throw new IllegalStateException("Except " + mode + " but " + key.getMode()); + } + LOGGER.info("Turn current node ability: {}, turn: {}", key, turn); abilities.put(key.getName(), turn); // notify event AbilityUpdateEvent abilityUpdateEvent = new AbilityUpdateEvent(); - abilityUpdateEvent.setTable(Collections.unmodifiableMap(currentRunningAbility)); + abilityUpdateEvent.setTable(Collections.unmodifiableMap(abilities)); abilityUpdateEvent.isOn = turn; abilityUpdateEvent.abilityKey = key; NotifyCenter.publishEvent(abilityUpdateEvent); @@ -94,7 +122,10 @@ public abstract class AbstractAbilityControlManager { * @param abilityKey ability key */ public void disableCurrentNodeAbility(AbilityKey abilityKey) { - doTurn(this.currentRunningAbility, abilityKey, false); + Map abilities = this.currentNodeAbilities.get(abilityKey.getMode()); + if (abilities != null) { + doTurn(abilities, abilityKey, false, abilityKey.getMode()); + } } /**. @@ -103,8 +134,15 @@ public abstract class AbstractAbilityControlManager { * @param abilityKey ability key from {@link AbilityKey} * @return whether support */ - public boolean isCurrentNodeAbilityRunning(AbilityKey abilityKey) { - return currentRunningAbility.getOrDefault(abilityKey.getName(), false); + public AbilityStatus isCurrentNodeAbilityRunning(AbilityKey abilityKey) { + Map abilities = currentNodeAbilities.get(abilityKey.getMode()); + if (abilities != null) { + Boolean support = abilities.get(abilityKey.getName()); + if (support != null) { + return support ? AbilityStatus.SUPPORTED : AbilityStatus.NOT_SUPPORTED; + } + } + return AbilityStatus.UNKNOWN; } /**. @@ -112,39 +150,19 @@ public abstract class AbstractAbilityControlManager { * * @return current node abilities */ - protected abstract Map initCurrentNodeAbilities(); - - /** - * initialize mode. - * - * @return mode. - */ - protected abstract AbilityMode initializeMode(); + protected abstract Map> initCurrentNodeAbilities(); /**. * Return the abilities current node * * @return current abilities */ - public Map getCurrentNodeAbilities() { - return Collections.unmodifiableMap(currentRunningAbility); - } - - /**. - * Close - */ - public final void destroy() { - LOGGER.warn("[DefaultAbilityControlManager] - Start destroying..."); - // hook - doDestroy(); - LOGGER.warn("[DefaultAbilityControlManager] - Destruction of the end"); - } - - /**. - * hook for subclass - */ - protected void doDestroy() { - // for server ability manager + public Map getCurrentNodeAbilities(AbilityMode mode) { + Map abilities = currentNodeAbilities.get(mode); + if (abilities != null) { + return Collections.unmodifiableMap(abilities); + } + return Collections.emptyMap(); } /** diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java index c4a96fccd..8047ce01a 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.remote.client.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.grpc.auto.BiRequestStreamGrpc; import com.alibaba.nacos.api.grpc.auto.Payload; @@ -62,9 +63,9 @@ import org.slf4j.LoggerFactory; import java.util.Map; import java.util.Optional; -import java.util.concurrent.CountDownLatch; import java.util.Arrays; import java.util.Properties; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -390,7 +391,7 @@ public abstract class GrpcClient extends RpcClient { conSetupRequest.setClientVersion(VersionUtils.getFullClientVersion()); conSetupRequest.setLabels(super.getLabels()); // set ability table - conSetupRequest.setAbilityTable(NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities()); + conSetupRequest.setAbilityTable(NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities(abilityMode())); conSetupRequest.setTenant(super.getTenant()); grpcConn.sendRequest(conSetupRequest); // wait for response @@ -413,6 +414,13 @@ public abstract class GrpcClient extends RpcClient { return null; } + /** + * ability mode: sdk client or cluster client. + * + * @return mode + */ + protected abstract AbilityMode abilityMode(); + @Override protected void afterReset(ConnectResetRequest request) { recAbilityContext.release(null); diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClusterClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClusterClient.java index 61f5b7649..7749f69b6 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClusterClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClusterClient.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.remote.client.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig; @@ -75,6 +76,11 @@ public class GrpcClusterClient extends GrpcClient { super(name, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig); } + @Override + protected AbilityMode abilityMode() { + return AbilityMode.CLUSTER_CLIENT; + } + @Override public int rpcPortOffset() { return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY, diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcSdkClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcSdkClient.java index 3b8f859e2..0ede2af6d 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcSdkClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcSdkClient.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.remote.client.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig; @@ -65,6 +66,11 @@ public class GrpcSdkClient extends GrpcClient { super(name, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig); } + @Override + protected AbilityMode abilityMode() { + return AbilityMode.SDK_CLIENT; + } + /** * constructor. * diff --git a/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTest.java b/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTest.java index 246952dda..c3f8bf8ed 100644 --- a/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTest.java +++ b/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTest.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.remote.client.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.api.grpc.auto.RequestGrpc; import com.alibaba.nacos.common.remote.client.RpcClient; import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig; @@ -70,6 +71,11 @@ public class GrpcClientTest { public void setUp() throws Exception { when(clientConfig.name()).thenReturn("testClient"); grpcClient = spy(new GrpcClient(clientConfig) { + @Override + protected AbilityMode abilityMode() { + return AbilityMode.SDK_CLIENT; + } + @Override public int rpcPortOffset() { return 1000; diff --git a/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTlsTest.java b/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTlsTest.java index 4a65577be..75397ae06 100644 --- a/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTlsTest.java +++ b/common/src/test/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClientTlsTest.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.common.remote.client.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import org.junit.Test; import static org.mockito.Mockito.when; @@ -33,6 +34,12 @@ public class GrpcClientTlsTest extends GrpcClientTest { when(clientConfig.tlsConfig()).thenReturn(tlsConfig); grpcClient = new GrpcClient(clientConfig) { + + @Override + protected AbilityMode abilityMode() { + return AbilityMode.SDK_CLIENT; + } + @Override public int rpcPortOffset() { return 1000; @@ -51,6 +58,12 @@ public class GrpcClientTlsTest extends GrpcClientTest { when(clientConfig.tlsConfig()).thenReturn(tlsConfig); grpcClient = new GrpcClient(clientConfig) { + + @Override + protected AbilityMode abilityMode() { + return AbilityMode.SDK_CLIENT; + } + @Override public int rpcPortOffset() { return 1000; @@ -72,6 +85,11 @@ public class GrpcClientTlsTest extends GrpcClientTest { when(clientConfig.name()).thenReturn("testClient"); when(clientConfig.tlsConfig()).thenReturn(tlsConfig); grpcClient = new GrpcClient(clientConfig) { + @Override + protected AbilityMode abilityMode() { + return AbilityMode.SDK_CLIENT; + } + @Override public int rpcPortOffset() { return 1000; diff --git a/core/src/main/java/com/alibaba/nacos/core/ability/control/ServerAbilityControlManager.java b/core/src/main/java/com/alibaba/nacos/core/ability/control/ServerAbilityControlManager.java index 99e3fbb12..20b4ee32c 100644 --- a/core/src/main/java/com/alibaba/nacos/core/ability/control/ServerAbilityControlManager.java +++ b/core/src/main/java/com/alibaba/nacos/core/ability/control/ServerAbilityControlManager.java @@ -18,6 +18,8 @@ package com.alibaba.nacos.core.ability.control; import com.alibaba.nacos.api.ability.constant.AbilityKey; import com.alibaba.nacos.api.ability.constant.AbilityMode; +import com.alibaba.nacos.api.ability.register.impl.ClusterClientAbilities; +import com.alibaba.nacos.api.ability.register.impl.SdkClientAbilities; import com.alibaba.nacos.api.ability.register.impl.ServerAbilities; import com.alibaba.nacos.common.ability.AbstractAbilityControlManager; import com.alibaba.nacos.core.ability.config.AbilityConfigs; @@ -39,7 +41,13 @@ public class ServerAbilityControlManager extends AbstractAbilityControlManager { } @Override - protected Map initCurrentNodeAbilities() { + protected Map> initCurrentNodeAbilities() { + // init client abilities + Map> res = new HashMap<>(); + res.put(AbilityMode.CLUSTER_CLIENT, initClusterClientAbilities()); + res.put(AbilityMode.SDK_CLIENT, initSdkClientAbilities()); + + // init server abilities // static abilities Map staticAbilities = ServerAbilities.getStaticAbilities(); // all function server can support @@ -64,12 +72,25 @@ public class ServerAbilityControlManager extends AbstractAbilityControlManager { }); // load from ServerAbilities unIncludedInConfig.forEach(abilityKey -> abilityTable.put(abilityKey, staticAbilities.get(abilityKey))); - return abilityTable; + + res.put(AbilityMode.SERVER, abilityTable); + return res; } - @Override - protected AbilityMode initializeMode() { - return AbilityMode.SERVER; + /** + * init cluster client abilities. + */ + private Map initClusterClientAbilities() { + // static abilities + return ClusterClientAbilities.getStaticAbilities(); + } + + /** + * init sdk client abilities. + */ + private Map initSdkClientAbilities() { + // static abilities + return SdkClientAbilities.getStaticAbilities(); } @Override diff --git a/core/src/main/java/com/alibaba/nacos/core/listener/StartingApplicationListener.java b/core/src/main/java/com/alibaba/nacos/core/listener/StartingApplicationListener.java index 2ddacee91..19fe93a55 100644 --- a/core/src/main/java/com/alibaba/nacos/core/listener/StartingApplicationListener.java +++ b/core/src/main/java/com/alibaba/nacos/core/listener/StartingApplicationListener.java @@ -142,7 +142,6 @@ public class StartingApplicationListener implements NacosApplicationListener { ThreadPoolManager.shutdown(); WatchFileCenter.shutdown(); NotifyCenter.shutdown(); - NacosAbilityManagerHolder.getInstance().destroy(); closeExecutor(); diff --git a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java index d01420b62..526e8e70e 100644 --- a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java +++ b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.core.remote.grpc; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.grpc.auto.BiRequestStreamGrpc; import com.alibaba.nacos.api.grpc.auto.Payload; @@ -138,7 +139,7 @@ public class GrpcBiStreamRequestAcceptor extends BiRequestStreamGrpc.BiRequestSt } else { try { // finish register, tell client has set up successfully - connection.request(new SetupAckRequest(NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities()), 3000L); + connection.request(new SetupAckRequest(NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities(AbilityMode.SERVER)), 3000L); } catch (Exception e) { // nothing to do diff --git a/core/src/test/java/com/alibaba/nacos/core/ability/AbilityControlManagerTest.java b/core/src/test/java/com/alibaba/nacos/core/ability/AbilityControlManagerTest.java index 2170a7fb8..272bfe6d4 100644 --- a/core/src/test/java/com/alibaba/nacos/core/ability/AbilityControlManagerTest.java +++ b/core/src/test/java/com/alibaba/nacos/core/ability/AbilityControlManagerTest.java @@ -18,6 +18,7 @@ package com.alibaba.nacos.core.ability; import com.alibaba.nacos.api.ability.constant.AbilityKey; import com.alibaba.nacos.api.ability.constant.AbilityMode; +import com.alibaba.nacos.api.ability.constant.AbilityStatus; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -41,18 +42,18 @@ public class AbilityControlManagerTest { @Test public void testCurrentNodeAbility() { - Set keySet = serverAbilityControlManager.getCurrentNodeAbilities().keySet(); + Set keySet = serverAbilityControlManager.getCurrentNodeAbilities(AbilityMode.SERVER).keySet(); // diable all keySet.forEach(key -> serverAbilityControlManager.disableCurrentNodeAbility(AbilityKey.getEnum(AbilityMode.SERVER, key))); // get all keySet.forEach(key -> { - Assert.assertFalse(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.getEnum(AbilityMode.SERVER, key))); + Assert.assertNotEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.getEnum(AbilityMode.SERVER, key)), AbilityStatus.SUPPORTED); }); // enable all keySet.forEach(key -> serverAbilityControlManager.enableCurrentNodeAbility(AbilityKey.getEnum(AbilityMode.SERVER, key))); // get all keySet.forEach(key -> { - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.getEnum(AbilityMode.SERVER, key))); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.getEnum(AbilityMode.SERVER, key)), AbilityStatus.SUPPORTED); }); } diff --git a/core/src/test/java/com/alibaba/nacos/core/ability/TestServerAbilityControlManager.java b/core/src/test/java/com/alibaba/nacos/core/ability/TestServerAbilityControlManager.java index 798857f80..087b94ef1 100644 --- a/core/src/test/java/com/alibaba/nacos/core/ability/TestServerAbilityControlManager.java +++ b/core/src/test/java/com/alibaba/nacos/core/ability/TestServerAbilityControlManager.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.core.ability; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.common.JustForTest; import com.alibaba.nacos.core.ability.control.ServerAbilityControlManager; @@ -25,8 +26,8 @@ public class TestServerAbilityControlManager extends ServerAbilityControlManager @JustForTest public void setCurrentSupportingAbility(Map ability) { - currentRunningAbility.clear(); - currentRunningAbility.putAll(ability); + currentNodeAbilities.get(AbilityMode.SERVER).clear(); + currentNodeAbilities.get(AbilityMode.SERVER).putAll(ability); } } diff --git a/core/src/test/java/com/alibaba/nacos/core/ability/config/AbilityConfigsTest.java b/core/src/test/java/com/alibaba/nacos/core/ability/config/AbilityConfigsTest.java index eb182d28f..ccca0bb2c 100644 --- a/core/src/test/java/com/alibaba/nacos/core/ability/config/AbilityConfigsTest.java +++ b/core/src/test/java/com/alibaba/nacos/core/ability/config/AbilityConfigsTest.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.core.ability.config; import com.alibaba.nacos.api.ability.constant.AbilityKey; +import com.alibaba.nacos.api.ability.constant.AbilityStatus; import com.alibaba.nacos.api.ability.register.AbstractAbilityRegistry; import com.alibaba.nacos.api.ability.register.impl.ServerAbilities; import com.alibaba.nacos.common.event.ServerConfigChangeEvent; @@ -92,16 +93,16 @@ public class AbilityConfigsTest { fill(); ServerAbilityControlManager manager = new ServerAbilityControlManager(); // config has higher priority - Assert.assertTrue(manager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); - Assert.assertFalse(manager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2)); + Assert.assertEquals(manager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); + Assert.assertNotEquals(manager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2), AbilityStatus.SUPPORTED); // clear currentAbilities.clear(); } @Test public void testInit() { - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2)); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2), AbilityStatus.SUPPORTED); } @Test @@ -110,24 +111,24 @@ public class AbilityConfigsTest { environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_1.getName(), Boolean.TRUE.toString()); environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_2.getName(), Boolean.TRUE.toString()); abilityConfigs.onEvent(new ServerConfigChangeEvent()); - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2)); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2), AbilityStatus.SUPPORTED); // test change environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_1.getName(), Boolean.FALSE.toString()); abilityConfigs.onEvent(new ServerConfigChangeEvent()); - Assert.assertFalse(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2)); + Assert.assertNotEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2), AbilityStatus.SUPPORTED); environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_1.getName(), Boolean.TRUE.toString()); abilityConfigs.onEvent(new ServerConfigChangeEvent()); - Assert.assertTrue(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); + Assert.assertEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_1.getName(), Boolean.FALSE.toString()); environment.setProperty(AbilityConfigs.PREFIX + AbilityKey.SERVER_TEST_2.getName(), Boolean.FALSE.toString()); abilityConfigs.onEvent(new ServerConfigChangeEvent()); - Assert.assertFalse(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1)); - Assert.assertFalse(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2)); + Assert.assertNotEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_1), AbilityStatus.SUPPORTED); + Assert.assertNotEquals(serverAbilityControlManager.isCurrentNodeAbilityRunning(AbilityKey.SERVER_TEST_2), AbilityStatus.SUPPORTED); } } diff --git a/test/core-test/src/test/java/com/alibaba/nacos/test/ability/AbilityDiscovery.java b/test/core-test/src/test/java/com/alibaba/nacos/test/ability/AbilityDiscovery.java index bbd21257a..4e3252008 100644 --- a/test/core-test/src/test/java/com/alibaba/nacos/test/ability/AbilityDiscovery.java +++ b/test/core-test/src/test/java/com/alibaba/nacos/test/ability/AbilityDiscovery.java @@ -63,7 +63,9 @@ public class AbilityDiscovery { private ConnectionManager connectionManager; private RpcClient client; - + + private RpcClient clusterClient; + private ConfigService configService; private AbstractAbilityControlManager oldInstance; @@ -74,10 +76,14 @@ public class AbilityDiscovery { private volatile boolean serverSuccess = false; private volatile boolean clientSuccess = false; + + private volatile boolean clusterSuccess = false; private Field abstractAbilityControlManager; private Field registryHandlerFields; + + private Field serverReuqestHandlersField; private Field currentConnField; @@ -104,7 +110,11 @@ public class AbilityDiscovery { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:" + port); configService = NacosFactory.createConfigService(properties); - + + // server request handler + serverReuqestHandlersField = RpcClient.class.getDeclaredField("serverRequestHandlers"); + serverReuqestHandlersField.setAccessible(true); + // init client client = RpcClientFactory.createClient(UUID.randomUUID().toString(), ConnectionType.GRPC, new HashMap<>()); client.serverListFactory(new ServerListFactory() { @@ -125,6 +135,26 @@ public class AbilityDiscovery { }); // connect to server client.start(); + + clusterClient = RpcClientFactory.createClusterClient(UUID.randomUUID().toString(), ConnectionType.GRPC, new HashMap<>()); + clusterClient.serverListFactory(new ServerListFactory() { + @Override + public String genNextServer() { + return "127.0.0.1:" + port; + } + + @Override + public String getCurrentServer() { + return "127.0.0.1:" + port; + } + + @Override + public List getServerList() { + return Collections.singletonList("127.0.0.1:" + port); + } + }); + // connect to server + clusterClient.start(); } @Test @@ -153,6 +183,8 @@ public class AbilityDiscovery { @Test public void testClientJudge() throws Exception { + List handlers = (List) serverReuqestHandlersField.get(client); + handlers.clear(); // register client.registerServerRequestHandler(new ServerRequestHandler() { @Override @@ -164,7 +196,7 @@ public class AbilityDiscovery { return new Response(){}; } }); - + // get id Connection conn = (Connection) currentConnField.get(client); @@ -179,6 +211,23 @@ public class AbilityDiscovery { Thread.sleep(4000); Assert.assertTrue(clientSuccess); } + + @Test + public void testClusterClient() throws IllegalAccessException, NacosException, InterruptedException, NoSuchFieldException { + Map handlers = (Map) registryHandlerFields + .get(requestHandlerRegistry); + + // set handler + RequestHandler oldRequestHandler = handlers.remove(ConfigQueryRequest.class.getSimpleName()); + handlers.put(ConfigQueryRequest.class.getSimpleName(), new ClusterClientRequestHandler(filters)); + configService.getConfig("test", "DEFAULT_GROUP", 2000); + // wait server invoke + Thread.sleep(3000); + Assert.assertTrue(clusterSuccess); + // recover + handlers.remove(ConfigQueryRequest.class.getSimpleName()); + handlers.put(ConfigQueryRequest.class.getSimpleName(), oldRequestHandler); + } @After public void recover() throws IllegalAccessException, NacosException { @@ -199,11 +248,30 @@ public class AbilityDiscovery { @Override public ConfigQueryResponse handle(ConfigQueryRequest request, RequestMeta meta) throws NacosException { - if (meta.getConnectionAbility(AbilityKey.SERVER_TEST_1).equals(AbilityStatus.SUPPORTED) && meta - .getConnectionAbility(AbilityKey.SERVER_TEST_2).equals(AbilityStatus.NOT_SUPPORTED)) { + if (meta.getConnectionAbility(AbilityKey.SDK_CLIENT_TEST_1).equals(AbilityStatus.SUPPORTED)) { serverSuccess = true; } return new ConfigQueryResponse(); } } + + /** + * just to test ability. + */ + class ClusterClientRequestHandler extends RequestHandler { + + public ClusterClientRequestHandler(RequestFilters requestFilters) throws NoSuchFieldException, IllegalAccessException { + Field declaredField = RequestHandler.class.getDeclaredField("requestFilters"); + declaredField.setAccessible(true); + declaredField.set(this, requestFilters); + } + + @Override + public ConfigQueryResponse handle(ConfigQueryRequest request, RequestMeta meta) throws NacosException { + if (meta.getConnectionAbility(AbilityKey.CLUSTER_CLIENT_TEST_1).equals(AbilityStatus.SUPPORTED)) { + clusterSuccess = true; + } + return new ConfigQueryResponse(); + } + } } diff --git a/test/core-test/src/test/java/com/alibaba/nacos/test/ability/component/TestServerAbilityControlManager.java b/test/core-test/src/test/java/com/alibaba/nacos/test/ability/component/TestServerAbilityControlManager.java index b1f58f3eb..cba747a94 100644 --- a/test/core-test/src/test/java/com/alibaba/nacos/test/ability/component/TestServerAbilityControlManager.java +++ b/test/core-test/src/test/java/com/alibaba/nacos/test/ability/component/TestServerAbilityControlManager.java @@ -1,18 +1,29 @@ package com.alibaba.nacos.test.ability.component; import com.alibaba.nacos.api.ability.constant.AbilityKey; +import com.alibaba.nacos.api.ability.constant.AbilityMode; import com.alibaba.nacos.core.ability.control.ServerAbilityControlManager; import java.util.HashMap; import java.util.Map; public class TestServerAbilityControlManager extends ServerAbilityControlManager { - + @Override - protected Map initCurrentNodeAbilities() { + protected Map> initCurrentNodeAbilities() { Map map = new HashMap<>(); map.put(AbilityKey.SERVER_TEST_1, true); map.put(AbilityKey.SERVER_TEST_2, false); - return map; + HashMap res = new HashMap<>(); + res.put(AbilityMode.SERVER, map); + + Map map1 = new HashMap<>(); + map1.put(AbilityKey.SDK_CLIENT_TEST_1, true); + res.put(AbilityMode.SDK_CLIENT, map1); + + Map map2 = new HashMap<>(); + map2.put(AbilityKey.CLUSTER_CLIENT_TEST_1, true); + res.put(AbilityMode.CLUSTER_CLIENT, map2); + return res; } }