From f5aa648c51f3c81140558d3da722f0977f6d2577 Mon Sep 17 00:00:00 2001 From: xuekang <914468783@qq.com> Date: 星期五, 10 五月 2024 20:46:38 +0800 Subject: [PATCH] 初始化 --- ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java | 82 +++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java | 55 ++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java | 64 ++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java | 44 ++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java | 131 +++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java | 31 + ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java | 152 ++++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java | 155 +++++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java | 111 +++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java | 44 ++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java | 150 ++++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java | 66 +++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java | 110 +++++ ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java | 115 +++++ 14 files changed, 1,310 insertions(+), 0 deletions(-) diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java new file mode 100644 index 0000000..61a6f81 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * Nacos starter. + * + * @author nacos + */ +@SpringBootApplication(scanBasePackages = "com.alibaba.nacos") +@ServletComponentScan +@EnableScheduling +public class Nacos { + + public static void main(String[] args) { + // true 鍗曟満妯″紡 false 涓洪泦缇ゆā寮� 闆嗙兢妯″紡闇�鎼厤 cluster.conf 浣跨敤 浣跨敤鏂规硶璇锋煡鐪嬫枃妗� + System.setProperty("nacos.standalone", "true"); + System.setProperty("server.tomcat.accesslog.enabled", "false"); + // 鏈湴闆嗙兢鎼缓浣跨敤 鍒嗗埆鍦ㄦ墍鏈� nacos 鐩綍涓嬪垱寤� conf/cluster.conf 鏂囦欢鐢ㄤ簬缂栧啓闆嗙兢ip绔彛 + // 娉ㄦ剰 濡傛灉鏈湴鍚姩澶氫釜 nacos 姝ょ洰褰曚笉鑳界浉鍚� 渚嬪 nacos1 nacos2 nacos3 瀵瑰簲涓変釜nacos鏈嶅姟 + // System.setProperty("nacos.home", "D:/nacos"); + SpringApplication.run(Nacos.class, args); + } +} + diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java new file mode 100644 index 0000000..2afdaae --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java @@ -0,0 +1,82 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.config; + +import com.alibaba.nacos.console.filter.XssFilter; +import com.alibaba.nacos.core.code.ControllerMethodsCache; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.stereotype.Component; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import javax.annotation.PostConstruct; +import java.time.ZoneId; + +/** + * Console config. + * + * @author yshen + * @author nkorange + * @since 1.2.0 + */ +@Component +@EnableScheduling +@PropertySource("/application.properties") +public class ConsoleConfig { + + @Autowired + private ControllerMethodsCache methodsCache; + + /** + * Init. + */ + @PostConstruct + public void init() { + methodsCache.initClassMethod("com.alibaba.nacos.core.controller"); + methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); + methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller"); + methodsCache.initClassMethod("com.alibaba.nacos.console.controller"); + } + + @Bean + public CorsFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedHeader("*"); + config.setMaxAge(18000L); + config.addAllowedMethod("*"); + config.addAllowedOriginPattern("*"); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + + @Bean + public XssFilter xssFilter() { + return new XssFilter(); + } + + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(ZoneId.systemDefault().toString()); + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java new file mode 100644 index 0000000..f5b0e98 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java @@ -0,0 +1,110 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.controller; + +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.naming.controllers.OperatorController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +/** + * Health Controller. + * + * @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a> + */ +@RestController("consoleHealth") +@RequestMapping("/v1/console/health") +public class HealthController { + + private static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class); + + private final ConfigInfoPersistService configInfoPersistService; + + private final OperatorController apiCommands; + + @Autowired + public HealthController(ConfigInfoPersistService configInfoPersistService, OperatorController apiCommands) { + this.configInfoPersistService = configInfoPersistService; + this.apiCommands = apiCommands; + } + + /** + * Whether the Nacos is in broken states or not, and cannot recover except by being restarted. + * + * @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that + * Nacos is in broken states. + */ + @GetMapping("/liveness") + public ResponseEntity<String> liveness() { + return ResponseEntity.ok().body("OK"); + } + + /** + * Ready to receive the request or not. + * + * @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not + * ready. + */ + @GetMapping("/readiness") + public ResponseEntity<String> readiness(HttpServletRequest request) { + boolean isConfigReadiness = isConfigReadiness(); + boolean isNamingReadiness = isNamingReadiness(request); + + if (isConfigReadiness && isNamingReadiness) { + return ResponseEntity.ok().body("OK"); + } + + if (!isConfigReadiness && !isNamingReadiness) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config and Naming are not in readiness"); + } + + if (!isConfigReadiness) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config is not in readiness"); + } + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Naming is not in readiness"); + } + + private boolean isConfigReadiness() { + // check db + try { + configInfoPersistService.configInfoCount(""); + return true; + } catch (Exception e) { + LOGGER.error("Config health check fail.", e); + } + return false; + } + + private boolean isNamingReadiness(HttpServletRequest request) { + try { + apiCommands.metrics(request); + return true; + } catch (Exception e) { + LOGGER.error("Naming health check fail.", e); + } + return false; + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java new file mode 100644 index 0000000..ffe1e31 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java @@ -0,0 +1,155 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.controller; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.auth.annotation.Secured; +import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.common.model.RestResultUtils; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.service.repository.CommonPersistService; +import com.alibaba.nacos.console.model.Namespace; +import com.alibaba.nacos.console.model.NamespaceAllInfo; +import com.alibaba.nacos.console.service.NamespaceOperationService; +import com.alibaba.nacos.plugin.auth.constant.ActionTypes; +import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.UUID; +import java.util.regex.Pattern; + +/** + * namespace service. + * + * @author Nacos + */ +@RestController +@RequestMapping("/v1/console/namespaces") +public class NamespaceController { + + @Autowired + private CommonPersistService commonPersistService; + + @Autowired + private NamespaceOperationService namespaceOperationService; + + private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); + + private static final int NAMESPACE_ID_MAX_LENGTH = 128; + + /** + * Get namespace list. + * + * @return namespace list + */ + @GetMapping + public RestResult<List<Namespace>> getNamespaces() { + return RestResultUtils.success(namespaceOperationService.getNamespaceList()); + } + + /** + * get namespace all info by namespace id. + * + * @param namespaceId namespaceId + * @return namespace all info + */ + @GetMapping(params = "show=all") + public NamespaceAllInfo getNamespace(@RequestParam("namespaceId") String namespaceId) throws NacosException { + return namespaceOperationService.getNamespace(namespaceId); + } + + /** + * create namespace. + * + * @param namespaceName namespace Name + * @param namespaceDesc namespace Desc + * @return whether create ok + */ + @PostMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) + public Boolean createNamespace(@RequestParam("customNamespaceId") String namespaceId, + @RequestParam("namespaceName") String namespaceName, + @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { + if (StringUtils.isBlank(namespaceId)) { + namespaceId = UUID.randomUUID().toString(); + } else { + namespaceId = namespaceId.trim(); + if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) { + return false; + } + if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) { + return false; + } + } + try { + return namespaceOperationService.createNamespace(namespaceId, namespaceName, namespaceDesc); + } catch (NacosException e) { + return false; + } + } + + /** + * check namespaceId exist. + * + * @param namespaceId namespace id + * @return true if exist, otherwise false + */ + @GetMapping(params = "checkNamespaceIdExist=true") + public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId) { + if (StringUtils.isBlank(namespaceId)) { + return false; + } + return (commonPersistService.tenantInfoCountByTenantId(namespaceId) > 0); + } + + /** + * edit namespace. + * + * @param namespace namespace + * @param namespaceShowName namespace ShowName + * @param namespaceDesc namespace Desc + * @return whether edit ok + */ + @PutMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) + public Boolean editNamespace(@RequestParam("namespace") String namespace, + @RequestParam("namespaceShowName") String namespaceShowName, + @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { + return namespaceOperationService.editNamespace(namespace, namespaceShowName, namespaceDesc); + } + + /** + * del namespace by id. + * + * @param namespaceId namespace Id + * @return whether del ok + */ + @DeleteMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) + public Boolean deleteNamespace(@RequestParam("namespaceId") String namespaceId) { + return namespaceOperationService.removeNamespace(namespaceId); + } + +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java new file mode 100644 index 0000000..aa5ead4 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.controller; + +import com.alibaba.nacos.common.utils.VersionUtils; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +/** + * Server state controller. + * + * @author xingxuechao on:2019/2/27 11:17 AM + */ +@RestController +@RequestMapping("/v1/console/server") +public class ServerStateController { + + /** + * Get server state of current server. + * + * @return state json. + */ + @GetMapping("/state") + public ResponseEntity<Map<String, String>> serverState() { + Map<String, String> serverState = new HashMap<>(4); + serverState.put("standalone_mode", + EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER); + + serverState.put("function_mode", EnvUtil.getFunctionMode()); + serverState.put("version", VersionUtils.version); + + return ResponseEntity.ok().body(serverState); + } + +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java new file mode 100644 index 0000000..c01325d --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java @@ -0,0 +1,152 @@ +/* + * Copyright 1999-2022 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.console.controller.v2; + +import com.alibaba.nacos.api.annotation.NacosApi; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.api.NacosApiException; +import com.alibaba.nacos.api.model.v2.ErrorCode; +import com.alibaba.nacos.api.model.v2.Result; +import com.alibaba.nacos.auth.annotation.Secured; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.console.model.Namespace; +import com.alibaba.nacos.console.model.NamespaceAllInfo; +import com.alibaba.nacos.console.model.form.NamespaceForm; +import com.alibaba.nacos.console.service.NamespaceOperationService; +import com.alibaba.nacos.plugin.auth.constant.ActionTypes; +import com.alibaba.nacos.plugin.auth.constant.SignType; +import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.UUID; +import java.util.regex.Pattern; + +/** + * NamespaceControllerV2. + * + * @author dongyafei + * @date 2022/8/16 + */ +@NacosApi +@RestController +@RequestMapping("/v2/console/namespace") +public class NamespaceControllerV2 { + + private final NamespaceOperationService namespaceOperationService; + + public NamespaceControllerV2(NamespaceOperationService namespaceOperationService) { + this.namespaceOperationService = namespaceOperationService; + } + + private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); + + private static final int NAMESPACE_ID_MAX_LENGTH = 128; + + /** + * Get namespace list. + * + * @return namespace list + */ + @GetMapping("/list") + public Result<List<Namespace>> getNamespaceList() { + return Result.success(namespaceOperationService.getNamespaceList()); + } + + /** + * get namespace all info by namespace id. + * + * @param namespaceId namespaceId + * @return namespace all info + */ + @GetMapping() + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + + "namespaces", action = ActionTypes.READ, signType = SignType.CONSOLE) + public Result<NamespaceAllInfo> getNamespace(@RequestParam("namespaceId") String namespaceId) + throws NacosException { + return Result.success(namespaceOperationService.getNamespace(namespaceId)); + } + + /** + * create namespace. + * + * @param namespaceForm namespaceForm. + * @return whether create ok + */ + @PostMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + + "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE) + public Result<Boolean> createNamespace(NamespaceForm namespaceForm) throws NacosException { + + namespaceForm.validate(); + + String namespaceId = namespaceForm.getNamespaceId(); + String namespaceName = namespaceForm.getNamespaceName(); + String namespaceDesc = namespaceForm.getNamespaceDesc(); + + if (StringUtils.isBlank(namespaceId)) { + namespaceId = UUID.randomUUID().toString(); + } else { + namespaceId = namespaceId.trim(); + if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE, + "namespaceId [" + namespaceId + "] mismatch the pattern"); + } + if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE, + "too long namespaceId, over " + NAMESPACE_ID_MAX_LENGTH); + } + } + return Result.success(namespaceOperationService.createNamespace(namespaceId, namespaceName, namespaceDesc)); + } + + /** + * edit namespace. + * + * @param namespaceForm namespace params + * @return whether edit ok + */ + @PutMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + + "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE) + public Result<Boolean> editNamespace(NamespaceForm namespaceForm) throws NacosException { + namespaceForm.validate(); + return Result.success(namespaceOperationService + .editNamespace(namespaceForm.getNamespaceId(), namespaceForm.getNamespaceName(), + namespaceForm.getNamespaceDesc())); + } + + /** + * delete namespace by id. + * + * @param namespaceId namespace ID + * @return whether delete ok + */ + @DeleteMapping + @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + + "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE) + public Result<Boolean> deleteNamespace(@RequestParam("namespaceId") String namespaceId) { + return Result.success(namespaceOperationService.removeNamespace(namespaceId)); + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java new file mode 100644 index 0000000..8674ce8 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java @@ -0,0 +1,66 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.enums; + +/** + * the enum of namespace. + * 0 : Global configuration锛� 1 : Default private namespace 锛�2 : Custom namespace. + * + * @author chenglu + * @date 2021-05-25 17:01 + */ +public enum NamespaceTypeEnum { + + /** + * Global configuration. + */ + GLOBAL(0, "Global configuration"), + + /** + * Default private namespace. + */ + PRIVATE(1, "Default private namespace"), + + /** + * Custom namespace. + */ + CUSTOM(2, "Custom namespace"); + + /** + * the namespace type. + */ + private final int type; + + /** + * the description. + */ + private final String description; + + NamespaceTypeEnum(int type, String description) { + this.type = type; + this.description = description; + } + + public int getType() { + return type; + } + + public String getDescription() { + return description; + } +} + diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java new file mode 100644 index 0000000..b7c7fcd --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.exception; + +import com.alibaba.nacos.plugin.auth.exception.AccessException; +import com.alibaba.nacos.common.model.RestResultUtils; +import com.alibaba.nacos.common.utils.ExceptionUtil; +import com.alibaba.nacos.core.utils.Commons; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import javax.servlet.http.HttpServletRequest; + +/** + * Exception handler for console module. + * + * @author nkorange + * @since 1.2.0 + */ +@ControllerAdvice +public class ConsoleExceptionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleExceptionHandler.class); + + @ExceptionHandler(AccessException.class) + private ResponseEntity<String> handleAccessException(AccessException e) { + LOGGER.error("got exception. {}", e.getErrMsg()); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg()); + } + + @ExceptionHandler(IllegalArgumentException.class) + private ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionUtil.getAllExceptionMsg(e)); + } + + @ExceptionHandler(Exception.class) + private ResponseEntity<Object> handleException(HttpServletRequest request, Exception e) { + String uri = request.getRequestURI(); + LOGGER.error("CONSOLE {}", uri, e); + if (uri.contains(Commons.NACOS_SERVER_VERSION_V2)) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(RestResultUtils.failed(ExceptionUtil.getAllExceptionMsg(e))); + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtil.getAllExceptionMsg(e)); + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java new file mode 100644 index 0000000..df0c1f0 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java @@ -0,0 +1,131 @@ +/* + * Copyright 1999-2022 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.console.exception; + +import com.alibaba.nacos.api.annotation.NacosApi; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.api.NacosApiException; +import com.alibaba.nacos.api.model.v2.ErrorCode; +import com.alibaba.nacos.api.model.v2.Result; +import com.alibaba.nacos.common.utils.ExceptionUtil; +import com.alibaba.nacos.plugin.auth.exception.AccessException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConversionException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.HttpMediaTypeException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Exception Handler for Nacos API. + * @author dongyafei + * @date 2022/7/22 + */ + +@Order(-1) +@ControllerAdvice(annotations = {NacosApi.class}) +@ResponseBody +public class NacosApiExceptionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(NacosApiExceptionHandler.class); + + @ExceptionHandler(NacosApiException.class) + public ResponseEntity<Result<String>> handleNacosApiException(NacosApiException e) { + LOGGER.error("got exception. {} {}", e.getErrAbstract(), e.getErrMsg()); + return ResponseEntity.status(e.getErrCode()).body(new Result<>(e.getDetailErrCode(), e.getErrAbstract(), e.getErrMsg())); + } + + @ExceptionHandler(NacosException.class) + public ResponseEntity<Result<String>> handleNacosException(NacosException e) { + LOGGER.error("got exception. {}", e.getErrMsg()); + return ResponseEntity.status(e.getErrCode()).body(Result.failure(ErrorCode.SERVER_ERROR, e.getErrMsg())); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(HttpMessageNotReadableException.class) + public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.PARAMETER_MISSING, e.getMessage()); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(HttpMessageConversionException.class) + public Result<String> handleHttpMessageConversionException(HttpMessageConversionException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage()); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(NumberFormatException.class) + public Result<String> handleNumberFormatException(NumberFormatException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage()); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(IllegalArgumentException.class) + public Result<String> handleIllegalArgumentException(IllegalArgumentException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage()); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MissingServletRequestParameterException.class) + public Result<String> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.PARAMETER_MISSING, e.getMessage()); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(HttpMediaTypeException.class) + public Result<String> handleHttpMediaTypeException(HttpMediaTypeException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.MEDIA_TYPE_ERROR, e.getMessage()); + } + + @ResponseStatus(HttpStatus.FORBIDDEN) + @ExceptionHandler(AccessException.class) + public Result<String> handleAccessException(AccessException e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.ACCESS_DENIED, e.getErrMsg()); + } + + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(value = {DataAccessException.class, ServletException.class, IOException.class}) + public Result<String> handleDataAccessException(Exception e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(ErrorCode.DATA_ACCESS_ERROR, e.getMessage()); + } + + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(Exception.class) + public Result<String> handleOtherException(Exception e) { + LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e)); + return Result.failure(e.getMessage()); + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java new file mode 100644 index 0000000..192a609 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.filter; + +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * XSS filter. + * @author onewe + */ +public class XssFilter extends OncePerRequestFilter { + + private static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy"; + + private static final String CONTENT_SECURITY_POLICY = "script-src 'self'"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + + response.setHeader(CONTENT_SECURITY_POLICY_HEADER, CONTENT_SECURITY_POLICY); + filterChain.doFilter(request, response); + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java new file mode 100644 index 0000000..0a13166 --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java @@ -0,0 +1,115 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.model; + +/** + * Namespace. + * + * @author diamond + */ +public class Namespace { + + private String namespace; + + private String namespaceShowName; + + private String namespaceDesc; + + private int quota; + + private int configCount; + + /** + * see {@link com.alibaba.nacos.console.enums.NamespaceTypeEnum}. + */ + private int type; + + public String getNamespaceShowName() { + return namespaceShowName; + } + + public void setNamespaceShowName(String namespaceShowName) { + this.namespaceShowName = namespaceShowName; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public Namespace() { + } + + public Namespace(String namespace, String namespaceShowName) { + this.namespace = namespace; + this.namespaceShowName = namespaceShowName; + } + + public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) { + this.namespace = namespace; + this.namespaceShowName = namespaceShowName; + this.quota = quota; + this.configCount = configCount; + this.type = type; + } + + public Namespace(String namespace, String namespaceShowName, String namespaceDesc, int quota, int configCount, + int type) { + this.namespace = namespace; + this.namespaceShowName = namespaceShowName; + this.quota = quota; + this.configCount = configCount; + this.type = type; + this.namespaceDesc = namespaceDesc; + } + + public String getNamespaceDesc() { + return namespaceDesc; + } + + public void setNamespaceDesc(String namespaceDesc) { + this.namespaceDesc = namespaceDesc; + } + + public int getQuota() { + return quota; + } + + public void setQuota(int quota) { + this.quota = quota; + } + + public int getConfigCount() { + return configCount; + } + + public void setConfigCount(int configCount) { + this.configCount = configCount; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java new file mode 100644 index 0000000..92d9c8f --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java @@ -0,0 +1,31 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.console.model; + +/** + * all namespace info. + * + * @author Nacos + */ +public class NamespaceAllInfo extends Namespace { + + public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type, + String namespaceDesc) { + super(namespace, namespaceShowName, namespaceDesc, quota, configCount, type); + } + +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java new file mode 100644 index 0000000..851429a --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java @@ -0,0 +1,111 @@ +/* + * Copyright 1999-2022 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.console.model.form; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.api.NacosApiException; +import com.alibaba.nacos.api.model.v2.ErrorCode; +import org.springframework.http.HttpStatus; + +import java.io.Serializable; +import java.util.Objects; + +/** + * NamespaceForm. + * @author dongyafei + * @date 2022/8/16 + */ +public class NamespaceForm implements Serializable { + + private static final long serialVersionUID = -1078976569495343487L; + + private String namespaceId; + + private String namespaceName; + + private String namespaceDesc; + + public NamespaceForm() { + } + + public NamespaceForm(String namespaceId, String namespaceName, String namespaceDesc) { + this.namespaceId = namespaceId; + this.namespaceName = namespaceName; + this.namespaceDesc = namespaceDesc; + } + + public String getNamespaceId() { + return namespaceId; + } + + public void setNamespaceId(String namespaceId) { + this.namespaceId = namespaceId; + } + + public String getNamespaceName() { + return namespaceName; + } + + public void setNamespaceName(String namespaceName) { + this.namespaceName = namespaceName; + } + + public String getNamespaceDesc() { + return namespaceDesc; + } + + public void setNamespaceDesc(String namespaceDesc) { + this.namespaceDesc = namespaceDesc; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NamespaceForm that = (NamespaceForm) o; + return Objects.equals(namespaceId, that.namespaceId) && Objects.equals(namespaceName, that.namespaceName) + && Objects.equals(namespaceDesc, that.namespaceDesc); + } + + @Override + public int hashCode() { + return Objects.hash(namespaceId, namespaceName, namespaceDesc); + } + + @Override + public String toString() { + return "NamespaceVo{" + "namespaceId='" + namespaceId + '\'' + ", namespaceName='" + namespaceName + '\'' + + ", namespaceDesc='" + namespaceDesc + '\'' + '}'; + } + + /** + * check required param. + * @throws NacosException NacosException + */ + public void validate() throws NacosException { + if (null == namespaceId) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.PARAMETER_MISSING, "required parameter 'namespaceId' is missing"); + } + if (null == namespaceName) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.PARAMETER_MISSING, "required parameter 'namespaceName' is missing"); + } + } +} diff --git a/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java new file mode 100644 index 0000000..199261e --- /dev/null +++ b/ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java @@ -0,0 +1,150 @@ +/* + * Copyright 1999-2022 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.console.service; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.api.NacosApiException; +import com.alibaba.nacos.api.model.v2.ErrorCode; +import com.alibaba.nacos.common.utils.NamespaceUtil; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.model.TenantInfo; +import com.alibaba.nacos.config.server.service.repository.CommonPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.console.enums.NamespaceTypeEnum; +import com.alibaba.nacos.console.model.Namespace; +import com.alibaba.nacos.console.model.NamespaceAllInfo; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * NamespaceOperationService. + * + * @author dongyafei + * @date 2022/8/16 + */ + +@Service +public class NamespaceOperationService { + + private final ConfigInfoPersistService configInfoPersistService; + + private final CommonPersistService commonPersistService; + + private static final String DEFAULT_NAMESPACE = "public"; + + private static final String DEFAULT_NAMESPACE_SHOW_NAME = "Public"; + + private static final String DEFAULT_NAMESPACE_DESCRIPTION = "Public Namespace"; + + private static final int DEFAULT_QUOTA = 200; + + private static final String DEFAULT_CREATE_SOURCE = "nacos"; + + private static final String DEFAULT_TENANT = ""; + + private static final String DEFAULT_KP = "1"; + + public NamespaceOperationService(ConfigInfoPersistService configInfoPersistService, + CommonPersistService commonPersistService) { + this.configInfoPersistService = configInfoPersistService; + this.commonPersistService = commonPersistService; + } + + public List<Namespace> getNamespaceList() { + // TODO 鑾峰彇鐢╧p + List<TenantInfo> tenantInfos = commonPersistService.findTenantByKp(DEFAULT_KP); + + Namespace namespace0 = new Namespace(NamespaceUtil.getNamespaceDefaultId(), DEFAULT_NAMESPACE, DEFAULT_QUOTA, + configInfoPersistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType()); + List<Namespace> namespaceList = new ArrayList<>(); + namespaceList.add(namespace0); + + for (TenantInfo tenantInfo : tenantInfos) { + int configCount = configInfoPersistService.configInfoCount(tenantInfo.getTenantId()); + Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), + tenantInfo.getTenantDesc(), DEFAULT_QUOTA, configCount, NamespaceTypeEnum.CUSTOM.getType()); + namespaceList.add(namespaceTmp); + } + return namespaceList; + } + + /** + * query namespace by namespace id. + * + * @param namespaceId namespace Id. + * @return NamespaceAllInfo. + */ + public NamespaceAllInfo getNamespace(String namespaceId) throws NacosException { + // TODO 鑾峰彇鐢╧p + if (StringUtils.isBlank(namespaceId) || namespaceId.equals(NamespaceUtil.getNamespaceDefaultId())) { + return new NamespaceAllInfo(namespaceId, DEFAULT_NAMESPACE_SHOW_NAME, DEFAULT_QUOTA, + configInfoPersistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType(), + DEFAULT_NAMESPACE_DESCRIPTION); + } else { + TenantInfo tenantInfo = commonPersistService.findTenantByKp(DEFAULT_KP, namespaceId); + if (null == tenantInfo) { + throw new NacosApiException(HttpStatus.NOT_FOUND.value(), ErrorCode.NAMESPACE_NOT_EXIST, + "namespaceId [ " + namespaceId + " ] not exist"); + } + int configCount = configInfoPersistService.configInfoCount(namespaceId); + return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), DEFAULT_QUOTA, configCount, + NamespaceTypeEnum.CUSTOM.getType(), tenantInfo.getTenantDesc()); + } + } + + /** + * create namespace. + * + * @param namespaceId namespace ID + * @param namespaceName namespace Name + * @param namespaceDesc namespace Desc + * @return whether create ok + */ + public Boolean createNamespace(String namespaceId, String namespaceName, String namespaceDesc) + throws NacosException { + // TODO 鑾峰彇鐢╧p + if (commonPersistService.tenantInfoCountByTenantId(namespaceId) > 0) { + throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.NAMESPACE_ALREADY_EXIST, + "namespaceId [" + namespaceId + "] already exist"); + } + + commonPersistService + .insertTenantInfoAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc, DEFAULT_CREATE_SOURCE, + System.currentTimeMillis()); + return true; + } + + /** + * edit namespace. + */ + public Boolean editNamespace(String namespaceId, String namespaceName, String namespaceDesc) { + // TODO 鑾峰彇鐢╧p + commonPersistService.updateTenantNameAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc); + return true; + } + + /** + * remove namespace. + */ + public Boolean removeNamespace(String namespaceId) { + commonPersistService.removeTenantInfoAtomic(DEFAULT_KP, namespaceId); + return true; + } +} -- Gitblit v1.9.1