mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 11036: resource count update is refactored
status 11036: resolved fixed 1) Use row locks instead of global lock when update resource_count table. When update resource_count for account, make sure that we lock account+all related domains 2) Insert resource_count records for account/domain at the moment when account/domain is created. 3) As a part of DB upgrade, insert missing resource_count records for all non-removed accounts/domains Conflicts: core/src/com/cloud/alert/AlertManager.java server/test/com/cloud/agent/MockAgentManagerImpl.java
This commit is contained in:
parent
e981546067
commit
f6a79c603f
@ -81,7 +81,7 @@ public class CreateDomainCmd extends BaseCmd {
|
||||
@Override
|
||||
public void execute(){
|
||||
UserContext.current().setEventDetails("Domain Name: "+getDomainName()+((getParentDomainId()!=null)?", Parent DomainId :"+getParentDomainId():""));
|
||||
Domain domain = _mgr.createDomain(this);
|
||||
Domain domain = _accountService.createDomain(this);
|
||||
if (domain != null) {
|
||||
DomainResponse response = _responseGenerator.createDomainResponse(domain);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
package com.cloud.configuration;
|
||||
|
||||
public interface ResourceLimit {
|
||||
|
||||
public static enum OwnerType {Account, Domain}
|
||||
|
||||
public Long getId();
|
||||
|
||||
|
||||
@ -251,15 +251,6 @@ public interface ManagementService {
|
||||
|
||||
List<? extends Domain> searchForDomainChildren(ListDomainChildrenCmd cmd);
|
||||
|
||||
/**
|
||||
* create a new domain
|
||||
*
|
||||
* @param command
|
||||
* - the create command defining the name to use and the id of the parent domain under which to create the new
|
||||
* domain.
|
||||
*/
|
||||
Domain createDomain(CreateDomainCmd command);
|
||||
|
||||
/**
|
||||
* delete a domain with the given domainId
|
||||
*
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.api.commands.CreateAccountCmd;
|
||||
import com.cloud.api.commands.CreateDomainCmd;
|
||||
import com.cloud.api.commands.CreateUserCmd;
|
||||
import com.cloud.api.commands.DeleteAccountCmd;
|
||||
import com.cloud.api.commands.DeleteUserCmd;
|
||||
@ -31,11 +32,11 @@ import com.cloud.api.commands.EnableUserCmd;
|
||||
import com.cloud.api.commands.ListResourceLimitsCmd;
|
||||
import com.cloud.api.commands.LockUserCmd;
|
||||
import com.cloud.api.commands.UpdateAccountCmd;
|
||||
import com.cloud.api.commands.UpdateResourceLimitCmd;
|
||||
import com.cloud.api.commands.UpdateResourceCountCmd;
|
||||
import com.cloud.api.commands.UpdateResourceLimitCmd;
|
||||
import com.cloud.api.commands.UpdateUserCmd;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
@ -197,4 +198,6 @@ public interface AccountService {
|
||||
|
||||
Set<Long> getDomainChildrenIds(String parentDomainPath);
|
||||
|
||||
Domain createDomain(CreateDomainCmd cmd);
|
||||
|
||||
}
|
||||
|
||||
@ -122,5 +122,8 @@
|
||||
<dao name="NetworkDao" class="com.cloud.network.dao.NetworkDaoImpl" singleton="false"/>
|
||||
<dao name="IpAddressDao" class="com.cloud.network.dao.IPAddressDaoImpl" singleton="false"/>
|
||||
<dao name="VlanDao" class="com.cloud.dc.dao.VlanDaoImpl" singleton="false"/>
|
||||
<dao name="ResouceCountDao" class="com.cloud.configuration.dao.ResourceCountDaoImpl" singleton="false"/>
|
||||
<dao name="AccountDao" class="com.cloud.user.dao.AccountDaoImpl" singleton="false"/>
|
||||
<dao name="UserDao" class="com.cloud.user.dao.UserDaoImpl" singleton="false"/>
|
||||
</configuration-server>
|
||||
</components.xml>
|
||||
|
||||
@ -43,7 +43,8 @@ public interface AlertManager extends Manager {
|
||||
public static final short ALERT_TYPE_SSVM = 18;
|
||||
public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 19; // Usage job result
|
||||
public static final short ALERT_TYPE_STORAGE_DELETE = 20;
|
||||
public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 21;
|
||||
public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 21; // Generated when we fail to update the resource count
|
||||
public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 22;
|
||||
|
||||
void clearAlert(short alertType, long dataCenterId, long podId);
|
||||
|
||||
|
||||
@ -97,4 +97,9 @@ public class ResourceCountVO implements ResourceCount {
|
||||
public void setCount(long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("REsourceCount[").append("-").append(id).append("-").append(type).append("-").append(accountId).append("-").append(domainId).append("]").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ public class ApiDBUtils {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _accountMgr.findCorrectResourceLimit(account, type);
|
||||
return _accountMgr.findCorrectResourceLimit(account.getAccountId(), type);
|
||||
}
|
||||
|
||||
public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
|
||||
|
||||
@ -117,7 +117,6 @@ import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.test.IPRangeConfig;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
@ -2050,7 +2049,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
||||
if (forVirtualNetwork) {
|
||||
if (account != null) {
|
||||
// verify resource limits
|
||||
long ipResourceLimit = _accountMgr.findCorrectResourceLimit((AccountVO) account, ResourceType.public_ip);
|
||||
long ipResourceLimit = _accountMgr.findCorrectResourceLimit(account.getId(), ResourceType.public_ip);
|
||||
long accountIpRange = NetUtils.ip2Long(endIP) - NetUtils.ip2Long(startIP) + 1;
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(" IPResourceLimit " + ipResourceLimit + " accountIpRange " + accountIpRange);
|
||||
|
||||
@ -18,8 +18,11 @@
|
||||
|
||||
package com.cloud.configuration.dao;
|
||||
|
||||
import com.cloud.configuration.ResourceCountVO;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.configuration.ResourceCount.ResourceType;
|
||||
import com.cloud.configuration.ResourceCountVO;
|
||||
import com.cloud.configuration.ResourceLimit.OwnerType;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
||||
@ -55,15 +58,6 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
||||
* @param the count of resources in use for the given type and domain
|
||||
*/
|
||||
public void setDomainCount(long domainId, ResourceType type, long count);
|
||||
|
||||
/**
|
||||
* Update the count of resources in use for the given account and given resource type
|
||||
* @param accountId the id of the account to update resource count
|
||||
* @param type the type of resource (e.g. user_vm, public_ip, volume)
|
||||
* @param increment whether the change is adding or subtracting from the current count
|
||||
* @param delta the number of resources being added/released
|
||||
*/
|
||||
public void updateAccountCount(long accountId, ResourceType type, boolean increment, long delta);
|
||||
|
||||
/**
|
||||
* Update the count of resources in use for the given domain and given resource type
|
||||
@ -73,4 +67,17 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
|
||||
* @param delta the number of resources being added/released
|
||||
*/
|
||||
public void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta);
|
||||
|
||||
boolean updateById(long id, boolean increment, long delta);
|
||||
|
||||
ResourceCountVO findByDomainIdAndType(long domainId, ResourceType type);
|
||||
|
||||
ResourceCountVO findByAccountIdAndType(long accountId, ResourceType type);
|
||||
|
||||
Set<Long> listAllRowsToUpdateForAccount(long accountId, long domainId, ResourceType type);
|
||||
|
||||
Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
|
||||
|
||||
void createResourceCounts(long ownerId, OwnerType ownerType);
|
||||
|
||||
}
|
||||
|
||||
@ -18,18 +18,29 @@
|
||||
|
||||
package com.cloud.configuration.dao;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.configuration.ResourceCount.ResourceType;
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceCountVO;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.domain.dao.DomainDaoImpl;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
|
||||
@Local(value={ResourceCountDao.class})
|
||||
public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
|
||||
private SearchBuilder<ResourceCountVO> IdTypeSearch;
|
||||
private SearchBuilder<ResourceCountVO> DomainIdTypeSearch;
|
||||
|
||||
protected final DomainDaoImpl _domainDao = ComponentLocator.inject(DomainDaoImpl.class);
|
||||
|
||||
public ResourceCountDaoImpl() {
|
||||
IdTypeSearch = createSearchBuilder();
|
||||
@ -43,11 +54,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
||||
DomainIdTypeSearch.done();
|
||||
}
|
||||
|
||||
private ResourceCountVO findByAccountIdAndType(long accountId, ResourceType type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceCountVO findByAccountIdAndType(long accountId, ResourceType type) {
|
||||
SearchCriteria<ResourceCountVO> sc = IdTypeSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParameters("type", type);
|
||||
@ -55,11 +63,8 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
private ResourceCountVO findByDomainIdAndType(long domainId, ResourceType type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceCountVO findByDomainIdAndType(long domainId, ResourceType type) {
|
||||
SearchCriteria<ResourceCountVO> sc = DomainIdTypeSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
sc.setParameters("type", type);
|
||||
@ -70,59 +75,29 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
||||
@Override
|
||||
public long getAccountCount(long accountId, ResourceType type) {
|
||||
ResourceCountVO resourceCountVO = findByAccountIdAndType(accountId, type);
|
||||
return (resourceCountVO != null) ? resourceCountVO.getCount() : 0;
|
||||
return resourceCountVO.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainCount(long domainId, ResourceType type) {
|
||||
ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type);
|
||||
return (resourceCountVO != null) ? resourceCountVO.getCount() : 0;
|
||||
return resourceCountVO.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccountCount(long accountId, ResourceType type, long count) {
|
||||
ResourceCountVO resourceCountVO = findByAccountIdAndType(accountId, type);
|
||||
if (resourceCountVO == null) {
|
||||
if (count != 0) {
|
||||
resourceCountVO = new ResourceCountVO(accountId, null, type, count);
|
||||
persist(resourceCountVO);
|
||||
}
|
||||
} else {
|
||||
if (count != resourceCountVO.getCount()) {
|
||||
resourceCountVO.setCount(count);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
if (count != resourceCountVO.getCount()) {
|
||||
resourceCountVO.setCount(count);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainCount(long domainId, ResourceType type, long count) {
|
||||
ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type);
|
||||
if (resourceCountVO == null) {
|
||||
if (count != 0) {
|
||||
resourceCountVO = new ResourceCountVO(null, domainId, type, count);
|
||||
persist(resourceCountVO);
|
||||
}
|
||||
} else {
|
||||
if (count != resourceCountVO.getCount()) {
|
||||
resourceCountVO.setCount(count);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAccountCount(long accountId, ResourceType type, boolean increment, long delta) {
|
||||
delta = increment ? delta : delta * -1;
|
||||
|
||||
ResourceCountVO resourceCountVO = findByAccountIdAndType(accountId, type);
|
||||
|
||||
if (resourceCountVO == null) {
|
||||
resourceCountVO = new ResourceCountVO(accountId, null, type, 0);
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
persist(resourceCountVO);
|
||||
} else {
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
if (count != resourceCountVO.getCount()) {
|
||||
resourceCountVO.setCount(count);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
}
|
||||
@ -132,13 +107,63 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
|
||||
delta = increment ? delta : delta * -1;
|
||||
|
||||
ResourceCountVO resourceCountVO = findByDomainIdAndType(domainId, type);
|
||||
if (resourceCountVO == null) {
|
||||
resourceCountVO = new ResourceCountVO(null, domainId, type, 0);
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
persist(resourceCountVO);
|
||||
} else {
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateById(long id, boolean increment, long delta) {
|
||||
delta = increment ? delta : delta * -1;
|
||||
|
||||
ResourceCountVO resourceCountVO = findById(id);
|
||||
resourceCountVO.setCount(resourceCountVO.getCount() + delta);
|
||||
return update(resourceCountVO.getId(), resourceCountVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> listAllRowsToUpdateForAccount(long accountId, long domainId, ResourceType type) {
|
||||
Set<Long> rowIds = new HashSet<Long>();
|
||||
//Create resource count records if not exist
|
||||
//1) for account
|
||||
ResourceCountVO accountCountRecord = findByAccountIdAndType(accountId, type);
|
||||
rowIds.add(accountCountRecord.getId());
|
||||
|
||||
//2) for domain(s)
|
||||
rowIds.addAll(listRowsToUpdateForDomain(domainId, type));
|
||||
|
||||
return rowIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type) {
|
||||
Set<Long> rowIds = new HashSet<Long>();
|
||||
Set<Long> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
|
||||
for (Long domainIdToUpdate : domainIdsToUpdate) {
|
||||
ResourceCountVO domainCountRecord = findByDomainIdAndType(domainIdToUpdate, type);
|
||||
rowIds.add(domainCountRecord.getId());
|
||||
}
|
||||
return rowIds;
|
||||
}
|
||||
|
||||
@Override @DB
|
||||
public void createResourceCounts(long ownerId, ResourceLimit.OwnerType ownerType){
|
||||
Long accountId = null;
|
||||
Long domainId = null;
|
||||
if (ownerType == ResourceLimit.OwnerType.Account) {
|
||||
accountId = ownerId;
|
||||
} else if (ownerType == ResourceLimit.OwnerType.Domain) {
|
||||
domainId = ownerId;
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
|
||||
for (ResourceType resourceType : resourceTypes) {
|
||||
ResourceCountVO resourceCountVO = new ResourceCountVO(accountId, domainId, resourceType, 0);
|
||||
persist(resourceCountVO);
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ package com.cloud.configuration.dao;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimit.OwnerType;
|
||||
import com.cloud.configuration.ResourceLimitVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
@ -32,4 +33,5 @@ public interface ResourceLimitDao extends GenericDao<ResourceLimitVO, Long> {
|
||||
public List<ResourceLimitVO> listByDomainId(Long domainId);
|
||||
public boolean update(Long id, Long max);
|
||||
public ResourceCount.ResourceType getLimitType(String type);
|
||||
public ResourceLimitVO findByOwnerIdAndType(long ownerId, OwnerType ownerType, ResourceCount.ResourceType type);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.List;
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimit.OwnerType;
|
||||
import com.cloud.configuration.ResourceLimitVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
@ -99,7 +100,17 @@ public class ResourceLimitDaoImpl extends GenericDaoBase<ResourceLimitVO, Long>
|
||||
return validType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLimitVO findByOwnerIdAndType(long ownerId, OwnerType ownerType, ResourceCount.ResourceType type) {
|
||||
if (ownerType == OwnerType.Account) {
|
||||
return findByAccountIdAndType(ownerId, type);
|
||||
} else if (ownerType == OwnerType.Domain) {
|
||||
return findByDomainIdAndType(ownerId, type);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,12 @@ public class DomainVO implements Domain {
|
||||
@Column(name="network_domain")
|
||||
private String networkDomain;
|
||||
|
||||
public DomainVO() {}
|
||||
public DomainVO() {}
|
||||
|
||||
public DomainVO(long id, String name, long owner, Long parentId, String networkDomain) {
|
||||
this(name, owner, parentId, networkDomain);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public DomainVO(String name, long owner, Long parentId, String networkDomain) {
|
||||
this.parent = parentId;
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
package com.cloud.domain.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
@ -30,5 +31,6 @@ public interface DomainDao extends GenericDao<DomainVO, Long> {
|
||||
DomainVO findImmediateChildForParent(Long parentId);
|
||||
List<DomainVO> findImmediateChildrenForParent(Long parentId);
|
||||
List<DomainVO> findAllChildren(String path, Long parentId);
|
||||
List<DomainVO> findInactiveDomains();
|
||||
List<DomainVO> findInactiveDomains();
|
||||
Set<Long> getDomainParentIds(long domainId);
|
||||
}
|
||||
|
||||
@ -21,7 +21,9 @@ package com.cloud.domain.dao;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
@ -255,5 +257,19 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
|
||||
SearchCriteria<DomainVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("state", Domain.State.Inactive);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getDomainParentIds(long domainId) {
|
||||
Set<Long> parentDomains = new HashSet<Long>();
|
||||
Domain domain = findById(domainId);
|
||||
parentDomains.add(domain.getId());
|
||||
|
||||
while (domain.getParent() != null) {
|
||||
domain = findById(domain.getParent());
|
||||
parentDomains.add(domain.getId());
|
||||
}
|
||||
|
||||
return parentDomains;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2234,9 +2234,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
disconnectedRouters.add(router);
|
||||
}
|
||||
|
||||
//If rules fail to apply on one domR, no need to proceed with the rest
|
||||
//If ip fails to apply on one domR, no need to proceed with the rest
|
||||
if (!result) {
|
||||
throw new ResourceUnavailableException("Unable to apply firewall rules on router ", VirtualRouter.class, router.getId());
|
||||
throw new ResourceUnavailableException("Unable to associate ip addresses on router ", VirtualRouter.class, router.getId());
|
||||
}
|
||||
|
||||
} else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
|
||||
|
||||
@ -47,7 +47,9 @@ import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationVO;
|
||||
import com.cloud.configuration.ResourceLimit.OwnerType;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.configuration.dao.ResourceCountDao;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
@ -55,6 +57,8 @@ import com.cloud.dc.VlanVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.InternalErrorException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network.GuestIpType;
|
||||
@ -78,7 +82,11 @@ import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.test.IPRangeConfig;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.PasswordGenerator;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
@ -101,6 +109,10 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
private final NetworkDao _networkDao;
|
||||
private final VlanDao _vlanDao;
|
||||
private String _domainSuffix;
|
||||
private final ResourceCountDao _resourceCountDao;
|
||||
private final AccountDao _accountDao;
|
||||
private final UserDao _userDao;
|
||||
private final DomainDao _domainDao;
|
||||
|
||||
|
||||
public ConfigurationServerImpl() {
|
||||
@ -114,14 +126,15 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
_dataCenterDao = locator.getDao(DataCenterDao.class);
|
||||
_networkDao = locator.getDao(NetworkDao.class);
|
||||
_vlanDao = locator.getDao(VlanDao.class);
|
||||
_resourceCountDao = locator.getDao(ResourceCountDao.class);
|
||||
_accountDao = locator.getDao(AccountDao.class);
|
||||
_userDao = locator.getDao(UserDao.class);
|
||||
_domainDao = locator.getDao(DomainDao.class);
|
||||
}
|
||||
|
||||
@Override @DB
|
||||
public void persistDefaultValues() throws InternalErrorException {
|
||||
|
||||
// Create system user and admin user
|
||||
saveUser();
|
||||
|
||||
|
||||
// Get init
|
||||
String init = _configDao.getValue("init");
|
||||
|
||||
@ -131,6 +144,14 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
if (init == null || init.equals("false")) {
|
||||
s_logger.debug("ConfigurationServer is saving default values to the database.");
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
// Create ROOT domain
|
||||
saveRootDomain();
|
||||
|
||||
// Create system user and admin user
|
||||
saveUser();
|
||||
|
||||
// Save default Configuration Table values
|
||||
List<String> categories = Config.getCategories();
|
||||
for (String category : categories) {
|
||||
@ -199,11 +220,9 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
//Create default networks
|
||||
createDefaultNetworks();
|
||||
|
||||
//Create userIpAddress ranges
|
||||
|
||||
|
||||
//Update existing vlans with networkId
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
||||
|
||||
List<VlanVO> vlans = _vlanDao.listAll();
|
||||
if (vlans != null && !vlans.isEmpty()) {
|
||||
@ -218,14 +237,17 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
String startIp = range[0];
|
||||
String endIp = range[1];
|
||||
|
||||
txn.start();
|
||||
|
||||
IPRangeConfig config = new IPRangeConfig();
|
||||
long startIPLong = NetUtils.ip2Long(startIp);
|
||||
long endIPLong = NetUtils.ip2Long(endIp);
|
||||
config.savePublicIPRange(txn, startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId());
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
// Set init to true
|
||||
_configDao.update("init", "true");
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
// keystore for SSL/TLS connection
|
||||
@ -240,8 +262,6 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
// Update the cloud identifier
|
||||
updateCloudIdentifier();
|
||||
|
||||
// Set init to true
|
||||
_configDao.update("init", "true");
|
||||
}
|
||||
|
||||
|
||||
@ -273,27 +293,24 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
// insert system account
|
||||
String insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (1, 'system', '1', '1')";
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
// insert system user
|
||||
insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) VALUES (1, 'system', '', 1, 'system', 'cloud', now())";
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
|
||||
// insert admin user
|
||||
long id = 2;
|
||||
String username = "admin";
|
||||
String firstname = "admin";
|
||||
String lastname = "cloud";
|
||||
String password = "password";
|
||||
txn.start();
|
||||
|
||||
//Create system/admin accounts
|
||||
AccountVO systemAccount = new AccountVO(1);
|
||||
systemAccount.setAccountName("system");
|
||||
systemAccount.setType(Account.ACCOUNT_TYPE_ADMIN);;
|
||||
systemAccount.setDomainId(1);
|
||||
systemAccount.setState(Account.State.enabled);
|
||||
_accountDao.persist(systemAccount);
|
||||
|
||||
AccountVO adminAccount = new AccountVO(1);
|
||||
adminAccount.setAccountName("admin");
|
||||
adminAccount.setType(Account.ACCOUNT_TYPE_ADMIN);;
|
||||
adminAccount.setDomainId(1);
|
||||
adminAccount.setState(Account.State.enabled);
|
||||
_accountDao.persist(adminAccount);
|
||||
|
||||
//Create system/admin users
|
||||
MessageDigest md5 = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
@ -301,6 +318,7 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
return;
|
||||
}
|
||||
|
||||
String password = "password";
|
||||
md5.reset();
|
||||
BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
|
||||
String pwStr = pwInt.toString(16);
|
||||
@ -310,29 +328,36 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
sb.append('0'); // make sure the MD5 password is 32 digits long
|
||||
}
|
||||
sb.append(pwStr);
|
||||
|
||||
// create an account for the admin user first
|
||||
insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (" + id + ", '" + username + "', '1', '1')";
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
|
||||
// now insert the user
|
||||
insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) " +
|
||||
"VALUES (" + id + ",'" + username + "','" + sb.toString() + "', 2, '" + firstname + "','" + lastname + "',now())";
|
||||
password = sb.toString();
|
||||
|
||||
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
UserVO systemUser = new UserVO(1);
|
||||
systemUser.setUsername("system");
|
||||
systemUser.setPassword("");
|
||||
systemUser.setAccountId(1);
|
||||
systemUser.setFirstname("system");
|
||||
systemUser.setLastname("system");
|
||||
systemUser.setState(Account.State.enabled);
|
||||
_userDao.persist(systemUser);
|
||||
|
||||
|
||||
|
||||
UserVO adminUser = new UserVO(2);
|
||||
adminUser.setUsername("admin");
|
||||
adminUser.setPassword(password);
|
||||
adminUser.setAccountId(2);
|
||||
adminUser.setFirstname("admin");
|
||||
adminUser.setLastname("cloud");
|
||||
adminUser.setState(Account.State.enabled);
|
||||
_userDao.persist(adminUser);
|
||||
|
||||
|
||||
//create resource counts
|
||||
try {
|
||||
_resourceCountDao.createResourceCounts(1, OwnerType.Account);
|
||||
_resourceCountDao.createResourceCounts(2, OwnerType.Account);
|
||||
} catch (Exception ex) {
|
||||
// if exception happens, it might mean that resource counts are already created by another management server being started in the cluster
|
||||
s_logger.warn("Failed to create initial resource counts for system/admin accounts");
|
||||
}
|
||||
|
||||
try {
|
||||
String tableName = "security_group";
|
||||
@ -358,7 +383,6 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
"VALUES ('default', 'Default Security Group', 2, 1, 'admin')";
|
||||
}
|
||||
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
@ -369,6 +393,8 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
rs.close();
|
||||
} catch (Exception ex) {
|
||||
s_logger.warn("Failed to create default security group for default admin account due to ", ex);
|
||||
} finally {
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,7 +928,7 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void updateVlanWithNetworkId(VlanVO vlan) {
|
||||
long zoneId = vlan.getDataCenterId();
|
||||
long networkId = 0L;
|
||||
@ -939,5 +965,19 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
||||
}
|
||||
return networks.get(0).getId();
|
||||
}
|
||||
|
||||
@DB
|
||||
public void saveRootDomain() {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
DomainVO domain = new DomainVO(1, "ROOT", 2, null, null);
|
||||
domain.setPath("/");
|
||||
domain.setLevel(0);
|
||||
_domainDao.persist(domain);
|
||||
_resourceCountDao.createResourceCounts(1, OwnerType.Domain);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ import com.cloud.alert.AlertVO;
|
||||
import com.cloud.alert.dao.AlertDao;
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.commands.CreateDomainCmd;
|
||||
import com.cloud.api.commands.CreateSSHKeyPairCmd;
|
||||
import com.cloud.api.commands.DeleteDomainCmd;
|
||||
import com.cloud.api.commands.DeleteSSHKeyPairCmd;
|
||||
@ -2968,59 +2967,6 @@ public class ManagementServerImpl implements ManagementServer {
|
||||
return _domainDao.search(sc, searchFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_DOMAIN_CREATE, eventDescription = "creating Domain")
|
||||
public DomainVO createDomain(CreateDomainCmd cmd) {
|
||||
String name = cmd.getDomainName();
|
||||
Long parentId = cmd.getParentDomainId();
|
||||
Long ownerId = UserContext.current().getCaller().getId();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
String networkDomain = cmd.getNetworkDomain();
|
||||
|
||||
if (ownerId == null) {
|
||||
ownerId = Long.valueOf(1);
|
||||
}
|
||||
|
||||
if (parentId == null) {
|
||||
parentId = Long.valueOf(DomainVO.ROOT_DOMAIN);
|
||||
}
|
||||
|
||||
DomainVO parentDomain = _domainDao.findById(parentId);
|
||||
if (parentDomain == null) {
|
||||
throw new InvalidParameterValueException("Unable to create domain " + name + ", parent domain " + parentId + " not found.");
|
||||
}
|
||||
|
||||
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(
|
||||
"Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
|
||||
+ "and the hyphen ('-'); can't start or end with \"-\"");
|
||||
}
|
||||
}
|
||||
|
||||
SearchCriteria<DomainVO> sc = _domainDao.createSearchCriteria();
|
||||
sc.addAnd("name", SearchCriteria.Op.EQ, name);
|
||||
sc.addAnd("parent", SearchCriteria.Op.EQ, parentId);
|
||||
List<DomainVO> domains = _domainDao.search(sc, null);
|
||||
if ((domains == null) || domains.isEmpty()) {
|
||||
DomainVO domain = new DomainVO(name, ownerId, parentId, networkDomain);
|
||||
try {
|
||||
return _domainDao.create(domain);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
s_logger.warn("Failed to create domain ", ex);
|
||||
throw ex;
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_DOMAIN_DELETE, eventDescription = "deleting Domain", async = true)
|
||||
public boolean deleteDomain(DeleteDomainCmd cmd) {
|
||||
|
||||
@ -1068,7 +1068,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
||||
}
|
||||
|
||||
// Verify that max doesn't exceed domain and account snapshot limits
|
||||
long accountLimit = _accountMgr.findCorrectResourceLimit(owner, ResourceType.snapshot);
|
||||
long accountLimit = _accountMgr.findCorrectResourceLimit(owner.getId(), ResourceType.snapshot);
|
||||
long domainLimit = _accountMgr.findCorrectResourceLimit(domain, ResourceType.snapshot);
|
||||
int max = cmd.getMaxSnaps().intValue();
|
||||
if (owner.getType() != Account.ACCOUNT_TYPE_ADMIN && ((accountLimit != -1 && max > accountLimit) || (domainLimit != -1 && max > domainLimit))) {
|
||||
|
||||
@ -20,10 +20,7 @@ package com.cloud.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -410,7 +407,6 @@ public class DatabaseConfig {
|
||||
|
||||
// Save default values for configuration fields
|
||||
saveVMTemplate();
|
||||
saveRootDomain();
|
||||
saveDefaultConfiguations();
|
||||
|
||||
txn.commit();
|
||||
@ -439,8 +435,6 @@ public class DatabaseConfig {
|
||||
saveServiceOffering();
|
||||
} else if ("diskOffering".equals(_currentObjectName)) {
|
||||
saveDiskOffering();
|
||||
} else if ("user".equals(_currentObjectName)) {
|
||||
saveUser();
|
||||
} else if ("configuration".equals(_currentObjectName)) {
|
||||
saveConfiguration();
|
||||
} else if ("storagePool".equals(_currentObjectName)) {
|
||||
@ -965,80 +959,6 @@ public class DatabaseConfig {
|
||||
*/
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void saveUser() {
|
||||
// insert system account
|
||||
String insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (1, 'system', '1', '1')";
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error creating system account", ex);
|
||||
}
|
||||
|
||||
// insert system user
|
||||
insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) VALUES (1, 'system', '', 1, 'system', 'cloud', now())";
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error creating system user", ex);
|
||||
}
|
||||
|
||||
// insert admin user
|
||||
long id = Long.parseLong(_currentObjectParams.get("id"));
|
||||
String username = _currentObjectParams.get("username");
|
||||
String firstname = _currentObjectParams.get("firstname");
|
||||
String lastname = _currentObjectParams.get("lastname");
|
||||
String password = _currentObjectParams.get("password");
|
||||
String email = _currentObjectParams.get("email");
|
||||
|
||||
if (email == null || email.equals("")) {
|
||||
printError("An email address for each user is required.");
|
||||
}
|
||||
|
||||
MessageDigest md5 = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
s_logger.error("error saving user", e);
|
||||
return;
|
||||
}
|
||||
md5.reset();
|
||||
BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
|
||||
String pwStr = pwInt.toString(16);
|
||||
int padding = 32 - pwStr.length();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < padding; i++) {
|
||||
sb.append('0'); // make sure the MD5 password is 32 digits long
|
||||
}
|
||||
sb.append(pwStr);
|
||||
|
||||
// create an account for the admin user first
|
||||
insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (" + id + ", '" + username + "', '1', '1')";
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error creating account", ex);
|
||||
}
|
||||
|
||||
// now insert the user
|
||||
insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, email, created) " +
|
||||
"VALUES (" + id + ",'" + username + "','" + sb.toString() + "', 2, '" + firstname + "','" + lastname + "','" + email + "',now())";
|
||||
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error creating user", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDefaultConfiguations() {
|
||||
for (String name : s_defaultConfigurationValues.keySet()) {
|
||||
String value = s_defaultConfigurationValues.get(name);
|
||||
@ -1126,42 +1046,6 @@ public class DatabaseConfig {
|
||||
return true;
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void saveRootDomain() {
|
||||
String insertSql = "insert into `cloud`.`domain` (id, name, parent, owner, path, level) values (1, 'ROOT', NULL, 2, '/', 0)";
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error creating ROOT domain", ex);
|
||||
}
|
||||
|
||||
/*
|
||||
String updateSql = "update account set domain_id = 1 where id = 2";
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareStatement(updateSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error updating admin user", ex);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
updateSql = "update account set domain_id = 1 where id = 1";
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
PreparedStatement stmt = txn.prepareStatement(updateSql);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
s_logger.error("error updating system user", ex);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
class DbConfigXMLHandler extends DefaultHandler {
|
||||
private DatabaseConfig _parent = null;
|
||||
|
||||
|
||||
@ -19,9 +19,16 @@ package com.cloud.upgrade.dao;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceCount.ResourceType;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
@ -55,11 +62,78 @@ public class Upgrade2211to2212 implements DbUpgrade {
|
||||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
createResourceCount(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] getCleanupScripts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void createResourceCount(Connection conn) {
|
||||
s_logger.debug("Creating missing resource_count records as a part of 2.2.11-2.2.12 upgrade");
|
||||
try {
|
||||
|
||||
//Get all non removed accounts
|
||||
List<Long> accounts = new ArrayList<Long>();
|
||||
PreparedStatement pstmt = conn.prepareStatement("SELECT id FROM account");
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
accounts.add(rs.getLong(1));
|
||||
}
|
||||
rs.close();
|
||||
|
||||
|
||||
//get all non removed domains
|
||||
List<Long> domains = new ArrayList<Long>();
|
||||
pstmt = conn.prepareStatement("SELECT id FROM domain");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
domains.add(rs.getLong(1));
|
||||
}
|
||||
rs.close();
|
||||
|
||||
for (Long accountId : accounts) {
|
||||
ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
|
||||
for (ResourceType resourceType : resourceTypes) {
|
||||
pstmt = conn.prepareStatement("SELECT * FROM resource_count WHERE type=? and account_id=?");
|
||||
pstmt.setString(1, resourceType.toString());
|
||||
pstmt.setLong(2, accountId);
|
||||
rs = pstmt.executeQuery();
|
||||
if (!rs.next()) {
|
||||
s_logger.debug("Inserting resource_count record of type " + resourceType + " for account id=" + accountId);
|
||||
pstmt = conn.prepareStatement("INSERT INTO resource_count (account_id, domain_id, type, count) VALUES (?, null, ?, 0)");
|
||||
pstmt.setLong(1, accountId);
|
||||
pstmt.setString(2, resourceType.toString());
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
pstmt.close();
|
||||
}
|
||||
|
||||
for (Long domainId : domains) {
|
||||
ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
|
||||
for (ResourceType resourceType : resourceTypes) {
|
||||
pstmt = conn.prepareStatement("SELECT * FROM resource_count WHERE type=? and domain_id=?");
|
||||
pstmt.setString(1, resourceType.toString());
|
||||
pstmt.setLong(2, domainId);
|
||||
rs = pstmt.executeQuery();
|
||||
if (!rs.next()) {
|
||||
s_logger.debug("Inserting resource_count record of type " + resourceType + " for domain id=" + domainId);
|
||||
pstmt = conn.prepareStatement("INSERT INTO resource_count (account_id, domain_id, type, count) VALUES (null, ?, ?, 0)");
|
||||
pstmt.setLong(1, domainId);
|
||||
pstmt.setString(2, resourceType.toString());
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to create default security groups for existing accounts due to", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -49,11 +49,11 @@ public interface AccountManager extends AccountService {
|
||||
/**
|
||||
* Finds the resource limit for a specified account and type. If the account has an infinite limit, will check
|
||||
* the account's parent domain, and if that limit is also infinite, will return the ROOT domain's limit.
|
||||
* @param account
|
||||
* @param accountId
|
||||
* @param type
|
||||
* @return resource limit
|
||||
*/
|
||||
public long findCorrectResourceLimit(AccountVO account, ResourceType type);
|
||||
public long findCorrectResourceLimit(long accountId, ResourceType type);
|
||||
|
||||
/**
|
||||
* Finds the resource limit for a specified domain and type. If the domain has an infinite limit, will check
|
||||
|
||||
@ -38,8 +38,10 @@ import org.apache.log4j.Logger;
|
||||
import com.cloud.acl.ControlledEntity;
|
||||
import com.cloud.acl.SecurityChecker;
|
||||
import com.cloud.acl.SecurityChecker.AccessType;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.commands.CreateAccountCmd;
|
||||
import com.cloud.api.commands.CreateDomainCmd;
|
||||
import com.cloud.api.commands.CreateUserCmd;
|
||||
import com.cloud.api.commands.DeleteAccountCmd;
|
||||
import com.cloud.api.commands.DeleteUserCmd;
|
||||
@ -57,6 +59,7 @@ import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.ResourceCount.ResourceType;
|
||||
import com.cloud.configuration.ResourceCountVO;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.configuration.ResourceLimitVO;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.configuration.dao.ResourceCountDao;
|
||||
@ -68,7 +71,6 @@ import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -183,8 +185,6 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
@Inject
|
||||
private VirtualMachineManager _itMgr;
|
||||
@Inject
|
||||
private UsageEventDao _usageEventDao;
|
||||
@Inject
|
||||
private RemoteAccessVpnDao _remoteAccessVpnDao;
|
||||
@Inject
|
||||
private RemoteAccessVpnService _remoteAccessVpnMgr;
|
||||
@ -192,10 +192,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
private VpnUserDao _vpnUser;
|
||||
@Inject
|
||||
private DataCenterDao _dcDao;
|
||||
@Inject
|
||||
private AlertManager _alertMgr;
|
||||
|
||||
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
|
||||
|
||||
private final GlobalLock m_resourceCountLock = GlobalLock.getInternLock("resource.count");
|
||||
|
||||
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
|
||||
|
||||
UserVO _systemUser;
|
||||
AccountVO _systemAccount;
|
||||
@ -223,6 +225,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
|
||||
String value = configs.get(Config.AccountCleanupInterval.key());
|
||||
_cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 hour.
|
||||
|
||||
ResourceCountSearch = _resourceCountDao.createSearchBuilder();
|
||||
ResourceCountSearch.and("id", ResourceCountSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
ResourceCountSearch.and("accountId", ResourceCountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
ResourceCountSearch.done();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -252,57 +260,27 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
public void incrementResourceCount(long accountId, ResourceType type, Long... delta) {
|
||||
long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue();
|
||||
|
||||
if (m_resourceCountLock.lock(120)) { // 2 minutes
|
||||
try {
|
||||
_resourceCountDao.updateAccountCount(accountId, type, true, numToIncrement);
|
||||
|
||||
// on a per-domain basis, increment the count
|
||||
// FIXME: can this increment be done on the database side in a custom update statement?
|
||||
Account account = _accountDao.findByIdIncludingRemoved(accountId);
|
||||
Long domainId = account.getDomainId();
|
||||
while (domainId != null) {
|
||||
_resourceCountDao.updateDomainCount(domainId, type, true, numToIncrement);
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
domainId = domain.getParent();
|
||||
}
|
||||
} finally {
|
||||
m_resourceCountLock.unlock();
|
||||
}
|
||||
if (!updateResourceCount(accountId, type, true, numToIncrement)) {
|
||||
//we should fail the operation (resource creation) when failed to update the resource count
|
||||
throw new CloudRuntimeException("Failed to increment resource count of type " + type + " for account id=" + accountId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementResourceCount(long accountId, ResourceType type, Long... delta) {
|
||||
long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue();
|
||||
|
||||
if (m_resourceCountLock.lock(120)) { // 2 minutes
|
||||
try {
|
||||
assert ((_resourceCountDao.getAccountCount(accountId, type) - numToDecrement) >= 0) : "Resource counts can not be negative. Check where we skipped increment.";
|
||||
_resourceCountDao.updateAccountCount(accountId, type, false, numToDecrement);
|
||||
|
||||
// on a per-domain basis, decrement the count
|
||||
// FIXME: can this decrement be done on the database side in a custom update statement?
|
||||
Account account = _accountDao.findByIdIncludingRemoved(accountId); // find all accounts, even removed accounts
|
||||
// if this happens to be for an account
|
||||
// that's being deleted
|
||||
Long domainId = account.getDomainId();
|
||||
while (domainId != null) {
|
||||
assert ((_resourceCountDao.getDomainCount(domainId, type) - numToDecrement) >= 0) : "Resource counts can not be negative. Check where we skipped increment.";
|
||||
_resourceCountDao.updateDomainCount(domainId, type, false, numToDecrement);
|
||||
DomainVO domain = _domainDao.findByIdIncludingRemoved(domainId);
|
||||
domainId = domain.getParent();
|
||||
}
|
||||
} finally {
|
||||
m_resourceCountLock.unlock();
|
||||
}
|
||||
|
||||
if (!updateResourceCount(accountId, type, false, numToDecrement)) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId,
|
||||
"Failed to decrement resource count of type " + type + " for account id=" + accountId + "; use updateResourceCount API to recalculate/fix the problem");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long findCorrectResourceLimit(AccountVO account, ResourceType type) {
|
||||
public long findCorrectResourceLimit(long accountId, ResourceType type) {
|
||||
long max = -1;
|
||||
|
||||
ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(account.getId(), type);
|
||||
ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(accountId, type);
|
||||
|
||||
// Check if limit is configured for account
|
||||
if (limit != null) {
|
||||
@ -361,46 +339,49 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @DB
|
||||
public boolean resourceLimitExceeded(Account account, ResourceType type, long... count) {
|
||||
long numResources = ((count.length == 0) ? 1 : count[0]);
|
||||
|
||||
// Don't place any limits on system or admin accounts
|
||||
long accountType = account.getType();
|
||||
if (accountType == Account.ACCOUNT_TYPE_ADMIN || accountType == Account.ACCOUNT_ID_SYSTEM) {
|
||||
if (isAdmin(account.getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
try {
|
||||
//Lock all rows first so nobody else can read it
|
||||
Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdateForAccount(account.getId(), account.getDomainId(), type);
|
||||
SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
|
||||
sc.setParameters("id", rowIdsToLock.toArray());
|
||||
_resourceCountDao.lockRows(sc, null, true);
|
||||
|
||||
if (m_resourceCountLock.lock(120)) { // 2 minutes
|
||||
try {
|
||||
// Check account limits
|
||||
AccountVO accountVo = _accountDao.findById(account.getAccountId());
|
||||
long accountLimit = findCorrectResourceLimit(accountVo, type);
|
||||
long potentialCount = _resourceCountDao.getAccountCount(account.getId(), type) + numResources;
|
||||
if (accountLimit != -1 && potentialCount > accountLimit) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check all domains in the account's domain hierarchy
|
||||
Long domainId = account.getDomainId();
|
||||
while (domainId != null) {
|
||||
ResourceLimitVO domainLimit = _resourceLimitDao.findByDomainIdAndType(domainId, type);
|
||||
if (domainLimit != null) {
|
||||
long domainCount = _resourceCountDao.getDomainCount(domainId, type);
|
||||
if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
domainId = domain.getParent();
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
m_resourceCountLock.unlock();
|
||||
// Check account limits
|
||||
long accountLimit = findCorrectResourceLimit(account.getId(), type);
|
||||
long potentialCount = _resourceCountDao.getAccountCount(account.getId(), type) + numResources;
|
||||
if (potentialCount > accountLimit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
// check all domains in the account's domain hierarchy
|
||||
Long domainId = account.getDomainId();
|
||||
while (domainId != null) {
|
||||
ResourceLimitVO domainLimit = _resourceLimitDao.findByDomainIdAndType(domainId, type);
|
||||
if (domainLimit != null) {
|
||||
long domainCount = _resourceCountDao.getDomainCount(domainId, type);
|
||||
if ((domainCount + numResources) > domainLimit.getMax().longValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
domainId = domain.getParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -487,7 +468,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
}
|
||||
} else {
|
||||
AccountVO account = _accountDao.findById(accountId);
|
||||
limits.add(new ResourceLimitVO(null, accountId, type, findCorrectResourceLimit(account, type)));
|
||||
limits.add(new ResourceLimitVO(null, accountId, type, findCorrectResourceLimit(account.getId(), type)));
|
||||
}
|
||||
} else if (domainId != null) {
|
||||
if (type == null) {
|
||||
@ -745,69 +726,80 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @DB
|
||||
public long updateAccountResourceCount(long accountId, ResourceType type) {
|
||||
Long count=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
|
||||
if (m_resourceCountLock.lock(120)) { // 2 minutes
|
||||
try {
|
||||
switch (type) {
|
||||
case user_vm:
|
||||
count = _userVmDao.countAllocatedVMsForAccount(accountId);
|
||||
break;
|
||||
case volume:
|
||||
count = _volumeDao.countAllocatedVolumesForAccount(accountId);
|
||||
long virtualRouterCount = _vmDao.countAllocatedVirtualRoutersForAccount(accountId);
|
||||
count = count - virtualRouterCount; // don't count the volumes of virtual router
|
||||
break;
|
||||
case snapshot:
|
||||
count = _snapshotDao.countSnapshotsForAccount(accountId);
|
||||
break;
|
||||
case public_ip:
|
||||
count = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
||||
break;
|
||||
case template:
|
||||
count = _vmTemplateDao.countTemplatesForAccount(accountId);
|
||||
break;
|
||||
}
|
||||
_resourceCountDao.setAccountCount(accountId, type, (count == null) ? 0 : count.longValue());
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to update resource count for account with Id" + accountId);
|
||||
} finally {
|
||||
m_resourceCountLock.unlock();
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
try {
|
||||
// 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);
|
||||
|
||||
switch (type) {
|
||||
case user_vm:
|
||||
count = _userVmDao.countAllocatedVMsForAccount(accountId);
|
||||
break;
|
||||
case volume:
|
||||
count = _volumeDao.countAllocatedVolumesForAccount(accountId);
|
||||
long virtualRouterCount = _vmDao.countAllocatedVirtualRoutersForAccount(accountId);
|
||||
count = count - virtualRouterCount; // don't count the volumes of virtual router
|
||||
break;
|
||||
case snapshot:
|
||||
count = _snapshotDao.countSnapshotsForAccount(accountId);
|
||||
break;
|
||||
case public_ip:
|
||||
count = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
||||
break;
|
||||
case template:
|
||||
count = _vmTemplateDao.countTemplatesForAccount(accountId);
|
||||
break;
|
||||
}
|
||||
_resourceCountDao.setAccountCount(accountId, type, (count == null) ? 0 : count.longValue());
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to update resource count for account with Id" + accountId);
|
||||
} finally {
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
return (count==null)?0:count.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @DB
|
||||
public long updateDomainResourceCount(long domainId, ResourceType type) {
|
||||
long count=0;
|
||||
|
||||
if (m_resourceCountLock.lock(120)) { // 2 minutes
|
||||
try {
|
||||
List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
|
||||
// for each child domain update the resource count
|
||||
for (DomainVO domainChild : domainChildren) {
|
||||
long domainCount = updateDomainResourceCount(domainChild.getId(), type);
|
||||
count = count + domainCount; // add the child domain count to parent domain count
|
||||
}
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
try {
|
||||
//Lock all rows first so nobody else can read it
|
||||
Set<Long> rowIdsToLock = _resourceCountDao.listRowsToUpdateForDomain(domainId, type);
|
||||
SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
|
||||
sc.setParameters("id", rowIdsToLock.toArray());
|
||||
_resourceCountDao.lockRows(sc, null, true);
|
||||
|
||||
List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
|
||||
// for each child domain update the resource count
|
||||
for (DomainVO domainChild : domainChildren) {
|
||||
long domainCount = updateDomainResourceCount(domainChild.getId(), type);
|
||||
count = count + domainCount; // add the child domain count to parent domain count
|
||||
}
|
||||
|
||||
List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
|
||||
for (AccountVO account : accounts) {
|
||||
long accountCount = updateAccountResourceCount(account.getId(), type);
|
||||
count = count + accountCount; // add account's resource count to parent domain count
|
||||
}
|
||||
List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
|
||||
for (AccountVO account : accounts) {
|
||||
long accountCount = updateAccountResourceCount(account.getId(), type);
|
||||
count = count + accountCount; // add account's resource count to parent domain count
|
||||
}
|
||||
|
||||
_resourceCountDao.setDomainCount(domainId, type, count);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId);
|
||||
} finally {
|
||||
m_resourceCountLock.unlock();
|
||||
}
|
||||
_resourceCountDao.setDomainCount(domainId, type, count);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to update resource count for domain with Id " + domainId);
|
||||
} finally {
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -1274,7 +1266,11 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
+ "and the hyphen ('-'); can't start or end with \"-\"");
|
||||
}
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
//Create account itself
|
||||
if (accountId == null) {
|
||||
if ((userType < Account.ACCOUNT_TYPE_NORMAL) || (userType > Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)) {
|
||||
throw new InvalidParameterValueException("Invalid account type " + userType + " given; unable to create user");
|
||||
@ -1330,10 +1326,15 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
s_logger.debug("Creating user: " + username + ", account: " + accountName + " (id:" + accountId + "), domain: " + domainId + " timezone:" + timezone);
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
//Create resource count records for the account
|
||||
_resourceCountDao.createResourceCounts(accountId, ResourceLimit.OwnerType.Account);
|
||||
|
||||
//Create a user
|
||||
UserVO dbUser = _userDao.persist(user);
|
||||
|
||||
//Create default security group
|
||||
_networkGroupMgr.createDefaultSecurityGroup(accountId);
|
||||
|
||||
txn.commit();
|
||||
|
||||
if (!user.getPassword().equals(dbUser.getPassword())) {
|
||||
@ -2034,16 +2035,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
|
||||
@Override
|
||||
public Set<Long> getDomainParentIds(long domainId) {
|
||||
Set<Long> parentDomains = new HashSet<Long>();
|
||||
Domain domain = _domainDao.findById(domainId);
|
||||
parentDomains.add(domain.getId());
|
||||
|
||||
while (domain.getParent() != null) {
|
||||
domain = _domainDao.findById(domain.getParent());
|
||||
parentDomains.add(domain.getId());
|
||||
}
|
||||
|
||||
return parentDomains;
|
||||
return _domainDao.getDomainParentIds(domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2060,4 +2052,94 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
||||
|
||||
return childDomains;
|
||||
}
|
||||
|
||||
@DB
|
||||
public boolean updateResourceCount(long accountId, ResourceType type, boolean increment, long delta) {
|
||||
boolean result = true;
|
||||
try {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
Set<Long> rowsToLock = _resourceCountDao.listAllRowsToUpdateForAccount(accountId, getAccount(accountId).getDomainId(), 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;
|
||||
}
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Failed to update resource count for account id=" + accountId);
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_DOMAIN_CREATE, eventDescription = "creating Domain")
|
||||
@DB
|
||||
public Domain createDomain(CreateDomainCmd cmd) {
|
||||
String name = cmd.getDomainName();
|
||||
Long parentId = cmd.getParentDomainId();
|
||||
Long ownerId = UserContext.current().getCaller().getId();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
String networkDomain = cmd.getNetworkDomain();
|
||||
|
||||
if (ownerId == null) {
|
||||
ownerId = Long.valueOf(1);
|
||||
}
|
||||
|
||||
if (parentId == null) {
|
||||
parentId = Long.valueOf(DomainVO.ROOT_DOMAIN);
|
||||
}
|
||||
|
||||
DomainVO parentDomain = _domainDao.findById(parentId);
|
||||
if (parentDomain == null) {
|
||||
throw new InvalidParameterValueException("Unable to create domain " + name + ", parent domain " + parentId + " not found.");
|
||||
}
|
||||
|
||||
if (parentDomain.getState().equals(Domain.State.Inactive)) {
|
||||
throw new CloudRuntimeException("The domain cannot be created as the parent domain " + parentDomain.getName() + " is being deleted");
|
||||
}
|
||||
|
||||
checkAccess(caller, parentDomain);
|
||||
|
||||
if (networkDomain != null) {
|
||||
if (!NetUtils.verifyDomainName(networkDomain)) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
|
||||
+ "and the hyphen ('-'); can't start or end with \"-\"");
|
||||
}
|
||||
}
|
||||
|
||||
SearchCriteria<DomainVO> sc = _domainDao.createSearchCriteria();
|
||||
sc.addAnd("name", SearchCriteria.Op.EQ, name);
|
||||
sc.addAnd("parent", SearchCriteria.Op.EQ, parentId);
|
||||
List<DomainVO> domains = _domainDao.search(sc, null);
|
||||
if ((domains == null) || domains.isEmpty()) {
|
||||
DomainVO domain = new DomainVO(name, ownerId, parentId, networkDomain);
|
||||
try {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
domain = _domainDao.create(domain);
|
||||
_resourceCountDao.createResourceCounts(domain.getId(), ResourceLimit.OwnerType.Domain);
|
||||
|
||||
txn.commit();
|
||||
return domain;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
s_logger.warn("Failed to create domain ", ex);
|
||||
throw ex;
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Domain with name " + name + " already exists for the parent id=" + parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,6 @@ public class MockAgentManagerImpl implements AgentManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
|
||||
// TODO Auto-generated method stub
|
||||
@ -200,7 +199,6 @@ public class MockAgentManagerImpl implements AgentManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isHostNativeHAEnabled(long hostId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -10,6 +10,7 @@ import javax.naming.ConfigurationException;
|
||||
import com.cloud.acl.ControlledEntity;
|
||||
import com.cloud.acl.SecurityChecker.AccessType;
|
||||
import com.cloud.api.commands.CreateAccountCmd;
|
||||
import com.cloud.api.commands.CreateDomainCmd;
|
||||
import com.cloud.api.commands.CreateUserCmd;
|
||||
import com.cloud.api.commands.DeleteAccountCmd;
|
||||
import com.cloud.api.commands.DeleteUserCmd;
|
||||
@ -221,7 +222,7 @@ public class MockAccountManagerImpl implements Manager, AccountManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long findCorrectResourceLimit(AccountVO account, ResourceType type) {
|
||||
public long findCorrectResourceLimit(long accountId, ResourceType type) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
@ -338,5 +339,10 @@ public class MockAccountManagerImpl implements Manager, AccountManager {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Domain createDomain(CreateDomainCmd cmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1076,7 +1076,9 @@ CREATE TABLE `cloud`.`resource_count` (
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_resource_count__account_id` FOREIGN KEY `fk_resource_count__account_id`(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_resource_count__domain_id` FOREIGN KEY `fk_resource_count__domain_id`(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE,
|
||||
INDEX `i_resource_count__type`(`type`)
|
||||
INDEX `i_resource_count__type`(`type`),
|
||||
UNIQUE `i_resource_count__type_accountId`(`type`, `account_id`),
|
||||
UNIQUE `i_resource_count__type_domaintId`(`type`, `domain_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`op_host_capacity` (
|
||||
|
||||
@ -54,3 +54,7 @@ ALTER TABLE `cloud_usage`.`usage_port_forwarding` ADD INDEX `i_usage_port_forwar
|
||||
ALTER TABLE `cloud_usage`.`usage_network_offering` ADD INDEX `i_usage_network_offering__account_id`(`account_id`);
|
||||
ALTER TABLE `cloud_usage`.`usage_network_offering` ADD INDEX `i_usage_network_offering__created`(`created`);
|
||||
ALTER TABLE `cloud_usage`.`usage_network_offering` ADD INDEX `i_usage_network_offering__deleted`(`deleted`);
|
||||
|
||||
ALTER TABLE `cloud`.`resource_count` ADD UNIQUE `i_resource_count__type_accountId`(`type`, `account_id`);
|
||||
ALTER TABLE `cloud`.`resource_count` ADD UNIQUE `i_resource_count__type_domaintId`(`type`, `domain_id`);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user