xuekang
2024-05-10 f5aa648c51f3c81140558d3da722f0977f6d2577
初始化
14个文件已添加
1310 ■■■■■ 已修改文件
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/Nacos.java
New file
@@ -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);
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java
New file
@@ -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());
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
New file
@@ -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;
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
New file
@@ -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);
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
New file
@@ -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);
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/controller/v2/NamespaceControllerV2.java
New file
@@ -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));
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/enums/NamespaceTypeEnum.java
New file
@@ -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;
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
New file
@@ -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));
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/exception/NacosApiExceptionHandler.java
New file
@@ -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());
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/filter/XssFilter.java
New file
@@ -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);
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/Namespace.java
New file
@@ -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;
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/NamespaceAllInfo.java
New file
@@ -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);
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/model/form/NamespaceForm.java
New file
@@ -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");
        }
    }
}
ruoyi-visual/ruoyi-nacos/src/main/java/com/alibaba/nacos/console/service/NamespaceOperationService.java
New file
@@ -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 获取用kp
        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 获取用kp
        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 获取用kp
        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 获取用kp
        commonPersistService.updateTenantNameAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc);
        return true;
    }
    /**
     * remove namespace.
     */
    public Boolean removeNamespace(String namespaceId) {
        commonPersistService.removeTenantInfoAtomic(DEFAULT_KP, namespaceId);
        return true;
    }
}