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