Added AffinityGroup View in order to include VM details while listing AffinityGroups.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3403b547 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3403b547 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3403b547 Branch: refs/heads/marvin_refactor Commit: 3403b547735fe14e22b879f2627776548394951e Parents: 09a6eb7 Author: Prachi Damle <[email protected]> Authored: Thu Apr 4 22:46:11 2013 -0700 Committer: Prachi Damle <[email protected]> Committed: Thu Apr 11 13:23:23 2013 -0700 ---------------------------------------------------------------------- .../cloudstack/affinity/AffinityGroupResponse.java | 16 +- .../user/affinitygroup/ListAffinityGroupsCmd.java | 26 +-- .../affinitygroup/UpdateVMAffinityGroupCmd.java | 8 +- .../org/apache/cloudstack/query/QueryService.java | 4 + client/tomcatconf/applicationContext.xml.in | 10 + client/tomcatconf/componentContext.xml.in | 1 + .../affinity/HostAntiAffinityProcessor.java | 9 +- server/src/com/cloud/api/ApiDBUtils.java | 14 + .../src/com/cloud/api/query/QueryManagerImpl.java | 108 +++++++ .../com/cloud/api/query/ViewResponseHelper.java | 18 + .../cloud/api/query/dao/AffinityGroupJoinDao.java | 37 +++ .../api/query/dao/AffinityGroupJoinDaoImpl.java | 155 +++++++++ .../cloud/api/query/vo/AffinityGroupJoinVO.java | 248 +++++++++++++++ .../affinity/dao/AffinityGroupDaoImpl.java | 1 - .../affinity/dao/AffinityGroupVMMapDaoImpl.java | 1 - setup/db/db/schema-410to420.sql | 34 ++- 16 files changed, 661 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java b/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java index 073a82c..1ae7c59 100644 --- a/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java +++ b/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.affinity; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.apache.cloudstack.api.ApiConstants; @@ -24,6 +25,7 @@ import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.EntityReference; import org.apache.cloudstack.api.response.ControlledEntityResponse; import org.apache.cloudstack.api.response.ControlledViewEntityResponse; +import org.apache.cloudstack.api.response.UserVmResponse; import com.cloud.network.security.SecurityGroup; import com.cloud.serializer.Param; @@ -31,7 +33,7 @@ import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @EntityReference(value = AffinityGroup.class) -public class AffinityGroupResponse extends BaseResponse implements ControlledEntityResponse { +public class AffinityGroupResponse extends BaseResponse implements ControlledViewEntityResponse { @SerializedName(ApiConstants.ID) @Param(description="the ID of the affinity group") private String id; @@ -55,8 +57,12 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledEnt @Param(description = "the type of the affinity group") private String type; + @SerializedName("virtualmachine") + @Param(description = "virtual machines associated with this affinity group ", responseObject = UserVmResponse.class) + private Set<UserVmResponse> vmList; public AffinityGroupResponse() { + this.vmList = new LinkedHashSet<UserVmResponse>(); } @Override @@ -136,4 +142,12 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledEnt } + public void setVMList(Set<UserVmResponse> vmList) { + this.vmList = vmList; + } + + public void addVM(UserVmResponse vm) { + this.vmList.add(vm); + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java index effbd86..9310fb9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java @@ -16,23 +16,16 @@ // under the License. package org.apache.cloudstack.api.command.user.affinitygroup; -import java.util.ArrayList; -import java.util.List; - -import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.log4j.Logger; import com.cloud.async.AsyncJob; -import com.cloud.utils.Pair; @APICommand(name = "listAffinityGroups", description = "Lists affinity groups", responseObject = AffinityGroupResponse.class) public class ListAffinityGroupsCmd extends BaseListCmd { @@ -83,22 +76,11 @@ public class ListAffinityGroupsCmd extends BaseListCmd { @Override public void execute(){ - Pair<List<? extends AffinityGroup>, Integer> result = _affinityGroupService.listAffinityGroups(id, - affinityGroupName, + ListResponse<AffinityGroupResponse> response = _queryService.listAffinityGroups(id, affinityGroupName, affinityGroupType, virtualMachineId, this.getStartIndex(), this.getPageSizeVal()); - if (result != null) { - ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>(); - List<AffinityGroupResponse> groupResponses = new ArrayList<AffinityGroupResponse>(); - for (AffinityGroup group : result.first()) { - AffinityGroupResponse groupResponse = _responseGenerator.createAffinityGroupResponse(group); - groupResponses.add(groupResponse); - } - response.setResponses(groupResponses, result.second()); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to search for affinity groups"); - } + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } @Override http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java index 94f8446..44d017b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.user.affinitygroup; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import org.apache.cloudstack.affinity.AffinityGroupResponse; @@ -27,6 +28,7 @@ import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.log4j.Logger; @@ -131,8 +133,12 @@ public class UpdateVMAffinityGroupCmd extends BaseAsyncCmd { InsufficientCapacityException, ServerApiException { UserContext.current().setEventDetails("Vm Id: "+getId()); UserVm result = _affinityGroupService.updateVMAffinityGroups(getId(), getAffinityGroupIdList()); + ArrayList<VMDetails> dc = new ArrayList<VMDetails>(); + dc.add(VMDetails.valueOf("affgrp")); + EnumSet<VMDetails> details = EnumSet.copyOf(dc); + if (result != null){ - UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0); + UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", details, result).get(0); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/api/src/org/apache/cloudstack/query/QueryService.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index c3f86aa..443c5df 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.query; +import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; @@ -97,4 +98,7 @@ public interface QueryService { public ListResponse<ServiceOfferingResponse> searchForServiceOfferings(ListServiceOfferingsCmd cmd); public ListResponse<ZoneResponse> listDataCenters(ListZonesByCmd cmd); + + public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName, + String affinityGroupType, Long vmId, Long startIndex, Long pageSize); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/client/tomcatconf/applicationContext.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 67b1286..0d13877 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -836,5 +836,15 @@ <bean id="baremetalDhcpDaoImpl" class="com.cloud.baremetal.database.BaremetalDhcpDaoImpl" /> <bean id="baremetalPxeDaoImpl" class="com.cloud.baremetal.database.BaremetalPxeDaoImpl" /> --> + + <bean id="AffinityGroupServiceImpl" class="org.apache.cloudstack.affinity.AffinityGroupServiceImpl"/> + <bean id="DeploymentPlanningManager" class="com.cloud.deploy.DeploymentPlanningManagerImpl" /> + + <bean id="AffinityGroupJoinDaoImpl" class="com.cloud.api.query.dao.AffinityGroupJoinDaoImpl"> + </bean> + <bean id="AffinityGroupDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl"> + </bean> + <bean id="AffinityGroupVMMapDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl"> + </bean> </beans> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/client/tomcatconf/componentContext.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 7f3e02d..92838fd 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -31,6 +31,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + <!-- OSS deployment configuration http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java ---------------------------------------------------------------------- diff --git a/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java b/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java index 88030f2..4049571 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java +++ b/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java @@ -65,8 +65,13 @@ public class HostAntiAffinityProcessor extends AffinityProcessorBase implements for (Long groupVMId : groupVMIds) { VMInstanceVO groupVM = _vmInstanceDao.findById(groupVMId); - if (groupVM != null && !groupVM.isRemoved() && groupVM.getHostId() != null) { - avoid.addHost(groupVM.getHostId()); + if (groupVM != null && !groupVM.isRemoved()) { + if (groupVM.getHostId() != null) { + avoid.addHost(groupVM.getHostId()); + } else if (VirtualMachine.State.Stopped.equals(groupVM.getState()) + && groupVM.getLastHostId() != null) { + avoid.addHost(groupVM.getLastHostId()); + } } } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/ApiDBUtils.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index d21e2c4..303f328 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -26,6 +26,7 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import org.apache.cloudstack.affinity.AffinityGroup; +import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; @@ -52,6 +53,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.springframework.stereotype.Component; import com.cloud.api.query.dao.AccountJoinDao; +import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AsyncJobJoinDao; import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; @@ -69,6 +71,7 @@ import com.cloud.api.query.dao.UserAccountJoinDao; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.VolumeJoinDao; import com.cloud.api.query.vo.AccountJoinVO; +import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; @@ -382,6 +385,7 @@ public class ApiDBUtils { static NicSecondaryIpDao _nicSecondaryIpDao; static VpcProvisioningService _vpcProvSvc; static AffinityGroupDao _affinityGroupDao; + static AffinityGroupJoinDao _affinityGroupJoinDao; @Inject private ManagementServer ms; @Inject public AsyncJobManager asyncMgr; @@ -487,6 +491,7 @@ public class ApiDBUtils { @Inject private NicSecondaryIpDao nicSecondaryIpDao; @Inject private VpcProvisioningService vpcProvSvc; @Inject private AffinityGroupDao affinityGroupDao; + @Inject private AffinityGroupJoinDao affinityGroupJoinDao; @PostConstruct void init() { @@ -591,6 +596,7 @@ public class ApiDBUtils { _nicSecondaryIpDao = nicSecondaryIpDao; _vpcProvSvc = vpcProvSvc; _affinityGroupDao = affinityGroupDao; + _affinityGroupJoinDao = affinityGroupJoinDao; // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); } @@ -1597,4 +1603,12 @@ public class ApiDBUtils { public static AffinityGroup getAffinityGroup(String groupName, long accountId) { return _affinityGroupDao.findByAccountAndName(accountId, groupName); } + + public static AffinityGroupResponse newAffinityGroupResponse(AffinityGroupJoinVO group) { + return _affinityGroupJoinDao.newAffinityGroupResponse(group); + } + + public static AffinityGroupResponse fillAffinityGroupDetails(AffinityGroupResponse resp, AffinityGroupJoinVO group) { + return _affinityGroupJoinDao.setAffinityGroupResponse(resp, group); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/query/QueryManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 951d09e..a498c18 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -27,6 +27,11 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.affinity.AffinityGroup; +import org.apache.cloudstack.affinity.AffinityGroupResponse; +import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; +import org.apache.cloudstack.affinity.AffinityGroupVO; +import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; @@ -69,6 +74,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.api.query.dao.AccountJoinDao; +import com.cloud.api.query.dao.AffinityGroupJoinDao; import com.cloud.api.query.dao.AsyncJobJoinDao; import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; @@ -86,6 +92,7 @@ import com.cloud.api.query.dao.UserAccountJoinDao; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.VolumeJoinDao; import com.cloud.api.query.vo.AccountJoinVO; +import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; @@ -138,6 +145,7 @@ import com.cloud.utils.Ternary; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; 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.SearchCriteria.Func; @@ -246,6 +254,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Inject private HighAvailabilityManager _haMgr; + @Inject + AffinityGroupVMMapDao _affinityGroupVMMapDao; + + @Inject + private AffinityGroupJoinDao _affinityGroupJoinDao; + /* (non-Javadoc) * @see com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack.api.command.admin.user.ListUsersCmd) */ @@ -2328,5 +2342,99 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { return false; } + @Override + public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName, + String affinityGroupType, Long vmId, Long startIndex, Long pageSize) { + Pair<List<AffinityGroupJoinVO>, Integer> result = listAffinityGroupsInternal(affinityGroupId, + affinityGroupName, affinityGroupType, vmId, startIndex, pageSize); + ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>(); + List<AffinityGroupResponse> agResponses = ViewResponseHelper.createAffinityGroupResponses(result.first()); + response.setResponses(agResponses, result.second()); + return response; + } + + + public Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsInternal(Long affinityGroupId, + String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize) { + + Account caller = UserContext.current().getCaller(); + + Long accountId = caller.getAccountId(); + Long domainId = caller.getDomainId(); + + 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); + return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize); + } + + Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize); + SearchBuilder<AffinityGroupJoinVO> groupSearch = _affinityGroupJoinDao.createSearchBuilder(); + groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select + // distinct + + SearchCriteria<AffinityGroupJoinVO> 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); + } + + + Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, + searchFilter); + // search group details by ids + Integer count = uniqueGroupsPair.second(); + if (count.intValue() == 0) { + // empty result + return uniqueGroupsPair; + } + List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first(); + Long[] vrIds = new Long[uniqueGroups.size()]; + int i = 0; + for (AffinityGroupJoinVO v : uniqueGroups) { + vrIds[i++] = v.getId(); + } + List<AffinityGroupJoinVO> vrs = _affinityGroupJoinDao.searchByIds(vrIds); + return new Pair<List<AffinityGroupJoinVO>, Integer>(vrs, count); + + } + + private Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsByVM(long vmId, long pageInd, long pageSize) { + Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize); + Pair<List<AffinityGroupVMMapVO>, Integer> agVmMappingPair = _affinityGroupVMMapDao.listByInstanceId(vmId, sf); + Integer count = agVmMappingPair.second(); + if (count.intValue() == 0) { + // handle empty result cases + return new Pair<List<AffinityGroupJoinVO>, Integer>(new ArrayList<AffinityGroupJoinVO>(), count); + } + List<AffinityGroupVMMapVO> agVmMappings = agVmMappingPair.first(); + Long[] agIds = new Long[agVmMappings.size()]; + int i = 0; + for (AffinityGroupVMMapVO agVm : agVmMappings) { + agIds[i++] = agVm.getAffinityGroupId(); + } + List<AffinityGroupJoinVO> ags = _affinityGroupJoinDao.searchByIds(agIds); + return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/query/ViewResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 931327a..dc2727e 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -21,6 +21,7 @@ import java.util.EnumSet; import java.util.Hashtable; import java.util.List; +import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.response.AccountResponse; @@ -45,6 +46,7 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.vo.AccountJoinVO; +import com.cloud.api.query.vo.AffinityGroupJoinVO; import com.cloud.api.query.vo.AsyncJobJoinVO; import com.cloud.api.query.vo.DataCenterJoinVO; import com.cloud.api.query.vo.DiskOfferingJoinVO; @@ -303,4 +305,20 @@ public class ViewResponseHelper { } return respList; } + + public static List<AffinityGroupResponse> createAffinityGroupResponses(List<AffinityGroupJoinVO> groups) { + Hashtable<Long, AffinityGroupResponse> vrDataList = new Hashtable<Long, AffinityGroupResponse>(); + for (AffinityGroupJoinVO vr : groups) { + AffinityGroupResponse vrData = vrDataList.get(vr.getId()); + if (vrData == null) { + // first time encountering this AffinityGroup + vrData = ApiDBUtils.newAffinityGroupResponse(vr); + } else { + // update vms + vrData = ApiDBUtils.fillAffinityGroupDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList<AffinityGroupResponse>(vrDataList.values()); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java b/server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java new file mode 100644 index 0000000..c029b3f --- /dev/null +++ b/server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java @@ -0,0 +1,37 @@ +// 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 com.cloud.api.query.dao; + +import java.util.List; + +import org.apache.cloudstack.affinity.AffinityGroup; +import org.apache.cloudstack.affinity.AffinityGroupResponse; +import com.cloud.api.query.vo.AffinityGroupJoinVO; +import com.cloud.user.Account; +import com.cloud.utils.db.GenericDao; + +public interface AffinityGroupJoinDao extends GenericDao<AffinityGroupJoinVO, Long> { + + AffinityGroupResponse newAffinityGroupResponse(AffinityGroupJoinVO vsg); + + AffinityGroupResponse setAffinityGroupResponse(AffinityGroupResponse vsgData, AffinityGroupJoinVO vsg); + + List<AffinityGroupJoinVO> newAffinityGroupView(AffinityGroup ag); + + List<AffinityGroupJoinVO> searchByIds(Long... ids); +} + http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java new file mode 100644 index 0000000..98c6440 --- /dev/null +++ b/server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java @@ -0,0 +1,155 @@ +// 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 com.cloud.api.query.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + + +import org.apache.cloudstack.affinity.AffinityGroup; +import org.apache.cloudstack.affinity.AffinityGroupResponse; +import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.query.vo.AffinityGroupJoinVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.user.Account; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value = { AffinityGroupJoinDao.class }) +public class AffinityGroupJoinDaoImpl extends GenericDaoBase<AffinityGroupJoinVO, Long> implements AffinityGroupJoinDao { + public static final Logger s_logger = Logger.getLogger(AffinityGroupJoinDaoImpl.class); + + @Inject + private ConfigurationDao _configDao; + + private final SearchBuilder<AffinityGroupJoinVO> agSearch; + + private final SearchBuilder<AffinityGroupJoinVO> agIdSearch; + + protected AffinityGroupJoinDaoImpl() { + + agSearch = createSearchBuilder(); + agSearch.and("idIN", agSearch.entity().getId(), SearchCriteria.Op.IN); + agSearch.done(); + + agIdSearch = createSearchBuilder(); + agIdSearch.and("id", agIdSearch.entity().getId(), SearchCriteria.Op.EQ); + agIdSearch.done(); + + this._count = "select count(distinct id) from affinity_group_view WHERE "; + } + + @Override + public AffinityGroupResponse newAffinityGroupResponse(AffinityGroupJoinVO vag) { + AffinityGroupResponse agResponse = new AffinityGroupResponse(); + agResponse.setId(vag.getUuid()); + agResponse.setName(vag.getName()); + agResponse.setDescription(vag.getDescription()); + + ApiResponseHelper.populateOwner(agResponse, vag); + + // update vm information + long instanceId = vag.getVmId(); + if (instanceId > 0) { + UserVmResponse resp = new UserVmResponse(); + resp.setObjectName("virtualmachine"); + resp.setId(vag.getVmUuid()); + resp.setName(vag.getVmName()); + resp.setDisplayName(vag.getVmDisplayName()); + resp.setState(vag.getVmState().toString()); + agResponse.addVM(resp); + } + + agResponse.setObjectName("affinitygroup"); + return agResponse; + } + + @Override + public AffinityGroupResponse setAffinityGroupResponse(AffinityGroupResponse vagData, AffinityGroupJoinVO vag) { + // update vm information + long instanceId = vag.getVmId(); + if (instanceId > 0) { + UserVmResponse resp = new UserVmResponse(); + resp.setObjectName("virtualmachine"); + resp.setId(vag.getVmUuid()); + resp.setName(vag.getVmName()); + resp.setDisplayName(vag.getVmDisplayName()); + resp.setState(vag.getVmState().toString()); + vagData.addVM(resp); + } + return vagData; + } + + @Override + public List<AffinityGroupJoinVO> newAffinityGroupView(AffinityGroup ag) { + + SearchCriteria<AffinityGroupJoinVO> sc = agIdSearch.create(); + sc.setParameters("id", ag.getId()); + return searchIncludingRemoved(sc, null, null, false); + } + + @Override + public List<AffinityGroupJoinVO> searchByIds(Long... agIds) { + // set detail batch query size + int DETAILS_BATCH_SIZE = 2000; + String batchCfg = _configDao.getValue("detail.batch.query.size"); + if ( batchCfg != null ){ + DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg); + } + // query details by batches + List<AffinityGroupJoinVO> uvList = new ArrayList<AffinityGroupJoinVO>(); + // query details by batches + int curr_index = 0; + if (agIds.length > DETAILS_BATCH_SIZE) { + while ((curr_index + DETAILS_BATCH_SIZE) <= agIds.length) { + Long[] ids = new Long[DETAILS_BATCH_SIZE]; + for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) { + ids[k] = agIds[j]; + } + SearchCriteria<AffinityGroupJoinVO> sc = agSearch.create(); + sc.setParameters("idIN", ids); + List<AffinityGroupJoinVO> vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + curr_index += DETAILS_BATCH_SIZE; + } + } + if (curr_index < agIds.length) { + int batch_size = (agIds.length - curr_index); + // set the ids value + Long[] ids = new Long[batch_size]; + for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) { + ids[k] = agIds[j]; + } + SearchCriteria<AffinityGroupJoinVO> sc = agSearch.create(); + sc.setParameters("idIN", ids); + List<AffinityGroupJoinVO> vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + } + return uvList; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java b/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java new file mode 100644 index 0000000..e68996c --- /dev/null +++ b/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java @@ -0,0 +1,248 @@ +// 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 com.cloud.api.query.vo; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.vm.VirtualMachine; + +@Entity +@Table(name = "affinity_group_view") +public class AffinityGroupJoinVO extends BaseViewVO implements ControlledViewEntity { + + @Id + @Column(name="id", updatable=false, nullable = false) + private long id; + + @Column(name="name") + private String name; + + @Column(name = "description") + private String description; + + @Column(name = "uuid") + private String uuid; + + @Column(name="account_id") + private long accountId; + + @Column(name="account_uuid") + private String accountUuid; + + @Column(name="account_name") + private String accountName = null; + + @Column(name="account_type") + private short accountType; + + @Column(name="domain_id") + private long domainId; + + @Column(name="domain_uuid") + private String domainUuid; + + @Column(name="domain_name") + private String domainName = null; + + @Column(name="domain_path") + private String domainPath = null; + + @Column(name = "vm_id") + private long vmId; + + @Column(name = "vm_uuid") + private String vmUuid; + + @Column(name = "vm_name") + private String vmName; + + @Column(name = "vm_display_name") + private String vmDisplayName; + + @Column(name = "vm_state") + @Enumerated(value = EnumType.STRING) + protected VirtualMachine.State vmState = null; + + + public AffinityGroupJoinVO() { + } + + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + + @Override + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + @Override + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public short getAccountType() { + return accountType; + } + + public void setAccountType(short accountType) { + this.accountType = accountType; + } + + @Override + public long getDomainId() { + return domainId; + } + + public void setDomainId(long domainId) { + this.domainId = domainId; + } + + @Override + public String getDomainUuid() { + return domainUuid; + } + + public void setDomainUuid(String domainUuid) { + this.domainUuid = domainUuid; + } + + @Override + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public String getDomainPath() { + return domainPath; + } + + public void setDomainPath(String domainPath) { + this.domainPath = domainPath; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public long getVmId() { + return vmId; + } + + public void setVmId(long vmId) { + this.vmId = vmId; + } + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getVmName() { + return vmName; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + + public String getVmDisplayName() { + return vmDisplayName; + } + + public void setVmDisplayName(String vmDisplayName) { + this.vmDisplayName = vmDisplayName; + } + + public VirtualMachine.State getVmState() { + return vmState; + } + + public void setVmState(VirtualMachine.State vmState) { + this.vmState = vmState; + } + + @Override + public String getProjectUuid() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getProjectName() { + // TODO Auto-generated method stub + return null; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java b/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java index f7db418..d189d60 100644 --- a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java +++ b/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java @@ -26,7 +26,6 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -@Component @Local(value = { AffinityGroupDao.class }) public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long> implements AffinityGroupDao { private SearchBuilder<AffinityGroupVO> AccountIdSearch; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java b/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java index b17d0b3..abc2a2b 100644 --- a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java +++ b/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java @@ -37,7 +37,6 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.Transaction; -@Component @Local(value = { AffinityGroupVMMapDao.class }) public class AffinityGroupVMMapDaoImpl extends GenericDaoBase<AffinityGroupVMMapVO, Long> implements AffinityGroupVMMapDao { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3403b547/setup/db/db/schema-410to420.sql ---------------------------------------------------------------------- diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 6464c08..ae08ebe 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -648,6 +648,38 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id; - +DROP VIEW IF EXISTS `cloud`.`affinity_group_view`; +CREATE VIEW `cloud`.`affinity_group_view` AS + select + affinity_group.id id, + affinity_group.name name, + affinity_group.description description, + affinity_group.uuid uuid, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + vm_instance.id vm_id, + vm_instance.uuid vm_uuid, + vm_instance.name vm_name, + vm_instance.state vm_state, + user_vm.display_name vm_display_name + from + `cloud`.`affinity_group` + inner join + `cloud`.`account` ON affinity_group.account_id = account.id + inner join + `cloud`.`domain` ON affinity_group.domain_id = domain.id + left join + `cloud`.`affinity_group_vm_map` ON affinity_group.id = affinity_group_vm_map.affinity_group_id + left join + `cloud`.`vm_instance` ON vm_instance.id = affinity_group_vm_map.instance_id + left join + `cloud`.`user_vm` ON user_vm.id = vm_instance.id; + -- Re-enable foreign key checking, at the end of the upgrade path SET foreign_key_checks = 1;
