bug 12983: resource limits for projects

This commit is contained in:
Alena Prokharchyk 2012-01-19 10:04:06 -08:00
parent 5d266b3b4b
commit ad1076f21d
7 changed files with 41 additions and 8 deletions

View File

@ -30,6 +30,7 @@ import com.cloud.api.ServerApiException;
import com.cloud.api.response.ProjectResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.projects.Project;
import com.cloud.user.UserContext;
@ -47,7 +48,7 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of the project to be modified")
private Long id;
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="new Admin account for the project, should be specified with domainId")
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="new Admin account for the project")
private String accountName;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="display text of the project")
@ -91,7 +92,7 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Override
public void execute(){
public void execute() throws ResourceAllocationException{
UserContext.current().setEventDetails("Project id: "+ getId());
Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
if (project != null) {

View File

@ -27,7 +27,7 @@ public interface Resource {
volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain),
snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
template ("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
project ("project", 5, ResourceOwnerType.Domain);
project ("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain);
private String name;
private ResourceOwnerType[] supportedOwners;

View File

@ -50,7 +50,7 @@ public interface ProjectService {
Project findByNameAndDomainId(String name, long domainId);
Project updateProject(long id, String displayText, String newOwnerName);
Project updateProject(long id, String displayText, String newOwnerName) throws ResourceAllocationException;
boolean addAccountToProject(long projectId, String accountName, String email);

View File

@ -214,8 +214,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
UserContext.current().setEventDetails("Project id=" + project.getId());
}
//Increment resource count for the Owner's domain
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.project);
//Increment resource count
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
txn.commit();
@ -266,7 +266,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
project.setState(State.Disabled);
boolean updateResult = _projectDao.update(projectId, project);
_resourceLimitMgr.decrementResourceCount(project.getProjectAccountId(), ResourceType.project);
_resourceLimitMgr.decrementResourceCount(getProjectOwner(projectId).getId(), ResourceType.project);
txn.commit();
if (updateResult) {
@ -494,7 +494,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
@Override @DB
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true)
public Project updateProject(long projectId, String displayText, String newOwnerName) {
public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{
Account caller = UserContext.current().getCaller();
//check that the project exists
@ -527,14 +527,20 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
}
//do resource limit check
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
//unset the role for the old owner
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
currentOwner.setAccountRole(Role.Regular);
_projectAccountDao.update(currentOwner.getId(), currentOwner);
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
//set new owner
futureOwner.setAccountRole(Role.Admin);
_projectAccountDao.update(futureOwner.getId(), futureOwner);
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
} else {
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);

View File

@ -19,6 +19,7 @@ package com.cloud.projects.dao;
import java.util.List;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectAccountVO;
import com.cloud.utils.db.GenericDao;
@ -34,4 +35,6 @@ public interface ProjectAccountDao extends GenericDao<ProjectAccountVO, Long>{
List<Long> listPermittedAccountIds(long accountId);
List<Long> listAdministratedProjects(long adminAccountId);
Long countByAccountIdAndRole(long accountId, ProjectAccount.Role role);
}

View File

@ -27,6 +27,7 @@ import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
@Local(value={ProjectAccountDao.class})
@ -34,6 +35,7 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> CountByRoleSearch;
protected ProjectAccountDaoImpl() {
AllFieldsSearch = createSearchBuilder();
@ -53,6 +55,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
ProjectAccountSearch.selectField(ProjectAccountSearch.entity().getProjectAccountId());
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ);
ProjectAccountSearch.done();
CountByRoleSearch = createSearchBuilder(Long.class);
CountByRoleSearch.select(null, Func.COUNT, CountByRoleSearch.entity().getId());
CountByRoleSearch.and("accountId", CountByRoleSearch.entity().getAccountId(), Op.EQ);
CountByRoleSearch.and("role", CountByRoleSearch.entity().getAccountRole(), Op.EQ);
CountByRoleSearch.done();
}
@Override
@ -122,4 +130,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
sc.setParameters("accountId", adminAccountId);
return customSearch(sc, null);
}
@Override
public Long countByAccountIdAndRole(long accountId, ProjectAccount.Role role) {
SearchCriteria<Long> sc = CountByRoleSearch.create();
sc.setParameters("accountId", accountId);
sc.setParameters("role", role);
return customSearch(sc, null).get(0);
}
}

View File

@ -52,6 +52,8 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount.Role;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
@ -112,6 +114,9 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
private EntityManager _entityMgr;
@Inject
private ProjectDao _projectDao;
@Inject
private ProjectAccountDao _projectAccountDao;
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
ScheduledExecutorService _rcExecutor;
@ -690,6 +695,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
} else if (type == Resource.ResourceType.template) {
newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
} else if (type == Resource.ResourceType.project) {
newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
} else {
throw new InvalidParameterValueException("Unsupported resource type " + type);
}