Don't remove the domain when it has accounts that are removed, but require cleanup

This commit is contained in:
alena 2011-08-30 13:34:06 -07:00
parent 155a6b7aaf
commit 4dd4b41344
6 changed files with 89 additions and 35 deletions

View File

@ -29,5 +29,6 @@ public interface DomainDao extends GenericDao<DomainVO, Long> {
public boolean isChildDomain(Long parentId, Long childId);
DomainVO findImmediateChildForParent(Long parentId);
List<DomainVO> findImmediateChildrenForParent(Long parentId);
List<DomainVO> findAllChildren(String path, Long parentId);
List<DomainVO> findAllChildren(String path, Long parentId);
List<DomainVO> findInactiveDomains();
}

View File

@ -27,6 +27,7 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
@ -44,6 +45,7 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
protected SearchBuilder<DomainVO> DomainPairSearch;
protected SearchBuilder<DomainVO> ImmediateChildDomainSearch;
protected SearchBuilder<DomainVO> FindAllChildrenSearch;
protected SearchBuilder<DomainVO> AllFieldsSearch;
public DomainDaoImpl () {
DomainNameLikeSearch = createSearchBuilder();
@ -67,6 +69,14 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
FindAllChildrenSearch.and("path", FindAllChildrenSearch.entity().getPath(), SearchCriteria.Op.LIKE);
FindAllChildrenSearch.and("id", FindAllChildrenSearch.entity().getId(), SearchCriteria.Op.NEQ);
FindAllChildrenSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("owner", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("path", AllFieldsSearch.entity().getPath(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("parent", AllFieldsSearch.entity().getParent(), SearchCriteria.Op.EQ);
AllFieldsSearch.done();
}
@ -238,5 +248,12 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
}
}
return result;
}
@Override
public List<DomainVO> findInactiveDomains() {
SearchCriteria<DomainVO> sc = AllFieldsSearch.create();
sc.setParameters("state", Domain.State.Inactive);
return listBy(sc);
}
}

View File

@ -2945,7 +2945,7 @@ public class ManagementServerImpl implements ManagementServer {
String name = cmd.getDomainName();
Long parentId = cmd.getParentDomainId();
Long ownerId = UserContext.current().getCaller().getId();
Account account = UserContext.current().getCaller();
Account caller = UserContext.current().getCaller();
String networkDomain = cmd.getNetworkDomain();
if (ownerId == null) {
@ -2960,11 +2960,13 @@ public class ManagementServerImpl implements ManagementServer {
if (parentDomain == null) {
throw new InvalidParameterValueException("Unable to create domain " + name + ", parent domain " + parentId + " not found.");
}
if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), parentId)) {
throw new PermissionDeniedException("Unable to create domain " + name + ", permission denied.");
if (parentDomain.getState().equals(Domain.State.Inactive)) {
throw new CloudRuntimeException("The domain cannot be created as the parent domain " + parentDomain.getName() + " is being deleted");
}
_accountMgr.checkAccess(caller, parentDomain);
if (networkDomain != null) {
if (!NetUtils.verifyDomainName(networkDomain)) {
throw new InvalidParameterValueException(
@ -2993,41 +2995,48 @@ public class ManagementServerImpl implements ManagementServer {
@Override
@ActionEvent(eventType = EventTypes.EVENT_DOMAIN_DELETE, eventDescription = "deleting Domain", async = true)
public boolean deleteDomain(DeleteDomainCmd cmd) {
Account account = UserContext.current().getCaller();
Account caller = UserContext.current().getCaller();
Long domainId = cmd.getId();
Boolean cleanup = cmd.getCleanup();
if ((domainId == DomainVO.ROOT_DOMAIN) || ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId))) {
throw new PermissionDeniedException("Unable to delete domain " + domainId + ", permission denied.");
DomainVO domain = _domainDao.findById(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Failed to delete domain " + domainId + ", domain not found");
} else if (domainId == DomainVO.ROOT_DOMAIN) {
throw new PermissionDeniedException("Can't delete ROOT domain");
}
_accountMgr.checkAccess(caller, domain);
//mark domain as inactive
s_logger.debug("Marking domain id=" + domainId + " as " + Domain.State.Inactive + " before actually deleting it");
domain.setState(Domain.State.Inactive);
_domainDao.update(domainId, domain);
try {
DomainVO domain = _domainDao.findById(domainId);
if (domain != null) {
long ownerId = domain.getAccountId();
if ((cleanup != null) && cleanup.booleanValue()) {
boolean success = cleanupDomain(domainId, ownerId);
if (!success) {
s_logger.error("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domainId + ").");
return false;
}
} else {
long ownerId = domain.getAccountId();
if ((cleanup != null) && cleanup.booleanValue()) {
if (!cleanupDomain(domainId, ownerId)) {
s_logger.error("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domainId + ").");
return false;
}
} else {
List<AccountVO> accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId);
if (accountsForCleanup.isEmpty()) {
if (!_domainDao.remove(domainId)) {
s_logger.error("Delete failed on domain " + domain.getName() + " (id: " + domainId
+ "); please make sure all users and sub domains have been removed from the domain before deleting");
return false;
} else {
domain.setState(Domain.State.Inactive);
_domainDao.update(domainId, domain);
}
}
} else {
s_logger.warn("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup");
return false;
}
} else {
throw new InvalidParameterValueException("Failed to delete domain " + domainId + ", domain not found");
}
cleanupDomainOfferings(domainId);
return true;
} catch (InvalidParameterValueException ex) {
throw ex;
} catch (Exception ex) {
s_logger.error("Exception deleting domain with id " + domainId, ex);
return false;
@ -3087,9 +3096,15 @@ public class ManagementServerImpl implements ManagementServer {
s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup");
}
}
// delete the domain itself
boolean deleteDomainSuccess = _domainDao.remove(domainId);
//don't remove the domain if there are accounts required cleanup
boolean deleteDomainSuccess = true;
List<AccountVO> accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domainId);
if (accountsForCleanup.isEmpty()) {
deleteDomainSuccess = _domainDao.remove(domainId);
} else {
s_logger.debug("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup");
}
return success && deleteDomainSuccess;
}

View File

@ -1860,7 +1860,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
txn = Transaction.open(Transaction.CLOUD_DB);
//Cleanup removed accounts
List<AccountVO> removedAccounts = _accountDao.findCleanupsForRemovedAccounts();
List<AccountVO> removedAccounts = _accountDao.findCleanupsForRemovedAccounts(null);
s_logger.info("Found " + removedAccounts.size() + " removed accounts to cleanup");
for (AccountVO account : removedAccounts) {
s_logger.debug("Cleaning up " + account.getId());
@ -1886,6 +1886,22 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
}
}
//cleanup inactive domains
List<DomainVO> inactiveDomains = _domainDao.findInactiveDomains();
for (DomainVO inactiveDomain : inactiveDomains) {
long domainId = inactiveDomain.getId();
try {
List<AccountVO> accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId);
if (accountsForCleanupInDomain.isEmpty()) {
s_logger.debug("Removing inactive domain id=" + domainId);
_domainDao.remove(domainId);
} else {
s_logger.debug("Can't remove inactive domain id=" + domainId + " as it has accounts that need clenaup");
}
} catch (Exception e) {
s_logger.error("Skipping due to error on domain " + domainId, e);
}
}
} catch (Exception e) {
s_logger.error("Exception ", e);

View File

@ -37,7 +37,7 @@ public interface AccountDao extends GenericDao<AccountVO, Long> {
List<AccountVO> findActiveAccounts(Long maxAccountId, Filter filter);
List<AccountVO> findRecentlyDeletedAccounts(Long maxAccountId, Date earliestRemovedDate, Filter filter);
List<AccountVO> findNewAccounts(Long minAccountId, Filter filter);
List<AccountVO> findCleanupsForRemovedAccounts();
List<AccountVO> findCleanupsForRemovedAccounts(Long domainId);
List<AccountVO> findAdminAccountsForDomain(Long domainId);
List<AccountVO> findActiveAccountsForDomain(Long domain);
void markForCleanup(long accountId);

View File

@ -71,7 +71,8 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
CleanupForRemovedAccountsSearch = createSearchBuilder();
CleanupForRemovedAccountsSearch.and("cleanup", CleanupForRemovedAccountsSearch.entity().getNeedsCleanup(), SearchCriteria.Op.EQ);
CleanupForRemovedAccountsSearch.and("removed", CleanupForRemovedAccountsSearch.entity().getRemoved(), SearchCriteria.Op.NNULL);
CleanupForRemovedAccountsSearch.and("removed", CleanupForRemovedAccountsSearch.entity().getRemoved(), SearchCriteria.Op.NNULL);
CleanupForRemovedAccountsSearch.and("domainid", CleanupForRemovedAccountsSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
CleanupForRemovedAccountsSearch.done();
CleanupForDisabledAccountsSearch = createSearchBuilder();
@ -82,9 +83,13 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
}
@Override
public List<AccountVO> findCleanupsForRemovedAccounts() {
public List<AccountVO> findCleanupsForRemovedAccounts(Long domainId) {
SearchCriteria<AccountVO> sc = CleanupForRemovedAccountsSearch.create();
sc.setParameters("cleanup", true);
sc.setParameters("cleanup", true);
if (domainId != null) {
sc.setParameters("domainid", domainId);
}
return searchIncludingRemoved(sc, null, null, false);
}