You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2013/11/08 06:42:11 UTC
[1/2] git commit: updated refs/heads/master to cb6d8d0
Updated Branches:
refs/heads/master 5d6d14bc1 -> cb6d8d019
CLOUDSTACK-5045 - [Automation][BVT] Affinity group type is missing "create affinity group page" and failed to create Affinity group
Changes:
- Refer the injected list of AffinityGroupProcessor
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1047a539
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1047a539
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1047a539
Branch: refs/heads/master
Commit: 1047a5398d417f791513f3e892b05c22944bed10
Parents: 5d6d14b
Author: Prachi Damle <pr...@cloud.com>
Authored: Thu Nov 7 16:22:18 2013 -0800
Committer: Prachi Damle <pr...@cloud.com>
Committed: Thu Nov 7 21:39:17 2013 -0800
----------------------------------------------------------------------
.../affinity/AffinityGroupServiceImpl.java | 1108 +++++++++---------
1 file changed, 545 insertions(+), 563 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1047a539/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
index b7b51c9..1ac9dcc 100644
--- a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
+++ b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
@@ -1,563 +1,545 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.affinity;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-
-
-
-
-
-
-
-
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.network.Network;
-import com.cloud.network.dao.NetworkDomainVO;
-import com.cloud.network.security.SecurityGroup;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.UserVmDao;
-
-@Local(value = { AffinityGroupService.class })
-public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGroupService, Manager,
- StateListener<State, VirtualMachine.Event, VirtualMachine> {
-
- public static final Logger s_logger = Logger.getLogger(AffinityGroupServiceImpl.class);
- private String _name;
-
- @Inject
- AccountManager _accountMgr;
-
- @Inject
- AffinityGroupDao _affinityGroupDao;
-
- @Inject
- AffinityGroupVMMapDao _affinityGroupVMMapDao;
-
- @Inject
- AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
-
- @Inject
- private UserVmDao _userVmDao;
-
- @Inject
- DomainDao _domainDao;
-
- @Inject
- DomainManager _domainMgr;
-
- protected List<AffinityGroupProcessor> _affinityProcessors;
-
- public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
- return _affinityProcessors;
- }
-
- public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
- this._affinityProcessors = affinityProcessors;
- }
-
- @DB
- @Override
- @ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_CREATE, eventDescription = "Creating Affinity Group", create = true)
- public AffinityGroup createAffinityGroup(String account, Long domainId, String affinityGroupName,
- String affinityGroupType, String description) {
-
- Account caller = CallContext.current().getCallingAccount();
-
- //validate the affinityGroupType
- Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
- if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
- if (!typeProcessorMap.containsKey(affinityGroupType)) {
- throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type"
- + affinityGroupType);
- }
- } else {
- throw new InvalidParameterValueException(
- "Unable to create affinity group, no Affinity Group Types configured");
- }
-
- AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
-
- if (processor.isAdminControlledGroup()) {
- throw new PermissionDeniedException("Cannot create the affinity group");
- }
-
- return createAffinityGroupInternal(account, domainId, affinityGroupName, affinityGroupType, description);
- }
-
- @DB
- @Override
- public AffinityGroup createAffinityGroupInternal(String account, final Long domainId, final String affinityGroupName,
- final String affinityGroupType, final String description) {
-
- Account caller = CallContext.current().getCallingAccount();
-
- // validate the affinityGroupType
- Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
- if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
- if (!typeProcessorMap.containsKey(affinityGroupType)) {
- throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type"
- + affinityGroupType);
- }
- } else {
- throw new InvalidParameterValueException(
- "Unable to create affinity group, no Affinity Group Types configured");
- }
-
- final AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
-
- if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getType())) {
- throw new PermissionDeniedException("Cannot create the affinity group");
- }
-
- ControlledEntity.ACLType aclType = null;
- Account owner = null;
- boolean domainLevel = false;
-
- if (account != null && domainId != null) {
-
- owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
- aclType = ControlledEntity.ACLType.Account;
-
- } else if (domainId != null && account == null) {
-
- if (!_accountMgr.isRootAdmin(caller.getType())) {
- // non root admin need to pass both account and domain
- throw new InvalidParameterValueException(
- "Unable to create affinity group, account name must be passed with the domainId");
- } else if (!processor.canBeSharedDomainWide()) {
- // cannot be domain level
- throw new InvalidParameterValueException("Unable to create affinity group, account name is needed");
- }
-
- DomainVO domain = _domainDao.findById(domainId);
- if (domain == null) {
- throw new InvalidParameterValueException("Unable to find domain by specified id");
- }
- _accountMgr.checkAccess(caller, domain);
-
- // domain level group, owner is SYSTEM.
- owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
- aclType = ControlledEntity.ACLType.Domain;
- domainLevel = true;
-
- } else {
- owner = caller;
- aclType = ControlledEntity.ACLType.Account;
- }
-
- if (_affinityGroupDao.isNameInUse(owner.getAccountId(), owner.getDomainId(), affinityGroupName)) {
- throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
- + affinityGroupName + " already exisits.");
- }
- if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) {
- throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
- + affinityGroupName + " already exisits under the domain.");
- }
-
- final Account ownerFinal = owner;
- final ControlledEntity.ACLType aclTypeFinal = aclType;
- AffinityGroupVO group = Transaction.execute(new TransactionCallback<AffinityGroupVO>() {
- @Override
- public AffinityGroupVO doInTransaction(TransactionStatus status) {
- AffinityGroupVO group = new AffinityGroupVO(affinityGroupName, affinityGroupType, description, ownerFinal.getDomainId(),
- ownerFinal.getId(), aclTypeFinal);
- _affinityGroupDao.persist(group);
-
- if (domainId != null && aclTypeFinal == ACLType.Domain) {
- boolean subDomainAccess = false;
- subDomainAccess = processor.subDomainAccess();
- AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess);
- _affinityGroupDomainMapDao.persist(domainMap);
- }
-
- return group;
- }
- });
-
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Created affinity group =" + affinityGroupName);
- }
-
- return group;
- }
-
-
- @DB
- @Override
- @ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_DELETE, eventDescription = "Deleting affinity group")
- public boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName) {
-
- Account caller = CallContext.current().getCallingAccount();
- Account owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
-
- AffinityGroupVO group = null;
- if (affinityGroupId != null) {
- group = _affinityGroupDao.findById(affinityGroupId);
- if (group == null) {
- throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupId
- + "; failed to delete group.");
- }
- } else if (affinityGroupName != null) {
- group = _affinityGroupDao.findByAccountAndName(owner.getAccountId(), affinityGroupName);
- if (group == null) {
- throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupName
- + "; failed to delete group.");
- }
- } else {
- throw new InvalidParameterValueException(
- "Either the affinity group Id or group name must be specified to delete the group");
- }
- if (affinityGroupId == null) {
- affinityGroupId = group.getId();
- }
- // check permissions
- _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, group);
-
- final Long affinityGroupIdFinal = affinityGroupId;
- Transaction.execute(new TransactionCallbackNoReturn() {
- @Override
- public void doInTransactionWithoutResult(TransactionStatus status) {
-
- AffinityGroupVO group = _affinityGroupDao.lockRow(affinityGroupIdFinal, true);
- if (group == null) {
- throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupIdFinal);
- }
-
- List<AffinityGroupVMMapVO> affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupIdFinal);
- if (!affinityGroupVmMap.isEmpty()) {
- SearchBuilder<AffinityGroupVMMapVO> listByAffinityGroup = _affinityGroupVMMapDao.createSearchBuilder();
- listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(),
- SearchCriteria.Op.EQ);
- listByAffinityGroup.done();
- SearchCriteria<AffinityGroupVMMapVO> sc = listByAffinityGroup.create();
- sc.setParameters("affinityGroupId", affinityGroupIdFinal);
-
- _affinityGroupVMMapDao.lockRows(sc, null, true);
- _affinityGroupVMMapDao.remove(sc);
- }
-
- // call processor to handle the group delete
- AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType());
- if (processor != null) {
- processor.handleDeleteGroup(group);
- }
-
- _affinityGroupDao.expunge(affinityGroupIdFinal);
- }
- });
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Deleted affinity group id=" + affinityGroupId);
- }
- return true;
- }
-
- @Override
- public Pair<List<? extends AffinityGroup>, Integer> listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize) {
- Filter searchFilter = new Filter(AffinityGroupVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
- Account caller = CallContext.current().getCallingAccount();
-
- Long accountId = caller.getAccountId();
- Long domainId = caller.getDomainId();
-
- SearchBuilder<AffinityGroupVMMapVO> vmInstanceSearch = _affinityGroupVMMapDao.createSearchBuilder();
- vmInstanceSearch.and("instanceId", vmInstanceSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
-
- SearchBuilder<AffinityGroupVO> groupSearch = _affinityGroupDao.createSearchBuilder();
-
- SearchCriteria<AffinityGroupVO> sc = groupSearch.create();
-
- if (accountId != null) {
- sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
- }
-
- if (domainId != null) {
- sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
- }
-
- if (affinityGroupId != null) {
- sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
- }
-
- if (affinityGroupName != null) {
- sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName);
- }
-
- if (affinityGroupType != null) {
- sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType);
- }
-
- if (vmId != null) {
- UserVmVO userVM = _userVmDao.findById(vmId);
- if (userVM == null) {
- throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance "
- + vmId + "; instance not found.");
- }
- _accountMgr.checkAccess(caller, null, true, userVM);
- // add join to affinity_groups_vm_map
- groupSearch.join("vmInstanceSearch", vmInstanceSearch, groupSearch.entity().getId(), vmInstanceSearch
- .entity().getAffinityGroupId(), JoinBuilder.JoinType.INNER);
- sc.setJoinParameters("vmInstanceSearch", "instanceId", vmId);
- }
-
- Pair<List<AffinityGroupVO>, Integer> result = _affinityGroupDao.searchAndCount(sc, searchFilter);
- return new Pair<List<? extends AffinityGroup>, Integer>(result.first(), result.second());
- }
-
-
- @Override
- public List<String> listAffinityGroupTypes() {
- Account caller = CallContext.current().getCallingAccount();
-
- List<String> types = new ArrayList<String>();
- Map<String, AffinityGroupProcessor> componentMap = ComponentContext.getComponentsOfType(AffinityGroupProcessor.class);
-
- if (componentMap.size() > 0) {
- for (Entry<String, AffinityGroupProcessor> entry : componentMap.entrySet()) {
- AffinityGroupProcessor processor = entry.getValue();
- if (processor.isAdminControlledGroup()) {
- continue; // we dont list the type if this group can be
- // created only as an admin/system operation.
- }
- types.add(processor.getType());
- }
-
- }
- return types;
- }
-
- protected Map<String, AffinityGroupProcessor> getAffinityTypeToProcessorMap() {
- Map<String, AffinityGroupProcessor> typeProcessorMap = new HashMap<String, AffinityGroupProcessor>();
- Map<String, AffinityGroupProcessor> componentMap = ComponentContext
- .getComponentsOfType(AffinityGroupProcessor.class);
-
- if (componentMap.size() > 0) {
- for (Entry<String, AffinityGroupProcessor> entry : componentMap.entrySet()) {
- typeProcessorMap.put(entry.getValue().getType(), entry.getValue());
- }
- }
- return typeProcessorMap;
- }
-
- @Override
- public boolean isAdminControlledGroup(AffinityGroup group) {
-
- if (group != null) {
- String affinityGroupType = group.getType();
- Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
- if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
- AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
- if (processor != null) {
- return processor.isAdminControlledGroup();
- }
- }
- }
- return false;
-
- }
-
- @Override
- public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
- _name = name;
- VirtualMachine.State.getStateMachine().registerListener(this);
- return true;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public AffinityGroup getAffinityGroup(Long groupId) {
- return _affinityGroupDao.findById(groupId);
- }
-
- @Override
- public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
- boolean status, Object opaque) {
- return true;
- }
-
- @Override
- public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
- boolean status, Object opaque) {
- if (!status) {
- return false;
- }
- if ((newState == State.Expunging) || (newState == State.Error)) {
- // cleanup all affinity groups associations of the Expunged VM
- SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
- sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
- _affinityGroupVMMapDao.expunge(sc);
- }
- return true;
- }
-
- @Override
- public UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds) {
- // Verify input parameters
- UserVmVO vmInstance = _userVmDao.findById(vmId);
- if (vmInstance == null) {
- throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
- }
-
- // Check that the VM is stopped
- if (!vmInstance.getState().equals(State.Stopped)) {
- s_logger.warn("Unable to update affinity groups of the virtual machine " + vmInstance.toString()
- + " in state " + vmInstance.getState());
- throw new InvalidParameterValueException("Unable update affinity groups of the virtual machine "
- + vmInstance.toString() + " " + "in state " + vmInstance.getState()
- + "; make sure the virtual machine is stopped and not in an error state before updating.");
- }
-
- Account caller = CallContext.current().getCallingAccount();
- Account owner = _accountMgr.getAccount(vmInstance.getAccountId());
-
- // check that the affinity groups exist
- for (Long affinityGroupId : affinityGroupIds) {
- AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
- if (ag == null) {
- throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId);
- } else {
- // verify permissions
- _accountMgr.checkAccess(caller, null, true, owner, ag);
- // Root admin has access to both VM and AG by default, but make sure the
- // owner of these entities is same
- if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getType())) {
- if (ag.getAccountId() != owner.getAccountId()) {
- throw new PermissionDeniedException("Affinity Group " + ag
- + " does not belong to the VM's account");
- }
- }
- }
- }
- _affinityGroupVMMapDao.updateMap(vmId, affinityGroupIds);
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Updated VM :" + vmId + " affinity groups to =" + affinityGroupIds);
- }
- // APIResponseHelper will pull out the updated affinitygroups.
- return vmInstance;
-
- }
-
- @Override
- public boolean isAffinityGroupProcessorAvailable(String affinityGroupType) {
- for (AffinityGroupProcessor processor : _affinityProcessors) {
- if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) {
- return true;
- }
- }
- return false;
- }
-
- private AffinityGroupProcessor getAffinityGroupProcessorForType(String affinityGroupType) {
- for (AffinityGroupProcessor processor : _affinityProcessors) {
- if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) {
- return processor;
- }
- }
- return null;
- }
-
- @Override
- public boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId) {
- Long groupDomainId = null;
-
- AffinityGroupDomainMapVO domainMap = _affinityGroupDomainMapDao.findByAffinityGroup(affinityGroupId);
- if (domainMap == null) {
- return false;
- } else {
- groupDomainId = domainMap.getDomainId();
- }
-
- if (domainId == groupDomainId.longValue()) {
- return true;
- }
-
- if (domainMap.subdomainAccess) {
- Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
- if (parentDomains.contains(groupDomainId)) {
- return true;
- }
- }
-
- return false;
- }
-
-}
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.affinity;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+import org.springframework.context.annotation.Primary;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.network.Network;
+import com.cloud.network.dao.NetworkDomainVO;
+import com.cloud.network.security.SecurityGroup;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Event;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+
+@Local(value = { AffinityGroupService.class })
+public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGroupService, Manager,
+ StateListener<State, VirtualMachine.Event, VirtualMachine> {
+
+ public static final Logger s_logger = Logger.getLogger(AffinityGroupServiceImpl.class);
+ private String _name;
+
+ @Inject
+ AccountManager _accountMgr;
+
+ @Inject
+ AffinityGroupDao _affinityGroupDao;
+
+ @Inject
+ AffinityGroupVMMapDao _affinityGroupVMMapDao;
+
+ @Inject
+ AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
+
+ @Inject
+ private UserVmDao _userVmDao;
+
+ @Inject
+ DomainDao _domainDao;
+
+ @Inject
+ DomainManager _domainMgr;
+
+ protected List<AffinityGroupProcessor> _affinityProcessors;
+
+ public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
+ return _affinityProcessors;
+ }
+
+ public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
+ this._affinityProcessors = affinityProcessors;
+ }
+
+ @DB
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_CREATE, eventDescription = "Creating Affinity Group", create = true)
+ public AffinityGroup createAffinityGroup(String account, Long domainId, String affinityGroupName,
+ String affinityGroupType, String description) {
+
+ Account caller = CallContext.current().getCallingAccount();
+
+ //validate the affinityGroupType
+ Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
+ if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
+ if (!typeProcessorMap.containsKey(affinityGroupType)) {
+ throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type"
+ + affinityGroupType);
+ }
+ } else {
+ throw new InvalidParameterValueException(
+ "Unable to create affinity group, no Affinity Group Types configured");
+ }
+
+ AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
+
+ if (processor.isAdminControlledGroup()) {
+ throw new PermissionDeniedException("Cannot create the affinity group");
+ }
+
+ return createAffinityGroupInternal(account, domainId, affinityGroupName, affinityGroupType, description);
+ }
+
+ @DB
+ @Override
+ public AffinityGroup createAffinityGroupInternal(String account, final Long domainId, final String affinityGroupName,
+ final String affinityGroupType, final String description) {
+
+ Account caller = CallContext.current().getCallingAccount();
+
+ // validate the affinityGroupType
+ Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
+ if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
+ if (!typeProcessorMap.containsKey(affinityGroupType)) {
+ throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type"
+ + affinityGroupType);
+ }
+ } else {
+ throw new InvalidParameterValueException(
+ "Unable to create affinity group, no Affinity Group Types configured");
+ }
+
+ final AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
+
+ if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getType())) {
+ throw new PermissionDeniedException("Cannot create the affinity group");
+ }
+
+ ControlledEntity.ACLType aclType = null;
+ Account owner = null;
+ boolean domainLevel = false;
+
+ if (account != null && domainId != null) {
+
+ owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
+ aclType = ControlledEntity.ACLType.Account;
+
+ } else if (domainId != null && account == null) {
+
+ if (!_accountMgr.isRootAdmin(caller.getType())) {
+ // non root admin need to pass both account and domain
+ throw new InvalidParameterValueException(
+ "Unable to create affinity group, account name must be passed with the domainId");
+ } else if (!processor.canBeSharedDomainWide()) {
+ // cannot be domain level
+ throw new InvalidParameterValueException("Unable to create affinity group, account name is needed");
+ }
+
+ DomainVO domain = _domainDao.findById(domainId);
+ if (domain == null) {
+ throw new InvalidParameterValueException("Unable to find domain by specified id");
+ }
+ _accountMgr.checkAccess(caller, domain);
+
+ // domain level group, owner is SYSTEM.
+ owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
+ aclType = ControlledEntity.ACLType.Domain;
+ domainLevel = true;
+
+ } else {
+ owner = caller;
+ aclType = ControlledEntity.ACLType.Account;
+ }
+
+ if (_affinityGroupDao.isNameInUse(owner.getAccountId(), owner.getDomainId(), affinityGroupName)) {
+ throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
+ + affinityGroupName + " already exisits.");
+ }
+ if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) {
+ throw new InvalidParameterValueException("Unable to create affinity group, a group with name "
+ + affinityGroupName + " already exisits under the domain.");
+ }
+
+ final Account ownerFinal = owner;
+ final ControlledEntity.ACLType aclTypeFinal = aclType;
+ AffinityGroupVO group = Transaction.execute(new TransactionCallback<AffinityGroupVO>() {
+ @Override
+ public AffinityGroupVO doInTransaction(TransactionStatus status) {
+ AffinityGroupVO group = new AffinityGroupVO(affinityGroupName, affinityGroupType, description, ownerFinal.getDomainId(),
+ ownerFinal.getId(), aclTypeFinal);
+ _affinityGroupDao.persist(group);
+
+ if (domainId != null && aclTypeFinal == ACLType.Domain) {
+ boolean subDomainAccess = false;
+ subDomainAccess = processor.subDomainAccess();
+ AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess);
+ _affinityGroupDomainMapDao.persist(domainMap);
+ }
+
+ return group;
+ }
+ });
+
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Created affinity group =" + affinityGroupName);
+ }
+
+ return group;
+ }
+
+
+ @DB
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_DELETE, eventDescription = "Deleting affinity group")
+ public boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName) {
+
+ Account caller = CallContext.current().getCallingAccount();
+ Account owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
+
+ AffinityGroupVO group = null;
+ if (affinityGroupId != null) {
+ group = _affinityGroupDao.findById(affinityGroupId);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupId
+ + "; failed to delete group.");
+ }
+ } else if (affinityGroupName != null) {
+ group = _affinityGroupDao.findByAccountAndName(owner.getAccountId(), affinityGroupName);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupName
+ + "; failed to delete group.");
+ }
+ } else {
+ throw new InvalidParameterValueException(
+ "Either the affinity group Id or group name must be specified to delete the group");
+ }
+ if (affinityGroupId == null) {
+ affinityGroupId = group.getId();
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, group);
+
+ final Long affinityGroupIdFinal = affinityGroupId;
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+
+ AffinityGroupVO group = _affinityGroupDao.lockRow(affinityGroupIdFinal, true);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupIdFinal);
+ }
+
+ List<AffinityGroupVMMapVO> affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupIdFinal);
+ if (!affinityGroupVmMap.isEmpty()) {
+ SearchBuilder<AffinityGroupVMMapVO> listByAffinityGroup = _affinityGroupVMMapDao.createSearchBuilder();
+ listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(),
+ SearchCriteria.Op.EQ);
+ listByAffinityGroup.done();
+ SearchCriteria<AffinityGroupVMMapVO> sc = listByAffinityGroup.create();
+ sc.setParameters("affinityGroupId", affinityGroupIdFinal);
+
+ _affinityGroupVMMapDao.lockRows(sc, null, true);
+ _affinityGroupVMMapDao.remove(sc);
+ }
+
+ // call processor to handle the group delete
+ AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType());
+ if (processor != null) {
+ processor.handleDeleteGroup(group);
+ }
+
+ _affinityGroupDao.expunge(affinityGroupIdFinal);
+ }
+ });
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Deleted affinity group id=" + affinityGroupId);
+ }
+ return true;
+ }
+
+ @Override
+ public Pair<List<? extends AffinityGroup>, Integer> listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize) {
+ Filter searchFilter = new Filter(AffinityGroupVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+ Account caller = CallContext.current().getCallingAccount();
+
+ Long accountId = caller.getAccountId();
+ Long domainId = caller.getDomainId();
+
+ SearchBuilder<AffinityGroupVMMapVO> vmInstanceSearch = _affinityGroupVMMapDao.createSearchBuilder();
+ vmInstanceSearch.and("instanceId", vmInstanceSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
+
+ SearchBuilder<AffinityGroupVO> groupSearch = _affinityGroupDao.createSearchBuilder();
+
+ SearchCriteria<AffinityGroupVO> sc = groupSearch.create();
+
+ if (accountId != null) {
+ sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
+ }
+
+ if (domainId != null) {
+ sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+ }
+
+ if (affinityGroupId != null) {
+ sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
+ }
+
+ if (affinityGroupName != null) {
+ sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName);
+ }
+
+ if (affinityGroupType != null) {
+ sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType);
+ }
+
+ if (vmId != null) {
+ UserVmVO userVM = _userVmDao.findById(vmId);
+ if (userVM == null) {
+ throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance "
+ + vmId + "; instance not found.");
+ }
+ _accountMgr.checkAccess(caller, null, true, userVM);
+ // add join to affinity_groups_vm_map
+ groupSearch.join("vmInstanceSearch", vmInstanceSearch, groupSearch.entity().getId(), vmInstanceSearch
+ .entity().getAffinityGroupId(), JoinBuilder.JoinType.INNER);
+ sc.setJoinParameters("vmInstanceSearch", "instanceId", vmId);
+ }
+
+ Pair<List<AffinityGroupVO>, Integer> result = _affinityGroupDao.searchAndCount(sc, searchFilter);
+ return new Pair<List<? extends AffinityGroup>, Integer>(result.first(), result.second());
+ }
+
+
+ @Override
+ public List<String> listAffinityGroupTypes() {
+ List<String> types = new ArrayList<String>();
+
+ for (AffinityGroupProcessor processor : _affinityProcessors) {
+ if (processor.isAdminControlledGroup()) {
+ continue; // we dont list the type if this group can be
+ // created only as an admin/system operation.
+ }
+ types.add(processor.getType());
+ }
+
+ return types;
+ }
+
+ protected Map<String, AffinityGroupProcessor> getAffinityTypeToProcessorMap() {
+ Map<String, AffinityGroupProcessor> typeProcessorMap = new HashMap<String, AffinityGroupProcessor>();
+
+ for (AffinityGroupProcessor processor : _affinityProcessors) {
+ typeProcessorMap.put(processor.getType(), processor);
+ }
+
+ return typeProcessorMap;
+ }
+
+ @Override
+ public boolean isAdminControlledGroup(AffinityGroup group) {
+
+ if (group != null) {
+ String affinityGroupType = group.getType();
+ Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
+ if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
+ AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
+ if (processor != null) {
+ return processor.isAdminControlledGroup();
+ }
+ }
+ }
+ return false;
+
+ }
+
+ @Override
+ public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ VirtualMachine.State.getStateMachine().registerListener(this);
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public AffinityGroup getAffinityGroup(Long groupId) {
+ return _affinityGroupDao.findById(groupId);
+ }
+
+ @Override
+ public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
+ boolean status, Object opaque) {
+ return true;
+ }
+
+ @Override
+ public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo,
+ boolean status, Object opaque) {
+ if (!status) {
+ return false;
+ }
+ if ((newState == State.Expunging) || (newState == State.Error)) {
+ // cleanup all affinity groups associations of the Expunged VM
+ SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
+ sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
+ _affinityGroupVMMapDao.expunge(sc);
+ }
+ return true;
+ }
+
+ @Override
+ public UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds) {
+ // Verify input parameters
+ UserVmVO vmInstance = _userVmDao.findById(vmId);
+ if (vmInstance == null) {
+ throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+ }
+
+ // Check that the VM is stopped
+ if (!vmInstance.getState().equals(State.Stopped)) {
+ s_logger.warn("Unable to update affinity groups of the virtual machine " + vmInstance.toString()
+ + " in state " + vmInstance.getState());
+ throw new InvalidParameterValueException("Unable update affinity groups of the virtual machine "
+ + vmInstance.toString() + " " + "in state " + vmInstance.getState()
+ + "; make sure the virtual machine is stopped and not in an error state before updating.");
+ }
+
+ Account caller = CallContext.current().getCallingAccount();
+ Account owner = _accountMgr.getAccount(vmInstance.getAccountId());
+
+ // check that the affinity groups exist
+ for (Long affinityGroupId : affinityGroupIds) {
+ AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
+ if (ag == null) {
+ throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId);
+ } else {
+ // verify permissions
+ _accountMgr.checkAccess(caller, null, true, owner, ag);
+ // Root admin has access to both VM and AG by default, but make sure the
+ // owner of these entities is same
+ if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getType())) {
+ if (ag.getAccountId() != owner.getAccountId()) {
+ throw new PermissionDeniedException("Affinity Group " + ag
+ + " does not belong to the VM's account");
+ }
+ }
+ }
+ }
+ _affinityGroupVMMapDao.updateMap(vmId, affinityGroupIds);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Updated VM :" + vmId + " affinity groups to =" + affinityGroupIds);
+ }
+ // APIResponseHelper will pull out the updated affinitygroups.
+ return vmInstance;
+
+ }
+
+ @Override
+ public boolean isAffinityGroupProcessorAvailable(String affinityGroupType) {
+ for (AffinityGroupProcessor processor : _affinityProcessors) {
+ if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private AffinityGroupProcessor getAffinityGroupProcessorForType(String affinityGroupType) {
+ for (AffinityGroupProcessor processor : _affinityProcessors) {
+ if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) {
+ return processor;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId) {
+ Long groupDomainId = null;
+
+ AffinityGroupDomainMapVO domainMap = _affinityGroupDomainMapDao.findByAffinityGroup(affinityGroupId);
+ if (domainMap == null) {
+ return false;
+ } else {
+ groupDomainId = domainMap.getDomainId();
+ }
+
+ if (domainId == groupDomainId.longValue()) {
+ return true;
+ }
+
+ if (domainMap.subdomainAccess) {
+ Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
+ if (parentDomains.contains(groupDomainId)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
[2/2] git commit: updated refs/heads/master to cb6d8d0
Posted by pr...@apache.org.
CLOUDSTACK-5045 [Automation][BVT] Affinity group type is missing "create affinity group page" and failed to create Affinity group
Changes:
- Changes to Unit tests needed after this fix.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cb6d8d01
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cb6d8d01
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cb6d8d01
Branch: refs/heads/master
Commit: cb6d8d01901c00134d63d4a39172128582d378fc
Parents: 1047a53
Author: Prachi Damle <pr...@cloud.com>
Authored: Thu Nov 7 21:22:03 2013 -0800
Committer: Prachi Damle <pr...@cloud.com>
Committed: Thu Nov 7 21:40:39 2013 -0800
----------------------------------------------------------------------
.../org/apache/cloudstack/affinity/AffinityApiUnitTest.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cb6d8d01/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
----------------------------------------------------------------------
diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
index 97e093f..91d6958 100644
--- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
+++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
@@ -63,6 +63,7 @@ import org.apache.cloudstack.test.utils.SpringUtils;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.event.ActionEventUtils;
import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.deploy.DeploymentPlanner;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventVO;
@@ -88,7 +89,7 @@ import com.cloud.vm.dao.UserVmDao;
public class AffinityApiUnitTest {
@Inject
- AffinityGroupService _affinityService;
+ AffinityGroupServiceImpl _affinityService;
@Inject
AccountManager _acctMgr;
@@ -144,6 +145,10 @@ public class AffinityApiUnitTest {
when(_processor.getType()).thenReturn("mock");
when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(acct);
+ List<AffinityGroupProcessor> affinityProcessors = new ArrayList<AffinityGroupProcessor>();
+ affinityProcessors.add(_processor);
+ _affinityService.setAffinityGroupProcessors(affinityProcessors);
+
AffinityGroupVO group = new AffinityGroupVO("group1", "mock", "mock group", domainId, 200L,
ControlledEntity.ACLType.Account);
Mockito.when(_affinityGroupDao.persist(Mockito.any(AffinityGroupVO.class))).thenReturn(group);