Commit 7bdfe80e authored by Jason Song's avatar Jason Song

app and namespace standard

1. add org info display
2. add input validator
3. add org id prefix to namespace
4. hotfix: to clear id value for create
parent e90fd82a
......@@ -15,7 +15,9 @@ import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.biz.service.AdminService;
import com.ctrip.framework.apollo.biz.service.AppService;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.core.dto.AppDTO;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.core.exception.NotFoundException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
......@@ -30,6 +32,9 @@ public class AppController {
@RequestMapping(path = "/apps", method = RequestMethod.POST)
public AppDTO createOrUpdate(@RequestBody AppDTO dto) {
if (!InputValidator.isValidClusterNamespace(dto.getAppId())) {
throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
}
App entity = BeanUtils.transfrom(App.class, dto);
App managedEntity = appService.findOne(entity.getAppId());
if (managedEntity != null) {
......
......@@ -13,7 +13,9 @@ import org.springframework.web.bind.annotation.RestController;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.service.ClusterService;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.core.dto.ClusterDTO;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.core.exception.NotFoundException;
@RestController
......@@ -24,6 +26,9 @@ public class ClusterController {
@RequestMapping(path = "/apps/{appId}/clusters", method = RequestMethod.POST)
public ClusterDTO createOrUpdate(@PathVariable("appId") String appId, @RequestBody ClusterDTO dto) {
if (!InputValidator.isValidClusterNamespace(dto.getName())) {
throw new BadRequestException(String.format("Cluster格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
}
Cluster entity = BeanUtils.transfrom(Cluster.class, dto);
Cluster managedEntity = clusterService.findOne(appId, entity.getName());
if (managedEntity != null) {
......
......@@ -13,7 +13,9 @@ import org.springframework.web.bind.annotation.RestController;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.service.NamespaceService;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.core.dto.NamespaceDTO;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.core.exception.NotFoundException;
@RestController
......@@ -25,6 +27,9 @@ public class NamespaceController {
@RequestMapping(path = "/apps/{appId}/clusters/{clusterName}/namespaces", method = RequestMethod.POST)
public NamespaceDTO createOrUpdate(@PathVariable("appId") String appId,
@PathVariable("clusterName") String clusterName, @RequestBody NamespaceDTO dto) {
if (!InputValidator.isValidClusterNamespace(dto.getNamespaceName())) {
throw new BadRequestException(String.format("Namespace格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
}
Namespace entity = BeanUtils.transfrom(Namespace.class, dto);
Namespace managedEntity = namespaceService.findOne(appId, clusterName, entity.getNamespaceName());
if (managedEntity != null) {
......
......@@ -44,7 +44,7 @@ public class AppNamespaceService {
@Transactional
public void createDefaultAppNamespace(String appId, String createBy) {
if (!isAppNamespaceNameUnique(appId, appId)) {
if (!isAppNamespaceNameUnique(appId, ConfigConsts.NAMESPACE_APPLICATION)) {
throw new ServiceException("appnamespace not unique");
}
AppNamespace appNs = new AppNamespace();
......@@ -64,6 +64,7 @@ public class AppNamespaceService {
if (!isAppNamespaceNameUnique(appNamespace.getAppId(), appNamespace.getName())) {
throw new ServiceException("appnamespace not unique");
}
appNamespace.setId(0);//protection
appNamespace.setDataChangeCreatedBy(createBy);
appNamespace.setDataChangeLastModifiedBy(createBy);
appNamespace = appNamespaceRepository.save(appNamespace);
......
......@@ -61,6 +61,7 @@ public class AppService {
if (!isAppIdUnique(entity.getAppId())) {
throw new ServiceException("appId not unique");
}
entity.setId(0);//protection
App app = appRepository.save(entity);
auditService.audit(App.class.getSimpleName(), app.getId(), Audit.OP.INSERT,
......
......@@ -53,6 +53,7 @@ public class ClusterService {
if (!isClusterNameUnique(entity.getAppId(), entity.getName())) {
throw new ServiceException("cluster not unique");
}
entity.setId(0);//protection
Cluster cluster = clusterRepository.save(entity);
auditService.audit(Cluster.class.getSimpleName(), cluster.getId(), Audit.OP.INSERT,
......
......@@ -16,6 +16,7 @@ public class CommitService {
public void save(Commit commit, String user){
commit.setId(0);//protection
commit.setDataChangeCreatedBy(user);
commit.setDataChangeCreatedTime(new Date());
commitRepository.save(commit);
......
......@@ -88,6 +88,7 @@ public class ItemService {
@Transactional
public Item save(Item entity) {
entity.setId(0);//protection
Item item = itemRepository.save(entity);
auditService.audit(Item.class.getSimpleName(), item.getId(), Audit.OP.INSERT,
......
......@@ -27,6 +27,7 @@ public class ItemSetService {
if (!CollectionUtils.isEmpty(changeSet.getCreateItems())) {
for (ItemDTO item : changeSet.getCreateItems()) {
Item entity = BeanUtils.transfrom(Item.class, item);
entity.setId(0);//protection
entity.setDataChangeCreatedBy(operator);
entity.setDataChangeLastModifiedBy(operator);
itemRepository.save(entity);
......
......@@ -68,6 +68,7 @@ public class NamespaceService {
if (!isNamespaceUnique(entity.getAppId(), entity.getClusterName(), entity.getNamespaceName())) {
throw new ServiceException("namespace not unique");
}
entity.setId(0);//protection
Namespace namespace = namespaceRepository.save(entity);
auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.INSERT,
......
package com.ctrip.framework.apollo.common.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class InputValidator {
public static final String INVALID_CLUSTER_NAMESPACE_MESSAGE = "只允许输入数字,字母和符号 - _ .";
public static final String CLUSTER_NAMESPACE_VALIDATOR = "[0-9a-zA-z_.-]+";
private static final Pattern CLUSTER_NAMESPACE_PATTERN =
Pattern.compile(CLUSTER_NAMESPACE_VALIDATOR);
public static boolean isValidClusterNamespace(String input) {
Matcher matcher = CLUSTER_NAMESPACE_PATTERN.matcher(input);
return matcher.matches();
}
}
package com.ctrip.framework.apollo.common;
import com.ctrip.framework.apollo.common.utils.InputValidatorTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
InputValidatorTest.class
})
public class AllTests {
}
package com.ctrip.framework.apollo.common.utils;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class InputValidatorTest {
@Test
public void testIsValidClusterNamespaceWithCorrectInput() throws Exception {
String someValidInput = "a1-b2_c3.d4";
assertTrue(InputValidator.isValidClusterNamespace(someValidInput));
}
@Test
public void testIsValidClusterNamespaceWithInCorrectInput() throws Exception {
String someInvalidInput = "中文123";
assertFalse(InputValidator.isValidClusterNamespace(someInvalidInput));
String anotherInvalidInput = "123@#{}";
assertFalse(InputValidator.isValidClusterNamespace(anotherInvalidInput));
}
}
......@@ -4,7 +4,9 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
import com.ctrip.framework.apollo.common.http.RichResponseEntity;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.portal.PortalSettings;
import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo;
import com.ctrip.framework.apollo.portal.listener.AppCreationEvent;
......@@ -70,6 +72,9 @@ public class AppController {
checkArgument(app.getName(), app.getAppId(), app.getOwnerEmail(), app.getOwnerName(),
app.getOrgId(), app.getOrgName());
if (!InputValidator.isValidClusterNamespace(app.getAppId())) {
throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
}
appService.enrichUserInfo(app);
App createdApp = appService.createOrUpdateAppInLocal(app);
......@@ -85,6 +90,9 @@ public class AppController {
checkArgument(app.getName(), app.getAppId(), app.getOwnerEmail(), app.getOwnerName(),
app.getOrgId(), app.getOrgName());
if (!InputValidator.isValidClusterNamespace(app.getAppId())) {
throw new BadRequestException(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE);
}
appService.createApp(Env.valueOf(env), app);
......
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.core.dto.NamespaceDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.exception.BadRequestException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.form.NamespaceCreationModel;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceVO;
import com.ctrip.framework.apollo.portal.listener.AppNamespaceCreationEvent;
import com.ctrip.framework.apollo.portal.service.AppService;
import com.ctrip.framework.apollo.portal.service.NamespaceService;
import org.slf4j.Logger;
......@@ -33,6 +37,9 @@ public class NamespaceController {
Logger logger = LoggerFactory.getLogger(NamespaceController.class);
@Autowired
private AppService appService;
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
......@@ -70,6 +77,13 @@ public class NamespaceController {
public void createAppNamespace(@PathVariable String appId, @RequestBody AppNamespace appNamespace) {
checkArgument(appNamespace.getAppId(), appNamespace.getName());
if (!InputValidator.isValidClusterNamespace(appNamespace.getName())) {
throw new BadRequestException(String.format("Namespace格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE));
}
//add app org id as prefix
App app = appService.load(appId);
appNamespace.setName(String.format("%s.%s", app.getOrgId(), appNamespace.getName()));
String operator = userInfoHolder.getUser().getUserId();
if (StringUtils.isEmpty(appNamespace.getDataChangeCreatedBy())) {
......
......@@ -34,7 +34,7 @@
<table class="project-info">
<tbody>
<tr>
<th>应用ID:</th>
<th>AppId:</th>
<td ng-bind="appBaseInfo.appId"></td>
</tr>
<tr>
......@@ -42,11 +42,15 @@
<td ng-bind="appBaseInfo.name"></td>
</tr>
<tr>
<th>Owner:</th>
<th>部门:</th>
<td ng-bind="appBaseInfo.orgInfo"></td>
</tr>
<tr>
<th>负责人:</th>
<td ng-bind="appBaseInfo.ownerName"></td>
</tr>
<tr>
<th>Owner Email:</th>
<th>负责人Email:</th>
<td ng-bind="appBaseInfo.ownerEmail"></td>
</tr>
<tr ng-show="missEnvs.length > 0">
......
......@@ -24,7 +24,8 @@
<div class="row">
<div class="col-md-6">新建Namespace</div>
<div class="col-md-6 text-right">
<button type="button" class="btn btn-success" ng-show="step == 2" ng-click="back()">返回</button>
<button type="button" class="btn btn-success" ng-show="step == 2" ng-click="back()">返回
</button>
</div>
</div>
......@@ -49,9 +50,14 @@
<div class="form-group" ng-show="type == 'create'">
<label class="col-sm-3 control-label"><font style="color: red">*</font>名称</label>
<div class="col-sm-4">
<input type="text" class="form-control" ng-model="appNamespace.name" ng-required="type == 'create'">
<div class="input-group">
<span class="input-group-addon" ng-bind="appBaseInfo.namespacePrefix"></span>
<input type="text" class="form-control" ng-model="appNamespace.name"
ng-required="type == 'create'">
</div>
</div>
<span ng-bind="concatNamespace()" style="line-height: 34px;"></span>
</div>
<div class="form-group" ng-show="type == 'create'">
<label class="col-sm-3 control-label">备注</label>
<div class="col-sm-7">
......@@ -61,7 +67,9 @@
<div class="form-group" ng-show="type == 'link'">
<label class="col-sm-3 control-label"><font style="color: red">*</font>namespace</label>
<div class="col-sm-4">
<select id="namespaces"><option></option></select>
<select id="namespaces">
<option></option>
</select>
</div>
</div>
......
......@@ -7,6 +7,7 @@ create_app_module.controller('CreateAppController', ['$scope', '$window', 'toast
var org = {};
org.id = item.orgId;
org.text = item.orgName + '(' + item.orgId + ')';
org.name = item.orgName;
organizations.push(org);
});
$('#organization').select2({
......@@ -27,7 +28,7 @@ create_app_module.controller('CreateAppController', ['$scope', '$window', 'toast
}
$scope.app.orgId = selectedOrg.id;
$scope.app.orgName = selectedOrg.text;
$scope.app.orgName = selectedOrg.name;
AppService.create($scope.app).then(function (result) {
toastr.success('添加成功!');
......
......@@ -25,12 +25,26 @@ namespace_module.controller("LinkNamespaceController",
toastr.error(AppUtil.errorMsg(result), "load public namespace error");
});
AppService.load($scope.appId).then(function (result) {
$scope.appBaseInfo = result;
$scope.appBaseInfo.namespacePrefix = result.orgId + '.';
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载App信息出错");
});
$scope.appNamespace = {
appId:$scope.appId,
name:'',
comment:''
};
$scope.concatNamespace = function() {
if (!$scope.appBaseInfo) {
return '';
}
return $scope.appBaseInfo.namespacePrefix + $scope.appNamespace.name;
};
var selectedClusters = [];
$scope.collectSelectedClusters = function (data) {
selectedClusters = data;
......
......@@ -95,6 +95,7 @@ application_module.controller("ConfigBaseInfoController",
AppService.load($rootScope.pageContext.appId).then(function (result) {
$scope.appBaseInfo = result;
$scope.appBaseInfo.orgInfo = result.orgName + '(' + result.orgId + ')';
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "加载App信息出错");
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment