diff --git a/common/src/main/java/com/alibaba/nacos/common/paramcheck/AbstractParamChecker.java b/common/src/main/java/com/alibaba/nacos/common/paramcheck/AbstractParamChecker.java index 6bb827ad7c8..dca59cf9698 100644 --- a/common/src/main/java/com/alibaba/nacos/common/paramcheck/AbstractParamChecker.java +++ b/common/src/main/java/com/alibaba/nacos/common/paramcheck/AbstractParamChecker.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.common.paramcheck; import java.util.List; +import java.util.function.Function; /** * The type Abstract param checker. @@ -46,6 +47,15 @@ public AbstractParamChecker() { */ public abstract ParamCheckResponse checkParamInfoList(List paramInfos); + /** + * Check param info list param check response. + * + * @param paramInfos the param infos + * @param extensionsParamChecker custom param checker function, accept params return paramCheckResponse. + * @return the param check response + */ + public abstract ParamCheckResponse checkParamInfoList(List paramInfos, Function extensionsParamChecker); + /** * Init param check rule. */ diff --git a/common/src/main/java/com/alibaba/nacos/common/paramcheck/DefaultParamChecker.java b/common/src/main/java/com/alibaba/nacos/common/paramcheck/DefaultParamChecker.java index d720828558f..560fab05b2b 100644 --- a/common/src/main/java/com/alibaba/nacos/common/paramcheck/DefaultParamChecker.java +++ b/common/src/main/java/com/alibaba/nacos/common/paramcheck/DefaultParamChecker.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.function.Function; import java.util.regex.Pattern; /** @@ -58,6 +60,11 @@ public String getCheckerType() { @Override public ParamCheckResponse checkParamInfoList(List paramInfos) { + return this.checkParamInfoList(paramInfos, null); + } + + @Override + public ParamCheckResponse checkParamInfoList(List paramInfos, Function extensionsParamChecker) { ParamCheckResponse paramCheckResponse = new ParamCheckResponse(); if (paramInfos == null) { paramCheckResponse.setSuccess(true); @@ -68,6 +75,14 @@ public ParamCheckResponse checkParamInfoList(List paramInfos) { if (!paramCheckResponse.isSuccess()) { return paramCheckResponse; } + // if extensionsParamChecker exists, check params + if (Objects.nonNull(extensionsParamChecker)) { + paramCheckResponse = extensionsParamChecker.apply(paramInfo); + // if not success ,return + if (!paramCheckResponse.isSuccess()) { + return paramCheckResponse; + } + } } paramCheckResponse.setSuccess(true); return paramCheckResponse; diff --git a/common/src/test/java/com/alibaba/nacos/common/paramcheck/MockParamChecker.java b/common/src/test/java/com/alibaba/nacos/common/paramcheck/MockParamChecker.java index 2660ee6c78f..9ced54bd2d6 100644 --- a/common/src/test/java/com/alibaba/nacos/common/paramcheck/MockParamChecker.java +++ b/common/src/test/java/com/alibaba/nacos/common/paramcheck/MockParamChecker.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.common.paramcheck; import java.util.List; +import java.util.function.Function; public class MockParamChecker extends AbstractParamChecker { @@ -30,6 +31,11 @@ public ParamCheckResponse checkParamInfoList(List paramInfos) { return new ParamCheckResponse(); } + @Override + public ParamCheckResponse checkParamInfoList(List paramInfos, Function extensionsParamChecker) { + return new ParamCheckResponse(); + } + @Override public void initParamCheckRule() { } diff --git a/core/src/main/java/com/alibaba/nacos/core/paramcheck/ParamCheckerFilter.java b/core/src/main/java/com/alibaba/nacos/core/paramcheck/ParamCheckerFilter.java index 6b1d1418bb1..c0ae7bbe354 100644 --- a/core/src/main/java/com/alibaba/nacos/core/paramcheck/ParamCheckerFilter.java +++ b/core/src/main/java/com/alibaba/nacos/core/paramcheck/ParamCheckerFilter.java @@ -24,6 +24,7 @@ import com.alibaba.nacos.common.paramcheck.ParamInfo; import com.alibaba.nacos.core.code.ControllerMethodsCache; import com.alibaba.nacos.core.exception.ErrorCode; +import com.alibaba.nacos.core.utils.NamespaceParamCheckUtils; import com.alibaba.nacos.plugin.control.Loggers; import javax.servlet.Filter; @@ -79,7 +80,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha List paramInfoList = httpParamExtractor.extractParam(req); ParamCheckerManager paramCheckerManager = ParamCheckerManager.getInstance(); AbstractParamChecker paramChecker = paramCheckerManager.getParamChecker(ServerParamCheckConfig.getInstance().getActiveParamChecker()); - ParamCheckResponse paramCheckResponse = paramChecker.checkParamInfoList(paramInfoList); + ParamCheckResponse paramCheckResponse = paramChecker.checkParamInfoList(paramInfoList, + paramInfo -> NamespaceParamCheckUtils.checkNamespaceExists(paramInfo.getNamespaceId())); if (paramCheckResponse.isSuccess()) { chain.doFilter(req, resp); } else { diff --git a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/RemoteParamCheckFilter.java b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/RemoteParamCheckFilter.java index 78875fbf31c..d3c0112339f 100644 --- a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/RemoteParamCheckFilter.java +++ b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/RemoteParamCheckFilter.java @@ -28,6 +28,7 @@ import com.alibaba.nacos.core.paramcheck.ExtractorManager; import com.alibaba.nacos.core.paramcheck.ServerParamCheckConfig; import com.alibaba.nacos.core.remote.AbstractRequestFilter; +import com.alibaba.nacos.core.utils.NamespaceParamCheckUtils; import com.alibaba.nacos.plugin.control.Loggers; import org.springframework.stereotype.Component; @@ -60,7 +61,8 @@ protected Response filter(Request request, RequestMeta meta, Class handlerClazz) ParamCheckerManager paramCheckerManager = ParamCheckerManager.getInstance(); AbstractParamChecker paramChecker = paramCheckerManager.getParamChecker( ServerParamCheckConfig.getInstance().getActiveParamChecker()); - ParamCheckResponse checkResponse = paramChecker.checkParamInfoList(paramInfoList); + ParamCheckResponse checkResponse = paramChecker.checkParamInfoList(paramInfoList, + paramInfo -> NamespaceParamCheckUtils.checkNamespaceExists(paramInfo.getNamespaceId())); if (!checkResponse.isSuccess()) { return generateFailResponse(request, checkResponse.getMessage(), handlerClazz); } diff --git a/core/src/main/java/com/alibaba/nacos/core/utils/NamespaceParamCheckUtils.java b/core/src/main/java/com/alibaba/nacos/core/utils/NamespaceParamCheckUtils.java new file mode 100644 index 00000000000..632d1eb1f77 --- /dev/null +++ b/core/src/main/java/com/alibaba/nacos/core/utils/NamespaceParamCheckUtils.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * 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 + * + * https://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.utils; + +import com.alibaba.nacos.api.common.Constants; +import com.alibaba.nacos.common.paramcheck.ParamCheckResponse; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; +import com.alibaba.nacos.sys.utils.ApplicationUtils; + +import java.util.Objects; + +/** + *

+ * namespace checker util. + *

+ * + * @author fuhouyu + * @since 2024/11/30 17:47 + */ +public class NamespaceParamCheckUtils { + + private NamespaceParamCheckUtils() { + + } + + /** + * check namespaceId exists. + * if namespace is null or empty or default public. return true. + * else query namespace by id. when not exists,then return false. + * @param namespaceId namespaceId + * @return paramCheckResponse + */ + public static ParamCheckResponse checkNamespaceExists(String namespaceId) { + ParamCheckResponse paramCheckResponse = new ParamCheckResponse(); + if (StringUtils.isEmpty(namespaceId) || Objects.equals(Constants.DEFAULT_NAMESPACE_ID, namespaceId)) { + paramCheckResponse.setSuccess(true); + return paramCheckResponse; + } + NamespacePersistService namespacePersistService = ApplicationUtils.getBean(NamespacePersistService.class); + int count = namespacePersistService.tenantInfoCountByTenantId(namespaceId); + // if namespaceId is not exists, return false. + if (count == 0) { + paramCheckResponse.setSuccess(false); + paramCheckResponse.setMessage("namespaceId [ " + namespaceId + " ] not exist"); + return paramCheckResponse; + } + // else return true + paramCheckResponse.setSuccess(true); + return paramCheckResponse; + } +} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/paramcheck/RpcParamCheckTest.java b/naming/src/test/java/com/alibaba/nacos/naming/paramcheck/RpcParamCheckTest.java index 7f79afe7758..71eb1a0ad51 100644 --- a/naming/src/test/java/com/alibaba/nacos/naming/paramcheck/RpcParamCheckTest.java +++ b/naming/src/test/java/com/alibaba/nacos/naming/paramcheck/RpcParamCheckTest.java @@ -20,7 +20,9 @@ import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.response.Response; +import com.alibaba.nacos.common.paramcheck.ParamCheckResponse; import com.alibaba.nacos.core.remote.grpc.RemoteParamCheckFilter; +import com.alibaba.nacos.core.utils.NamespaceParamCheckUtils; import com.alibaba.nacos.naming.remote.rpc.handler.InstanceRequestHandler; import com.alibaba.nacos.sys.env.EnvUtil; import org.junit.jupiter.api.Test; @@ -46,6 +48,13 @@ class RpcParamCheckTest { @Test void testFilter() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + MockedStatic namespaceParamCheckUtilsMockedStatic = Mockito.mockStatic(NamespaceParamCheckUtils.class); + // namespace check successResponse + ParamCheckResponse paramCheckResponse = new ParamCheckResponse(); + paramCheckResponse.setSuccess(true); + namespaceParamCheckUtilsMockedStatic.when(() -> NamespaceParamCheckUtils.checkNamespaceExists("test111")).thenReturn(paramCheckResponse); + namespaceParamCheckUtilsMockedStatic.when(() -> NamespaceParamCheckUtils.checkNamespaceExists("test@@@")).thenReturn(paramCheckResponse); + MockedStatic mockedStatic = Mockito.mockStatic(EnvUtil.class); mockedStatic.when(() -> EnvUtil.getProperty(Mockito.any(), Mockito.any(), Mockito.any())).thenAnswer((k) -> k.getArgument(2)); RemoteParamCheckFilter filter = new RemoteParamCheckFilter(); @@ -59,5 +68,6 @@ void testFilter() throws NoSuchMethodException, InvocationTargetException, Illeg Response response2 = (Response) method.invoke(filter, request, null, InstanceRequestHandler.class); assertEquals(400, response2.getErrorCode()); mockedStatic.close(); + namespaceParamCheckUtilsMockedStatic.close(); } } diff --git a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/AbstractInstanceOperate_ITCase.java b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/AbstractInstanceOperate_ITCase.java index ae2dec1b957..f8c800cecbe 100644 --- a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/AbstractInstanceOperate_ITCase.java +++ b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/AbstractInstanceOperate_ITCase.java @@ -25,9 +25,11 @@ import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.client.naming.remote.NamingClientProxy; import com.alibaba.nacos.common.utils.ReflectUtils; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import java.util.Arrays; @@ -42,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; public abstract class AbstractInstanceOperate_ITCase { @@ -53,6 +56,9 @@ public abstract class AbstractInstanceOperate_ITCase { @Value("${server.servlet.context-path}") private String contextPath; + @MockBean + private NamespacePersistService namespacePersistService; + @BeforeEach public void init() throws Exception { @@ -178,6 +184,7 @@ public void regService() throws NacosException, InterruptedException { properties.put(PropertyKeyConst.NAMESPACE, "t3"); properties.put(PropertyKeyConst.CONTEXT_PATH, contextPath); + when(namespacePersistService.tenantInfoCountByTenantId("t3")).thenReturn(1); naming = NamingFactory.createNamingService(properties); TimeUnit.SECONDS.sleep(10); diff --git a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java index 351454fabf8..7abd023c5b8 100644 --- a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java +++ b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java @@ -24,12 +24,14 @@ import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.test.base.Params; import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -41,6 +43,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; /** * @author nkorange @@ -55,6 +58,9 @@ class CPInstancesAPI_ITCase extends NamingBase { private NamingService naming2; + @MockBean + private NamespacePersistService namespacePersistService; + @LocalServerPort private int port; @@ -75,6 +81,8 @@ void setUp() throws Exception { properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port); naming2 = NamingFactory.createNamingService(properties); isNamingServerReady(); + when(namespacePersistService.tenantInfoCountByTenantId(TEST_NAMESPACE_1)).thenReturn(1); + when(namespacePersistService.tenantInfoCountByTenantId(TEST_NAMESPACE_2)).thenReturn(1); } @AfterEach diff --git a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java index 9f9b2d8a89a..8aa1208eae5 100644 --- a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java +++ b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java @@ -26,10 +26,12 @@ import com.alibaba.nacos.api.naming.listener.NamingEvent; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import java.util.Arrays; @@ -50,6 +52,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; /** * @author nkorange @@ -64,6 +67,9 @@ class MultiTenant_ITCase { private NamingService naming2; + @MockBean + private NamespacePersistService namespacePersistService; + @LocalServerPort private int port; @@ -93,6 +99,10 @@ void init() throws Exception { properties.put(PropertyKeyConst.NAMESPACE, "namespace-2"); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port); naming2 = NamingFactory.createNamingService(properties); + + + when(namespacePersistService.tenantInfoCountByTenantId("namespace-1")).thenReturn(1); + when(namespacePersistService.tenantInfoCountByTenantId("namespace-2")).thenReturn(1); } /** diff --git a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java index 7336f0f5b48..0d8ba5bca1e 100644 --- a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java +++ b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java @@ -22,12 +22,15 @@ import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.test.base.Params; import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; @@ -49,6 +52,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; /** * @author nkorange @@ -71,6 +75,9 @@ class MultiTenant_InstanceAPI_ITCase { @Autowired private TestRestTemplate restTemplate; + @MockBean + private NamespacePersistService namespacePersistService; + private URL base; @BeforeEach @@ -100,6 +107,9 @@ void init() throws Exception { properties.put(PropertyKeyConst.NAMESPACE, "namespace-2"); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port); naming2 = NamingFactory.createNamingService(properties); + + when(namespacePersistService.tenantInfoCountByTenantId("namespace-1")).thenReturn(1); + when(namespacePersistService.tenantInfoCountByTenantId("namespace-2")).thenReturn(1); } /** diff --git a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java index f88334411dc..e7008adc390 100644 --- a/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java +++ b/test/naming-test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java @@ -27,12 +27,14 @@ import com.alibaba.nacos.client.naming.listener.NamingChangeEvent; import com.alibaba.nacos.common.utils.ConcurrentHashSet; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.test.base.Params; import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -47,6 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.when; /** * Created by wangtong.wt on 2018/6/20. @@ -65,6 +68,9 @@ class Subscribe_ITCase extends NamingBase { private volatile List instances = Collections.emptyList(); + @MockBean + private NamespacePersistService namespacePersistService; + @BeforeEach void init() throws Exception { instances.clear(); @@ -272,6 +278,8 @@ void subscribeSameServiceForTwoNamingService() throws Exception { Properties properties2 = new Properties(); properties2.setProperty("serverAddr", "127.0.0.1" + ":" + port); properties2.setProperty("namespace", "ns-002"); + when(namespacePersistService.tenantInfoCountByTenantId("ns-001")).thenReturn(1); + when(namespacePersistService.tenantInfoCountByTenantId("ns-002")).thenReturn(1); final NamingService naming2 = NamingFactory.createNamingService(properties2); final ConcurrentHashSet concurrentHashSet1 = new ConcurrentHashSet();