Commit e533198e by lepdou

improve delete namespace

parent 08048b5a
......@@ -4,6 +4,7 @@ import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
......@@ -26,6 +27,10 @@ public interface InstanceConfigRepository extends PagingAndSortingRepository<Ins
List<InstanceConfig> findByConfigAppIdAndConfigClusterNameAndConfigNamespaceNameAndDataChangeLastModifiedTimeAfterAndReleaseKeyNotIn(
String appId, String clusterName, String namespaceName, Date validDate, Set<String> releaseKey);
@Modifying
@Query("delete from InstanceConfig where ConfigAppId=?1 and ConfigClusterName=?2 and ConfigNamespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName);
@Query(
value = "select b.Id from `InstanceConfig` a inner join `Instance` b on b.Id =" +
" a.`InstanceId` where a.`ConfigAppId` = :configAppId and a.`ConfigClusterName` = " +
......
......@@ -4,6 +4,8 @@ import com.ctrip.framework.apollo.biz.entity.ReleaseHistory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
......@@ -16,4 +18,9 @@ public interface ReleaseHistoryRepository extends PagingAndSortingRepository<Rel
clusterName, String namespaceName, Pageable pageable);
List<ReleaseHistory> findByReleaseId(long releaseId);
@Modifying
@Query("update ReleaseHistory set isdeleted=1,DataChange_LastModifiedBy = ?4 where appId=?1 and clusterName=?2 and namespaceName = ?3")
int batchDelete(String appId, String clusterName, String namespaceName, String operator);
}
......@@ -34,9 +34,7 @@ public class AppNamespaceService {
private ClusterService clusterService;
@Autowired
private AuditService auditService;
@Autowired
private ServerConfigService serverConfigService;
public boolean isAppNamespaceNameUnique(String appId, String namespaceName) {
Objects.requireNonNull(appId, "AppId must not be null");
Objects.requireNonNull(namespaceName, "Namespace must not be null");
......
......@@ -172,4 +172,9 @@ public class InstanceService {
return instanceConfigRepository.save(existedInstanceConfig);
}
@Transactional
public int batchDeleteInstanceConfig(String configAppId, String configClusterName, String configNamespaceName){
return instanceConfigRepository.batchDelete(configAppId, configClusterName, configNamespaceName);
}
}
package com.ctrip.framework.apollo.biz.service;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
......@@ -17,6 +15,7 @@ import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.repository.NamespaceRepository;
import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.exception.ServiceException;
......@@ -38,6 +37,15 @@ public class NamespaceService {
private ReleaseService releaseService;
@Autowired
private ClusterService clusterService;
@Autowired
private NamespaceBranchService namespaceBranchService;
@Autowired
private ReleaseHistoryService releaseHistoryService;
@Autowired
private NamespaceLockService namespaceLockService;
@Autowired
private InstanceService instanceService;
public Namespace findOne(Long namespaceId) {
......@@ -57,25 +65,25 @@ public class NamespaceService {
return namespaces;
}
public List<Namespace> findByAppIdAndNamespaceName(String appId, String namespaceName){
public List<Namespace> findByAppIdAndNamespaceName(String appId, String namespaceName) {
return namespaceRepository.findByAppIdAndNamespaceName(appId, namespaceName);
}
public Namespace findChildNamespace(String appId, String parentClusterName, String namespaceName){
public Namespace findChildNamespace(String appId, String parentClusterName, String namespaceName) {
List<Namespace> namespaces = findByAppIdAndNamespaceName(appId, namespaceName);
if (CollectionUtils.isEmpty(namespaces) || namespaces.size() == 1){
if (CollectionUtils.isEmpty(namespaces) || namespaces.size() == 1) {
return null;
}
List<Cluster> childClusters = clusterService.findChildClusters(appId, parentClusterName);
if (CollectionUtils.isEmpty(childClusters)){
if (CollectionUtils.isEmpty(childClusters)) {
return null;
}
Set<String> childClusterNames = childClusters.stream().map(Cluster::getName).collect(Collectors.toSet());
//the child namespace is the intersection of the child clusters and child namespaces
for (Namespace namespace: namespaces){
if (childClusterNames.contains(namespace.getClusterName())){
for (Namespace namespace : namespaces) {
if (childClusterNames.contains(namespace.getClusterName())) {
return namespace;
}
}
......@@ -83,7 +91,7 @@ public class NamespaceService {
return null;
}
public Namespace findChildNamespace(Namespace parentNamespace){
public Namespace findChildNamespace(Namespace parentNamespace) {
String appId = parentNamespace.getAppId();
String parentClusterName = parentNamespace.getClusterName();
String namespaceName = parentNamespace.getNamespaceName();
......@@ -92,12 +100,12 @@ public class NamespaceService {
}
public Namespace findParentNamespace(Namespace namespace){
public Namespace findParentNamespace(Namespace namespace) {
String appId = namespace.getAppId();
String namespaceName = namespace.getNamespaceName();
Cluster cluster = clusterService.findOne(appId, namespace.getClusterName());
if (cluster != null && cluster.getParentClusterId() > 0){
if (cluster != null && cluster.getParentClusterId() > 0) {
Cluster parentCluster = clusterService.findOne(cluster.getParentClusterId());
return findOne(appId, parentCluster.getName(), namespaceName);
}
......@@ -105,7 +113,7 @@ public class NamespaceService {
return null;
}
public boolean isChildNamespace(Namespace namespace){
public boolean isChildNamespace(Namespace namespace) {
return findParentNamespace(namespace) != null;
}
......@@ -118,11 +126,11 @@ public class NamespaceService {
}
@Transactional
public void deleteByAppIdAndClusterName(String appId, String clusterName, String operator){
public void deleteByAppIdAndClusterName(String appId, String clusterName, String operator) {
List<Namespace> toDeleteNamespaces = findNamespaces(appId, clusterName);
for (Namespace namespace: toDeleteNamespaces){
for (Namespace namespace : toDeleteNamespaces) {
deleteNamespace(namespace, operator);
......@@ -130,17 +138,33 @@ public class NamespaceService {
}
@Transactional
public Namespace deleteNamespace(Namespace namespace, String operator){
public Namespace deleteNamespace(Namespace namespace, String operator) {
String appId = namespace.getAppId();
String clusterName = namespace.getClusterName();
String namespaceName = namespace.getNamespaceName();
itemService.batchDelete(namespace.getId(), operator);
commitService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
if (!isChildNamespace(namespace)){
if (!isChildNamespace(namespace)) {
releaseService.batchDelete(appId, clusterName, namespace.getNamespaceName(), operator);
}
//delete child namespace
Namespace childNamespace = findChildNamespace(namespace);
if (childNamespace != null) {
namespaceBranchService.deleteBranch(appId, clusterName, namespaceName,
childNamespace.getClusterName(), NamespaceBranchStatus.DELETED, operator);
//delete child namespace's releases. Notice: delete child namespace will not delete child namespace's releases
releaseService.batchDelete(appId, childNamespace.getClusterName(), namespaceName, operator);
}
releaseHistoryService.batchDelete(appId, clusterName, namespaceName, operator);
instanceService.batchDeleteInstanceConfig(appId, clusterName, namespaceName);
namespaceLockService.unlock(namespace.getId());
namespace.setDeleted(true);
namespace.setDataChangeLastModifiedBy(operator);
......@@ -158,7 +182,7 @@ public class NamespaceService {
Namespace namespace = namespaceRepository.save(entity);
auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.INSERT,
namespace.getDataChangeCreatedBy());
namespace.getDataChangeCreatedBy());
return namespace;
}
......@@ -171,7 +195,7 @@ public class NamespaceService {
managedNamespace = namespaceRepository.save(managedNamespace);
auditService.audit(Namespace.class.getSimpleName(), managedNamespace.getId(), Audit.OP.UPDATE,
managedNamespace.getDataChangeLastModifiedBy());
managedNamespace.getDataChangeLastModifiedBy());
return managedNamespace;
}
......@@ -182,7 +206,7 @@ public class NamespaceService {
//load all private app namespace
List<AppNamespace> privateAppNamespaces = appNamespaceService.findPrivateAppNamespace(appId);
//create all private namespace
for (AppNamespace appNamespace: privateAppNamespaces){
for (AppNamespace appNamespace : privateAppNamespaces) {
Namespace ns = new Namespace();
ns.setAppId(appId);
ns.setClusterName(clusterName);
......
......@@ -25,9 +25,6 @@ public class ReleaseHistoryService {
private ReleaseHistoryRepository releaseHistoryRepository;
@Autowired
private ReleaseService releaseService;
@Autowired
private AuditService auditService;
private Gson gson = new Gson();
......@@ -72,4 +69,8 @@ public class ReleaseHistoryService {
return releaseHistory;
}
@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return releaseHistoryRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
}
package com.ctrip.framework.apollo.biz.service;
import com.ctrip.framework.apollo.biz.AbstractIntegrationTest;
import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.biz.entity.Commit;
import com.ctrip.framework.apollo.biz.entity.InstanceConfig;
import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.Release;
import com.ctrip.framework.apollo.biz.entity.ReleaseHistory;
import com.ctrip.framework.apollo.biz.repository.InstanceConfigRepository;
import com.ctrip.framework.apollo.common.entity.AppNamespace;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author lepdou 2016-11-28
*/
public class NamespaceServiceTest extends AbstractIntegrationTest {
@Autowired
private NamespaceService namespaceService;
@Autowired
private ItemService itemService;
@Autowired
private CommitService commitService;
@Autowired
private AppNamespaceService appNamespaceService;
@Autowired
private ClusterService clusterService;
@Autowired
private ReleaseService releaseService;
@Autowired
private ReleaseHistoryService releaseHistoryService;
@Autowired
private InstanceConfigRepository instanceConfigRepository;
private String testApp = "testApp";
private String testCluster = "default";
private String testChildCluster = "child-cluster";
private String testPrivateNamespace = "application";
private String testUser = "apollo";
@Test
@Sql(scripts = "/sql/namespace-test.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testDeleteNamespace() {
Namespace namespace = new Namespace();
namespace.setAppId(testApp);
namespace.setClusterName(testCluster);
namespace.setNamespaceName(testPrivateNamespace);
namespace.setId(1);
namespaceService.deleteNamespace(namespace, testUser);
List<Item> items = itemService.findItems(testApp, testCluster, testPrivateNamespace);
List<Commit> commits = commitService.find(testApp, testCluster, testPrivateNamespace, new PageRequest(0, 10));
AppNamespace appNamespace = appNamespaceService.findOne(testApp, testPrivateNamespace);
List<Cluster> childClusters = clusterService.findChildClusters(testApp, testCluster);
InstanceConfig instanceConfig = instanceConfigRepository.findOne(1L);
List<Release> parentNamespaceReleases = releaseService.findActiveReleases(testApp, testCluster,
testPrivateNamespace,
new PageRequest(0, 10));
List<Release> childNamespaceReleases = releaseService.findActiveReleases(testApp, testChildCluster,
testPrivateNamespace,
new PageRequest(0, 10));
Page<ReleaseHistory> releaseHistories =
releaseHistoryService
.findReleaseHistoriesByNamespace(testApp, testCluster, testPrivateNamespace, new PageRequest(0, 10));
assertEquals(0, items.size());
assertEquals(0, commits.size());
assertNotNull(appNamespace);
assertEquals(0, childClusters.size());
assertEquals(0, parentNamespaceReleases.size());
assertEquals(0, childNamespaceReleases.size());
assertTrue(!releaseHistories.hasContent());
assertNull(instanceConfig);
}
}
DELETE FROM App;
DELETE FROM AppNamespace;
DELETE FROM Cluster;
DELETE FROM namespace;
DELETE FROM grayreleaserule;
......@@ -6,3 +7,5 @@ DELETE FROM release;
DELETE FROM item;
DELETE FROM releasemessage;
DELETE FROM releasehistory;
DELETE FROM namespacelock;
DELETE FROM `commit`;
INSERT INTO `app` ( `AppId`, `Name`, `OrgId`, `OrgName`, `OwnerName`, `OwnerEmail`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)VALUES('testApp', 'test', 'default', 'default', 'default', 'default', 0, 'default', 'default');
INSERT INTO `cluster` (`ID`, `Name`, `AppId`, `ParentClusterId`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`) VALUES (1, 'default', 'testApp', 0, 0, 'default', 'default');
INSERT INTO `cluster` (`Name`, `AppId`, `ParentClusterId`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)VALUES('child-cluster', 'testApp', 1, 0, 'default', 'default');
INSERT INTO `appnamespace` (`Name`, `AppId`, `Format`, `IsPublic`) VALUES ( 'application', 'testApp', 'properties', 0);
INSERT INTO `namespace` (`ID`, `AppId`, `ClusterName`, `NamespaceName`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)VALUES(1,'testApp', 'default', 'application', 0, 'apollo', 'apollo');
INSERT INTO `namespace` (`AppId`, `ClusterName`, `NamespaceName`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`)VALUES('testApp', 'child-cluster', 'application', 0, 'apollo', 'apollo');
INSERT INTO `commit` (`ChangeSets`, `AppId`, `ClusterName`, `NamespaceName`)VALUES('{}', 'testApp', 'default', 'application');
INSERT INTO `item` (`NamespaceId`, `Key`, `Value`, `Comment`, `LineNum`)VALUES(1, 'k1', 'v1', '', 1);
INSERT INTO `namespacelock` (`NamespaceId`)VALUES(1);
INSERT INTO `release` (`AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES('branch-test', 'default', 'application', '{}', 0);
INSERT INTO `release` (`AppId`, `ClusterName`, `NamespaceName`, `Configurations`, `IsAbandoned`)VALUES('branch-test', 'child-cluster', 'application', '{}', 0);
INSERT INTO `releasehistory` (`AppId`, `ClusterName`, `NamespaceName`, `BranchName`, `ReleaseId`, `PreviousReleaseId`, `Operation`, `OperationContext`)VALUES('branch-test', 'default', 'application', 'default', 0, 0, 7, '{}');
INSERT INTO `instanceconfig` (`ID`, `InstanceId`, `ConfigAppId`, `ConfigClusterName`, `ConfigNamespaceName`, `ReleaseKey`, `ReleaseDeliveryTime`, `DataChange_CreatedTime`, `DataChange_LastTime`)
VALUES
(1, 90, 'testApp', 'default', 'application', '20160829134524-dee271ddf9fced58', '2016-08-29 13:45:24', '2016-08-30 17:03:32', '2016-10-19 11:13:47');
......@@ -7,4 +7,4 @@
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
\ No newline at end of file
</configuration>
......@@ -16,4 +16,5 @@ public interface RolePermissionRepository extends PagingAndSortingRepository<Rol
* find role permissions by role ids
*/
List<RolePermission> findByRoleIdIn(Collection<Long> roleId);
}
......@@ -25,4 +25,5 @@ public interface UserRoleRepository extends PagingAndSortingRepository<UserRole,
* find user roles by userIds and roleId
*/
List<UserRole> findByUserIdInAndRoleId(Collection<String> userId, long roleId);
}
......@@ -22,6 +22,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Type;
import java.util.HashMap;
......@@ -57,15 +58,26 @@ public class NamespaceService {
NamespaceDTO createdNamespace = namespaceAPI.createNamespace(env, namespace);
Cat.logEvent(CatEventType.CREATE_NAMESPACE,
String.format("%s+%s+%s+%s", namespace.getAppId(), env, namespace.getClusterName(),
namespace.getNamespaceName()));
String.format("%s+%s+%s+%s", namespace.getAppId(), env, namespace.getClusterName(),
namespace.getNamespaceName()));
return createdNamespace;
}
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName){
namespaceAPI.deleteNamespace(env, appId, clusterName, namespaceName, userInfoHolder.getUser().getUserId());
@Transactional
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName) {
AppNamespace appNamespace = appNamespaceService.findByAppIdAndName(appId, namespaceName);
if (appNamespace != null && !appNamespace.isPublic()){
throw new BadRequestException("private namespace can not be deleted");
}
String operator = userInfoHolder.getUser().getUserId();
namespaceAPI.deleteNamespace(env, appId, clusterName, namespaceName, operator);
}
public NamespaceDTO loadNamespaceBaseInfo(String appId, Env env, String clusterName, String namespaceName) {
NamespaceDTO namespace = namespaceAPI.loadNamespace(appId, env, clusterName, namespaceName);
if (namespace == null) {
......@@ -93,7 +105,7 @@ public class NamespaceService {
namespaceVOs.add(namespaceVO);
} catch (Exception e) {
logger.error("parse namespace error. app id:{}, env:{}, clusterName:{}, namespace:{}",
appId, env, clusterName, namespace.getNamespaceName(), e);
appId, env, clusterName, namespace.getNamespaceName(), e);
throw e;
}
}
......
......@@ -36,21 +36,19 @@ import java.util.Set;
*/
@Service
public class RolePermissionService implements InitializingBean {
@Autowired
private RoleRepository roleRepository;
@Autowired
private RolePermissionRepository rolePermissionRepository;
@Autowired
private UserRoleRepository userRoleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Autowired
private ServerConfigService serverConfigService;
private List<String> superAdminUsers;
private Splitter configSplitter;
......
......@@ -41,6 +41,7 @@ public class NamespaceServiceTest {
@InjectMocks
private NamespaceService namespaceService;
@Before
public void setup() {
}
......@@ -98,5 +99,4 @@ public class NamespaceServiceTest {
}
}
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