// 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.inject.Inject; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiResponseHelper; import com.cloud.api.query.vo.VolumeJoinVO; import com.cloud.offering.ServiceOffering; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.user.AccountManager; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation<VolumeJoinVO, VolumeResponse> implements VolumeJoinDao { public static final Logger s_logger = Logger.getLogger(VolumeJoinDaoImpl.class); @Inject private ConfigurationDao _configDao; @Inject public AccountManager _accountMgr; private final SearchBuilder<VolumeJoinVO> volSearch; private final 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(); _count = "select count(distinct id) from volume_view WHERE "; } @Override public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) { 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()); if (volume.getVolumeType() != null) { 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()); if (volume.getVmState() != null) { volResponse.setVirtualMachineState(volume.getVmState().toString()); } if (volume.getVmDisplayName() != null) { volResponse.setVirtualMachineDisplayName(volume.getVmDisplayName()); } else { volResponse.setVirtualMachineDisplayName(volume.getVmName()); } } if (volume.getProvisioningType() != null) { volResponse.setProvisioningType(volume.getProvisioningType().toString()); } // Show the virtual size of the volume volResponse.setSize(volume.getSize()); volResponse.setMinIops(volume.getMinIops()); volResponse.setMaxIops(volume.getMaxIops()); volResponse.setCreated(volume.getCreated()); if (volume.getState() != null) { 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.getVolumeStoreSize()); volResponse.setCreated(volume.getCreatedOnStore()); if (view == ResponseView.Full) volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volume.getDataCenterId(), 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"); } } if (view == ResponseView.Full) { volResponse.setPath(volume.getPath()); } // populate owner. ApiResponseHelper.populateOwner(volResponse, volume); // DiskOfferingVO diskOffering = // ApiDBUtils.findDiskOfferingById(volume.getDiskOfferingId()); if (volume.getDiskOfferingId() > 0) { boolean isServiceOffering = false; if (volume.getVolumeType().equals(Volume.Type.ROOT)) { isServiceOffering = true; } else { // can't rely on the fact that the volume is the datadisk as it might have been created as a root, and // then detached later long offeringId = volume.getDiskOfferingId(); if (ApiDBUtils.findDiskOfferingById(offeringId) == null) { isServiceOffering = true; } } if (isServiceOffering) { volResponse.setServiceOfferingId(volume.getDiskOfferingUuid()); volResponse.setServiceOfferingName(volume.getDiskOfferingName()); volResponse.setServiceOfferingDisplayText(volume.getDiskOfferingDisplayText()); } else { volResponse.setDiskOfferingId(volume.getDiskOfferingUuid()); volResponse.setDiskOfferingName(volume.getDiskOfferingName()); volResponse.setDiskOfferingDisplayText(volume.getDiskOfferingDisplayText()); } volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString()); volResponse.setBytesReadRate(volume.getBytesReadRate()); volResponse.setBytesWriteRate(volume.getBytesReadRate()); volResponse.setIopsReadRate(volume.getIopsWriteRate()); volResponse.setIopsWriteRate(volume.getIopsWriteRate()); } // return hypervisor and storage pool info for ROOT and Resource domain only if (view == ResponseView.Full) { if (volume.getState() != Volume.State.UploadOp) { if (volume.getHypervisorType() != null) { volResponse.setHypervisor(volume.getHypervisorType().toString()); } else { volResponse.setHypervisor(ApiDBUtils.getHypervisorTypeFromFormat(volume.getDataCenterId(), volume.getFormat()).toString()); } } Long poolId = volume.getPoolId(); String poolName = (poolId == null) ? "none" : volume.getPoolName(); volResponse.setStoragePoolName(poolName); volResponse.setStoragePoolId(volume.getPoolUuid()); } 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) { addTagInformation(volume, volResponse); } volResponse.setExtractable(isExtractable); volResponse.setDisplayVolume(volume.isDisplayVolume()); volResponse.setChainInfo(volume.getChainInfo()); volResponse.setTemplateId(volume.getTemplateUuid()); volResponse.setTemplateName(volume.getTemplateName()); volResponse.setTemplateDisplayText(volume.getTemplateDisplayText()); volResponse.setIsoId(volume.getIsoUuid()); volResponse.setIsoName(volume.getIsoName()); volResponse.setIsoDisplayText(volume.getIsoDisplayText()); // set async job if (volume.getJobId() != null) { volResponse.setJobId(volume.getJobUuid()); volResponse.setJobStatus(volume.getJobStatus()); } volResponse.setObjectName("volume"); return volResponse; } @Override public VolumeResponse setVolumeResponse(ResponseView view, VolumeResponse volData, VolumeJoinVO vol) { long tag_id = vol.getTagId(); if (tag_id > 0) { addTagInformation(vol, volData); } 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... volIds) { // 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<VolumeJoinVO> uvList = new ArrayList<VolumeJoinVO>(); // query details by batches int curr_index = 0; if (volIds.length > DETAILS_BATCH_SIZE) { while ((curr_index + DETAILS_BATCH_SIZE) <= volIds.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] = volIds[j]; } SearchCriteria<VolumeJoinVO> sc = volSearch.create(); sc.setParameters("idIN", ids); List<VolumeJoinVO> vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { uvList.addAll(vms); } curr_index += DETAILS_BATCH_SIZE; } } if (curr_index < volIds.length) { int batch_size = (volIds.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] = volIds[j]; } SearchCriteria<VolumeJoinVO> sc = volSearch.create(); sc.setParameters("idIN", ids); List<VolumeJoinVO> vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { uvList.addAll(vms); } } return uvList; } }