Commit 7bdfe80e by 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,9 +64,10 @@ 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);
appNamespace = appNamespaceRepository.save(appNamespace);
auditService.audit(AppNamespace.class.getSimpleName(), appNamespace.getId(), Audit.OP.INSERT,
createBy);
......
......@@ -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;
......@@ -34,6 +38,9 @@ public class NamespaceController {
Logger logger = LoggerFactory.getLogger(NamespaceController.class);
@Autowired
private AppService appService;
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private UserInfoHolder userInfoHolder;
......@@ -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,14 +24,15 @@
<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>
</header>
<div class="panel-body">
<form class="form-horizontal" ng-show="step == 1" ng-submit="createNamespace()">
<form class="form-horizontal" ng-show="step == 1" ng-submit="createNamespace()">
<div class="form-group">
<label class="col-sm-3 control-label">应用ID</label>
<div class="col-sm-6" ng-bind="appId">
......@@ -49,8 +50,13 @@
<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>
......@@ -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