diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java index a78a454192f..b4284c957d7 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java @@ -30,9 +30,9 @@ import com.alibaba.nacos.config.server.model.ConfigCacheGray; import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; import com.alibaba.nacos.config.server.model.gray.TagGrayRule; +import com.alibaba.nacos.config.server.service.LongPollingService; import com.alibaba.nacos.config.server.service.query.ConfigChainRequestExtractorService; import com.alibaba.nacos.config.server.service.query.ConfigQueryChainService; -import com.alibaba.nacos.config.server.service.LongPollingService; import com.alibaba.nacos.config.server.service.query.enums.ResponseCode; import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; @@ -81,6 +81,12 @@ public ConfigServletInner(LongPollingService longPollingService, ConfigQueryChai this.configQueryChainService = configQueryChainService; } + private static String getDecryptContent(ConfigQueryChainResponse chainResponse, String dataId) { + Pair pair = EncryptionHandler.decryptHandler(dataId, chainResponse.getEncryptedDataKey(), + chainResponse.getContent()); + return pair.getSecond(); + } + /** * long polling the config. */ @@ -142,6 +148,7 @@ public String doGetConfig(HttpServletRequest request, HttpServletResponse respon switch (chainResponse.getStatus()) { case CONFIG_NOT_FOUND: + case SPECIAL_TAG_CONFIG_NOT_FOUND: return handlerConfigNotFound(response, apiVersion); case CONFIG_QUERY_CONFLICT: return handlerConfigConflict(response, apiVersion); @@ -162,9 +169,11 @@ private String handlerConfigNotFound(HttpServletResponse response, ApiVersionEnu private String handlerConfigConflict(HttpServletResponse response, ApiVersionEnum apiVersion) throws IOException { response.setStatus(HttpServletResponse.SC_CONFLICT); if (apiVersion == ApiVersionEnum.V1) { - return writeResponseForV1(response, Result.failure(ErrorCode.RESOURCE_CONFLICT, "requested file is being modified, please try later.")); + return writeResponseForV1(response, + Result.failure(ErrorCode.RESOURCE_CONFLICT, "requested file is being modified, please try later.")); } else { - return writeResponseForV2(response, Result.failure(ErrorCode.RESOURCE_CONFLICT, "requested file is being modified, please try later.")); + return writeResponseForV2(response, + Result.failure(ErrorCode.RESOURCE_CONFLICT, "requested file is being modified, please try later.")); } } @@ -204,10 +213,11 @@ private String handleResponseForV2(HttpServletResponse response, ConfigQueryChai } private void setResponseHeadForV1(HttpServletResponse response, ConfigQueryChainResponse chainResponse) { - String contentType = chainResponse.getContentType() != null ? chainResponse.getContentType() : FileTypeEnum.TEXT.getFileType(); - FileTypeEnum fileTypeEnum = FileTypeEnum.getFileTypeEnumByFileExtensionOrFileType(contentType); - String contentTypeHeader = fileTypeEnum.getContentType(); - response.setHeader(HttpHeaderConsts.CONTENT_TYPE, contentTypeHeader); + String contentType = chainResponse.getContentType(); + if (StringUtils.isBlank(contentType)) { + contentType = FileTypeEnum.TEXT.getContentType(); + } + response.setHeader(HttpHeaderConsts.CONTENT_TYPE, contentType); } private void setResponseHeadForV2(HttpServletResponse response) { @@ -238,12 +248,6 @@ private void writeContentForV2(HttpServletResponse response, ConfigQueryChainRes } } - private static String getDecryptContent(ConfigQueryChainResponse chainResponse, String dataId) { - Pair pair = EncryptionHandler.decryptHandler(dataId, chainResponse.getEncryptedDataKey(), - chainResponse.getContent()); - return pair.getSecond(); - } - private String writeResponseForV1(HttpServletResponse response, Result result) throws IOException { PrintWriter writer = response.getWriter(); writer.println(result.getData()); @@ -282,20 +286,23 @@ private void logPullEvent(String dataId, String group, String tenant, String req if (status == ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_QUERY_CONFLICT) { ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, -1, pullEvent, ConfigTraceService.PULL_TYPE_CONFLICT, -1, clientIp, notify, "http"); - } else if (status == ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND || chainResponse.getContent() == null) { + } else if (status == ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND + || chainResponse.getContent() == null) { ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, -1, pullEvent, ConfigTraceService.PULL_TYPE_NOTFOUND, -1, clientIp, notify, "http"); } else { long delayed = notify ? -1 : System.currentTimeMillis() - chainResponse.getLastModified(); - ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, chainResponse.getLastModified(), pullEvent, - ConfigTraceService.PULL_TYPE_OK, delayed, clientIp, notify, "http"); + ConfigTraceService.logPullEvent(dataId, group, tenant, requestIpApp, chainResponse.getLastModified(), + pullEvent, ConfigTraceService.PULL_TYPE_OK, delayed, clientIp, notify, "http"); } } - private void setCommonResponseHead(HttpServletResponse response, ConfigQueryChainResponse chainResponse, String tag) { - String contentType = chainResponse.getContentType() != null ? chainResponse.getContentType() : FileTypeEnum.TEXT.getFileType(); + private void setCommonResponseHead(HttpServletResponse response, ConfigQueryChainResponse chainResponse, + String tag) { + String configType = chainResponse.getConfigType() != null ? chainResponse.getConfigType() + : FileTypeEnum.TEXT.getFileType(); - response.setHeader(CONFIG_TYPE, contentType); + response.setHeader(CONFIG_TYPE, configType); response.setHeader(CONTENT_MD5, chainResponse.getMd5()); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); @@ -312,8 +319,9 @@ private void setCommonResponseHead(HttpServletResponse response, ConfigQueryChai response.setHeader("isBeta", "true"); } else if (TagGrayRule.TYPE_TAG.equals(chainResponse.getMatchedGray().getGrayRule().getType())) { try { - response.setHeader(TagGrayRule.TYPE_TAG, URLEncoder.encode(chainResponse.getMatchedGray().getGrayRule().getRawGrayRuleExp(), - StandardCharsets.UTF_8.displayName())); + response.setHeader(TagGrayRule.TYPE_TAG, + URLEncoder.encode(chainResponse.getMatchedGray().getGrayRule().getRawGrayRuleExp(), + StandardCharsets.UTF_8.displayName())); } catch (Exception e) { LOGGER.error("Error encoding tag", e); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java index b49f24ed3ad..f803df9ed47 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java @@ -114,6 +114,7 @@ public ConfigQueryResponse handle(ConfigQueryRequest request, RequestMeta meta) response.setMd5(chainResponse.getMd5()); response.setEncryptedDataKey(chainResponse.getEncryptedDataKey()); response.setContent(chainResponse.getContent()); + response.setContentType(chainResponse.getConfigType()); response.setLastModified(chainResponse.getLastModified()); String pullType = ConfigTraceService.PULL_TYPE_OK; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/DefaultConfigQueryHandlerChainBuilder.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/DefaultConfigQueryHandlerChainBuilder.java index 464befe65e8..6a93d5c4aea 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/DefaultConfigQueryHandlerChainBuilder.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/DefaultConfigQueryHandlerChainBuilder.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.service.query; import com.alibaba.nacos.config.server.service.query.handler.ConfigChainEntryHandler; +import com.alibaba.nacos.config.server.service.query.handler.ConfigContentTypeHandler; import com.alibaba.nacos.config.server.service.query.handler.FormalHandler; import com.alibaba.nacos.config.server.service.query.handler.GrayRuleMatchHandler; import com.alibaba.nacos.config.server.service.query.handler.SpecialTagNotFoundHandler; @@ -32,6 +33,7 @@ public class DefaultConfigQueryHandlerChainBuilder implements ConfigQueryHandler public ConfigQueryHandlerChain build() { ConfigQueryHandlerChain chain = new ConfigQueryHandlerChain(); chain.addHandler(new ConfigChainEntryHandler()) + .addHandler(new ConfigContentTypeHandler()) .addHandler(new GrayRuleMatchHandler()) .addHandler(new SpecialTagNotFoundHandler()) .addHandler(new FormalHandler()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/AbstractConfigQueryHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/AbstractConfigQueryHandler.java index 90254ea819d..56ac3b9d764 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/AbstractConfigQueryHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/AbstractConfigQueryHandler.java @@ -17,9 +17,8 @@ package com.alibaba.nacos.config.server.service.query.handler; /** - * AbstractConfigQueryHandler. - * This abstract class provides a base implementation for configuration query handlers. - * It implements the {@link ConfigQueryHandler} interface and handles the chaining of handlers. + * AbstractConfigQueryHandler. This abstract class provides a base implementation for configuration query handlers. It + * implements the {@link ConfigQueryHandler} interface and handles the chaining of handlers. * * @author Nacos */ @@ -27,12 +26,14 @@ public abstract class AbstractConfigQueryHandler implements ConfigQueryHandler { public ConfigQueryHandler nextHandler; - public void setNextHandler(ConfigQueryHandler nextHandler) { - this.nextHandler = nextHandler; - } - + @Override public ConfigQueryHandler getNextHandler() { return this.nextHandler; } + @Override + public void setNextHandler(ConfigQueryHandler nextHandler) { + this.nextHandler = nextHandler; + } + } \ No newline at end of file diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandler.java new file mode 100644 index 00000000000..5b65c031a19 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandler.java @@ -0,0 +1,52 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.enums.FileTypeEnum; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; + +import java.io.IOException; + +/** + * The type Config content type handler. + * @author Sunrisea + */ +public class ConfigContentTypeHandler extends AbstractConfigQueryHandler { + + private static final String CONFIG_CONTENT_TYPE_HANDLER_NAME = "ConfigContentTypeHandler"; + + @Override + public String getName() { + return CONFIG_CONTENT_TYPE_HANDLER_NAME; + } + + @Override + public ConfigQueryChainResponse handle(ConfigQueryChainRequest request) throws IOException { + ConfigQueryChainResponse response = getNextHandler().handle(request); + if (response.getStatus() == ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND + || response.getStatus() == ConfigQueryChainResponse.ConfigQueryStatus.SPECIAL_TAG_CONFIG_NOT_FOUND) { + return response; + } + String contentType = + response.getContentType() != null ? response.getContentType() : FileTypeEnum.TEXT.getFileType(); + FileTypeEnum fileTypeEnum = FileTypeEnum.getFileTypeEnumByFileExtensionOrFileType(contentType); + String contentTypeHeader = fileTypeEnum.getContentType(); + response.setContentType(contentTypeHeader); + return response; + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandler.java index dccbe620ca0..f99b4afeda7 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandler.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.query.handler; +import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.model.CacheItem; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; @@ -24,9 +25,9 @@ import java.io.IOException; /** - * Formal Handler. - * This class represents a formal handler in the configuration query processing chain. - * If the request has not been processed by previous handlers, it will be handled by this handler. + * Formal Handler. This class represents a formal handler in the configuration query processing chain. If the request + * has not been processed by previous handlers, it will be handled by this handler. + * * @author Nacos */ public class FormalHandler extends AbstractConfigQueryHandler { @@ -48,16 +49,19 @@ public ConfigQueryChainResponse handle(ConfigQueryChainRequest request) throws I CacheItem cacheItem = ConfigChainEntryHandler.getThreadLocalCacheItem(); String md5 = cacheItem.getConfigCache().getMd5(); + String content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); + if (StringUtils.isBlank(content)) { + response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND); + return response; + } long lastModified = cacheItem.getConfigCache().getLastModifiedTs(); String encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); - String contentType = cacheItem.getType(); - String content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); - + String configType = cacheItem.getType(); response.setContent(content); response.setMd5(md5); response.setLastModified(lastModified); response.setEncryptedDataKey(encryptedDataKey); - response.setContentType(contentType); + response.setConfigType(configType); response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_FORMAL); return response; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandler.java index 412fd8d78ef..1fab9e03c68 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandler.java @@ -25,9 +25,8 @@ import java.io.IOException; /** - * GrayRuleMatchHandler. - * This class represents a gray rule handler in the configuration query processing chain. - * It checks if the request matches any gray rules and processes the request accordingly. + * GrayRuleMatchHandler. This class represents a gray rule handler in the configuration query processing chain. It + * checks if the request matches any gray rules and processes the request accordingly. * * @author Nacos */ @@ -69,7 +68,7 @@ public ConfigQueryChainResponse handle(ConfigQueryChainRequest request) throws I response.setLastModified(lastModified); response.setEncryptedDataKey(encryptedDataKey); response.setMatchedGray(matchedGray); - response.setContentType(cacheItem.getType()); + response.setConfigType(cacheItem.getType()); response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_GRAY); return response; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandler.java index 900e755ecf9..542203aaebd 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandler.java @@ -17,8 +17,6 @@ package com.alibaba.nacos.config.server.service.query.handler; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.config.server.model.CacheItem; -import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; @@ -43,25 +41,7 @@ public String getName() { public ConfigQueryChainResponse handle(ConfigQueryChainRequest request) throws IOException { if (StringUtils.isNotBlank(request.getTag())) { ConfigQueryChainResponse response = new ConfigQueryChainResponse(); - - String dataId = request.getDataId(); - String group = request.getGroup(); - String tenant = request.getTenant(); - - CacheItem cacheItem = ConfigChainEntryHandler.getThreadLocalCacheItem(); - String md5 = cacheItem.getConfigCache().getMd5(); - long lastModified = cacheItem.getConfigCache().getLastModifiedTs(); - String encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); - String contentType = cacheItem.getType(); - String content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); - - response.setContent(content); - response.setMd5(md5); - response.setLastModified(lastModified); - response.setEncryptedDataKey(encryptedDataKey); - response.setContentType(contentType); response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.SPECIAL_TAG_CONFIG_NOT_FOUND); - return response; } else { return nextHandler.handle(request); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/query/model/ConfigQueryChainResponse.java b/config/src/main/java/com/alibaba/nacos/config/server/service/query/model/ConfigQueryChainResponse.java index 1028e35aa03..051a25cdd00 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/query/model/ConfigQueryChainResponse.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/query/model/ConfigQueryChainResponse.java @@ -32,6 +32,8 @@ public class ConfigQueryChainResponse { private String contentType; + private String configType; + private String encryptedDataKey; private String md5; @@ -89,6 +91,14 @@ public void setContentType(String contentType) { this.contentType = contentType; } + public String getConfigType() { + return configType; + } + + public void setConfigType(String configType) { + this.configType = configType; + } + public String getEncryptedDataKey() { return encryptedDataKey; } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java index 8a640a3e74c..29e185af350 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java @@ -26,10 +26,10 @@ import com.alibaba.nacos.config.server.model.gray.ConfigGrayPersistInfo; import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; import com.alibaba.nacos.config.server.model.gray.TagGrayRule; -import com.alibaba.nacos.config.server.service.query.ConfigQueryChainService; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService; +import com.alibaba.nacos.config.server.service.query.ConfigQueryChainService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.sys.env.EnvUtil; @@ -205,9 +205,9 @@ void testGetTagNotFound() throws Exception { //check content&md5 assertNull(response.getContent()); - assertEquals(MD5Utils.md5Hex(content, "UTF-8"), response.getMd5()); + assertNull(response.getMd5()); assertEquals(CONFIG_NOT_FOUND, response.getErrorCode()); - assertEquals("key_testGetTag_NotFound", response.getEncryptedDataKey()); + assertNull(response.getEncryptedDataKey()); //check flags. assertFalse(response.isBeta()); diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/DefaultChainRequestExtractorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/DefaultChainRequestExtractorTest.java new file mode 100644 index 00000000000..765c9a8183d --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/DefaultChainRequestExtractorTest.java @@ -0,0 +1,159 @@ +/* + * Copyright 1999-2024 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.service.query; + +import com.alibaba.nacos.api.config.remote.request.ConfigQueryRequest; +import com.alibaba.nacos.api.remote.request.RequestMeta; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.utils.RequestUtil; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.servlet.http.HttpServletRequest; + +import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class DefaultChainRequestExtractorTest { + + @InjectMocks + private DefaultChainRequestExtractor defaultChainRequestExtractor; + + @Mock + private HttpServletRequest request; + + private MockedStatic requestUtilMockedStatic; + + @BeforeEach + public void setUp() { + requestUtilMockedStatic = Mockito.mockStatic(RequestUtil.class); + Mockito.reset(request); + } + + @AfterEach + public void tearDown() { + requestUtilMockedStatic.close(); + } + + @Test + public void extractWithAllParametersShouldReturnCorrectConfigQueryChainRequest() { + when(request.getParameter("dataId")).thenReturn("dataId"); + when(request.getParameter("group")).thenReturn("group"); + when(request.getParameter("tenant")).thenReturn("tenant"); + when(request.getParameter("tag")).thenReturn("tag"); + when(request.getHeader(VIPSERVER_TAG)).thenReturn("autoTag"); + requestUtilMockedStatic.when(() -> RequestUtil.getRemoteIp(request)).thenReturn("127.0.0.1"); + + ConfigQueryChainRequest result = defaultChainRequestExtractor.extract(request); + + assertEquals("dataId", result.getDataId()); + assertEquals("group", result.getGroup()); + assertEquals("tenant", result.getTenant()); + assertEquals("tag", result.getTag()); + assertEquals("127.0.0.1", result.getAppLabels().get(BetaGrayRule.CLIENT_IP_LABEL)); + assertEquals("tag", result.getAppLabels().get(TagGrayRule.VIP_SERVER_TAG_LABEL)); + } + + @Test + public void extractWithEmptyTenantShouldReturnCorrectConfigQueryChainRequest() { + when(request.getParameter("dataId")).thenReturn("dataId"); + when(request.getParameter("group")).thenReturn("group"); + when(request.getParameter("tenant")).thenReturn(""); + when(request.getParameter("tag")).thenReturn("tag"); + when(request.getHeader(VIPSERVER_TAG)).thenReturn("autoTag"); + requestUtilMockedStatic.when(() -> RequestUtil.getRemoteIp(request)).thenReturn("127.0.0.1"); + + ConfigQueryChainRequest result = defaultChainRequestExtractor.extract(request); + + assertEquals("dataId", result.getDataId()); + assertEquals("group", result.getGroup()); + assertEquals("", result.getTenant()); + assertEquals("tag", result.getTag()); + assertEquals("127.0.0.1", result.getAppLabels().get(BetaGrayRule.CLIENT_IP_LABEL)); + assertEquals("tag", result.getAppLabels().get(TagGrayRule.VIP_SERVER_TAG_LABEL)); + } + + @Test + public void extractWithEmptyTagAndAutoTagShouldReturnCorrectConfigQueryChainRequest() { + when(request.getParameter("dataId")).thenReturn("dataId"); + when(request.getParameter("group")).thenReturn("group"); + when(request.getParameter("tenant")).thenReturn("tenant"); + when(request.getParameter("tag")).thenReturn(""); + when(request.getHeader(VIPSERVER_TAG)).thenReturn(""); + requestUtilMockedStatic.when(() -> RequestUtil.getRemoteIp(request)).thenReturn("127.0.0.1"); + + ConfigQueryChainRequest result = defaultChainRequestExtractor.extract(request); + + assertEquals("dataId", result.getDataId()); + assertEquals("group", result.getGroup()); + assertEquals("tenant", result.getTenant()); + assertEquals("", result.getTag()); + assertEquals("127.0.0.1", result.getAppLabels().get(BetaGrayRule.CLIENT_IP_LABEL)); + assertNull(result.getAppLabels().get(TagGrayRule.VIP_SERVER_TAG_LABEL)); + } + + @Test + public void extractWithAutoTagShouldReturnCorrectConfigQueryChainRequest() { + when(request.getParameter("dataId")).thenReturn("dataId"); + when(request.getParameter("group")).thenReturn("group"); + when(request.getParameter("tenant")).thenReturn("tenant"); + when(request.getParameter("tag")).thenReturn(""); + when(request.getHeader(VIPSERVER_TAG)).thenReturn("autoTag"); + when(RequestUtil.getRemoteIp(request)).thenReturn("127.0.0.1"); + + ConfigQueryChainRequest result = defaultChainRequestExtractor.extract(request); + + assertEquals("dataId", result.getDataId()); + assertEquals("group", result.getGroup()); + assertEquals("tenant", result.getTenant()); + assertEquals("", result.getTag()); + assertEquals("127.0.0.1", result.getAppLabels().get(BetaGrayRule.CLIENT_IP_LABEL)); + assertEquals("autoTag", result.getAppLabels().get(TagGrayRule.VIP_SERVER_TAG_LABEL)); + } + + @Test + public void extractWithConfigQueryRequestShouldReturnCorrectConfigQueryChainRequest() { + ConfigQueryRequest configQueryRequest = new ConfigQueryRequest(); + configQueryRequest.setDataId("dataId"); + configQueryRequest.setGroup("group"); + configQueryRequest.setTenant("tenant"); + configQueryRequest.setTag("tag"); + + RequestMeta requestMeta = new RequestMeta(); + requestMeta.setClientIp("127.0.0.1"); + ConfigQueryChainRequest result = defaultChainRequestExtractor.extract(configQueryRequest, requestMeta); + + assertEquals("dataId", result.getDataId()); + assertEquals("group", result.getGroup()); + assertEquals("tenant", result.getTenant()); + assertEquals("tag", result.getTag()); + assertEquals("127.0.0.1", result.getAppLabels().get(BetaGrayRule.CLIENT_IP_LABEL)); + assertEquals("tag", result.getAppLabels().get(TagGrayRule.VIP_SERVER_TAG_LABEL)); + } +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigChainEntryHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigChainEntryHandlerTest.java new file mode 100644 index 00000000000..067b1815d42 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigChainEntryHandlerTest.java @@ -0,0 +1,155 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.model.CacheItem; +import com.alibaba.nacos.config.server.service.ConfigCacheService; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; +import com.alibaba.nacos.config.server.utils.GroupKey2; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ConfigChainEntryHandlerTest { + + @InjectMocks + private ConfigChainEntryHandler configChainEntryHandler; + + private MockedStatic mockedStaticGroupKey2; + + private MockedStatic mockedStaticConfigCacheService; + + @Mock + private ConfigQueryHandler nextHandler; + + @Mock + private CacheItem cacheItem; + + @BeforeEach + public void setUp() { + mockedStaticGroupKey2 = Mockito.mockStatic(GroupKey2.class); + mockedStaticConfigCacheService = Mockito.mockStatic(ConfigCacheService.class); + configChainEntryHandler.setNextHandler(nextHandler); + } + + @AfterEach + public void tearDown() { + mockedStaticGroupKey2.close(); + mockedStaticConfigCacheService.close(); + } + + @Test + public void handleLockSuccessAndCacheItemNotNullShouldInvokeNextHandler() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + String groupKey = "groupKey"; + mockedStaticGroupKey2.when(() -> GroupKey2.getKey(anyString(), anyString(), anyString())).thenReturn(groupKey); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.tryConfigReadLock(groupKey)).thenReturn(1); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.getContentCache(groupKey)).thenReturn(cacheItem); + + ConfigQueryChainResponse nextResponse = new ConfigQueryChainResponse(); + nextResponse.setResultCode(200); + when(nextHandler.handle(request)).thenReturn(nextResponse); + ConfigQueryChainResponse response = configChainEntryHandler.handle(request); + + assertEquals(200, response.getResultCode()); + verify(nextHandler, times(1)).handle(request); + } + + @Test + public void handleLockSuccessAndCacheItemNullShouldReturnNotFound() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + String groupKey = "groupKey"; + mockedStaticGroupKey2.when(() -> GroupKey2.getKey(anyString(), anyString(), anyString())).thenReturn(groupKey); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.tryConfigReadLock(groupKey)).thenReturn(1); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.getContentCache(groupKey)).thenReturn(null); + + ConfigQueryChainResponse response = configChainEntryHandler.handle(request); + + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND, response.getStatus()); + verify(nextHandler, never()).handle(any()); + } + + @Test + public void handleLockFailureShouldReturnConflict() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + String groupKey = "groupKey"; + mockedStaticGroupKey2.when(() -> GroupKey2.getKey(anyString(), anyString(), anyString())).thenReturn(groupKey); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.tryConfigReadLock(groupKey)).thenReturn(-1); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.getContentCache(groupKey)).thenReturn(cacheItem); + + ConfigQueryChainResponse response = configChainEntryHandler.handle(request); + + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_QUERY_CONFLICT, response.getStatus()); + verify(nextHandler, never()).handle(any()); + } + + @Test + public void handleLockSuccessAndNextHandlerNullShouldReturnEmptyResponse() throws IOException { + configChainEntryHandler.setNextHandler(null); + + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + String groupKey = "groupKey"; + mockedStaticGroupKey2.when(() -> GroupKey2.getKey(anyString(), anyString(), anyString())).thenReturn(groupKey); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.tryConfigReadLock(groupKey)).thenReturn(1); + mockedStaticConfigCacheService.when(() -> ConfigCacheService.getContentCache(groupKey)).thenReturn(cacheItem); + + ConfigQueryChainResponse response = configChainEntryHandler.handle(request); + assertNull(response.getStatus()); + verify(nextHandler, never()).handle(any()); + } + + @Test + public void testGetName() { + assertEquals("chainEntryHandler", configChainEntryHandler.getName()); + } + +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandlerTest.java new file mode 100644 index 00000000000..69f64c61efb --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/ConfigContentTypeHandlerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.enums.FileTypeEnum; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ConfigContentTypeHandlerTest { + + private ConfigContentTypeHandler configContentTypeHandler = new ConfigContentTypeHandler(); + + @Mock + private ConfigQueryHandler nextHandler; + + @BeforeEach + public void setUp() { + configContentTypeHandler.setNextHandler(nextHandler); + } + + @Test + public void handleConfigNotFoundReturnsSameResponse() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse response = new ConfigQueryChainResponse(); + response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND); + + when(nextHandler.handle(request)).thenReturn(response); + + ConfigQueryChainResponse actualResponse = configContentTypeHandler.handle(request); + + assertEquals(response, actualResponse); + } + + @Test + public void handleSpecialTagConfigNotFoundReturnsSameResponse() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse response = new ConfigQueryChainResponse(); + response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.SPECIAL_TAG_CONFIG_NOT_FOUND); + + when(nextHandler.handle(request)).thenReturn(response); + + ConfigQueryChainResponse actualResponse = configContentTypeHandler.handle(request); + + assertEquals(response, actualResponse); + } + + @Test + public void handleContentTypeIsNullDefaultsToText() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse response = new ConfigQueryChainResponse(); + response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_FORMAL); + + when(nextHandler.handle(request)).thenReturn(response); + + ConfigQueryChainResponse actualResponse = configContentTypeHandler.handle(request); + + assertEquals(FileTypeEnum.TEXT.getContentType(), actualResponse.getContentType()); + } + + @Test + public void handleContentTypeIsNotNullSetsCorrectContentType() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse response = new ConfigQueryChainResponse(); + response.setStatus(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_FORMAL); + response.setContentType(FileTypeEnum.JSON.name()); + + when(nextHandler.handle(request)).thenReturn(response); + + ConfigQueryChainResponse actualResponse = configContentTypeHandler.handle(request); + + assertEquals(FileTypeEnum.JSON.getContentType(), actualResponse.getContentType()); + } +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandlerTest.java new file mode 100644 index 00000000000..4d5fa3b0788 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/FormalHandlerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.model.CacheItem; +import com.alibaba.nacos.config.server.model.ConfigCache; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskService; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class FormalHandlerTest { + + @InjectMocks + private FormalHandler formalHandler; + + private MockedStatic configDiskServiceFactoryMockedStatic; + + private MockedStatic configChainEntryHandlerMockedStatic; + + @Mock + private ConfigDiskService configDiskService; + + @Mock + private CacheItem cacheItem; + + @Mock + private ConfigCache configCache; + + @BeforeEach + public void setUp() throws IOException { + configDiskServiceFactoryMockedStatic = Mockito.mockStatic(ConfigDiskServiceFactory.class); + configChainEntryHandlerMockedStatic = Mockito.mockStatic(ConfigChainEntryHandler.class); + configChainEntryHandlerMockedStatic.when(ConfigChainEntryHandler::getThreadLocalCacheItem) + .thenReturn(cacheItem); + configDiskServiceFactoryMockedStatic.when(ConfigDiskServiceFactory::getInstance).thenReturn(configDiskService); + } + + @AfterEach + public void tearDown() { + configDiskServiceFactoryMockedStatic.close(); + configChainEntryHandlerMockedStatic.close(); + } + + @Test + public void handleContentEmptyShouldReturnConfigNotFound() throws IOException { + when(cacheItem.getConfigCache()).thenReturn(configCache); + when(configCache.getMd5()).thenReturn("mockMd5"); + when(configDiskService.getContent("dataId", "group", "tenant")).thenReturn(""); + + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + ConfigQueryChainResponse response = formalHandler.handle(request); + + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_NOT_FOUND, response.getStatus()); + } + + @Test + public void handleContentNotEmptyShouldReturnConfigFoundFormal() throws IOException { + when(cacheItem.getConfigCache()).thenReturn(configCache); + when(configCache.getMd5()).thenReturn("mockMd5"); + when(configCache.getLastModifiedTs()).thenReturn(123456789L); + when(configCache.getEncryptedDataKey()).thenReturn("mockEncryptedDataKey"); + when(cacheItem.getType()).thenReturn("mockType"); + when(configDiskService.getContent("dataId", "group", "tenant")).thenReturn("mockContent"); + + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + ConfigQueryChainResponse response = formalHandler.handle(request); + + assertEquals("mockContent", response.getContent()); + assertEquals("mockMd5", response.getMd5()); + assertEquals(123456789L, response.getLastModified()); + assertEquals("mockEncryptedDataKey", response.getEncryptedDataKey()); + assertEquals("mockType", response.getConfigType()); + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_FORMAL, response.getStatus()); + } + + @Test + public void testGetName() { + assertEquals("formalHandler", formalHandler.getName()); + } + +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandlerTest.java new file mode 100644 index 00000000000..bbbc86678ed --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/GrayRuleMatchHandlerTest.java @@ -0,0 +1,142 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.model.CacheItem; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskService; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class GrayRuleMatchHandlerTest { + + @InjectMocks + private GrayRuleMatchHandler grayRuleMatchHandler; + + private MockedStatic configChainEntryHandlerMockedStatic; + + private MockedStatic configDiskServiceFactoryMockedStatic; + + @Mock + private CacheItem cacheItem; + + @Mock + private ConfigCacheGray configCacheGray; + + @Mock + private ConfigDiskService configDiskService; + + @Mock + private ConfigQueryHandler nextHandler; + + @BeforeEach + public void setUp() { + configChainEntryHandlerMockedStatic = Mockito.mockStatic(ConfigChainEntryHandler.class); + configChainEntryHandlerMockedStatic.when(ConfigChainEntryHandler::getThreadLocalCacheItem) + .thenReturn(cacheItem); + configDiskServiceFactoryMockedStatic = Mockito.mockStatic(ConfigDiskServiceFactory.class); + configDiskServiceFactoryMockedStatic.when(ConfigDiskServiceFactory::getInstance).thenReturn(configDiskService); + } + + @AfterEach + public void tearDown() { + configChainEntryHandlerMockedStatic.close(); + configDiskServiceFactoryMockedStatic.close(); + } + + @Test + public void handleNoGrayRulesShouldPassToNextHandler() throws IOException { + when(cacheItem.getSortConfigGrays()).thenReturn(Collections.emptyList()); + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse expectedResponse = new ConfigQueryChainResponse(); + expectedResponse.setResultCode(123); // 假设这是下一个处理器的响应 + + when(nextHandler.handle(request)).thenReturn(expectedResponse); + grayRuleMatchHandler.setNextHandler(nextHandler); + + ConfigQueryChainResponse response = grayRuleMatchHandler.handle(request); + + assertEquals(expectedResponse, response); + } + + @Test + public void handleNoMatchingGrayRuleShouldPassToNextHandler() throws IOException { + when(cacheItem.getSortConfigGrays()).thenReturn(Collections.singletonList(configCacheGray)); + when(configCacheGray.match(any())).thenReturn(false); + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + ConfigQueryChainResponse expectedResponse = new ConfigQueryChainResponse(); + expectedResponse.setResultCode(123); // 假设这是下一个处理器的响应 + + when(nextHandler.handle(request)).thenReturn(expectedResponse); + grayRuleMatchHandler.setNextHandler(nextHandler); + + ConfigQueryChainResponse response = grayRuleMatchHandler.handle(request); + + assertEquals(expectedResponse, response); + } + + @Test + public void handleMatchingGrayRuleShouldReturnConfigResponse() throws IOException { + when(cacheItem.getSortConfigGrays()).thenReturn(Collections.singletonList(configCacheGray)); + when(configCacheGray.match(any())).thenReturn(true); + when(configCacheGray.getLastModifiedTs()).thenReturn(123456L); + when(configCacheGray.getMd5()).thenReturn("md5"); + when(configCacheGray.getEncryptedDataKey()).thenReturn("encryptedKey"); + when(configCacheGray.getGrayName()).thenReturn("grayName"); + when(cacheItem.getType()).thenReturn("configType"); + when(configDiskService.getGrayContent(anyString(), anyString(), anyString(), anyString())).thenReturn( + "content"); + + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setDataId("dataId"); + request.setGroup("group"); + request.setTenant("tenant"); + + ConfigQueryChainResponse response = grayRuleMatchHandler.handle(request); + + assertEquals("content", response.getContent()); + assertEquals("md5", response.getMd5()); + assertEquals(123456L, response.getLastModified()); + assertEquals("encryptedKey", response.getEncryptedDataKey()); + assertEquals("configType", response.getConfigType()); + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.CONFIG_FOUND_GRAY, response.getStatus()); + } + + @Test + public void testGetName() { + assertEquals("grayRuleMatchHandler", grayRuleMatchHandler.getName()); + } +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandlerTest.java new file mode 100644 index 00000000000..817f0f35cc2 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/query/handler/SpecialTagNotFoundHandlerTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2024 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.service.query.handler; + +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainRequest; +import com.alibaba.nacos.config.server.service.query.model.ConfigQueryChainResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class SpecialTagNotFoundHandlerTest { + + @InjectMocks + private SpecialTagNotFoundHandler specialTagNotFoundHandler; + + @Mock + private ConfigQueryHandler nextHandler; + + @Test + public void handleTagNotEmptyReturnsSpecialTagNotFoundResponse() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setTag("someTag"); + ConfigQueryChainResponse response = specialTagNotFoundHandler.handle(request); + assertEquals(ConfigQueryChainResponse.ConfigQueryStatus.SPECIAL_TAG_CONFIG_NOT_FOUND, response.getStatus()); + } + + @Test + public void handleTagEmptyDelegatesToNextHandler() throws IOException { + ConfigQueryChainRequest request = new ConfigQueryChainRequest(); + request.setTag(""); + ConfigQueryChainResponse expectedResponse = new ConfigQueryChainResponse(); + when(nextHandler.handle(request)).thenReturn(expectedResponse); + ConfigQueryChainResponse response = specialTagNotFoundHandler.handle(request); + assertEquals(expectedResponse, response); + } + + @Test + public void getName() { + assertEquals("specialTagNotFoundHandler", specialTagNotFoundHandler.getName()); + } + +} \ No newline at end of file