Skip to content

Commit

Permalink
Merge pull request #461 from lepdou/namespace_delete
Browse files Browse the repository at this point in the history
 improve delete namespace
  • Loading branch information
nobodyiam authored Nov 28, 2016
2 parents 509ef4c + e533198 commit 0b6022c
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 36 deletions.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);

}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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);
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
</configuration>
Loading

0 comments on commit 0b6022c

Please sign in to comment.