You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2013/10/23 21:43:37 UTC
[20/47] New Transaction API
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java
index a385739..193a49e 100755
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/com/cloud/projects/ProjectManagerImpl.java
@@ -82,6 +82,10 @@ import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.sun.mail.smtp.SMTPMessage;
import com.sun.mail.smtp.SMTPSSLTransport;
@@ -175,7 +179,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create=true)
@DB
- public Project createProject(String name, String displayText, String accountName, Long domainId) throws ResourceAllocationException{
+ public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException{
Account caller = CallContext.current().getCallingAccount();
Account owner = caller;
@@ -201,30 +205,32 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
//do resource limit check
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
- Transaction txn = Transaction.currentTxn();
- txn.start();
+ final Account ownerFinal = owner;
+ return Transaction.execute(new TransactionCallback<Project>() {
+ @Override
+ public Project doInTransaction(TransactionStatus status) {
- //Create an account associated with the project
- StringBuilder acctNm = new StringBuilder("PrjAcct-");
- acctNm.append(name).append("-").append(owner.getDomainId());
-
- Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
-
- Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId()));
-
- //assign owner to the project
- assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Admin);
-
- if (project != null) {
- CallContext.current().setEventDetails("Project id=" + project.getId());
- }
-
- //Increment resource count
- _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
-
- txn.commit();
+ //Create an account associated with the project
+ StringBuilder acctNm = new StringBuilder("PrjAcct-");
+ acctNm.append(name).append("-").append(ownerFinal.getDomainId());
+
+ Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
+
+ Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
+
+ //assign owner to the project
+ assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
+
+ if (project != null) {
+ CallContext.current().setEventDetails("Project id=" + project.getId());
+ }
+
+ //Increment resource count
+ _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
- return project;
+ return project;
+ }
+ });
}
@@ -268,20 +274,24 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
@DB
@Override
- public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) {
+ public boolean deleteProject(Account caller, long callerUserId, final 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=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
- project.setState(State.Disabled);
- 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);
- }
+ boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ 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(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);
+ }
+
+ return updateResult;
+ }
+ });
- txn.commit();
if (updateResult) {
//pass system caller when clenaup projects account
@@ -298,7 +308,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
}
@DB
- private boolean cleanupProject(Project project, AccountVO caller, Long callerUserId) {
+ private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) {
boolean result=true;
//Delete project's account
AccountVO account = _accountDao.findById(project.getProjectAccountId());
@@ -308,20 +318,22 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
if (result) {
//Unassign all users from the project
-
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
- List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
- for (ProjectAccount projectAccount : projectAccounts) {
- result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
- }
-
- s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
- _projectInvitationDao.cleanupInvitations(project.getId());
-
- txn.commit();
+ result = Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ boolean result = true;
+ s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
+ List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
+ for (ProjectAccount projectAccount : projectAccounts) {
+ result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
+ }
+
+ s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
+ _projectInvitationDao.cleanupInvitations(project.getId());
+
+ return result;
+ }
+ });
if (result) {
s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
}
@@ -366,26 +378,28 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
}
@Override @DB
- public boolean deleteAccountFromProject(long projectId, long accountId) {
- boolean success = true;
- Transaction txn = Transaction.currentTxn();
- txn.start();
+ public boolean deleteAccountFromProject(final long projectId, final long accountId) {
+ return Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ boolean success = true;
+
+ //remove account
+ ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
+ success = _projectAccountDao.remove(projectAccount.getId());
+
+ //remove all invitations for account
+ if (success) {
+ s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
+ ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
+ if (invite != null) {
+ success = success && _projectInvitationDao.remove(invite.getId());
+ }
+ }
- //remove account
- ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
- success = _projectAccountDao.remove(projectAccount.getId());
-
- //remove all invitations for account
- if (success) {
- s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
- ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
- if (invite != null) {
- success = success && _projectInvitationDao.remove(invite.getId());
+ return success;
}
- }
-
- txn.commit();
- return success;
+ });
}
@Override
@@ -442,11 +456,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
@Override @DB
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true)
- public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{
+ public Project updateProject(final long projectId, final String displayText, final String newOwnerName) throws ResourceAllocationException{
Account caller = CallContext.current().getCallingAccount();
//check that the project exists
- ProjectVO project = getProject(projectId);
+ final ProjectVO project = getProject(projectId);
if (project == null) {
throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
@@ -455,47 +469,51 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
//verify permissions
_accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
- Transaction txn = Transaction.currentTxn();
- txn.start();
- if (displayText != null) {
- project.setDisplayText(displayText);
- _projectDao.update(projectId, project);
- }
-
- if (newOwnerName != null) {
- //check that the new owner exists
- Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
- if (futureOwnerAccount == null) {
- throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
- }
- Account currentOwnerAccount = getProjectOwner(projectId);
- if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
- ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
- if (futureOwner == null) {
- throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
+ Transaction.executeWithException(new TransactionCallbackWithException<Object>() {
+ @Override
+ public Object doInTransaction(TransactionStatus status) throws ResourceAllocationException {
+ if (displayText != null) {
+ project.setDisplayText(displayText);
+ _projectDao.update(projectId, project);
}
-
- //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);
+
+ if (newOwnerName != null) {
+ //check that the new owner exists
+ Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
+ if (futureOwnerAccount == null) {
+ throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
+ }
+ Account currentOwnerAccount = getProjectOwner(projectId);
+ if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
+ ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
+ if (futureOwner == null) {
+ 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);
+ }
+ }
+
+ return null;
}
- }
+ }, ResourceAllocationException.class);
- txn.commit();
return _projectDao.findById(projectId);
@@ -649,37 +667,40 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
}
@DB
- public boolean activeInviteExists(Project project, Long accountId, String email) {
- Transaction txn = Transaction.currentTxn();
- txn.start();
- //verify if the invitation was already generated
- ProjectInvitationVO invite = null;
- if (accountId != null) {
- invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
- } else if (email != null) {
- invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
- }
-
- if (invite != null) {
- if (invite.getState() == ProjectInvitation.State.Completed ||
- (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
- return true;
- } else {
- if (invite.getState() == ProjectInvitation.State.Pending) {
- expireInvitation(invite);
- }
- //remove the expired/declined invitation
+ public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
+ return Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ //verify if the invitation was already generated
+ ProjectInvitationVO invite = null;
if (accountId != null) {
- s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
+ invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
} else if (email != null) {
- s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
+ invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
+ }
+
+ if (invite != null) {
+ if (invite.getState() == ProjectInvitation.State.Completed ||
+ (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
+ return true;
+ } else {
+ if (invite.getState() == ProjectInvitation.State.Pending) {
+ expireInvitation(invite);
+ }
+ //remove the expired/declined invitation
+ if (accountId != null) {
+ s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
+ } else if (email != null) {
+ s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
+ }
+
+ _projectInvitationDao.expunge(invite.getId());
+ }
}
- _projectInvitationDao.expunge(invite.getId());
+ return false;
}
- }
- txn.commit();
- return false;
+ });
}
public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
@@ -710,7 +731,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
@Override @DB
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async=true)
- public boolean updateInvitation(long projectId, String accountName, String token, boolean accept) {
+ public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) {
Account caller = CallContext.current().getCallingAccount();
Long accountId = null;
boolean result = true;
@@ -721,7 +742,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
}
//check that the project exists
- Project project = getProject(projectId);
+ final Project project = getProject(projectId);
if (project == null) {
throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
@@ -755,29 +776,37 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
expireInvitation(invite);
throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
} else {
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
-
- //update invitation
- s_logger.debug("Marking invitation " + invite + " with state " + newState);
- invite.setState(newState);
- result = _projectInvitationDao.update(invite.getId(), invite);
-
- if (result && accept) {
- //check if account already exists for the project (was added before invitation got accepted)
- ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
- if (projectAccount != null) {
- s_logger.debug("Account " + accountName + " already added to the project id=" + projectId);
- } else {
- assignAccountToProject(project, accountId, ProjectAccount.Role.Regular);
+
+ final ProjectInvitationVO inviteFinal = invite;
+ final Long accountIdFinal = accountId;
+ final String accountNameFinal = accountName;
+ result = Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ boolean result = true;
+
+ ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
+
+ //update invitation
+ s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
+ inviteFinal.setState(newState);
+ result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
+
+ if (result && accept) {
+ //check if account already exists for the project (was added before invitation got accepted)
+ ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
+ if (projectAccount != null) {
+ s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
+ } else {
+ assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular);
+ }
+ } else {
+ s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
+ }
+
+ return result;
}
- } else {
- s_logger.warn("Failed to update project invitation " + invite + " with state " + newState);
- }
-
- txn.commit();
+ });
}
} else {
throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
@@ -794,11 +823,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project")
@DB
- public Project activateProject(long projectId) {
+ public Project activateProject(final long projectId) {
Account caller = CallContext.current().getCallingAccount();
//check that the project exists
- ProjectVO project = getProject(projectId);
+ final ProjectVO project = getProject(projectId);
if (project == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
@@ -821,15 +850,15 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
}
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- project.setState(Project.State.Active);
- _projectDao.update(projectId, project);
-
- _accountMgr.enableAccount(project.getProjectAccountId());
-
- txn.commit();
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ project.setState(Project.State.Active);
+ _projectDao.update(projectId, project);
+
+ _accountMgr.enableAccount(project.getProjectAccountId());
+ }
+ });
return _projectDao.findById(projectId);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 7a9343c..2a245f1 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -143,6 +143,9 @@ import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@@ -783,10 +786,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
}
@DB
- protected boolean doDeleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) {
+ protected boolean doDeleteHost(final long hostId, boolean isForced, final boolean isForceDeleteStorage) {
User caller = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
// Verify that host exists
- HostVO host = _hostDao.findById(hostId);
+ final HostVO host = _hostDao.findById(hostId);
if (host == null) {
throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
}
@@ -799,7 +802,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
// Get storage pool host mappings here because they can be removed as a
// part of handleDisconnect later
// TODO: find out the bad boy, what's a buggy logic!
- List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
+ final List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer)dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host,
new Boolean(isForced), new Boolean(isForceDeleteStorage));
@@ -817,74 +820,77 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
return true;
}
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
- _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
-
- // delete host details
- _hostDetailsDao.deleteDetails(hostId);
-
- host.setGuid(null);
- Long clusterId = host.getClusterId();
- host.setClusterId(null);
- _hostDao.update(host.getId(), host);
-
- _hostDao.remove(hostId);
- if (clusterId != null) {
- List<HostVO> hosts = listAllHostsInCluster(clusterId);
- if (hosts.size() == 0) {
- ClusterVO cluster = _clusterDao.findById(clusterId);
- cluster.setGuid(null);
- _clusterDao.update(clusterId, cluster);
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+
+ _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
+ _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
+
+ // delete host details
+ _hostDetailsDao.deleteDetails(hostId);
+
+ host.setGuid(null);
+ Long clusterId = host.getClusterId();
+ host.setClusterId(null);
+ _hostDao.update(host.getId(), host);
+
+ _hostDao.remove(hostId);
+ if (clusterId != null) {
+ List<HostVO> hosts = listAllHostsInCluster(clusterId);
+ if (hosts.size() == 0) {
+ ClusterVO cluster = _clusterDao.findById(clusterId);
+ cluster.setGuid(null);
+ _clusterDao.update(clusterId, cluster);
+ }
+ }
+
+ try {
+ resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
+ } catch (NoTransitionException e) {
+ s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
+ }
+
+ // Delete the associated entries in host ref table
+ _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
+
+ // Make sure any VMs that were marked as being on this host are cleaned up
+ List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
+ for (VMInstanceVO vm : vms) {
+ // this is how VirtualMachineManagerImpl does it when it syncs VM states
+ vm.setState(State.Stopped);
+ vm.setHostId(null);
+ _vmDao.persist(vm);
+ }
+
+ // For pool ids you got, delete local storage host entries in pool table
+ // where
+ for (StoragePoolHostVO pool : pools) {
+ Long poolId = pool.getPoolId();
+ StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
+ if (storagePool.isLocal() && isForceDeleteStorage) {
+ storagePool.setUuid(null);
+ storagePool.setClusterId(null);
+ _storagePoolDao.update(poolId, storagePool);
+ _storagePoolDao.remove(poolId);
+ s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
+ }
+ }
+
+ // delete the op_host_capacity entry
+ Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
+ SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
+ hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
+ hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
+ _capacityDao.remove(hostCapacitySC);
+ // remove from dedicated resources
+ DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
+ if (dr != null) {
+ _dedicatedDao.remove(dr.getId());
+ }
}
- }
-
- try {
- resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
- } catch (NoTransitionException e) {
- s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
- }
-
- // Delete the associated entries in host ref table
- _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
+ });
- // Make sure any VMs that were marked as being on this host are cleaned up
- List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
- for (VMInstanceVO vm : vms) {
- // this is how VirtualMachineManagerImpl does it when it syncs VM states
- vm.setState(State.Stopped);
- vm.setHostId(null);
- _vmDao.persist(vm);
- }
-
- // For pool ids you got, delete local storage host entries in pool table
- // where
- for (StoragePoolHostVO pool : pools) {
- Long poolId = pool.getPoolId();
- StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
- if (storagePool.isLocal() && isForceDeleteStorage) {
- storagePool.setUuid(null);
- storagePool.setClusterId(null);
- _storagePoolDao.update(poolId, storagePool);
- _storagePoolDao.remove(poolId);
- s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
- }
- }
-
- // delete the op_host_capacity entry
- Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
- SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
- hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
- hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
- _capacityDao.remove(hostCapacitySC);
- // remove from dedicated resources
- DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
- if (dr != null) {
- _dedicatedDao.remove(dr.getId());
- }
- txn.commit();
return true;
}
@@ -904,63 +910,61 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
@Override
@DB
- public boolean deleteCluster(DeleteClusterCmd cmd) {
- Transaction txn = Transaction.currentTxn();
+ public boolean deleteCluster(final DeleteClusterCmd cmd) {
try {
- txn.start();
- ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
- if (cluster == null) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored.");
- }
- txn.rollback();
- throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
- }
-
- Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
-
- List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
- if (hosts.size() > 0) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
- }
- txn.rollback();
- throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
- }
-
- // don't allow to remove the cluster if it has non-removed storage
- // pools
- List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
- if (storagePools.size() > 0) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
- }
- txn.rollback();
- throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
- }
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
+ if (cluster == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored.");
+ }
+ throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
+ }
+
+ Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
+
+ List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
+ if (hosts.size() > 0) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
+ }
+ throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
+ }
+
+ // don't allow to remove the cluster if it has non-removed storage
+ // pools
+ List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
+ if (storagePools.size() > 0) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
+ }
+ throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
+ }
+
+ if (_clusterDao.remove(cmd.getId())) {
+ _capacityDao.removeBy(null, null, null, cluster.getId(), null);
+ // If this cluster is of type vmware, and if the nexus vswitch
+ // global parameter setting is turned
+ // on, remove the row in cluster_vsm_map for this cluster id.
+ if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
+ _clusterVSMMapDao.removeByClusterId(cmd.getId());
+ }
+ // remove from dedicated resources
+ DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
+ if (dr != null) {
+ _dedicatedDao.remove(dr.getId());
+ }
+ }
- if (_clusterDao.remove(cmd.getId())) {
- _capacityDao.removeBy(null, null, null, cluster.getId(), null);
- // If this cluster is of type vmware, and if the nexus vswitch
- // global parameter setting is turned
- // on, remove the row in cluster_vsm_map for this cluster id.
- if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
- _clusterVSMMapDao.removeByClusterId(cmd.getId());
- }
- // remove from dedicated resources
- DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
- if (dr != null) {
- _dedicatedDao.remove(dr.getId());
}
- }
-
- txn.commit();
+ });
return true;
} catch (CloudRuntimeException e) {
throw e;
} catch (Throwable t) {
s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
- txn.rollback();
return false;
}
}
@@ -1034,26 +1038,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
}
if (doUpdate) {
- Transaction txn = Transaction.currentTxn();
- try {
- txn.start();
- _clusterDao.update(cluster.getId(), cluster);
- txn.commit();
- } catch (Exception e) {
- s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
- throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
- }
+ _clusterDao.update(cluster.getId(), cluster);
}
if (newManagedState != null && !newManagedState.equals(oldManagedState)) {
- Transaction txn = Transaction.currentTxn();
if (newManagedState.equals(Managed.ManagedState.Unmanaged)) {
boolean success = false;
try {
- txn.start();
cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
_clusterDao.update(cluster.getId(), cluster);
- txn.commit();
List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
for (HostVO host : hosts) {
if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) &&
@@ -1092,16 +1085,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
}
} finally {
- txn.start();
cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError);
_clusterDao.update(cluster.getId(), cluster);
- txn.commit();
}
} else if (newManagedState.equals(Managed.ManagedState.Managed)) {
- txn.start();
cluster.setManagedState(Managed.ManagedState.Managed);
_clusterDao.update(cluster.getId(), cluster);
- txn.commit();
}
}
@@ -2459,35 +2448,37 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
- public boolean releaseHostReservation(Long hostId) {
- Transaction txn = Transaction.currentTxn();
+ public boolean releaseHostReservation(final Long hostId) {
try {
- txn.start();
- PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
- if (reservationEntry != null) {
- long id = reservationEntry.getId();
- PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
- if (hostReservation == null) {
+ return Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+ if (reservationEntry != null) {
+ long id = reservationEntry.getId();
+ PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
+ if (hostReservation == null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored.");
+ }
+ return false;
+ }
+ hostReservation.setResourceUsage(null);
+ _plannerHostReserveDao.persist(hostReservation);
+ return true;
+ }
+
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored.");
}
- txn.rollback();
+
return false;
}
- hostReservation.setResourceUsage(null);
- _plannerHostReserveDao.persist(hostReservation);
- txn.commit();
- return true;
- }
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored.");
- }
- return false;
+ });
} catch (CloudRuntimeException e) {
throw e;
} catch (Throwable t) {
s_logger.error("Unable to release host reservation for host: " + hostId, t);
- txn.rollback();
return false;
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f62e28c1/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index 1f8713a..bfe32ec 100755
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -90,6 +90,10 @@ import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@@ -361,8 +365,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
@Override
@DB
- public void checkResourceLimit(Account account, ResourceType type, long... count) throws ResourceAllocationException {
- long numResources = ((count.length == 0) ? 1 : count[0]);
+ public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {
+ final long numResources = ((count.length == 0) ? 1 : count[0]);
Project project = null;
// Don't place any limits on system or root admin accounts
@@ -374,53 +378,55 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
project = _projectDao.findByProjectAccountId(account.getId());
}
- Transaction txn = Transaction.currentTxn();
- txn.start();
- try {
- // Lock all rows first so nobody else can read it
- Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
- SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
- sc.setParameters("id", rowIdsToLock.toArray());
- _resourceCountDao.lockRows(sc, null, true);
-
- // Check account limits
- long accountLimit = findCorrectResourceLimitForAccount(account, type);
- long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
- if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
- String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
- + " in domain id=" + account.getDomainId() + " has been exceeded.";
- if (project != null) {
- message = "Maximum number of resources of type '" + type + "' for project name=" + project.getName()
+ final Project projectFinal = project;
+ Transaction.executeWithException(new TransactionCallbackWithException<Object>() {
+ @Override
+ public Object doInTransaction(TransactionStatus status) throws ResourceAllocationException {
+ // Lock all rows first so nobody else can read it
+ Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(account.getId(), ResourceOwnerType.Account, type);
+ SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+ sc.setParameters("id", rowIdsToLock.toArray());
+ _resourceCountDao.lockRows(sc, null, true);
+
+ // Check account limits
+ long accountLimit = findCorrectResourceLimitForAccount(account, type);
+ long potentialCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type) + numResources;
+ if (accountLimit != Resource.RESOURCE_UNLIMITED && potentialCount > accountLimit) {
+ String message = "Maximum number of resources of type '" + type + "' for account name=" + account.getAccountName()
+ " in domain id=" + account.getDomainId() + " has been exceeded.";
+ if (projectFinal != null) {
+ message = "Maximum number of resources of type '" + type + "' for project name=" + projectFinal.getName()
+ + " in domain id=" + account.getDomainId() + " has been exceeded.";
+ }
+ throw new ResourceAllocationException(message, type);
}
- throw new ResourceAllocationException(message, type);
- }
-
- // check all domains in the account's domain hierarchy
- Long domainId = null;
- if (project != null) {
- domainId = project.getDomainId();
- } else {
- domainId = account.getDomainId();
- }
-
- while (domainId != null) {
- DomainVO domain = _domainDao.findById(domainId);
- // no limit check if it is ROOT domain
- if (domainId != Domain.ROOT_DOMAIN) {
- ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
- if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
- long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
- if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
- throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
+
+ // check all domains in the account's domain hierarchy
+ Long domainId = null;
+ if (projectFinal != null) {
+ domainId = projectFinal.getDomainId();
+ } else {
+ domainId = account.getDomainId();
+ }
+
+ while (domainId != null) {
+ DomainVO domain = _domainDao.findById(domainId);
+ // no limit check if it is ROOT domain
+ if (domainId != Domain.ROOT_DOMAIN) {
+ ResourceLimitVO domainLimit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
+ if (domainLimit != null && domainLimit.getMax().longValue() != Resource.RESOURCE_UNLIMITED) {
+ long domainCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
+ if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
+ throw new ResourceAllocationException("Maximum number of resources of type '" + type + "' for domain id=" + domainId + " has been exceeded.", type);
+ }
}
}
+ domainId = domain.getParent();
}
- domainId = domain.getParent();
+
+ return null;
}
- } finally {
- txn.commit();
- }
+ }, ResourceAllocationException.class);
}
@Override
@@ -716,143 +722,143 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
}
@DB
- protected boolean updateResourceCountForAccount(long accountId, ResourceType type, boolean increment, long delta) {
- boolean result = true;
+ protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) {
try {
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
-
- // Lock rows first
- SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
- sc.setParameters("id", rowsToLock.toArray());
- List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
-
- for (ResourceCountVO rowToUpdate : rowsToUpdate) {
- if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
- s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
- result = false;
+ return Transaction.execute(new TransactionCallback<Boolean>() {
+ @Override
+ public Boolean doInTransaction(TransactionStatus status) {
+ boolean result = true;
+ Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
+
+ // Lock rows first
+ SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+ sc.setParameters("id", rowsToLock.toArray());
+ List<ResourceCountVO> rowsToUpdate = _resourceCountDao.lockRows(sc, null, true);
+
+ for (ResourceCountVO rowToUpdate : rowsToUpdate) {
+ if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
+ s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
+ result = false;
+ }
+ }
+
+ return result;
}
- }
-
- txn.commit();
+ });
} catch (Exception ex) {
s_logger.error("Failed to update resource count for account id=" + accountId);
- result = false;
+ return false;
}
- return result;
}
@DB
- protected long recalculateDomainResourceCount(long domainId, ResourceType type) {
- long newCount = 0;
-
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- try {
- // Lock all rows first so nobody else can read it
- Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
- SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
- sc.setParameters("id", rowIdsToLock.toArray());
- _resourceCountDao.lockRows(sc, null, true);
-
- ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
- long oldCount = domainRC.getCount();
-
- List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
- // for each child domain update the resource count
- if (type.supportsOwner(ResourceOwnerType.Domain)) {
-
- // calculate project count here
- if (type == ResourceType.project) {
- newCount = newCount + _projectDao.countProjectsForDomain(domainId);
+ protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) {
+ return Transaction.execute(new TransactionCallback<Long>() {
+ @Override
+ public Long doInTransaction(TransactionStatus status) {
+ long newCount = 0;
+
+ // Lock all rows first so nobody else can read it
+ Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
+ SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+ sc.setParameters("id", rowIdsToLock.toArray());
+ _resourceCountDao.lockRows(sc, null, true);
+
+ ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
+ long oldCount = domainRC.getCount();
+
+ List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
+ // for each child domain update the resource count
+ if (type.supportsOwner(ResourceOwnerType.Domain)) {
+
+ // calculate project count here
+ if (type == ResourceType.project) {
+ newCount = newCount + _projectDao.countProjectsForDomain(domainId);
+ }
+
+ for (DomainVO domainChild : domainChildren) {
+ long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
+ newCount = newCount + domainCount; // add the child domain count to parent domain count
+ }
}
-
- for (DomainVO domainChild : domainChildren) {
- long domainCount = recalculateDomainResourceCount(domainChild.getId(), type);
- newCount = newCount + domainCount; // add the child domain count to parent domain count
+
+ if (type.supportsOwner(ResourceOwnerType.Account)) {
+ List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
+ for (AccountVO account : accounts) {
+ long accountCount = recalculateAccountResourceCount(account.getId(), type);
+ newCount = newCount + accountCount; // add account's resource count to parent domain count
+ }
}
- }
-
- if (type.supportsOwner(ResourceOwnerType.Account)) {
- List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
- for (AccountVO account : accounts) {
- long accountCount = recalculateAccountResourceCount(account.getId(), type);
- newCount = newCount + accountCount; // add account's resource count to parent domain count
+ _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
+
+ if (oldCount != newCount) {
+ s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
+ newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
}
+
+ return newCount;
}
- _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newCount);
-
- if (oldCount != newCount) {
- s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
- newCount + ") for type " + type + " for domain ID " + domainId + " is fixed during resource count recalculation.");
- }
- } catch (Exception e) {
- throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId);
- } finally {
- txn.commit();
- }
-
- return newCount;
+ });
}
@DB
- protected long recalculateAccountResourceCount(long accountId, ResourceType type) {
- Long newCount = null;
-
- Transaction txn = Transaction.currentTxn();
- txn.start();
-
- // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
- // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
- SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
- sc.setParameters("accountId", accountId);
- _resourceCountDao.lockRows(sc, null, true);
-
- ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
- long oldCount = 0;
- if (accountRC != null)
- oldCount = accountRC.getCount();
-
- if (type == Resource.ResourceType.user_vm) {
- newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
- } else if (type == Resource.ResourceType.volume) {
- newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
- long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
- newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
- } else if (type == Resource.ResourceType.snapshot) {
- newCount = _snapshotDao.countSnapshotsForAccount(accountId);
- } else if (type == Resource.ResourceType.public_ip) {
- newCount = calculatePublicIpForAccount(accountId);
- } else if (type == Resource.ResourceType.template) {
- newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
- } else if (type == Resource.ResourceType.project) {
- newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
- } else if (type == Resource.ResourceType.network) {
- newCount = _networkDao.countNetworksUserCanCreate(accountId);
- } else if (type == Resource.ResourceType.vpc) {
- newCount = _vpcDao.countByAccountId(accountId);
- } else if (type == Resource.ResourceType.cpu) {
- newCount = countCpusForAccount(accountId);
- } else if (type == Resource.ResourceType.memory) {
- newCount = calculateMemoryForAccount(accountId);
- } else if (type == Resource.ResourceType.primary_storage) {
- List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
- newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
- } else if (type == Resource.ResourceType.secondary_storage) {
- newCount = calculateSecondaryStorageForAccount(accountId);
- } else {
- throw new InvalidParameterValueException("Unsupported resource type " + type);
- }
- _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
-
- if (oldCount != newCount) {
- s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
- newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
- }
- txn.commit();
+ protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
+ Long newCount = Transaction.execute(new TransactionCallback<Long>() {
+ @Override
+ public Long doInTransaction(TransactionStatus status) {
+ Long newCount = null;
+
+ // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table
+ // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too
+ SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+ sc.setParameters("accountId", accountId);
+ _resourceCountDao.lockRows(sc, null, true);
+
+ ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
+ long oldCount = 0;
+ if (accountRC != null)
+ oldCount = accountRC.getCount();
+
+ if (type == Resource.ResourceType.user_vm) {
+ newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
+ } else if (type == Resource.ResourceType.volume) {
+ newCount = _volumeDao.countAllocatedVolumesForAccount(accountId);
+ long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
+ newCount = newCount - virtualRouterCount; // don't count the volumes of virtual router
+ } else if (type == Resource.ResourceType.snapshot) {
+ newCount = _snapshotDao.countSnapshotsForAccount(accountId);
+ } else if (type == Resource.ResourceType.public_ip) {
+ newCount = calculatePublicIpForAccount(accountId);
+ } else if (type == Resource.ResourceType.template) {
+ newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
+ } else if (type == Resource.ResourceType.project) {
+ newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
+ } else if (type == Resource.ResourceType.network) {
+ newCount = _networkDao.countNetworksUserCanCreate(accountId);
+ } else if (type == Resource.ResourceType.vpc) {
+ newCount = _vpcDao.countByAccountId(accountId);
+ } else if (type == Resource.ResourceType.cpu) {
+ newCount = countCpusForAccount(accountId);
+ } else if (type == Resource.ResourceType.memory) {
+ newCount = calculateMemoryForAccount(accountId);
+ } else if (type == Resource.ResourceType.primary_storage) {
+ List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
+ newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
+ } else if (type == Resource.ResourceType.secondary_storage) {
+ newCount = calculateSecondaryStorageForAccount(accountId);
+ } else {
+ throw new InvalidParameterValueException("Unsupported resource type " + type);
+ }
+ _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue());
+
+ if (oldCount != newCount) {
+ s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " +
+ newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation.");
+ }
+
+ return newCount;
+ }
+ });
return (newCount == null) ? 0 : newCount.longValue();
}