diff --git a/pigx-register/pom.xml b/pigx-register/pom.xml
index 861f0f596..7170bbb73 100644
--- a/pigx-register/pom.xml
+++ b/pigx-register/pom.xml
@@ -27,9 +27,7 @@
nacos 注册配置中心
- 2.2.4-OEM
- 7.10.2
- 2.2
+ 2.3.2-OEM
2.7.18
2021.0.8
2.7.11
@@ -37,35 +35,31 @@
- io.springboot.nacos
+ group.springframework.nacos
nacos-config
${nacos.version}
-
- org.apache.tomcat.embed
- tomcat-embed-jasper
-
- io.springboot.nacos
+ group.springframework.nacos
nacos-naming
${nacos.version}
- io.springboot.nacos
+ group.springframework.nacos
nacos-istio
${nacos.version}
- io.springboot.nacos
- nacos-plugin-default-impl
+ group.springframework.nacos
+ nacos-default-plugin-all
${nacos.version}
- io.springboot.nacos
+ group.springframework.nacos
nacos-prometheus
${nacos.version}
@@ -111,19 +105,6 @@
spring-boot-admin-starter-server
${spring-boot-admin.version}
-
-
- rocksdbjni
- org.rocksdb
- ${rocksdb.version}
-
-
-
-
- org.yaml
- snakeyaml
- ${snakeyaml.version}
-
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java b/pigx-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java
index ae9bcdf42..8c7ed9717 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java
@@ -18,6 +18,7 @@ package com.alibaba.nacos.config;
import com.alibaba.nacos.core.code.ControllerMethodsCache;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
@@ -45,6 +46,13 @@ public class ConsoleConfig {
@Autowired
private ControllerMethodsCache methodsCache;
+ @Value("${nacos.console.ui.enabled:true}")
+ private boolean consoleUiEnabled;
+
+ public boolean isConsoleUiEnabled() {
+ return consoleUiEnabled;
+ }
+
/**
* Init.
*/
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleModuleStateBuilder.java b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleModuleStateBuilder.java
new file mode 100644
index 000000000..3e0c91710
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleModuleStateBuilder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2023 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.config.ConsoleConfig;
+import com.alibaba.nacos.sys.module.ModuleState;
+import com.alibaba.nacos.sys.module.ModuleStateBuilder;
+import com.alibaba.nacos.sys.utils.ApplicationUtils;
+
+/**
+ * Console module state builder.
+ *
+ * @author xiweng.yy
+ */
+public class ConsoleModuleStateBuilder implements ModuleStateBuilder {
+
+ public static final String CONSOLE_MODULE = "console";
+
+ private static final String CONSOLE_UI_ENABLED = "console_ui_enabled";
+
+ @Override
+ public ModuleState build() {
+ ModuleState result = new ModuleState(CONSOLE_MODULE);
+ try {
+ ConsoleConfig consoleConfig = ApplicationUtils.getBean(ConsoleConfig.class);
+ result.newState(CONSOLE_UI_ENABLED, consoleConfig.isConsoleUiEnabled());
+ }
+ catch (Exception ignored) {
+ }
+ return result;
+ }
+
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
index f5b0e9813..00be63787 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
@@ -16,11 +16,10 @@
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 com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
+import com.alibaba.nacos.core.cluster.health.ModuleHealthCheckerHolder;
+import com.alibaba.nacos.core.cluster.health.ReadinessResult;
+import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -36,75 +35,32 @@ import javax.servlet.http.HttpServletRequest;
*/
@RestController("consoleHealth")
@RequestMapping("/v1/console/health")
+@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
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 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 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;
- }
+
+ /**
+ * 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 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 readiness(HttpServletRequest request) {
+ ReadinessResult result = ModuleHealthCheckerHolder.getInstance().checkReadiness();
+ if (result.isSuccess()) {
+ return ResponseEntity.ok().body("OK");
+ }
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result.getResultMessage());
+ }
+
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
index ffe1e31de..99181d79b 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
@@ -21,10 +21,11 @@ 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.console.paramcheck.ConsoleDefaultHttpParamExtractor;
+import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
+import com.alibaba.nacos.core.namespace.model.Namespace;
+import com.alibaba.nacos.core.paramcheck.ExtractorManager;
+import com.alibaba.nacos.core.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;
@@ -47,109 +48,120 @@ import java.util.regex.Pattern;
*/
@RestController
@RequestMapping("/v1/console/namespaces")
+@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
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> 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);
- }
-
+
+ @Autowired
+ private NamespacePersistService namespacePersistService;
+
+ @Autowired
+ private NamespaceOperationService namespaceOperationService;
+
+ private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
+
+ private final Pattern namespaceNameCheckPattern = Pattern.compile("^[^@#$%^&*]+$");
+
+ private static final int NAMESPACE_ID_MAX_LENGTH = 128;
+
+ /**
+ * Get namespace list.
+ * @return namespace list
+ */
+ @GetMapping
+ public RestResult> 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 Namespace 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;
+ }
+ // check unique
+ if (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
+ return false;
+ }
+ }
+ // contains illegal chars
+ if (!namespaceNameCheckPattern.matcher(namespaceName).matches()) {
+ 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 (namespacePersistService.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) {
+ // contains illegal chars
+ if (!namespaceNameCheckPattern.matcher(namespaceShowName).matches()) {
+ return false;
+ }
+ 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/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
index 39c95b60b..0dd31c756 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
@@ -18,12 +18,14 @@ package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
+import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
+import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import com.alibaba.nacos.sys.module.ModuleState;
import com.alibaba.nacos.sys.module.ModuleStateHolder;
-import lombok.SneakyThrows;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@@ -36,10 +38,9 @@ import java.util.Map;
*/
@RestController
@RequestMapping("/v1/console/server")
+@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class ServerStateController {
- private static final String ANNOUNCEMENT_FILE = "classpath:conf/announcement.conf";
-
/**
* Get server state of current server.
* @return state json.
@@ -53,9 +54,14 @@ public class ServerStateController {
return ResponseEntity.ok().body(serverState);
}
- @SneakyThrows
@GetMapping("/announcement")
- public RestResult getAnnouncement() {
+ public RestResult getAnnouncement(
+ @RequestParam(required = false, name = "language", defaultValue = "zh-CN") String language) {
+ return RestResultUtils.success();
+ }
+
+ @GetMapping("/guide")
+ public RestResult getConsoleUiGuide() {
return RestResultUtils.success();
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/HealthControllerV2.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/HealthControllerV2.java
new file mode 100644
index 000000000..5dd0dcb01
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/HealthControllerV2.java
@@ -0,0 +1,65 @@
+/*
+ * 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.v2;
+
+import com.alibaba.nacos.api.model.v2.Result;
+import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
+import com.alibaba.nacos.core.cluster.health.ModuleHealthCheckerHolder;
+import com.alibaba.nacos.core.cluster.health.ReadinessResult;
+import com.alibaba.nacos.core.paramcheck.ExtractorManager;
+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 ControllerV2.
+ *
+ * @author DiligenceLai
+ */
+@RestController("consoleHealthV2")
+@RequestMapping("/v2/console/health")
+@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
+public class HealthControllerV2 {
+
+ /**
+ * 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 Result liveness() {
+ return Result.success("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 Result readiness(HttpServletRequest request) {
+ ReadinessResult result = ModuleHealthCheckerHolder.getInstance().checkReadiness();
+ if (result.isSuccess()) {
+ return Result.success("ok");
+ }
+ return Result.failure(result.getResultMessage());
+ }
+
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java
index c01325d5a..2c8d155d5 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java
@@ -23,10 +23,12 @@ 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.console.paramcheck.ConsoleDefaultHttpParamExtractor;
+import com.alibaba.nacos.core.namespace.model.Namespace;
+import com.alibaba.nacos.core.namespace.model.form.NamespaceForm;
+import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
+import com.alibaba.nacos.core.paramcheck.ExtractorManager;
+import com.alibaba.nacos.core.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;
@@ -52,101 +54,118 @@ import java.util.regex.Pattern;
@NacosApi
@RestController
@RequestMapping("/v2/console/namespace")
+@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
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> 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 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 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 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 deleteNamespace(@RequestParam("namespaceId") String namespaceId) {
- return Result.success(namespaceOperationService.removeNamespace(namespaceId));
- }
+
+ private final NamespaceOperationService namespaceOperationService;
+
+ private NamespacePersistService namespacePersistService;
+
+ public NamespaceControllerV2(NamespaceOperationService namespaceOperationService,
+ NamespacePersistService namespacePersistService) {
+ this.namespaceOperationService = namespaceOperationService;
+ this.namespacePersistService = namespacePersistService;
+ }
+
+ private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
+
+ private final Pattern namespaceNameCheckPattern = Pattern.compile("^[^@#$%^&*]+$");
+
+ private static final int NAMESPACE_ID_MAX_LENGTH = 128;
+
+ /**
+ * Get namespace list.
+ * @return namespace list
+ */
+ @GetMapping("/list")
+ public Result> 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 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 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);
+ }
+ // check unique
+ if (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
+ throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
+ "the namespaceId is existed, namespaceId: " + namespaceForm.getNamespaceId());
+ }
+ }
+ // contains illegal chars
+ if (!namespaceNameCheckPattern.matcher(namespaceName).matches()) {
+ throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
+ "namespaceName [" + namespaceName + "] contains illegal char");
+ }
+ 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 editNamespace(NamespaceForm namespaceForm) throws NacosException {
+ namespaceForm.validate();
+ // contains illegal chars
+ if (!namespaceNameCheckPattern.matcher(namespaceForm.getNamespaceName()).matches()) {
+ throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
+ "namespaceName [" + namespaceForm.getNamespaceName() + "] contains illegal char");
+ }
+ 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 deleteNamespace(@RequestParam("namespaceId") String namespaceId) {
+ return Result.success(namespaceOperationService.removeNamespace(namespaceId));
+ }
+
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java b/pigx-register/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java
deleted file mode 100644
index 8674ce8ae..000000000
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java b/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
index b7c7fcdb5..5d0a65cec 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
@@ -16,6 +16,7 @@
package com.alibaba.nacos.console.exception;
+import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.plugin.auth.exception.AccessException;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.common.utils.ExceptionUtil;
@@ -26,6 +27,7 @@ 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 org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
@@ -37,28 +39,36 @@ import javax.servlet.http.HttpServletRequest;
*/
@ControllerAdvice
public class ConsoleExceptionHandler {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
-
- @ExceptionHandler(AccessException.class)
- private ResponseEntity handleAccessException(AccessException e) {
- LOGGER.error("got exception. {}", e.getErrMsg());
- return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
- }
-
- @ExceptionHandler(IllegalArgumentException.class)
- private ResponseEntity handleIllegalArgumentException(IllegalArgumentException e) {
- return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionUtil.getAllExceptionMsg(e));
- }
-
- @ExceptionHandler(Exception.class)
- private ResponseEntity