/** * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * * It is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package com.cloud.user; import java.util.List; import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.configuration.ResourceLimitVO; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchCriteria; @Local(value={AccountManager.class}) public class AccountManagerImpl implements AccountManager { public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class.getName()); private String _name; private AccountDao _accountDao; private DomainDao _domainDao; private UserDao _userDao; private VMTemplateDao _templateDao; ResourceLimitDao _resourceLimitDao; ResourceCountDao _resourceCountDao; @Override public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { _name = name; final ComponentLocator locator = ComponentLocator.getCurrentLocator(); _accountDao = locator.getDao(AccountDao.class); if (_accountDao == null) { throw new ConfigurationException("Unable to get the account dao."); } _domainDao = locator.getDao(DomainDao.class); if (_domainDao == null) { throw new ConfigurationException("Unable to get the domain dao."); } _userDao = locator.getDao(UserDao.class); if (_userDao == null) { throw new ConfigurationException("Unable to get the user dao."); } _templateDao = locator.getDao(VMTemplateDao.class); if (_templateDao == null) { throw new ConfigurationException("Unable to get the template dao."); } _resourceLimitDao = locator.getDao(ResourceLimitDao.class); if (_resourceLimitDao == null) { throw new ConfigurationException("Unable to get " + ResourceLimitDao.class.getName()); } _resourceCountDao = locator.getDao(ResourceCountDao.class); if (_resourceCountDao == null) { throw new ConfigurationException("Unable to get " + ResourceCountDao.class.getName()); } return true; } @Override public String getName() { return _name; } @Override public boolean start() { return true; } @Override public boolean stop() { return true; } public void incrementResourceCount(long accountId, ResourceType type, Long...delta) { long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue(); _resourceCountDao.updateCount(accountId, type, true, numToIncrement); } public void decrementResourceCount(long accountId, ResourceType type, Long...delta) { long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue(); _resourceCountDao.updateCount(accountId, type, false, numToDecrement); } public long findCorrectResourceLimit(AccountVO account, ResourceType type) { long max = -1; // Check account ResourceLimitVO limit = _resourceLimitDao.findByAccountIdAndType(account.getId(), type); if (limit != null) { max = limit.getMax().longValue(); } else { // If the account has an infinite limit, check the ROOT domain Long domainId = DomainVO.ROOT_DOMAIN; limit = _resourceLimitDao.findByDomainIdAndType(domainId, type); if (limit != null) { max = limit.getMax().longValue(); } } return max; } public boolean resourceLimitExceeded(AccountVO account, ResourceType type) { // 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) { return false; } long max = findCorrectResourceLimit(account, type); if (max >= 0) { long potentialCount = _resourceCountDao.getCount(account.getId(), type) + 1; return (potentialCount > max); } else { return false; } } public long getResourceCount(AccountVO account, ResourceType type) { return _resourceCountDao.getCount(account.getId(), type); } public ResourceLimitVO updateResourceLimit(Long domainId, Long accountId, ResourceType type, Long max) throws InvalidParameterValueException { // Either a domainId or an accountId must be passed in, but not both. if ((domainId == null) && (accountId == null)) { throw new InvalidParameterValueException("Either a domainId or domainId/accountId must be passed in."); } // Check if the domain or account exists and is valid if (accountId != null) { AccountVO account = _accountDao.findById(accountId); if (account == null) { throw new InvalidParameterValueException("Please specify a valid account ID."); } else if (account.getRemoved() != null) { throw new InvalidParameterValueException("Please specify an active account."); } else if (account.getType() == Account.ACCOUNT_TYPE_ADMIN || account.getType() == Account.ACCOUNT_ID_SYSTEM) { throw new InvalidParameterValueException("Please specify a non-admin account."); } } else if (domainId != null) { DomainVO domain = _domainDao.findById(domainId); if (domain == null) { throw new InvalidParameterValueException("Please specify a valid domain ID."); } else if (domain.getRemoved() != null) { throw new InvalidParameterValueException("Please specify an active domain."); } } // A valid limit type must be passed in if (type == null) { throw new InvalidParameterValueException("A valid limit type must be passed in."); } // Check if a limit with the specified domainId/accountId/type combo already exists Filter searchFilter = new Filter(ResourceLimitVO.class, null, false, null, null); SearchCriteria sc = _resourceLimitDao.createSearchCriteria(); if (domainId != null) { sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId); } if (accountId != null) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } if (type != null) { sc.addAnd("type", SearchCriteria.Op.EQ, type); } List<ResourceLimitVO> limits = _resourceLimitDao.search(sc, searchFilter); if (limits.size() == 1) { // Update the existing limit ResourceLimitVO limit = limits.get(0); _resourceLimitDao.update(limit.getId(), max); return _resourceLimitDao.findById(limit.getId()); } else { // Persist the new Limit return _resourceLimitDao.persist(new ResourceLimitVO(domainId, accountId, type, max)); } } }