Skip to content

Commit

Permalink
improve delete namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
lepdou committed Nov 28, 2016
1 parent 08048b5 commit e533198
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 36 deletions.
Expand Up @@ -4,6 +4,7 @@

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;
Expand All @@ -26,6 +27,10 @@ Page<InstanceConfig> findByConfigAppIdAndConfigClusterNameAndConfigNamespaceName
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` = " +
Expand Down
Expand Up @@ -4,6 +4,8 @@

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;
Expand All @@ -16,4 +18,9 @@ Page<ReleaseHistory> findByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc(Stri
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);

}
Expand Up @@ -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");
Expand Down
Expand Up @@ -172,4 +172,9 @@ public InstanceConfig updateInstanceConfig(InstanceConfig instanceConfig) {

return instanceConfigRepository.save(existedInstanceConfig);
}

@Transactional
public int batchDeleteInstanceConfig(String configAppId, String configClusterName, String configNamespaceName){
return instanceConfigRepository.batchDelete(configAppId, configClusterName, configNamespaceName);
}
}
@@ -1,8 +1,6 @@
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;
Expand All @@ -17,6 +15,7 @@
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;
Expand All @@ -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) {
Expand All @@ -57,33 +65,33 @@ public List<Namespace> findNamespaces(String appId, String clusterName) {
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;
}
}

return null;
}

public Namespace findChildNamespace(Namespace parentNamespace){
public Namespace findChildNamespace(Namespace parentNamespace) {
String appId = parentNamespace.getAppId();
String parentClusterName = parentNamespace.getClusterName();
String namespaceName = parentNamespace.getNamespaceName();
Expand All @@ -92,20 +100,20 @@ public Namespace findChildNamespace(Namespace parentNamespace){

}

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);
}

return null;
}

public boolean isChildNamespace(Namespace namespace){
public boolean isChildNamespace(Namespace namespace) {
return findParentNamespace(namespace) != null;
}

Expand All @@ -118,29 +126,45 @@ public boolean isNamespaceUnique(String appId, String cluster, String namespace)
}

@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);

}
}

@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);

Expand All @@ -158,7 +182,7 @@ public Namespace save(Namespace entity) {
Namespace namespace = namespaceRepository.save(entity);

auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.INSERT,
namespace.getDataChangeCreatedBy());
namespace.getDataChangeCreatedBy());

return namespace;
}
Expand All @@ -171,7 +195,7 @@ public Namespace update(Namespace namespace) {
managedNamespace = namespaceRepository.save(managedNamespace);

auditService.audit(Namespace.class.getSimpleName(), managedNamespace.getId(), Audit.OP.UPDATE,
managedNamespace.getDataChangeLastModifiedBy());
managedNamespace.getDataChangeLastModifiedBy());

return managedNamespace;
}
Expand All @@ -182,7 +206,7 @@ public void createPrivateNamespace(String appId, String clusterName, String crea
//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);
Expand Down
Expand Up @@ -24,9 +24,6 @@ public class ReleaseHistoryService {
@Autowired
private ReleaseHistoryRepository releaseHistoryRepository;

@Autowired
private ReleaseService releaseService;

@Autowired
private AuditService auditService;

Expand Down Expand Up @@ -72,4 +69,8 @@ public ReleaseHistory createReleaseHistory(String appId, String clusterName, Str
return releaseHistory;
}

@Transactional
public int batchDelete(String appId, String clusterName, String namespaceName, String operator){
return releaseHistoryRepository.batchDelete(appId, clusterName, namespaceName, operator);
}
}
@@ -0,0 +1,94 @@
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);
}

}
3 changes: 3 additions & 0 deletions apollo-biz/src/test/resources/sql/clean.sql
@@ -1,8 +1,11 @@
DELETE FROM App;
DELETE FROM AppNamespace;
DELETE FROM Cluster;
DELETE FROM namespace;
DELETE FROM grayreleaserule;
DELETE FROM release;
DELETE FROM item;
DELETE FROM releasemessage;
DELETE FROM releasehistory;
DELETE FROM namespacelock;
DELETE FROM `commit`;
32 changes: 32 additions & 0 deletions apollo-biz/src/test/resources/sql/namespace-test.sql
@@ -0,0 +1,32 @@
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');








2 changes: 1 addition & 1 deletion apollo-configservice/src/main/resources/logback.xml
Expand Up @@ -7,4 +7,4 @@
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
</configuration>

0 comments on commit e533198

Please sign in to comment.