You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2012/12/26 02:21:31 UTC
git commit: Create DB view for Volume to speed up ListVolumesCmd.
Updated Branches:
refs/heads/api_refactoring 78d70d349 -> 21c1623a0
Create DB view for Volume to speed up ListVolumesCmd.
Signed-off-by: Min Chen <mi...@citrix.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/21c1623a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/21c1623a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/21c1623a
Branch: refs/heads/api_refactoring
Commit: 21c1623a0321adb1082ec4677252cdd14f5f96ac
Parents: 78d70d3
Author: Min Chen <mi...@citrix.com>
Authored: Tue Dec 25 17:08:50 2012 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Tue Dec 25 17:08:50 2012 -0800
----------------------------------------------------------------------
api/src/com/cloud/storage/StorageService.java | 1 -
.../api/command/user/volume/ListVolumesCmd.java | 12 +-
.../cloudstack/api/response/VolumeResponse.java | 16 +-
.../org/apache/cloudstack/query/QueryService.java | 7 +-
server/src/com/cloud/api/ApiDBUtils.java | 20 +
server/src/com/cloud/api/ApiResponseHelper.java | 137 +--
server/src/com/cloud/api/ApiServer.java | 4 +-
.../src/com/cloud/api/query/QueryManagerImpl.java | 158 +++-
.../com/cloud/api/query/ViewResponseHelper.java | 19 +
.../src/com/cloud/api/query/dao/VolumeJoinDao.java | 37 +
.../com/cloud/api/query/dao/VolumeJoinDaoImpl.java | 230 ++++
.../src/com/cloud/api/query/vo/VolumeJoinVO.java | 1032 +++++++++++++++
.../configuration/DefaultComponentLibrary.java | 3 +
.../src/com/cloud/storage/StorageManagerImpl.java | 117 --
server/test/com/cloud/api/ListPerfTest.java | 14 +
setup/db/create-schema.sql | 82 ++
setup/db/db/schema-40to410.sql | 85 ++
17 files changed, 1703 insertions(+), 271 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/api/src/com/cloud/storage/StorageService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java
index 80f64d8..1967cba 100644
--- a/api/src/com/cloud/storage/StorageService.java
+++ b/api/src/com/cloud/storage/StorageService.java
@@ -115,7 +115,6 @@ public interface StorageService{
Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException;
- Pair<List<? extends Volume>, Integer> searchForVolumes(ListVolumesCmd cmd);
/**
* Uploads the volume to secondary storage
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
index c47e73d..bbee677 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
@@ -116,17 +116,7 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd {
@Override
public void execute(){
- Pair<List<? extends Volume>, Integer> volumes = _storageService.searchForVolumes(this);
-
- ListResponse<VolumeResponse> response = new ListResponse<VolumeResponse>();
- List<VolumeResponse> volResponses = new ArrayList<VolumeResponse>();
- for (Volume volume : volumes.first()) {
- VolumeResponse volResponse = _responseGenerator.createVolumeResponse(volume);
- volResponse.setObjectName("volume");
- volResponses.add(volResponse);
- }
-
- response.setResponses(volResponses, volumes.second());
+ ListResponse<VolumeResponse> response = _queryService.searchForVolumes(this);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
index 1b1ff14..bc21768 100644
--- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
@@ -17,7 +17,9 @@
package org.apache.cloudstack.api.response;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import com.cloud.storage.Volume;
import org.apache.cloudstack.api.ApiConstants;
@@ -28,7 +30,7 @@ import org.apache.cloudstack.api.Entity;
@Entity(value=Volume.class)
@SuppressWarnings("unused")
-public class VolumeResponse extends BaseResponse implements ControlledEntityResponse{
+public class VolumeResponse extends BaseResponse implements ControlledViewEntityResponse{
@SerializedName(ApiConstants.ID)
@Param(description = "ID of the disk volume")
private String id;
@@ -156,9 +158,11 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp
private String status;
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with volume", responseObject = ResourceTagResponse.class)
- private List<ResourceTagResponse> tags;
-
+ private Set<ResourceTagResponse> tags;
+ public VolumeResponse(){
+ tags = new HashSet<ResourceTagResponse>();
+ }
@Override
public String getObjectId() {
@@ -304,7 +308,11 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp
this.projectName = projectName;
}
- public void setTags(List<ResourceTagResponse> tags) {
+ public void setTags(Set<ResourceTagResponse> tags) {
this.tags = tags;
}
+
+ public void addTag(ResourceTagResponse tag){
+ this.tags.add(tag);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/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 1847ede..ef3c52f 100644
--- a/api/src/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/org/apache/cloudstack/query/QueryService.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCm
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
@@ -39,11 +40,11 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+
-import com.cloud.async.AsyncJob;
import com.cloud.exception.PermissionDeniedException;
-import com.cloud.storage.Snapshot;
/**
* Service used for list api query.
@@ -73,4 +74,6 @@ public interface QueryService {
public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd);
public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd);
+
+ public ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/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 5fa9ef7..7465873 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -35,6 +35,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.dao.HostJoinDao;
@@ -45,6 +46,7 @@ import com.cloud.api.query.dao.ProjectJoinDao;
import com.cloud.api.query.dao.ResourceTagJoinDao;
import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
+import com.cloud.api.query.dao.VolumeJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
@@ -56,6 +58,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
@@ -180,6 +183,7 @@ import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateS3VO;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO;
@@ -313,6 +317,7 @@ public class ApiDBUtils {
private static ProjectAccountJoinDao _projectAccountJoinDao;
private static ProjectInvitationJoinDao _projectInvitationJoinDao;
private static HostJoinDao _hostJoinDao;
+ private static VolumeJoinDao _volJoinDao;
private static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
private static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@@ -400,6 +405,7 @@ public class ApiDBUtils {
_projectAccountJoinDao = locator.getDao(ProjectAccountJoinDao.class);
_projectInvitationJoinDao = locator.getDao(ProjectInvitationJoinDao.class);
_hostJoinDao = locator.getDao(HostJoinDao.class);
+ _volJoinDao = locator.getDao(VolumeJoinDao.class);
_physicalNetworkTrafficTypeDao = locator.getDao(PhysicalNetworkTrafficTypeDao.class);
_physicalNetworkServiceProviderDao = locator.getDao(PhysicalNetworkServiceProviderDao.class);
@@ -1324,4 +1330,18 @@ public class ApiDBUtils {
public static List<HostJoinVO> newHostView(Host vr){
return _hostJoinDao.newHostView(vr);
}
+
+ public static VolumeResponse newVolumeResponse(VolumeJoinVO vr) {
+ return _volJoinDao.newVolumeResponse(vr);
+ }
+
+
+ public static VolumeResponse fillVolumeDetails(VolumeResponse vrData, VolumeJoinVO vr){
+ return _volJoinDao.setVolumeResponse(vrData, vr);
+ }
+
+ public static List<VolumeJoinVO> newVolumeView(Volume vr){
+ return _volJoinDao.newVolumeView(vr);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index b2bfee8..22e89dd 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -57,6 +57,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.api.response.ApiResponseSerializer;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
@@ -1019,138 +1020,10 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public VolumeResponse createVolumeResponse(Volume volume) {
- VolumeResponse volResponse = new VolumeResponse();
- volResponse.setId(volume.getUuid());
-
- if (volume.getName() != null) {
- volResponse.setName(volume.getName());
- } else {
- volResponse.setName("");
- }
-
- DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
- if (zone != null) {
- volResponse.setZoneId(zone.getUuid());
- volResponse.setZoneName(zone.getName());
- }
-
- volResponse.setVolumeType(volume.getVolumeType().toString());
- volResponse.setDeviceId(volume.getDeviceId());
-
- Long instanceId = volume.getInstanceId();
- if (instanceId != null && volume.getState() != Volume.State.Destroy) {
- VMInstanceVO vm = ApiDBUtils.findVMInstanceById(instanceId);
- if (vm != null) {
- volResponse.setVirtualMachineId(vm.getUuid());
- volResponse.setVirtualMachineName(vm.getHostName());
- volResponse.setVirtualMachineState(vm.getState().toString());
- UserVm userVm = ApiDBUtils.findUserVmById(vm.getId());
- if (userVm != null) {
- if (userVm.getDisplayName() != null) {
- volResponse.setVirtualMachineDisplayName(userVm.getDisplayName());
- }
- } else {
- s_logger.error("User Vm with Id: " + instanceId + " does not exist for volume " + volume.getId());
- }
- } else {
- s_logger.error("Vm with Id: " + instanceId + " does not exist for volume " + volume.getId());
- }
- }
-
- // Show the virtual size of the volume
- volResponse.setSize(volume.getSize());
-
- volResponse.setCreated(volume.getCreated());
- volResponse.setState(volume.getState().toString());
- if(volume.getState() == Volume.State.UploadOp){
- com.cloud.storage.VolumeHostVO volumeHostRef = ApiDBUtils.findVolumeHostRef(volume.getId(), volume.getDataCenterId());
- volResponse.setSize(volumeHostRef.getSize());
- volResponse.setCreated(volumeHostRef.getCreated());
- Account caller = UserContext.current().getCaller();
- if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)
- volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volumeHostRef.getFormat()).toString());
- if (volumeHostRef.getDownloadState() != Status.DOWNLOADED) {
- String volumeStatus = "Processing";
- if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
- if (volumeHostRef.getDownloadPercent() == 100) {
- volumeStatus = "Checking Volume";
- } else {
- volumeStatus = volumeHostRef.getDownloadPercent() + "% Uploaded";
- }
- volResponse.setState("Uploading");
- } else {
- volumeStatus = volumeHostRef.getErrorString();
- if(volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.NOT_DOWNLOADED){
- volResponse.setState("UploadNotStarted");
- }else {
- volResponse.setState("UploadError");
- }
- }
- volResponse.setStatus(volumeStatus);
- } else if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
- volResponse.setStatus("Upload Complete");
- volResponse.setState("Uploaded");
- } else {
- volResponse.setStatus("Successfully Installed");
- }
- }
-
- populateOwner(volResponse, volume);
-
- DiskOfferingVO diskOffering = ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId());
- if (diskOffering != null) {
- if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
- volResponse.setServiceOfferingId(diskOffering.getUuid());
- } else {
- volResponse.setDiskOfferingId(diskOffering.getUuid());
- }
-
- if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
- volResponse.setServiceOfferingName(diskOffering.getName());
- volResponse.setServiceOfferingDisplayText(diskOffering.getDisplayText());
- } else {
- volResponse.setDiskOfferingName(diskOffering.getName());
- volResponse.setDiskOfferingDisplayText(diskOffering.getDisplayText());
- }
- volResponse.setStorageType(diskOffering.getUseLocalStorage() ? ServiceOffering.StorageType.local.toString()
- : ServiceOffering.StorageType.shared.toString());
- }
- Long poolId = volume.getPoolId();
- String poolName = (poolId == null) ? "none" : ApiDBUtils.findStoragePoolById(poolId).getName();
- volResponse.setStoragePoolName(poolName);
- // volResponse.setSourceId(volume.getSourceId());
- // if (volume.getSourceType() != null) {
- // volResponse.setSourceType(volume.getSourceType().toString());
- // }
-
- // return hypervisor for ROOT and Resource domain only
- Account caller = UserContext.current().getCaller();
- if ((caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) && volume.getState() != Volume.State.UploadOp) {
- volResponse.setHypervisor(ApiDBUtils.getVolumeHyperType(volume.getId()).toString());
- }
-
- volResponse.setAttached(volume.getAttached());
- volResponse.setDestroyed(volume.getState() == Volume.State.Destroy);
- boolean isExtractable = true;
- if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont have any template dependence.
- VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
- if (template != null) { // For ISO based volumes template = null and we allow extraction of all ISO based volumes
- isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
- }
- }
-
- //set tag information
- List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Volume, volume.getId());
- List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
- for (ResourceTag tag : tags) {
- ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
- tagResponses.add(tagResponse);
- }
- volResponse.setTags(tagResponses);
-
- volResponse.setExtractable(isExtractable);
- volResponse.setObjectName("volume");
- return volResponse;
+ List<VolumeJoinVO> viewVrs = ApiDBUtils.newVolumeView(volume);
+ List<VolumeResponse> listVrs = ViewResponseHelper.createVolumeResponse(viewVrs.toArray(new VolumeJoinVO[viewVrs.size()]));
+ assert listVrs != null && listVrs.size() == 1 : "There should be one volume returned";
+ return listVrs.get(0);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 1551e44..3f027ed 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -55,6 +55,7 @@ import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.ConnectionClosedException;
@@ -464,7 +465,8 @@ public class ApiServer implements HttpRequestHandler {
&& !(cmdObj instanceof ListProjectsCmd)
&& !(cmdObj instanceof ListProjectAccountsCmd)
&& !(cmdObj instanceof ListProjectInvitationsCmd)
- && !(cmdObj instanceof ListHostsCmd)) {
+ && !(cmdObj instanceof ListHostsCmd)
+ && !(cmdObj instanceof ListVolumesCmd)) {
buildAsyncListResponse((BaseListCmd) cmdObj, caller);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/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 61af161..19577d2 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -39,6 +39,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCm
import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
@@ -51,6 +52,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.query.QueryService;
import org.apache.log4j.Logger;
@@ -65,6 +67,7 @@ import com.cloud.api.query.dao.ProjectJoinDao;
import com.cloud.api.query.dao.ResourceTagJoinDao;
import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
+import com.cloud.api.query.dao.VolumeJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
@@ -76,6 +79,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.async.AsyncJob;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
@@ -98,7 +102,12 @@ import com.cloud.projects.ProjectService;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.server.Criteria;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.tags.ResourceTagVO;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountManagerImpl;
@@ -119,6 +128,8 @@ import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.UserVmDao;
/**
@@ -189,6 +200,9 @@ public class QueryManagerImpl implements QueryService, Manager {
private HostJoinDao _hostJoinDao;
@Inject
+ private VolumeJoinDao _volumeJoinDao;
+
+ @Inject
private HighAvailabilityManager _haMgr;
@Override
@@ -1371,9 +1385,9 @@ public class QueryManagerImpl implements QueryService, Manager {
if ((Boolean) haHosts) {
sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.EQ);
} else {
- sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.NEQ);
- //FIXME: should we have another condition say tag = null?
- //hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
+ sb.and().op("tag", sb.entity().getTag(), SearchCriteria.Op.NEQ);
+ sb.or("tagNull", sb.entity().getTag(), SearchCriteria.Op.NULL);
+ sb.cp();
}
}
@@ -1439,4 +1453,142 @@ public class QueryManagerImpl implements QueryService, Manager {
}
+ @Override
+ public ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd) {
+ Pair<List<VolumeJoinVO>, Integer> result = searchForVolumesInternal(cmd);
+ ListResponse<VolumeResponse> response = new ListResponse<VolumeResponse>();
+
+ List<VolumeResponse> routerResponses = ViewResponseHelper.createVolumeResponse(result.first().toArray(new VolumeJoinVO[result.first().size()]));
+ response.setResponses(routerResponses, result.second());
+ return response;
+ }
+
+
+ private Pair<List<VolumeJoinVO>, Integer> searchForVolumesInternal(ListVolumesCmd cmd) {
+
+ Account caller = UserContext.current().getCaller();
+ List<Long> permittedAccounts = new ArrayList<Long>();
+
+ Long id = cmd.getId();
+ Long vmInstanceId = cmd.getVirtualMachineId();
+ String name = cmd.getVolumeName();
+ String keyword = cmd.getKeyword();
+ String type = cmd.getType();
+ Map<String, String> tags = cmd.getTags();
+
+ Long zoneId = cmd.getZoneId();
+ Long podId = null;
+ if (_accountMgr.isAdmin(caller.getType())) {
+ podId = cmd.getPodId();
+ }
+
+ Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+ _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+ Long domainId = domainIdRecursiveListProject.first();
+ Boolean isRecursive = domainIdRecursiveListProject.second();
+ ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+ Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+ // hack for now, this should be done better but due to needing a join I opted to
+ // do this quickly and worry about making it pretty later
+ SearchBuilder<VolumeJoinVO> sb = _volumeJoinDao.createSearchBuilder();
+ sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+ // ids to get
+ // number of
+ // records with
+ // pagination
+ _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+ sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+ sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+ sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
+ sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
+ sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+ // Only return volumes that are not destroyed
+ sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
+ sb.and("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
+ // display UserVM volumes only
+ sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
+ sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
+ sb.cp();
+
+ if (tags != null && !tags.isEmpty()) {
+ for (int count=0; count < tags.size(); count++) {
+ sb.or().op("key" + String.valueOf(count), sb.entity().getTagKey(), SearchCriteria.Op.EQ);
+ sb.and("value" + String.valueOf(count), sb.entity().getTagValue(), SearchCriteria.Op.EQ);
+ sb.cp();
+ }
+ }
+
+
+
+ // now set the SC criteria...
+ SearchCriteria<VolumeJoinVO> sc = sb.create();
+ _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+ if (keyword != null) {
+ SearchCriteria<VolumeJoinVO> ssc = _volumeJoinDao.createSearchCriteria();
+ ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+ ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+ sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+ }
+
+ if (name != null) {
+ sc.setParameters("name", "%" + name + "%");
+ }
+
+ sc.setParameters("systemUse", 1);
+
+ if (tags != null && !tags.isEmpty()) {
+ int count = 0;
+ for (String key : tags.keySet()) {
+ sc.setParameters("key" + String.valueOf(count), key);
+ sc.setParameters("value" + String.valueOf(count), tags.get(key));
+ count++;
+ }
+ }
+
+ if (id != null) {
+ sc.setParameters("id", id);
+ }
+
+ if (type != null) {
+ sc.setParameters("volumeType", "%" + type + "%");
+ }
+ if (vmInstanceId != null) {
+ sc.setParameters("instanceId", vmInstanceId);
+ }
+ if (zoneId != null) {
+ sc.setParameters("dataCenterId", zoneId);
+ }
+ if (podId != null) {
+ sc.setParameters("podId", podId);
+ }
+
+ // Don't return DomR and ConsoleProxy volumes
+ sc.setParameters("type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
+
+ // Only return volumes that are not destroyed
+ sc.setParameters("state", Volume.State.Destroy);
+
+ // search Volume details by ids
+ Pair<List<VolumeJoinVO>, Integer> uniqueVolPair = _volumeJoinDao.searchAndCount(sc, searchFilter);
+ Integer count = uniqueVolPair.second();
+ if (count.intValue() == 0) {
+ // empty result
+ return uniqueVolPair;
+ }
+ List<VolumeJoinVO> uniqueVols = uniqueVolPair.first();
+ Long[] vrIds = new Long[uniqueVols.size()];
+ int i = 0;
+ for (VolumeJoinVO v : uniqueVols) {
+ vrIds[i++] = v.getId();
+ }
+ List<VolumeJoinVO> vrs = _volumeJoinDao.searchByIds(vrIds);
+ return new Pair<List<VolumeJoinVO>, Integer>(vrs, count);
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/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 bb6c66b..b1a5399 100644
--- a/server/src/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/com/cloud/api/query/ViewResponseHelper.java
@@ -34,6 +34,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
@@ -48,6 +49,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.api.query.vo.SecurityGroupJoinVO;
import com.cloud.api.query.vo.UserAccountJoinVO;
import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@@ -214,4 +216,21 @@ public class ViewResponseHelper {
}
return new ArrayList<HostResponse>(vrDataList.values());
}
+
+ public static List<VolumeResponse> createVolumeResponse(VolumeJoinVO... volumes) {
+ Hashtable<Long, VolumeResponse> vrDataList = new Hashtable<Long, VolumeResponse>();
+ for (VolumeJoinVO vr : volumes) {
+ VolumeResponse vrData = vrDataList.get(vr.getId());
+ if ( vrData == null ){
+ // first time encountering this volume
+ vrData = ApiDBUtils.newVolumeResponse(vr);
+ }
+ else{
+ // update tags
+ vrData = ApiDBUtils.fillVolumeDetails(vrData, vr);
+ }
+ vrDataList.put(vr.getId(), vrData);
+ }
+ return new ArrayList<VolumeResponse>(vrDataList.values());
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/api/query/dao/VolumeJoinDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDao.java b/server/src/com/cloud/api/query/dao/VolumeJoinDao.java
new file mode 100644
index 0000000..67509cf
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/VolumeJoinDao.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.api.response.VolumeResponse;
+
+
+import com.cloud.api.query.vo.VolumeJoinVO;
+import com.cloud.storage.Volume;
+import com.cloud.utils.db.GenericDao;
+
+public interface VolumeJoinDao extends GenericDao<VolumeJoinVO, Long> {
+
+ VolumeResponse newVolumeResponse(VolumeJoinVO vol);
+
+ VolumeResponse setVolumeResponse(VolumeResponse volData, VolumeJoinVO vol);
+
+ List<VolumeJoinVO> newVolumeView(Volume vol);
+
+ List<VolumeJoinVO> searchByIds(Long... ids);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
new file mode 100644
index 0000000..f4691ce
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
@@ -0,0 +1,230 @@
+// 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 javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.vo.ResourceTagJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
+import org.apache.cloudstack.api.response.VolumeResponse;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.Storage;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+
+@Local(value={VolumeJoinDao.class})
+public class VolumeJoinDaoImpl extends GenericDaoBase<VolumeJoinVO, Long> implements VolumeJoinDao {
+ public static final Logger s_logger = Logger.getLogger(VolumeJoinDaoImpl.class);
+
+ private SearchBuilder<VolumeJoinVO> volSearch;
+
+ private SearchBuilder<VolumeJoinVO> volIdSearch;
+
+ protected VolumeJoinDaoImpl() {
+
+ volSearch = createSearchBuilder();
+ volSearch.and("idIN", volSearch.entity().getId(), SearchCriteria.Op.IN);
+ volSearch.done();
+
+ volIdSearch = createSearchBuilder();
+ volIdSearch.and("id", volIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+ volIdSearch.done();
+
+ this._count = "select count(distinct id) from volume_view WHERE ";
+ }
+
+
+
+
+ @Override
+ public VolumeResponse newVolumeResponse(VolumeJoinVO volume) {
+ Account caller = UserContext.current().getCaller();
+
+ VolumeResponse volResponse = new VolumeResponse();
+ volResponse.setId(volume.getUuid());
+
+ if (volume.getName() != null) {
+ volResponse.setName(volume.getName());
+ } else {
+ volResponse.setName("");
+ }
+
+ volResponse.setZoneId(volume.getDataCenterUuid());
+ volResponse.setZoneName(volume.getDataCenterName());
+
+ volResponse.setVolumeType(volume.getVolumeType().toString());
+ volResponse.setDeviceId(volume.getDeviceId());
+
+ long instanceId = volume.getVmId();
+ if (instanceId > 0 && volume.getState() != Volume.State.Destroy) {
+ volResponse.setVirtualMachineId(volume.getVmUuid());
+ volResponse.setVirtualMachineName(volume.getVmName());
+ volResponse.setVirtualMachineState(volume.getVmState().toString());
+ volResponse.setVirtualMachineDisplayName(volume.getVmDisplayName());
+ }
+
+ // Show the virtual size of the volume
+ volResponse.setSize(volume.getSize());
+
+ volResponse.setCreated(volume.getCreated());
+ volResponse.setState(volume.getState().toString());
+ if (volume.getState() == Volume.State.UploadOp) {
+ // com.cloud.storage.VolumeHostVO volumeHostRef =
+ // ApiDBUtils.findVolumeHostRef(volume.getId(),
+ // volume.getDataCenterId());
+ volResponse.setSize(volume.getVolumeHostSize());
+ volResponse.setCreated(volume.getVolumeHostCreated());
+
+ if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)
+ volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volume.getFormat()).toString());
+ if (volume.getDownloadState() != Status.DOWNLOADED) {
+ String volumeStatus = "Processing";
+ if (volume.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
+ if (volume.getDownloadPercent() == 100) {
+ volumeStatus = "Checking Volume";
+ } else {
+ volumeStatus = volume.getDownloadPercent() + "% Uploaded";
+ }
+ volResponse.setState("Uploading");
+ } else {
+ volumeStatus = volume.getErrorString();
+ if (volume.getDownloadState() == VMTemplateHostVO.Status.NOT_DOWNLOADED) {
+ volResponse.setState("UploadNotStarted");
+ } else {
+ volResponse.setState("UploadError");
+ }
+ }
+ volResponse.setStatus(volumeStatus);
+ } else if (volume.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
+ volResponse.setStatus("Upload Complete");
+ volResponse.setState("Uploaded");
+ } else {
+ volResponse.setStatus("Successfully Installed");
+ }
+ }
+
+ // populate owner.
+ ApiResponseHelper.populateOwner(volResponse, volume);
+
+ // DiskOfferingVO diskOffering =
+ // ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId());
+ if (volume.getDiskOfferingId() > 0) {
+ if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
+ volResponse.setServiceOfferingId(volume.getDiskOfferingUuid());
+ } else {
+ volResponse.setDiskOfferingId(volume.getDiskOfferingUuid());
+ }
+
+ if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
+ volResponse.setServiceOfferingName(volume.getDiskOfferingName());
+ volResponse.setServiceOfferingDisplayText(volume.getDiskOfferingDisplayText());
+ } else {
+ volResponse.setDiskOfferingName(volume.getDiskOfferingName());
+ volResponse.setDiskOfferingDisplayText(volume.getDiskOfferingDisplayText());
+ }
+ volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared
+ .toString());
+ }
+ Long poolId = volume.getPoolId();
+ String poolName = (poolId == null) ? "none" : volume.getPoolName();
+ volResponse.setStoragePoolName(poolName);
+
+ // return hypervisor for ROOT and Resource domain only
+ if ((caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)
+ && volume.getState() != Volume.State.UploadOp && volume.getHypervisorType() != null) {
+ volResponse.setHypervisor(volume.getHypervisorType().toString());
+ }
+
+ volResponse.setAttached(volume.getAttached());
+ volResponse.setDestroyed(volume.getState() == Volume.State.Destroy);
+ boolean isExtractable = true;
+ if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont
+ // have any
+ // template
+ // dependence.
+ if (volume.getTemplateId() > 0) { // For ISO based volumes template
+ // = null and we allow extraction
+ // of all ISO based volumes
+ isExtractable = volume.isExtractable() && volume.getTemplateType() != Storage.TemplateType.SYSTEM;
+ }
+ }
+
+ // update tag information
+ long tag_id = volume.getTagId();
+ if (tag_id > 0) {
+ ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
+ if (vtag != null) {
+ volResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
+ }
+ }
+
+ volResponse.setExtractable(isExtractable);
+ volResponse.setObjectName("volume");
+ return volResponse;
+ }
+
+
+
+ @Override
+ public VolumeResponse setVolumeResponse(VolumeResponse volData, VolumeJoinVO vol) {
+ long tag_id = vol.getTagId();
+ if (tag_id > 0) {
+ ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
+ if ( vtag != null ){
+ volData.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
+ }
+ }
+ return volData;
+ }
+
+
+
+
+ @Override
+ public List<VolumeJoinVO> newVolumeView(Volume vol) {
+ SearchCriteria<VolumeJoinVO> sc = volIdSearch.create();
+ sc.setParameters("id", vol.getId());
+ return searchIncludingRemoved(sc, null, null, false);
+ }
+
+
+
+
+ @Override
+ public List<VolumeJoinVO> searchByIds(Long... ids) {
+ SearchCriteria<VolumeJoinVO> sc = volSearch.create();
+ sc.setParameters("idIN", ids);
+ return searchIncludingRemoved(sc, null, null, false);
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
new file mode 100644
index 0000000..96c2615
--- /dev/null
+++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
@@ -0,0 +1,1032 @@
+// 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 java.util.Date;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+
+@Entity
+@Table(name="volume_view")
+public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
+
+ @Column(name="id")
+ private long id;
+
+ @Column(name="uuid")
+ private String uuid;
+
+
+ @Column(name="name")
+ private String name;
+
+ @Column(name = "device_id")
+ Long deviceId = null;
+
+ @Column(name = "volume_type")
+ @Enumerated(EnumType.STRING)
+ Volume.Type volumeType;
+
+ @Column(name = "size")
+ long size;
+
+ @Column(name = "state")
+ @Enumerated(value = EnumType.STRING)
+ private Volume.State state;
+
+ @Column(name=GenericDao.CREATED_COLUMN)
+ private Date created;
+
+ @Column(name = "attached")
+ @Temporal(value = TemporalType.TIMESTAMP)
+ Date attached;
+
+ @Column(name=GenericDao.REMOVED_COLUMN)
+ private Date removed;
+
+
+ @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="project_id")
+ private long projectId;
+
+ @Column(name="project_uuid")
+ private String projectUuid;
+
+ @Column(name="project_name")
+ private String projectName;
+
+ @Column(name="pod_id")
+ private long podId;
+
+ @Column(name="data_center_id")
+ private long dataCenterId;
+
+ @Column(name="data_center_uuid")
+ private String dataCenterUuid;
+
+ @Column(name="data_center_name")
+ private String dataCenterName;
+
+ @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;
+
+ @Column(name="vm_type")
+ @Enumerated(value=EnumType.STRING)
+ protected VirtualMachine.Type vmType;
+
+ @Column (name="volume_host_size")
+ private long volumeHostSize;
+
+ @Column(name="volume_host_created")
+ private Date volumeHostCreated;
+
+ @Column(name="format")
+ private Storage.ImageFormat format;
+
+ @Column (name="download_pct")
+ private int downloadPercent;
+
+ @Column (name="download_state")
+ @Enumerated(EnumType.STRING)
+ private Status downloadState;
+
+ @Column (name="error_str")
+ private String errorString;
+
+ @Column(name="hypervisor_type")
+ @Enumerated(value=EnumType.STRING)
+ private HypervisorType hypervisorType;
+
+
+ @Column(name="disk_offering_id")
+ private long diskOfferingId;
+
+ @Column(name="disk_offering_uuid")
+ private String diskOfferingUuid;
+
+ @Column(name="disk_offering_name")
+ private String diskOfferingName;
+
+ @Column(name="disk_offering_display_text")
+ private String diskOfferingDisplayText;
+
+ @Column(name="system_use")
+ private boolean systemUse;
+
+
+ @Column(name="use_local_storage")
+ private boolean useLocalStorage;
+
+ @Column(name="pool_id")
+ private long poolId;
+
+ @Column(name="pool_uuid")
+ private String poolUuid;
+
+ @Column(name="pool_name")
+ private String poolName;
+
+ @Column(name="template_id")
+ private long templateId;
+
+ @Column(name="template_uuid")
+ private String templateUuid;
+
+ @Column(name="extractable")
+ private boolean extractable;
+
+ @Column(name="template_type")
+ private Storage.TemplateType templateType;
+
+ @Column(name="job_id")
+ private long jobId;
+
+ @Column(name="job_uuid")
+ private String jobUuid;
+
+ @Column(name="job_status")
+ private int jobStatus;
+
+ @Column(name="tag_id")
+ private long tagId;
+
+ @Column(name="tag_uuid")
+ private String tagUuid;
+
+ @Column(name="tag_key")
+ private String tagKey;
+
+ @Column(name="tag_value")
+ private String tagValue;
+
+ @Column(name="tag_domain_id")
+ private long tagDomainId;
+
+ @Column(name="tag_account_id")
+ private long tagAccountId;
+
+ @Column(name="tag_resource_id")
+ private long tagResourceId;
+
+ @Column(name="tag_resource_uuid")
+ private String tagResourceUuid;
+
+ @Column(name="tag_resource_type")
+ @Enumerated(value=EnumType.STRING)
+ private TaggedResourceType tagResourceType;
+
+ @Column(name="tag_customer")
+ private String tagCustomer;
+
+
+
+ public VolumeJoinVO() {
+ }
+
+
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+
+
+ @Override
+ public void setId(long id) {
+ this.id = id;
+ }
+
+
+
+ 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;
+ }
+
+
+
+ public Long getDeviceId() {
+ return deviceId;
+ }
+
+
+
+ public void setDeviceId(Long deviceId) {
+ this.deviceId = deviceId;
+ }
+
+
+
+ public Volume.Type getVolumeType() {
+ return volumeType;
+ }
+
+
+
+ public void setVolumeType(Volume.Type volumeType) {
+ this.volumeType = volumeType;
+ }
+
+
+
+ public long getSize() {
+ return size;
+ }
+
+
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+
+
+ public Volume.State getState() {
+ return state;
+ }
+
+
+
+ public void setState(Volume.State state) {
+ this.state = state;
+ }
+
+
+
+ public Date getCreated() {
+ return created;
+ }
+
+
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
+
+
+ public Date getAttached() {
+ return attached;
+ }
+
+
+
+ public void setAttached(Date attached) {
+ this.attached = attached;
+ }
+
+
+
+ public Date getRemoved() {
+ return removed;
+ }
+
+
+
+ public void setRemoved(Date removed) {
+ this.removed = removed;
+ }
+
+
+
+ @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 long getProjectId() {
+ return projectId;
+ }
+
+
+
+ public void setProjectId(long projectId) {
+ this.projectId = projectId;
+ }
+
+
+
+ @Override
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+
+
+ public void setProjectUuid(String projectUuid) {
+ this.projectUuid = projectUuid;
+ }
+
+
+
+ @Override
+ public String getProjectName() {
+ return projectName;
+ }
+
+
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+
+
+ 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;
+ }
+
+
+
+ public VirtualMachine.Type getVmType() {
+ return vmType;
+ }
+
+
+
+ public void setVmType(VirtualMachine.Type vmType) {
+ this.vmType = vmType;
+ }
+
+
+
+ public long getVolumeHostSize() {
+ return volumeHostSize;
+ }
+
+
+
+ public void setVolumeHostSize(long volumeHostSize) {
+ this.volumeHostSize = volumeHostSize;
+ }
+
+
+
+ public Date getVolumeHostCreated() {
+ return volumeHostCreated;
+ }
+
+
+
+ public void setVolumeHostCreated(Date volumeHostCreated) {
+ this.volumeHostCreated = volumeHostCreated;
+ }
+
+
+
+ public Storage.ImageFormat getFormat() {
+ return format;
+ }
+
+
+
+ public void setFormat(Storage.ImageFormat format) {
+ this.format = format;
+ }
+
+
+
+ public int getDownloadPercent() {
+ return downloadPercent;
+ }
+
+
+
+ public void setDownloadPercent(int downloadPercent) {
+ this.downloadPercent = downloadPercent;
+ }
+
+
+
+ public Status getDownloadState() {
+ return downloadState;
+ }
+
+
+
+ public void setDownloadState(Status downloadState) {
+ this.downloadState = downloadState;
+ }
+
+
+
+ public String getErrorString() {
+ return errorString;
+ }
+
+
+
+ public void setErrorString(String errorString) {
+ this.errorString = errorString;
+ }
+
+
+
+ public HypervisorType getHypervisorType() {
+ return hypervisorType;
+ }
+
+
+
+ public void setHypervisorType(HypervisorType hypervisorType) {
+ this.hypervisorType = hypervisorType;
+ }
+
+
+
+ public long getDiskOfferingId() {
+ return diskOfferingId;
+ }
+
+
+
+ public void setDiskOfferingId(long diskOfferingId) {
+ this.diskOfferingId = diskOfferingId;
+ }
+
+
+
+ public String getDiskOfferingUuid() {
+ return diskOfferingUuid;
+ }
+
+
+
+ public void setDiskOfferingUuid(String diskOfferingUuid) {
+ this.diskOfferingUuid = diskOfferingUuid;
+ }
+
+
+
+ public String getDiskOfferingName() {
+ return diskOfferingName;
+ }
+
+
+
+ public void setDiskOfferingName(String diskOfferingName) {
+ this.diskOfferingName = diskOfferingName;
+ }
+
+
+
+ public String getDiskOfferingDisplayText() {
+ return diskOfferingDisplayText;
+ }
+
+
+
+ public void setDiskOfferingDisplayText(String diskOfferingDisplayText) {
+ this.diskOfferingDisplayText = diskOfferingDisplayText;
+ }
+
+
+
+ public boolean isUseLocalStorage() {
+ return useLocalStorage;
+ }
+
+
+
+ public void setUseLocalStorage(boolean useLocalStorage) {
+ this.useLocalStorage = useLocalStorage;
+ }
+
+
+
+ public long getPoolId() {
+ return poolId;
+ }
+
+
+
+ public void setPoolId(long poolId) {
+ this.poolId = poolId;
+ }
+
+
+
+ public String getPoolUuid() {
+ return poolUuid;
+ }
+
+
+
+ public void setPoolUuid(String poolUuid) {
+ this.poolUuid = poolUuid;
+ }
+
+
+
+ public String getPoolName() {
+ return poolName;
+ }
+
+
+
+ public void setPoolName(String poolName) {
+ this.poolName = poolName;
+ }
+
+
+
+ public long getTemplateId() {
+ return templateId;
+ }
+
+
+
+ public void setTemplateId(long templateId) {
+ this.templateId = templateId;
+ }
+
+
+
+ public String getTemplateUuid() {
+ return templateUuid;
+ }
+
+
+
+ public void setTemplateUuid(String templateUuid) {
+ this.templateUuid = templateUuid;
+ }
+
+
+
+ public boolean isExtractable() {
+ return extractable;
+ }
+
+
+
+ public void setExtractable(boolean extractable) {
+ this.extractable = extractable;
+ }
+
+
+
+ public Storage.TemplateType getTemplateType() {
+ return templateType;
+ }
+
+
+
+ public void setTemplateType(Storage.TemplateType templateType) {
+ this.templateType = templateType;
+ }
+
+
+
+ public long getJobId() {
+ return jobId;
+ }
+
+
+
+ public void setJobId(long jobId) {
+ this.jobId = jobId;
+ }
+
+
+
+ public String getJobUuid() {
+ return jobUuid;
+ }
+
+
+
+ public void setJobUuid(String jobUuid) {
+ this.jobUuid = jobUuid;
+ }
+
+
+
+ public int getJobStatus() {
+ return jobStatus;
+ }
+
+
+
+ public void setJobStatus(int jobStatus) {
+ this.jobStatus = jobStatus;
+ }
+
+
+
+ public long getTagId() {
+ return tagId;
+ }
+
+
+
+ public void setTagId(long tagId) {
+ this.tagId = tagId;
+ }
+
+
+
+ public String getTagUuid() {
+ return tagUuid;
+ }
+
+
+
+ public void setTagUuid(String tagUuid) {
+ this.tagUuid = tagUuid;
+ }
+
+
+
+ public String getTagKey() {
+ return tagKey;
+ }
+
+
+
+ public void setTagKey(String tagKey) {
+ this.tagKey = tagKey;
+ }
+
+
+
+ public String getTagValue() {
+ return tagValue;
+ }
+
+
+
+ public void setTagValue(String tagValue) {
+ this.tagValue = tagValue;
+ }
+
+
+
+ public long getTagDomainId() {
+ return tagDomainId;
+ }
+
+
+
+ public void setTagDomainId(long tagDomainId) {
+ this.tagDomainId = tagDomainId;
+ }
+
+
+
+ public long getTagAccountId() {
+ return tagAccountId;
+ }
+
+
+
+ public void setTagAccountId(long tagAccountId) {
+ this.tagAccountId = tagAccountId;
+ }
+
+
+
+ public long getTagResourceId() {
+ return tagResourceId;
+ }
+
+
+
+ public void setTagResourceId(long tagResourceId) {
+ this.tagResourceId = tagResourceId;
+ }
+
+
+
+ public String getTagResourceUuid() {
+ return tagResourceUuid;
+ }
+
+
+
+ public void setTagResourceUuid(String tagResourceUuid) {
+ this.tagResourceUuid = tagResourceUuid;
+ }
+
+
+
+ public TaggedResourceType getTagResourceType() {
+ return tagResourceType;
+ }
+
+
+
+ public void setTagResourceType(TaggedResourceType tagResourceType) {
+ this.tagResourceType = tagResourceType;
+ }
+
+
+
+ public String getTagCustomer() {
+ return tagCustomer;
+ }
+
+
+
+ public void setTagCustomer(String tagCustomer) {
+ this.tagCustomer = tagCustomer;
+ }
+
+
+
+ public long getDataCenterId() {
+ return dataCenterId;
+ }
+
+
+
+ public void setDataCenterId(long dataCenterId) {
+ this.dataCenterId = dataCenterId;
+ }
+
+
+
+ public String getDataCenterUuid() {
+ return dataCenterUuid;
+ }
+
+
+
+ public void setDataCenterUuid(String dataCenterUuid) {
+ this.dataCenterUuid = dataCenterUuid;
+ }
+
+
+
+ public String getDataCenterName() {
+ return dataCenterName;
+ }
+
+
+
+ public void setDataCenterName(String dataCenterName) {
+ this.dataCenterName = dataCenterName;
+ }
+
+
+
+ public long getPodId() {
+ return podId;
+ }
+
+
+
+ public void setPodId(long podId) {
+ this.podId = podId;
+ }
+
+
+
+ public boolean isSystemUse() {
+ return systemUse;
+ }
+
+
+
+ public void setSystemUse(boolean systemUse) {
+ this.systemUse = systemUse;
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index d50ac35..1824f49 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -34,6 +34,7 @@ import com.cloud.api.query.dao.ResourceTagJoinDaoImpl;
import com.cloud.api.query.dao.SecurityGroupJoinDaoImpl;
import com.cloud.api.query.dao.UserVmJoinDaoImpl;
import com.cloud.api.query.dao.HostJoinDaoImpl;
+import com.cloud.api.query.dao.VolumeJoinDaoImpl;
import com.cloud.async.AsyncJobExecutorContextImpl;
import com.cloud.async.AsyncJobManagerImpl;
import com.cloud.async.SyncQueueManagerImpl;
@@ -222,6 +223,7 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
import com.cloud.event.dao.EventJoinDaoImpl;
+
public class DefaultComponentLibrary extends ComponentLibraryBase implements ComponentLibrary {
protected void populateDaos() {
addDao("StackMaidDao", StackMaidDaoImpl.class);
@@ -241,6 +243,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("ProjectAccountJoinDao", ProjectAccountJoinDaoImpl.class);
addDao("ProjectInvitationJoinDao", ProjectInvitationJoinDaoImpl.class);
addDao("HostJoinDao", HostJoinDaoImpl.class);
+ addDao("VolumeJoinDao", VolumeJoinDaoImpl.class);
ComponentInfo<? extends GenericDao<?, ? extends Serializable>> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class);
info.addParameter("cache.size", "50");
info.addParameter("cache.time.to.live", "600");
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index 110e955..21ee972 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -3859,124 +3859,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
return secHost;
}
- @Override
- public Pair<List<? extends Volume>, Integer> searchForVolumes(ListVolumesCmd cmd) {
- Account caller = UserContext.current().getCaller();
- List<Long> permittedAccounts = new ArrayList<Long>();
-
- Long id = cmd.getId();
- Long vmInstanceId = cmd.getVirtualMachineId();
- String name = cmd.getVolumeName();
- String keyword = cmd.getKeyword();
- String type = cmd.getType();
- Map<String, String> tags = cmd.getTags();
-
- Long zoneId = cmd.getZoneId();
- Long podId = null;
- // Object host = null; TODO
- if (_accountMgr.isAdmin(caller.getType())) {
- podId = cmd.getPodId();
- // host = cmd.getHostId(); TODO
- }
-
- Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
- _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
- Long domainId = domainIdRecursiveListProject.first();
- Boolean isRecursive = domainIdRecursiveListProject.second();
- ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
- Filter searchFilter = new Filter(VolumeVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
- // hack for now, this should be done better but due to needing a join I opted to
- // do this quickly and worry about making it pretty later
- SearchBuilder<VolumeVO> sb = _volumeDao.createSearchBuilder();
- _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
- sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
- sb.and("instanceId", sb.entity().getInstanceId(), SearchCriteria.Op.EQ);
- sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
- sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
- // Only return volumes that are not destroyed
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
-
- SearchBuilder<DiskOfferingVO> diskOfferingSearch = _diskOfferingDao.createSearchBuilder();
- diskOfferingSearch.and("systemUse", diskOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.NEQ);
- sb.join("diskOfferingSearch", diskOfferingSearch, sb.entity().getDiskOfferingId(), diskOfferingSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER);
-
- // display UserVM volumes only
- SearchBuilder<VMInstanceVO> vmSearch = _vmInstanceDao.createSearchBuilder();
- vmSearch.and("type", vmSearch.entity().getType(), SearchCriteria.Op.NIN);
- vmSearch.or("nulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL);
- sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER);
-
- if (tags != null && !tags.isEmpty()) {
- SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
- for (int count=0; count < tags.size(); count++) {
- tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
- tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
- tagSearch.cp();
- }
- tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
- sb.groupBy(sb.entity().getId());
- sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
- }
-
- // now set the SC criteria...
- SearchCriteria<VolumeVO> sc = sb.create();
- _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
- if (keyword != null) {
- SearchCriteria<VolumeVO> ssc = _volumeDao.createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
- }
- if (name != null) {
- sc.setParameters("name", "%" + name + "%");
- }
-
- sc.setJoinParameters("diskOfferingSearch", "systemUse", 1);
-
- if (tags != null && !tags.isEmpty()) {
- int count = 0;
- sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.toString());
- for (String key : tags.keySet()) {
- sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
- sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
- count++;
- }
- }
-
- if (id != null) {
- sc.setParameters("id", id);
- }
-
- if (type != null) {
- sc.setParameters("volumeType", "%" + type + "%");
- }
- if (vmInstanceId != null) {
- sc.setParameters("instanceId", vmInstanceId);
- }
- if (zoneId != null) {
- sc.setParameters("dataCenterId", zoneId);
- }
- if (podId != null) {
- sc.setParameters("podId", podId);
- }
-
- // Don't return DomR and ConsoleProxy volumes
- sc.setJoinParameters("vmSearch", "type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
-
- // Only return volumes that are not destroyed
- sc.setParameters("state", Volume.State.Destroy);
-
- Pair<List<VolumeVO>, Integer> volumes = _volumeDao.searchAndCount(sc, searchFilter);
-
- return new Pair<List<? extends Volume>, Integer>(volumes.first(), volumes.second());
- }
@Override
public String getSupportedImageFormatForCluster(Long clusterId) {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/server/test/com/cloud/api/ListPerfTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/ListPerfTest.java b/server/test/com/cloud/api/ListPerfTest.java
index 47abcae..9f1b4b5 100644
--- a/server/test/com/cloud/api/ListPerfTest.java
+++ b/server/test/com/cloud/api/ListPerfTest.java
@@ -106,4 +106,18 @@ public class ListPerfTest extends APITest {
System.out.println("Time taken to list Hosts: " + (after - before) + " ms");
}
+
+ @Test
+ public void testListVolumes(){
+ // issue list Hosts calls
+ HashMap<String, String> params = new HashMap<String, String>();
+ params.put("response", "json");
+ params.put("listAll", "true");
+ params.put("sessionkey", sessionKey);
+ long before = System.currentTimeMillis();
+ String result = this.sendRequest("listVolumes", params);
+ long after = System.currentTimeMillis();
+ System.out.println("Time taken to list Volumes: " + (after - before) + " ms");
+
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index a95f190..4068cc6 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -3062,4 +3062,86 @@ left join op_host_capacity mem_caps on host.id = mem_caps.host_id and mem_caps.c
left join op_host_capacity cpu_caps on host.id = cpu_caps.host_id and cpu_caps.capacity_type = 1
left join async_job on async_job.instance_id = host.id and async_job.instance_type = "Host" and async_job.job_status = 0;
+DROP VIEW IF EXISTS `cloud`.`volume_view`;
+CREATE VIEW volume_view AS
+select
+volumes.id,
+volumes.uuid,
+volumes.name,
+volumes.device_id,
+volumes.volume_type,
+volumes.size,
+volumes.created,
+volumes.state,
+volumes.attached,
+volumes.removed,
+volumes.pod_id,
+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,
+projects.id project_id,
+projects.uuid project_uuid,
+projects.name project_name,
+data_center.id data_center_id,
+data_center.uuid data_center_uuid,
+data_center.name data_center_name,
+vm_instance.id vm_id,
+vm_instance.uuid vm_uuid,
+vm_instance.name vm_name,
+vm_instance.state vm_state,
+vm_instance.vm_type,
+user_vm.display_name vm_display_name,
+volume_host_ref.size volume_host_size,
+volume_host_ref.created volume_host_created,
+volume_host_ref.format,
+volume_host_ref.download_pct,
+volume_host_ref.download_state,
+volume_host_ref.error_str,
+disk_offering.id disk_offering_id,
+disk_offering.uuid disk_offering_uuid,
+disk_offering.name disk_offering_name,
+disk_offering.display_text disk_offering_display_text,
+disk_offering.use_local_storage,
+disk_offering.system_use,
+storage_pool.id pool_id,
+storage_pool.uuid pool_uuid,
+storage_pool.name pool_name,
+cluster.hypervisor_type,
+vm_template.id template_id,
+vm_template.uuid template_uuid,
+vm_template.extractable,
+vm_template.type template_type,
+resource_tags.id tag_id,
+resource_tags.uuid tag_uuid,
+resource_tags.key tag_key,
+resource_tags.value tag_value,
+resource_tags.domain_id tag_domain_id,
+resource_tags.account_id tag_account_id,
+resource_tags.resource_id tag_resource_id,
+resource_tags.resource_uuid tag_resource_uuid,
+resource_tags.resource_type tag_resource_type,
+resource_tags.customer tag_customer,
+async_job.id job_id,
+async_job.uuid job_uuid,
+async_job.job_status job_status,
+async_job.account_id job_account_id
+from volumes
+inner join account on volumes.account_id=account.id
+inner join domain on volumes.domain_id=domain.id
+left join projects on projects.project_account_id = account.id
+left join data_center on volumes.data_center_id = data_center.id
+left join vm_instance on volumes.instance_id = vm_instance.id
+left join user_vm on user_vm.id = vm_instance.id
+left join volume_host_ref on volumes.id = volume_host_ref.volume_id and volumes.data_center_id = volume_host_ref.zone_id
+left join disk_offering on volumes.disk_offering_id = disk_offering.id
+left join storage_pool on volumes.pool_id = storage_pool.id
+left join cluster on storage_pool.cluster_id = cluster.id
+left join vm_template on volumes.template_id = vm_template.id
+left join resource_tags on resource_tags.resource_id = volumes.id and resource_tags.resource_type = "Volume"
+left join async_job on async_job.instance_id = volumes.id and async_job.instance_type = "Volume" and async_job.job_status = 0;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/21c1623a/setup/db/db/schema-40to410.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql
index 6c58bd9..04df535 100644
--- a/setup/db/db/schema-40to410.sql
+++ b/setup/db/db/schema-40to410.sql
@@ -637,3 +637,88 @@ left join host_tags on host_tags.host_id = host.id
left join op_host_capacity mem_caps on host.id = mem_caps.host_id and mem_caps.capacity_type = 0
left join op_host_capacity cpu_caps on host.id = cpu_caps.host_id and cpu_caps.capacity_type = 1
left join async_job on async_job.instance_id = host.id and async_job.instance_type = "Host" and async_job.job_status = 0;
+
+DROP VIEW IF EXISTS `cloud`.`volume_view`;
+CREATE VIEW volume_view AS
+select
+volumes.id,
+volumes.uuid,
+volumes.name,
+volumes.device_id,
+volumes.volume_type,
+volumes.size,
+volumes.created,
+volumes.state,
+volumes.attached,
+volumes.removed,
+volumes.pod_id,
+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,
+projects.id project_id,
+projects.uuid project_uuid,
+projects.name project_name,
+data_center.id data_center_id,
+data_center.uuid data_center_uuid,
+data_center.name data_center_name,
+vm_instance.id vm_id,
+vm_instance.uuid vm_uuid,
+vm_instance.name vm_name,
+vm_instance.state vm_state,
+vm_instance.vm_type,
+user_vm.display_name vm_display_name,
+volume_host_ref.size volume_host_size,
+volume_host_ref.created volume_host_created,
+volume_host_ref.format,
+volume_host_ref.download_pct,
+volume_host_ref.download_state,
+volume_host_ref.error_str,
+disk_offering.id disk_offering_id,
+disk_offering.uuid disk_offering_uuid,
+disk_offering.name disk_offering_name,
+disk_offering.display_text disk_offering_display_text,
+disk_offering.use_local_storage,
+disk_offering.system_use,
+storage_pool.id pool_id,
+storage_pool.uuid pool_uuid,
+storage_pool.name pool_name,
+cluster.hypervisor_type,
+vm_template.id template_id,
+vm_template.uuid template_uuid,
+vm_template.extractable,
+vm_template.type template_type,
+resource_tags.id tag_id,
+resource_tags.uuid tag_uuid,
+resource_tags.key tag_key,
+resource_tags.value tag_value,
+resource_tags.domain_id tag_domain_id,
+resource_tags.account_id tag_account_id,
+resource_tags.resource_id tag_resource_id,
+resource_tags.resource_uuid tag_resource_uuid,
+resource_tags.resource_type tag_resource_type,
+resource_tags.customer tag_customer,
+async_job.id job_id,
+async_job.uuid job_uuid,
+async_job.job_status job_status,
+async_job.account_id job_account_id
+from volumes
+inner join account on volumes.account_id=account.id
+inner join domain on volumes.domain_id=domain.id
+left join projects on projects.project_account_id = account.id
+left join data_center on volumes.data_center_id = data_center.id
+left join vm_instance on volumes.instance_id = vm_instance.id
+left join user_vm on user_vm.id = vm_instance.id
+left join volume_host_ref on volumes.id = volume_host_ref.volume_id and volumes.data_center_id = volume_host_ref.zone_id
+left join disk_offering on volumes.disk_offering_id = disk_offering.id
+left join storage_pool on volumes.pool_id = storage_pool.id
+left join cluster on storage_pool.cluster_id = cluster.id
+left join vm_template on volumes.template_id = vm_template.id
+left join resource_tags on resource_tags.resource_id = volumes.id and resource_tags.resource_type = "Volume"
+left join async_job on async_job.instance_id = volumes.id and async_job.instance_type = "Volume" and async_job.job_status = 0;
+
+