bug 13700: delete projects as a part of domain cleanup

status 13700: resolved fixed
Reviewed-by: Frank
This commit is contained in:
Alena Prokharchyk 2012-02-15 16:32:27 -08:00
parent e34cd2ca4e
commit 5aaf15f0a7
5 changed files with 63 additions and 30 deletions

View File

@ -32,6 +32,7 @@ import com.cloud.utils.db.GenericDao;
@Entity
@Table(name="project_account")
@SuppressWarnings("unused")
public class ProjectAccountVO implements ProjectAccount{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)

View File

@ -17,4 +17,6 @@ public interface ProjectManager extends ProjectService {
boolean allowUserToCreateProject();
boolean deleteProject(Account caller, long callerUserId, ProjectVO project);
}

View File

@ -246,11 +246,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
@DB
public boolean deleteProject (long projectId) {
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
public boolean deleteProject(long projectId) {
UserContext ctx = UserContext.current();
Account caller = ctx.getCaller();
ProjectVO project= getProject(projectId);
//verify input parameters
@ -258,28 +256,39 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
}
_accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
_accountMgr.checkAccess(ctx.getCaller(),AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
return deleteProject(ctx.getCaller(), ctx.getCallerUserId(), project);
}
@DB
@Override
public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) {
//mark project as inactive first, so you can't add resources to it
Transaction txn = Transaction.currentTxn();
txn.start();
s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
project.setState(State.Disabled);
boolean updateResult = _projectDao.update(projectId, project);
_resourceLimitMgr.decrementResourceCount(getProjectOwner(projectId).getId(), ResourceType.project);
boolean updateResult = _projectDao.update(project.getId(), project);
//owner can be already removed at this point, so adding the conditional check
Account projectOwner = getProjectOwner(project.getId());
if (projectOwner != null) {
_resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
}
txn.commit();
if (updateResult) {
if (!cleanupProject(project, _accountDao.findById(caller.getId()), ctx.getCallerUserId())) {
s_logger.warn("Failed to cleanup project's id=" + projectId + " resources, not removing the project yet");
if (!cleanupProject(project, _accountDao.findById(caller.getId()), callerUserId)) {
s_logger.warn("Failed to cleanup project's id=" + project.getId() + " resources, not removing the project yet");
return false;
} else {
return _projectDao.remove(projectId);
return _projectDao.remove(project.getId());
}
} else {
s_logger.warn("Failed to mark the project id=" + projectId + " with state " + State.Disabled);
s_logger.warn("Failed to mark the project id=" + project.getId() + " with state " + State.Disabled);
return false;
}
}
}
@DB
@ -376,16 +385,14 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
accountId = caller.getId();
}
if (!listAll) {
if (domainId == null && accountId == null) {
accountId = caller.getId();
} else {
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || !isRecursive) {
DomainVO domain = _domainDao.findById(caller.getDomainId());
path = domain.getPath();
}
}
if (domainId == null && accountId == null) {
accountId = caller.getId();
} else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || (!isRecursive && !listAll)) {
DomainVO domain = _domainDao.findById(caller.getDomainId());
path = domain.getPath();
}
if (path != null) {
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
@ -469,8 +476,12 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
@Override
public Account getProjectOwner(long projectId) {
long accountId = _projectAccountDao.getProjectOwner(projectId).getAccountId();
return _accountMgr.getAccount(accountId);
ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId);
if (prAcct != null) {
return _accountMgr.getAccount(prAcct.getAccountId());
}
return null;
}
@Override

View File

@ -88,6 +88,7 @@ import com.cloud.projects.Project;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.projects.ProjectInvitationVO;
import com.cloud.projects.ProjectManager;
import com.cloud.projects.ProjectVO;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.server.auth.UserAuthenticator;
@ -1299,14 +1300,14 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
}
// cleanup inactive projects
List<? extends Project> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
List<ProjectVO> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
s_logger.info("Found " + inactiveProjects.size() + " disabled projects to cleanup");
for (Project project : inactiveProjects) {
for (ProjectVO project : inactiveProjects) {
try {
Account projectAccount = getAccount(project.getProjectAccountId());
if (projectAccount == null) {
s_logger.debug("Removing inactive project id=" + project.getId());
_projectMgr.deleteProject(project.getId());
_projectMgr.deleteProject(UserContext.current().getCaller(), UserContext.current().getCallerUserId(), project);
} else {
s_logger.debug("Can't remove disabled project " + project + " as it has non removed account id=" + project.getId());
}

View File

@ -41,6 +41,9 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.projects.ProjectManager;
import com.cloud.projects.ProjectVO;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
@ -73,6 +76,10 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
private DiskOfferingDao _diskOfferingDao;
@Inject
private ServiceOfferingDao _offeringsDao;
@Inject
private ProjectDao _projectDao;
@Inject
private ProjectManager _projectMgr;
@Override
public Domain getDomain(long domainId) {
@ -275,6 +282,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
}
private boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException {
s_logger.debug("Cleaning up domain id=" + domainId);
boolean success = true;
{
DomainVO domainHandle = _domainDao.findById(domainId);
@ -309,9 +317,19 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
List<AccountVO> accounts = _accountDao.search(sc, null);
for (AccountVO account : accounts) {
success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller()));
if (!success) {
s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup");
if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
s_logger.debug("Deleting account " + account + " as a part of domain id=" + domainId + " cleanup");
success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller()));
if (!success) {
s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup");
}
} else {
ProjectVO project = _projectDao.findByProjectAccountId(account.getId());
s_logger.debug("Deleting project " + project + " as a part of domain id=" + domainId + " cleanup");
success = (success && _projectMgr.deleteProject(UserContext.current().getCaller(), UserContext.current().getCallerUserId(), project));
if (!success) {
s_logger.warn("Failed to cleanup project " + project + " as a part of domain cleanup");
}
}
}