diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java index 4b2d76539e2..8d3aa5d9a76 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java @@ -3173,6 +3173,19 @@ public void insertTenantInfoAtomic(String kp, String tenantId, String tenantName } } + /** + * @author klw(213539@qq.com) + * @Description: count tenant_info by tenant_id + * @Date 2019/12/10 17:36 + * @param: tenantId + * @return int + */ + public int countByTenantId(String tenantId){ + String[] args = new String[1]; + args[0] = tenantId; + return jt.queryForObject("select count(1) from tenant_info where tenant_id = ?", args, Integer.class); + } + /** * Update tenantInfo showname * diff --git a/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java b/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java index 12720d87ee2..3e923deb368 100644 --- a/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java +++ b/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.regex.Pattern; /** * namespace service @@ -42,6 +43,10 @@ public class NamespaceController { @Autowired private PersistService persistService; + private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); + + private static final int NAMESPACE_ID_MAX_LENGTH = 128; + /** * Get namespace list * @@ -102,15 +107,44 @@ public NamespaceAllInfo getNamespace(HttpServletRequest request, HttpServletResp */ @PostMapping public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response, + @RequestParam("customNamespaceId") String namespaceId, @RequestParam("namespaceName") String namespaceName, @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { // TODO 获取用kp - String namespaceId = UUID.randomUUID().toString(); + 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; + } + if(persistService.countByTenantId(namespaceId) > 0){ + return false; + } + } persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos", System.currentTimeMillis()); return true; } + /** + * @author klw(213539@qq.com) + * @Description: check namespaceId exist + * @Date 2019/12/10 21:41 + * @param: namespaceId + * @return java.lang.Boolean + */ + @GetMapping(params = "checkNamespaceIdExist=true") + public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId){ + if(StringUtils.isBlank(namespaceId)){ + return false; + } + return (persistService.countByTenantId(namespaceId) > 0); + } + /** * edit namespace * diff --git a/console/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js b/console/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js index 88c6c9b9bfb..bdbb897582d 100644 --- a/console/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js +++ b/console/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js @@ -109,14 +109,17 @@ class NewNameSpace extends React.Component { this.setState({ disabled: true, }); + let { customNamespaceId } = values; + if (!customNamespaceId) { + customNamespaceId = ''; + } request({ - type: 'post', - url: 'v1/console/namespaces', + type: 'get', + url: 'v1/console/namespaces?checkNamespaceIdExist=true', contentType: 'application/x-www-form-urlencoded', beforeSend: () => this.openLoading(), data: { - namespaceName: values.namespaceShowName, - namespaceDesc: values.namespaceDesc, + customNamespaceId, }, success: res => { this.disabled = false; @@ -124,13 +127,38 @@ class NewNameSpace extends React.Component { disabled: false, }); if (res === true) { - this.closeDialog(); - this.props.getNameSpaces(); - this.refreshNameSpace(); // 刷新全局namespace - } else { Dialog.alert({ title: locale.notice, - content: res.message, + content: locale.namespaceIdAlreadyExist, + }); + } else { + request({ + type: 'post', + url: 'v1/console/namespaces', + contentType: 'application/x-www-form-urlencoded', + beforeSend: () => this.openLoading(), + data: { + customNamespaceId, + namespaceName: values.namespaceShowName, + namespaceDesc: values.namespaceDesc, + }, + success: res => { + this.disabled = false; + this.setState({ + disabled: false, + }); + if (res === true) { + this.closeDialog(); + this.props.getNameSpaces(); + this.refreshNameSpace(); // 刷新全局namespace + } else { + Dialog.alert({ + title: locale.notice, + content: locale.newnamespceFailedMessage, + }); + } + }, + complete: () => this.closeLoading(), }); } }, @@ -164,6 +192,32 @@ class NewNameSpace extends React.Component { } } + validateNamespzecId(rule, value, callback) { + if (!value || value.trim() === '') { + callback(); + } else { + const { locale = {} } = this.props; + if (value.length > 128) { + callback(locale.namespaceIdTooLong); + } + const chartReg = /^[\w-]+/g; + const matchResult = value.match(chartReg); + if (matchResult) { + if (matchResult.length > 1) { + callback(locale.input); + } else { + if (value.length !== matchResult[0].length) { + callback(locale.input); + return; + } + callback(); + } + } else { + callback(locale.input); + } + } + } + render() { const { locale = {} } = this.props; const footer = ( @@ -193,6 +247,14 @@ class NewNameSpace extends React.Component { style={{ width: '100%', position: 'relative' }} visible={this.state.loading} > + + +