From 4dd4b413449bdca9dca23adc12483cc5c9e20207 Mon Sep 17 00:00:00 2001 From: alena Date: Tue, 30 Aug 2011 13:34:06 -0700 Subject: [PATCH] Don't remove the domain when it has accounts that are removed, but require cleanup --- .../src/com/cloud/domain/dao/DomainDao.java | 3 +- .../com/cloud/domain/dao/DomainDaoImpl.java | 17 +++++ .../cloud/server/ManagementServerImpl.java | 73 +++++++++++-------- .../com/cloud/user/AccountManagerImpl.java | 18 ++++- server/src/com/cloud/user/dao/AccountDao.java | 2 +- .../com/cloud/user/dao/AccountDaoImpl.java | 11 ++- 6 files changed, 89 insertions(+), 35 deletions(-) diff --git a/server/src/com/cloud/domain/dao/DomainDao.java b/server/src/com/cloud/domain/dao/DomainDao.java index 6daa75a0133..5ccd860d512 100644 --- a/server/src/com/cloud/domain/dao/DomainDao.java +++ b/server/src/com/cloud/domain/dao/DomainDao.java @@ -29,5 +29,6 @@ public interface DomainDao extends GenericDao { public boolean isChildDomain(Long parentId, Long childId); DomainVO findImmediateChildForParent(Long parentId); List findImmediateChildrenForParent(Long parentId); - List findAllChildren(String path, Long parentId); + List findAllChildren(String path, Long parentId); + List findInactiveDomains(); } diff --git a/server/src/com/cloud/domain/dao/DomainDaoImpl.java b/server/src/com/cloud/domain/dao/DomainDaoImpl.java index 69cc7b56634..51ef94de4e9 100644 --- a/server/src/com/cloud/domain/dao/DomainDaoImpl.java +++ b/server/src/com/cloud/domain/dao/DomainDaoImpl.java @@ -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 implements Dom protected SearchBuilder DomainPairSearch; protected SearchBuilder ImmediateChildDomainSearch; protected SearchBuilder FindAllChildrenSearch; + protected SearchBuilder AllFieldsSearch; public DomainDaoImpl () { DomainNameLikeSearch = createSearchBuilder(); @@ -67,6 +69,14 @@ public class DomainDaoImpl extends GenericDaoBase 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 implements Dom } } return result; + } + + @Override + public List findInactiveDomains() { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("state", Domain.State.Inactive); + return listBy(sc); } } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 19b2e0f1f5d..ce7dff8b8cd 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -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 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 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; } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 4a79f56bde7..4b850e3cac7 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -1860,7 +1860,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag txn = Transaction.open(Transaction.CLOUD_DB); //Cleanup removed accounts - List removedAccounts = _accountDao.findCleanupsForRemovedAccounts(); + List 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 inactiveDomains = _domainDao.findInactiveDomains(); + for (DomainVO inactiveDomain : inactiveDomains) { + long domainId = inactiveDomain.getId(); + try { + List 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); diff --git a/server/src/com/cloud/user/dao/AccountDao.java b/server/src/com/cloud/user/dao/AccountDao.java index 2ff13f983ff..12465b27257 100644 --- a/server/src/com/cloud/user/dao/AccountDao.java +++ b/server/src/com/cloud/user/dao/AccountDao.java @@ -37,7 +37,7 @@ public interface AccountDao extends GenericDao { List findActiveAccounts(Long maxAccountId, Filter filter); List findRecentlyDeletedAccounts(Long maxAccountId, Date earliestRemovedDate, Filter filter); List findNewAccounts(Long minAccountId, Filter filter); - List findCleanupsForRemovedAccounts(); + List findCleanupsForRemovedAccounts(Long domainId); List findAdminAccountsForDomain(Long domainId); List findActiveAccountsForDomain(Long domain); void markForCleanup(long accountId); diff --git a/server/src/com/cloud/user/dao/AccountDaoImpl.java b/server/src/com/cloud/user/dao/AccountDaoImpl.java index 1d000b9b92a..57ad47018ce 100755 --- a/server/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/server/src/com/cloud/user/dao/AccountDaoImpl.java @@ -71,7 +71,8 @@ public class AccountDaoImpl extends GenericDaoBase 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 implements A } @Override - public List findCleanupsForRemovedAccounts() { + public List findCleanupsForRemovedAccounts(Long domainId) { SearchCriteria sc = CleanupForRemovedAccountsSearch.create(); - sc.setParameters("cleanup", true); + sc.setParameters("cleanup", true); + + if (domainId != null) { + sc.setParameters("domainid", domainId); + } return searchIncludingRemoved(sc, null, null, false); }