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.api.response.ProjectResponse;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.projects.Project; import com.cloud.projects.Project;
import com.cloud.user.UserContext; 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") @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of the project to be modified")
private Long id; 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; private String accountName;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="display text of the project") @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="display text of the project")
@ -91,7 +92,7 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@Override @Override
public void execute(){ public void execute() throws ResourceAllocationException{
UserContext.current().setEventDetails("Project id: "+ getId()); UserContext.current().setEventDetails("Project id: "+ getId());
Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName()); Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
if (project != null) { if (project != null) {

View File

@ -27,7 +27,7 @@ public interface Resource {
volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain), volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain),
snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain), snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
template ("template", 4, 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 String name;
private ResourceOwnerType[] supportedOwners; private ResourceOwnerType[] supportedOwners;

View File

@ -50,7 +50,7 @@ public interface ProjectService {
Project findByNameAndDomainId(String name, long domainId); 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); 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()); UserContext.current().setEventDetails("Project id=" + project.getId());
} }
//Increment resource count for the Owner's domain //Increment resource count
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.project); _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
txn.commit(); 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..."); s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
project.setState(State.Disabled); project.setState(State.Disabled);
boolean updateResult = _projectDao.update(projectId, project); boolean updateResult = _projectDao.update(projectId, project);
_resourceLimitMgr.decrementResourceCount(project.getProjectAccountId(), ResourceType.project); _resourceLimitMgr.decrementResourceCount(getProjectOwner(projectId).getId(), ResourceType.project);
txn.commit(); txn.commit();
if (updateResult) { if (updateResult) {
@ -494,7 +494,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
@Override @DB @Override @DB
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true) @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(); Account caller = UserContext.current().getCaller();
//check that the project exists //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"); 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 //unset the role for the old owner
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId()); ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
currentOwner.setAccountRole(Role.Regular); currentOwner.setAccountRole(Role.Regular);
_projectAccountDao.update(currentOwner.getId(), currentOwner); _projectAccountDao.update(currentOwner.getId(), currentOwner);
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
//set new owner //set new owner
futureOwner.setAccountRole(Role.Admin); futureOwner.setAccountRole(Role.Admin);
_projectAccountDao.update(futureOwner.getId(), futureOwner); _projectAccountDao.update(futureOwner.getId(), futureOwner);
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
} else { } else {
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId); 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 java.util.List;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectAccountVO; import com.cloud.projects.ProjectAccountVO;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
@ -34,4 +35,6 @@ public interface ProjectAccountDao extends GenericDao<ProjectAccountVO, Long>{
List<Long> listPermittedAccountIds(long accountId); List<Long> listPermittedAccountIds(long accountId);
List<Long> listAdministratedProjects(long adminAccountId); 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.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria.Op;
@Local(value={ProjectAccountDao.class}) @Local(value={ProjectAccountDao.class})
@ -34,6 +35,7 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch; protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch; final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch; final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch;
final GenericSearchBuilder<ProjectAccountVO, Long> CountByRoleSearch;
protected ProjectAccountDaoImpl() { protected ProjectAccountDaoImpl() {
AllFieldsSearch = createSearchBuilder(); AllFieldsSearch = createSearchBuilder();
@ -53,6 +55,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
ProjectAccountSearch.selectField(ProjectAccountSearch.entity().getProjectAccountId()); ProjectAccountSearch.selectField(ProjectAccountSearch.entity().getProjectAccountId());
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ); ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ);
ProjectAccountSearch.done(); 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 @Override
@ -122,4 +130,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
sc.setParameters("accountId", adminAccountId); sc.setParameters("accountId", adminAccountId);
return customSearch(sc, null); 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.exception.ResourceAllocationException;
import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressDao;
import com.cloud.projects.Project; 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.projects.dao.ProjectDao;
import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
@ -112,6 +114,9 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
private EntityManager _entityMgr; private EntityManager _entityMgr;
@Inject @Inject
private ProjectDao _projectDao; private ProjectDao _projectDao;
@Inject
private ProjectAccountDao _projectAccountDao;
protected SearchBuilder<ResourceCountVO> ResourceCountSearch; protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
ScheduledExecutorService _rcExecutor; ScheduledExecutorService _rcExecutor;
@ -690,6 +695,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId); newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
} else if (type == Resource.ResourceType.template) { } else if (type == Resource.ResourceType.template) {
newCount = _vmTemplateDao.countTemplatesForAccount(accountId); newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
} else if (type == Resource.ResourceType.project) {
newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
} else { } else {
throw new InvalidParameterValueException("Unsupported resource type " + type); throw new InvalidParameterValueException("Unsupported resource type " + type);
} }