Create DB views to improve ListHostsCmd performance.

Signed-off-by: Min Chen <min.chen@citrix.com>
This commit is contained in:
Min Chen 2012-12-22 21:47:05 -08:00
parent e5fc513257
commit e7fa1a86fb
23 changed files with 1541 additions and 320 deletions

View File

@ -146,14 +146,6 @@ public interface ManagementService {
*/
Pair<List<? extends Pod>, Integer> searchForPods(ListPodsByCmd cmd);
/**
* Searches for servers by the specified search criteria Can search by: "name", "type", "state", "dataCenterId",
* "podId"
*
* @param cmd
* @return List of Hosts
*/
List<? extends Host> searchForServers(ListHostsCmd cmd);
/**
* Creates a new template

View File

@ -28,6 +28,7 @@ import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Implementation;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
@ -164,32 +165,35 @@ public class ListHostsCmd extends BaseListCmd {
@Override
public void execute(){
List<? extends Host> result = new ArrayList<Host>();
List<? extends Host> hostsWithCapacity = new ArrayList<Host>();
ListResponse<HostResponse> response = null;
if (getVirtualMachineId() == null) {
response = _queryService.searchForServers(this);
} else {
List<? extends Host> result = new ArrayList<Host>();
List<? extends Host> hostsWithCapacity = new ArrayList<Host>();
if(getVirtualMachineId() != null){
Pair<List<? extends Host>, List<? extends Host>> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal());
Pair<List<? extends Host>, List<? extends Host>> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(),
this.getStartIndex(), this.getPageSizeVal());
result = hostsForMigration.first();
hostsWithCapacity = hostsForMigration.second();
}else{
result = _mgr.searchForServers(this);
}
ListResponse<HostResponse> response = new ListResponse<HostResponse>();
List<HostResponse> hostResponses = new ArrayList<HostResponse>();
for (Host host : result) {
HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
Boolean suitableForMigration = false;
if(hostsWithCapacity.contains(host)){
suitableForMigration = true;
response = new ListResponse<HostResponse>();
List<HostResponse> hostResponses = new ArrayList<HostResponse>();
for (Host host : result) {
HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
Boolean suitableForMigration = false;
if (hostsWithCapacity.contains(host)) {
suitableForMigration = true;
}
hostResponse.setSuitableForMigration(suitableForMigration);
hostResponse.setObjectName("host");
hostResponses.add(hostResponse);
}
hostResponse.setSuitableForMigration(suitableForMigration);
hostResponse.setObjectName("host");
hostResponses.add(hostResponse);
}
response.setResponses(hostResponses);
response.setResponses(hostResponses);
}
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -317,6 +317,11 @@ public class HostResponse extends BaseResponse {
this.events = events;
}
public String getHostTags() {
return hostTags;
}
public void setHostTags(String hostTags) {
this.hostTags = hostTags;
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.query;
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.user.ListUsersCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
@ -28,6 +29,7 @@ import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
@ -70,5 +72,5 @@ public interface QueryService {
public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd);
public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd);
}

View File

@ -1,22 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
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.
-->
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
<stringAttribute key="M2_GOALS" value="jetty:run"/>

View File

@ -104,6 +104,10 @@ under the License.
<priority value="INFO"/>
</category>
<category name="org.apache.cloudstack.api.command">
<priority value="DEBUG"/>
</category>
<category name="org">
<priority value="INFO"/>
</category>

View File

@ -22,9 +22,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
@ -35,6 +37,7 @@ import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.dao.InstanceGroupJoinDao;
import com.cloud.api.query.dao.ProjectAccountJoinDao;
import com.cloud.api.query.dao.ProjectInvitationJoinDao;
@ -44,6 +47,7 @@ import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO;
@ -305,6 +309,7 @@ public class ApiDBUtils {
private static ProjectJoinDao _projectJoinDao;
private static ProjectAccountJoinDao _projectAccountJoinDao;
private static ProjectInvitationJoinDao _projectInvitationJoinDao;
private static HostJoinDao _hostJoinDao;
private static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
private static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@ -390,6 +395,7 @@ public class ApiDBUtils {
_projectJoinDao = locator.getDao(ProjectJoinDao.class);
_projectAccountJoinDao = locator.getDao(ProjectAccountJoinDao.class);
_projectInvitationJoinDao = locator.getDao(ProjectInvitationJoinDao.class);
_hostJoinDao = locator.getDao(HostJoinDao.class);
_physicalNetworkTrafficTypeDao = locator.getDao(PhysicalNetworkTrafficTypeDao.class);
_physicalNetworkServiceProviderDao = locator.getDao(PhysicalNetworkServiceProviderDao.class);
@ -506,8 +512,8 @@ public class ApiDBUtils {
return _storageMgr.getStoragePoolTags(poolId);
}
public static boolean isLocalStorageActiveOnHost(Host host) {
return _storageMgr.isLocalStorageActiveOnHost(host);
public static boolean isLocalStorageActiveOnHost(Long hostId) {
return _storageMgr.isLocalStorageActiveOnHost(hostId);
}
public static InstanceGroupVO findInstanceGroupForVM(long vmId) {
@ -1295,5 +1301,15 @@ public class ApiDBUtils {
return _projectInvitationJoinDao.newProjectInvitationView(proj);
}
public static HostResponse newHostResponse(HostJoinVO vr, EnumSet<HostDetails> details) {
return _hostJoinDao.newHostResponse(vr, details);
}
public static HostResponse fillHostDetails(HostResponse vrData, HostJoinVO vr){
return _hostJoinDao.setHostResponse(vrData, vr);
}
public static List<HostJoinVO> newHostView(Host vr){
return _hostJoinDao.newHostView(vr);
}
}

View File

@ -45,6 +45,7 @@ import com.cloud.api.query.ViewResponseHelper;
import com.cloud.api.query.vo.ControlledViewEntity;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO;
@ -616,136 +617,10 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public HostResponse createHostResponse(Host host, EnumSet<HostDetails> details) {
HostResponse hostResponse = new HostResponse();
hostResponse.setId(host.getUuid());
hostResponse.setCapabilities(host.getCapabilities());
ClusterVO cluster = null;
if (host.getClusterId() != null) {
cluster = ApiDBUtils.findClusterById(host.getClusterId());
if (cluster != null) {
hostResponse.setClusterId(cluster.getUuid());
}
}
hostResponse.setCpuNumber(host.getCpus());
DataCenter zone = ApiDBUtils.findZoneById(host.getDataCenterId());
if (zone != null) {
hostResponse.setZoneId(zone.getUuid());
}
hostResponse.setDisconnectedOn(host.getDisconnectedOn());
hostResponse.setHypervisor(host.getHypervisorType());
hostResponse.setHostType(host.getType());
hostResponse.setLastPinged(new Date(host.getLastPinged()));
hostResponse.setManagementServerId(host.getManagementServerId());
hostResponse.setName(host.getName());
HostPodVO pod = ApiDBUtils.findPodById(host.getPodId());
if (pod != null) {
hostResponse.setPodId(pod.getUuid());
}
hostResponse.setRemoved(host.getRemoved());
hostResponse.setCpuSpeed(host.getSpeed());
hostResponse.setState(host.getStatus());
hostResponse.setIpAddress(host.getPrivateIpAddress());
hostResponse.setVersion(host.getVersion());
hostResponse.setCreated(host.getCreated());
if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)
|| details.contains(HostDetails.stats) || details.contains(HostDetails.events)) {
GuestOSCategoryVO guestOSCategory = ApiDBUtils.getHostGuestOSCategory(host.getId());
if (guestOSCategory != null) {
hostResponse.setOsCategoryId(guestOSCategory.getUuid());
hostResponse.setOsCategoryName(guestOSCategory.getName());
}
if (zone != null) {
hostResponse.setZoneName(zone.getName());
}
if (pod != null) {
hostResponse.setPodName(pod.getName());
}
if (cluster != null) {
hostResponse.setClusterName(cluster.getName());
hostResponse.setClusterType(cluster.getClusterType().toString());
}
}
DecimalFormat decimalFormat = new DecimalFormat("#.##");
if (host.getType() == Host.Type.Routing) {
if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)) {
// set allocated capacities
Long mem = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
Long cpu = ApiDBUtils.getMemoryOrCpuCapacitybyHost(host.getId(), Capacity.CAPACITY_TYPE_CPU);
hostResponse.setMemoryAllocated(mem);
hostResponse.setMemoryTotal(host.getTotalMemory());
String hostTags = ApiDBUtils.getHostTags(host.getId());
hostResponse.setHostTags(hostTags);
String haTag = ApiDBUtils.getHaTag();
if (haTag != null && !haTag.isEmpty() && hostTags != null && !hostTags.isEmpty()) {
if (haTag.equalsIgnoreCase(hostTags)) {
hostResponse.setHaHost(true);
} else {
hostResponse.setHaHost(false);
}
} else {
hostResponse.setHaHost(false);
}
hostResponse.setHypervisorVersion(host.getHypervisorVersion());
String cpuAlloc = decimalFormat.format(((float) cpu / (float) (host.getCpus() * host.getSpeed())) * 100f) + "%";
hostResponse.setCpuAllocated(cpuAlloc);
String cpuWithOverprovisioning = new Float(host.getCpus() * host.getSpeed() * ApiDBUtils.getCpuOverprovisioningFactor()).toString();
hostResponse.setCpuWithOverprovisioning(cpuWithOverprovisioning);
}
if (details.contains(HostDetails.all) || details.contains(HostDetails.stats)) {
// set CPU/RAM/Network stats
String cpuUsed = null;
HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId());
if (hostStats != null) {
float cpuUtil = (float) hostStats.getCpuUtilization();
cpuUsed = decimalFormat.format(cpuUtil) + "%";
hostResponse.setCpuUsed(cpuUsed);
hostResponse.setMemoryUsed((new Double(hostStats.getUsedMemory())).longValue());
hostResponse.setNetworkKbsRead((new Double(hostStats.getNetworkReadKBs())).longValue());
hostResponse.setNetworkKbsWrite((new Double(hostStats.getNetworkWriteKBs())).longValue());
}
}
} else if (host.getType() == Host.Type.SecondaryStorage) {
StorageStats secStorageStats = ApiDBUtils.getSecondaryStorageStatistics(host.getId());
if (secStorageStats != null) {
hostResponse.setDiskSizeTotal(secStorageStats.getCapacityBytes());
hostResponse.setDiskSizeAllocated(secStorageStats.getByteUsed());
}
}
hostResponse.setLocalStorageActive(ApiDBUtils.isLocalStorageActiveOnHost(host));
if (details.contains(HostDetails.all) || details.contains(HostDetails.events)) {
Set<com.cloud.host.Status.Event> possibleEvents = host.getStatus().getPossibleEvents();
if ((possibleEvents != null) && !possibleEvents.isEmpty()) {
String events = "";
Iterator<com.cloud.host.Status.Event> iter = possibleEvents.iterator();
while (iter.hasNext()) {
com.cloud.host.Status.Event event = iter.next();
events += event.toString();
if (iter.hasNext()) {
events += "; ";
}
}
hostResponse.setEvents(events);
}
}
hostResponse.setResourceState(host.getResourceState().toString());
hostResponse.setObjectName("host");
return hostResponse;
List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
List<HostResponse> listHosts = ViewResponseHelper.createHostResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
return listHosts.get(0);
}
@Override

View File

@ -85,6 +85,7 @@ import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
@ -460,7 +461,8 @@ public class ApiServer implements HttpRequestHandler {
&& !(cmdObj instanceof ListVMGroupsCmd)
&& !(cmdObj instanceof ListProjectsCmd)
&& !(cmdObj instanceof ListProjectAccountsCmd)
&& !(cmdObj instanceof ListProjectInvitationsCmd)) {
&& !(cmdObj instanceof ListProjectInvitationsCmd)
&& !(cmdObj instanceof ListHostsCmd)) {
buildAsyncListResponse((BaseListCmd) cmdObj, caller);
}

View File

@ -26,7 +26,9 @@ import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
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.user.ListUsersCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
@ -39,6 +41,7 @@ import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
@ -54,6 +57,7 @@ import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.dao.InstanceGroupJoinDao;
import com.cloud.api.query.dao.ProjectAccountJoinDao;
import com.cloud.api.query.dao.ProjectInvitationJoinDao;
@ -63,6 +67,7 @@ import com.cloud.api.query.dao.SecurityGroupJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO;
@ -78,6 +83,10 @@ import com.cloud.domain.dao.DomainDao;
import com.cloud.event.dao.EventJoinDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.HostTagVO;
import com.cloud.host.HostVO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.security.SecurityGroupVMMapVO;
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
@ -104,6 +113,7 @@ import com.cloud.utils.Ternary;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
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;
@ -175,6 +185,12 @@ public class QueryManagerImpl implements QueryService, Manager {
@Inject
private ProjectAccountJoinDao _projectAccountJoinDao;
@Inject
private HostJoinDao _hostJoinDao;
@Inject
private HighAvailabilityManager _haMgr;
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
@ -1309,5 +1325,118 @@ public class QueryManagerImpl implements QueryService, Manager {
return _projectAccountJoinDao.searchAndCount(sc, searchFilter);
}
@Override
public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd) {
//FIXME: do we need to support list hosts with VmId, maybe we should create another command just for this
// Right now it is handled separately outside this QueryService
s_logger.debug(">>>Searching for hosts>>>");
Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(cmd);
ListResponse<HostResponse> response = new ListResponse<HostResponse>();
s_logger.debug(">>>Generating Response>>>");
List<HostResponse> hostResponses = ViewResponseHelper.createHostResponse(cmd.getDetails(), hosts.first().toArray(new HostJoinVO[hosts.first().size()]));
response.setResponses(hostResponses, hosts.second());
return response;
}
public Pair<List<HostJoinVO>, Integer> searchForServersInternal(ListHostsCmd cmd) {
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
Object name = cmd.getHostName();
Object type = cmd.getType();
Object state = cmd.getState();
Object pod = cmd.getPodId();
Object cluster = cmd.getClusterId();
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
Object resourceState = cmd.getResourceState();
Object haHosts = cmd.getHaHost();
Long startIndex = cmd.getStartIndex();
Long pageSize = cmd.getPageSizeVal();
Filter searchFilter = new Filter(HostJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
SearchBuilder<HostJoinVO> sb = _hostJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
String haTag = _haMgr.getHaTag();
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
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);
}
}
SearchCriteria<HostJoinVO> sc = sb.create();
if (keyword != null) {
SearchCriteria<HostJoinVO> ssc = _hostJoinDao.createSearchCriteria();
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
}
if (id != null) {
sc.setParameters("id", id);
}
if (name != null) {
sc.setParameters("name", "%" + name + "%");
}
if (type != null) {
sc.setParameters("type", "%" + type);
}
if (state != null) {
sc.setParameters("status", state);
}
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
if (pod != null) {
sc.setParameters("podId", pod);
}
if (cluster != null) {
sc.setParameters("clusterId", cluster);
}
if (resourceState != null) {
sc.setParameters("resourceState", resourceState);
}
if (haHosts != null && haTag != null && !haTag.isEmpty()) {
sc.setJoinParameters("hostTagSearch", "tag", haTag);
}
// search host details by ids
Pair<List<HostJoinVO>, Integer> uniqueHostPair = _hostJoinDao.searchAndCount(sc, searchFilter);
Integer count = uniqueHostPair.second();
if ( count.intValue() == 0 ){
// handle empty result cases
return uniqueHostPair;
}
List<HostJoinVO> uniqueHosts = uniqueHostPair.first();
Long[] hostIds = new Long[uniqueHosts.size()];
int i = 0;
for (HostJoinVO v : uniqueHosts ){
hostIds[i++] = v.getId();
}
List<HostJoinVO> hosts = _hostJoinDao.searchByIds(hostIds);
return new Pair<List<HostJoinVO>, Integer>(hosts, count);
}
}

View File

@ -21,9 +21,11 @@ import java.util.EnumSet;
import java.util.Hashtable;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
@ -37,6 +39,7 @@ import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.api.query.vo.EventJoinVO;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.api.query.vo.InstanceGroupJoinVO;
import com.cloud.api.query.vo.ProjectAccountJoinVO;
import com.cloud.api.query.vo.ProjectInvitationJoinVO;
@ -193,4 +196,22 @@ public class ViewResponseHelper {
}
return respList;
}
public static List<HostResponse> createHostResponse(EnumSet<HostDetails> details, HostJoinVO... hosts) {
Hashtable<Long, HostResponse> vrDataList = new Hashtable<Long, HostResponse>();
// Initialise the vrdatalist with the input data
for (HostJoinVO vr : hosts) {
HostResponse vrData = vrDataList.get(vr.getId());
if ( vrData == null ){
// first time encountering this vm
vrData = ApiDBUtils.newHostResponse(vr, details);
}
else{
// update tags
vrData = ApiDBUtils.fillHostDetails(vrData, vr);
}
vrDataList.put(vr.getId(), vrData);
}
return new ArrayList<HostResponse>(vrDataList.values());
}
}

View File

@ -0,0 +1,38 @@
// 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.EnumSet;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.response.HostResponse;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.host.Host;
import com.cloud.utils.db.GenericDao;
public interface HostJoinDao extends GenericDao<HostJoinVO, Long> {
HostResponse newHostResponse(HostJoinVO host, EnumSet<HostDetails> details);
HostResponse setHostResponse(HostResponse response, HostJoinVO host);
List<HostJoinVO> newHostView(Host group);
List<HostJoinVO> searchByIds(Long... ids);
}

View File

@ -0,0 +1,222 @@
// 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.text.DecimalFormat;
import java.util.Date;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.host.Host;
import com.cloud.host.HostStats;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
import org.apache.cloudstack.api.response.HostResponse;
import com.cloud.storage.StorageStats;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Local(value={HostJoinDao.class})
public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements HostJoinDao {
public static final Logger s_logger = Logger.getLogger(HostJoinDaoImpl.class);
private SearchBuilder<HostJoinVO> vrSearch;
private SearchBuilder<HostJoinVO> vrIdSearch;
protected HostJoinDaoImpl() {
vrSearch = createSearchBuilder();
vrSearch.and("idIN", vrSearch.entity().getId(), SearchCriteria.Op.IN);
vrSearch.done();
vrIdSearch = createSearchBuilder();
vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
vrIdSearch.done();
this._count = "select count(distinct id) from host_view WHERE ";
}
@Override
public HostResponse newHostResponse(HostJoinVO host, EnumSet<HostDetails> details) {
HostResponse hostResponse = new HostResponse();
hostResponse.setId(host.getUuid());
hostResponse.setCapabilities(host.getCapabilities());
hostResponse.setClusterId(host.getClusterUuid());
hostResponse.setCpuNumber(host.getCpus());
hostResponse.setZoneId(host.getUuid());
hostResponse.setDisconnectedOn(host.getDisconnectedOn());
hostResponse.setHypervisor(host.getHypervisorType());
hostResponse.setHostType(host.getType());
hostResponse.setLastPinged(new Date(host.getLastPinged()));
hostResponse.setManagementServerId(host.getManagementServerId());
hostResponse.setName(host.getName());
hostResponse.setPodId(host.getPodUuid());
hostResponse.setRemoved(host.getRemoved());
hostResponse.setCpuSpeed(host.getSpeed());
hostResponse.setState(host.getStatus());
hostResponse.setIpAddress(host.getPrivateIpAddress());
hostResponse.setVersion(host.getVersion());
hostResponse.setCreated(host.getCreated());
if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)
|| details.contains(HostDetails.stats) || details.contains(HostDetails.events)) {
hostResponse.setOsCategoryId(host.getOsCategoryUuid());
hostResponse.setOsCategoryName(host.getOsCategoryName());
hostResponse.setZoneName(host.getZoneName());
hostResponse.setPodName(host.getPodName());
if ( host.getClusterId() > 0) {
hostResponse.setClusterName(host.getClusterName());
hostResponse.setClusterType(host.getClusterType().toString());
}
}
DecimalFormat decimalFormat = new DecimalFormat("#.##");
if (host.getType() == Host.Type.Routing) {
if (details.contains(HostDetails.all) || details.contains(HostDetails.capacity)) {
// set allocated capacities
Long mem = host.getMemReservedCapacity() + host.getMemUsedCapacity();
Long cpu = host.getCpuReservedCapacity() + host.getCpuReservedCapacity();
hostResponse.setMemoryAllocated(mem);
hostResponse.setMemoryTotal(host.getTotalMemory());
String hostTags = host.getTag();
hostResponse.setHostTags(host.getTag());
String haTag = ApiDBUtils.getHaTag();
if (haTag != null && !haTag.isEmpty() && hostTags != null && !hostTags.isEmpty()) {
if (haTag.equalsIgnoreCase(hostTags)) {
hostResponse.setHaHost(true);
} else {
hostResponse.setHaHost(false);
}
} else {
hostResponse.setHaHost(false);
}
hostResponse.setHypervisorVersion(host.getHypervisorVersion());
String cpuAlloc = decimalFormat.format(((float) cpu / (float) (host.getCpus() * host.getSpeed())) * 100f) + "%";
hostResponse.setCpuAllocated(cpuAlloc);
String cpuWithOverprovisioning = new Float(host.getCpus() * host.getSpeed() * ApiDBUtils.getCpuOverprovisioningFactor()).toString();
hostResponse.setCpuWithOverprovisioning(cpuWithOverprovisioning);
}
if (details.contains(HostDetails.all) || details.contains(HostDetails.stats)) {
// set CPU/RAM/Network stats
String cpuUsed = null;
HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId());
if (hostStats != null) {
float cpuUtil = (float) hostStats.getCpuUtilization();
cpuUsed = decimalFormat.format(cpuUtil) + "%";
hostResponse.setCpuUsed(cpuUsed);
hostResponse.setMemoryUsed((new Double(hostStats.getUsedMemory())).longValue());
hostResponse.setNetworkKbsRead((new Double(hostStats.getNetworkReadKBs())).longValue());
hostResponse.setNetworkKbsWrite((new Double(hostStats.getNetworkWriteKBs())).longValue());
}
}
} else if (host.getType() == Host.Type.SecondaryStorage) {
StorageStats secStorageStats = ApiDBUtils.getSecondaryStorageStatistics(host.getId());
if (secStorageStats != null) {
hostResponse.setDiskSizeTotal(secStorageStats.getCapacityBytes());
hostResponse.setDiskSizeAllocated(secStorageStats.getByteUsed());
}
}
hostResponse.setLocalStorageActive(ApiDBUtils.isLocalStorageActiveOnHost(host.getId()));
if (details.contains(HostDetails.all) || details.contains(HostDetails.events)) {
Set<com.cloud.host.Status.Event> possibleEvents = host.getStatus().getPossibleEvents();
if ((possibleEvents != null) && !possibleEvents.isEmpty()) {
String events = "";
Iterator<com.cloud.host.Status.Event> iter = possibleEvents.iterator();
while (iter.hasNext()) {
com.cloud.host.Status.Event event = iter.next();
events += event.toString();
if (iter.hasNext()) {
events += "; ";
}
}
hostResponse.setEvents(events);
}
}
hostResponse.setResourceState(host.getResourceState().toString());
hostResponse.setObjectName("host");
return hostResponse;
}
@Override
public HostResponse setHostResponse(HostResponse response, HostJoinVO host) {
String tag = host.getTag();
if (tag != null) {
if ( response.getHostTags() != null && response.getHostTags().length() > 0){
response.setHostTags(response.getHostTags() + "," + tag);
}
else{
response.setHostTags(tag);
}
}
return response;
}
@Override
public List<HostJoinVO> newHostView(Host host) {
SearchCriteria<HostJoinVO> sc = vrIdSearch.create();
sc.setParameters("id", host.getId());
return searchIncludingRemoved(sc, null, null, false);
}
@Override
public List<HostJoinVO> searchByIds(Long... ids) {
SearchCriteria<HostJoinVO> sc = vrSearch.create();
sc.setParameters("idIN", ids);
return searchIncludingRemoved(sc, null, null, false);
}
}

View File

@ -0,0 +1,503 @@
// 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.host.Status;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.org.Cluster;
import com.cloud.resource.ResourceState;
import com.cloud.utils.db.GenericDao;
/**
* Host DB view.
* @author minc
*
*/
@Entity
@Table(name="host_view")
public class HostJoinVO extends BaseViewVO {
@Column(name="id")
private long id;
@Column(name="uuid")
private String uuid;
@Column(name="name")
private String name;
@Column(name="status")
private Status status = null;
@Column(name="type")
@Enumerated(value=EnumType.STRING)
private Type type;
@Column(name="private_ip_address")
private String privateIpAddress;
@Column(name="disconnected")
@Temporal(value=TemporalType.TIMESTAMP)
private Date disconnectedOn;
@Column(name="version")
private String version;
@Column(name="hypervisor_type")
@Enumerated(value=EnumType.STRING)
private HypervisorType hypervisorType;
@Column(name="hypervisor_version")
private String hypervisorVersion;
@Column(name="capabilities")
private String caps;
@Column(name="last_ping")
private long lastPinged;
@Column(name=GenericDao.CREATED_COLUMN)
private Date created;
@Column(name=GenericDao.REMOVED_COLUMN)
private Date removed;
@Column(name="resource_state")
@Enumerated(value=EnumType.STRING)
private ResourceState resourceState;
@Column(name="mgmt_server_id")
private Long managementServerId;
@Column(name="cpus")
private Integer cpus;
@Column(name="speed")
private Long speed;
@Column(name="ram")
private long totalMemory;
@Column(name="cluster_id")
private long clusterId;
@Column(name="cluster_uuid")
private String clusterUuid;
@Column(name="cluster_name")
private String clusterName;
@Column(name="cluster_type")
@Enumerated(value=EnumType.STRING)
Cluster.ClusterType clusterType;
@Column(name="data_center_id")
private long zoneId;
@Column(name="data_center_uuid")
private String zoneUuid;
@Column(name="data_center_name")
private String zoneName;
@Column(name="pod_id")
private long podId;
@Column(name="pod_uuid")
private String podUuid;
@Column(name="pod_name")
private String podName;
@Column(name="guest_os_category_id")
private long osCategoryId;
@Column(name="guest_os_category_uuid")
private String osCategoryUuid;
@Column(name="guest_os_category_name")
private String osCategoryName;
@Column(name="tag")
private String tag;
@Column(name="memory_used_capacity")
private long memUsedCapacity;
@Column(name="memory_reserved_capacity")
private long memReservedCapacity;
@Column(name="cpu_used_capacity")
private long cpuUsedCapacity;
@Column(name="cpu_reserved_capacity")
private long cpuReservedCapacity;
@Column(name="job_id")
private long jobId;
@Column(name="job_uuid")
private String jobUuid;
@Column(name="job_status")
private int jobStatus;
/* (non-Javadoc)
* @see com.cloud.api.query.vo.BaseViewVO#getId()
*/
@Override
public long getId() {
return this.id;
}
/* (non-Javadoc)
* @see com.cloud.api.query.vo.BaseViewVO#setId(long)
*/
@Override
public void setId(long id) {
this.id = id;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public long getZoneId() {
return zoneId;
}
public void setZoneId(long zoneId) {
this.zoneId = zoneId;
}
public String getZoneUuid() {
return zoneUuid;
}
public void setZoneUuid(String zoneUuid) {
this.zoneUuid = zoneUuid;
}
public String getZoneName() {
return zoneName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getPrivateIpAddress() {
return privateIpAddress;
}
public void setPrivateIpAddress(String privateIpAddress) {
this.privateIpAddress = privateIpAddress;
}
public Date getDisconnectedOn() {
return disconnectedOn;
}
public void setDisconnectedOn(Date disconnectedOn) {
this.disconnectedOn = disconnectedOn;
}
public HypervisorType getHypervisorType() {
return hypervisorType;
}
public void setHypervisorType(HypervisorType hypervisorType) {
this.hypervisorType = hypervisorType;
}
public String getHypervisorVersion() {
return hypervisorVersion;
}
public void setHypervisorVersion(String hypervisorVersion) {
this.hypervisorVersion = hypervisorVersion;
}
public String getCapabilities() {
return caps;
}
public void setCapabilities(String caps) {
this.caps = caps;
}
public long getLastPinged() {
return lastPinged;
}
public void setLastPinged(long lastPinged) {
this.lastPinged = lastPinged;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getRemoved() {
return removed;
}
public void setRemoved(Date removed) {
this.removed = removed;
}
public ResourceState getResourceState() {
return resourceState;
}
public void setResourceState(ResourceState resourceState) {
this.resourceState = resourceState;
}
public Long getManagementServerId() {
return managementServerId;
}
public void setManagementServerId(Long managementServerId) {
this.managementServerId = managementServerId;
}
public Integer getCpus() {
return cpus;
}
public void setCpus(Integer cpus) {
this.cpus = cpus;
}
public Long getSpeed() {
return speed;
}
public void setSpeed(Long speed) {
this.speed = speed;
}
public long getTotalMemory() {
return totalMemory;
}
public void setTotalMemory(long totalMemory) {
this.totalMemory = totalMemory;
}
public long getClusterId() {
return clusterId;
}
public void setClusterId(long clusterId) {
this.clusterId = clusterId;
}
public String getClusterUuid() {
return clusterUuid;
}
public void setClusterUuid(String clusterUuid) {
this.clusterUuid = clusterUuid;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public Cluster.ClusterType getClusterType() {
return clusterType;
}
public void setClusterType(Cluster.ClusterType clusterType) {
this.clusterType = clusterType;
}
public long getOsCategoryId() {
return osCategoryId;
}
public void setOsCategoryId(long osCategoryId) {
this.osCategoryId = osCategoryId;
}
public String getOsCategoryUuid() {
return osCategoryUuid;
}
public void setOsCategoryUuid(String osCategoryUuid) {
this.osCategoryUuid = osCategoryUuid;
}
public String getOsCategoryName() {
return osCategoryName;
}
public void setOsCategoryName(String osCategoryName) {
this.osCategoryName = osCategoryName;
}
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 getPodId() {
return podId;
}
public void setPodId(long podId) {
this.podId = podId;
}
public String getPodUuid() {
return podUuid;
}
public void setPodUuid(String podUuid) {
this.podUuid = podUuid;
}
public String getPodName() {
return podName;
}
public void setPodName(String podName) {
this.podName = podName;
}
public long getMemUsedCapacity() {
return memUsedCapacity;
}
public void setMemUsedCapacity(long memUsedCapacity) {
this.memUsedCapacity = memUsedCapacity;
}
public long getMemReservedCapacity() {
return memReservedCapacity;
}
public void setMemReservedCapacity(long memReservedCapacity) {
this.memReservedCapacity = memReservedCapacity;
}
public long getCpuUsedCapacity() {
return cpuUsedCapacity;
}
public void setCpuUsedCapacity(long cpuUsedCapacity) {
this.cpuUsedCapacity = cpuUsedCapacity;
}
public long getCpuReservedCapacity() {
return cpuReservedCapacity;
}
public void setCpuReservedCapacity(long cpuReservedCapacity) {
this.cpuReservedCapacity = cpuReservedCapacity;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}

View File

@ -49,6 +49,7 @@ public class ApiResponseSerializer {
private static final Logger s_logger = Logger.getLogger(ApiResponseSerializer.class.getName());
public static String toSerializedString(ResponseObject result, String responseType) {
s_logger.trace("===Serializing Response===");
if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
return toJSONSerializedString(result);
} else {
@ -70,7 +71,7 @@ public class ApiResponseSerializer {
public static String toJSONSerializedString(ResponseObject result) {
if (result != null) {
Gson gson = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
StringBuilder sb = new StringBuilder();
sb.append("{ \"").append(result.getResponseName()).append("\" : ");
@ -81,15 +82,15 @@ public class ApiResponseSerializer {
if (nonZeroCount) {
sb.append("{ \"").append(ApiConstants.COUNT).append("\":").append(count);
}
if ((responses != null) && !responses.isEmpty()) {
String jsonStr = gson.toJson(responses.get(0));
String jsonStr = gson.toJson(responses.get(0));
jsonStr = unescape(jsonStr);
if (nonZeroCount) {
sb.append(" ,\"").append(responses.get(0).getObjectName()).append("\" : [ ").append(jsonStr);
}
for (int i = 1; i < ((ListResponse) result).getResponses().size(); i++) {
jsonStr = gson.toJson(responses.get(i));
jsonStr = unescape(jsonStr);
@ -97,10 +98,10 @@ public class ApiResponseSerializer {
}
sb.append(" ] }");
} else {
if (!nonZeroCount){
if (!nonZeroCount){
sb.append("{");
}
sb.append(" }");
}
} else if (result instanceof SuccessResponse) {
@ -108,7 +109,7 @@ public class ApiResponseSerializer {
} else if (result instanceof ExceptionResponse) {
String jsonErrorText = gson.toJson((ExceptionResponse) result);
jsonErrorText = unescape(jsonErrorText);
sb.append(jsonErrorText);
sb.append(jsonErrorText);
} else {
String jsonStr = gson.toJson(result);
if ((jsonStr != null) && !"".equals(jsonStr)) {
@ -178,7 +179,7 @@ public class ApiResponseSerializer {
}
return fields.toArray(new Field[] {});
}
private static void serializeResponseObjFieldsXML(StringBuilder sb, ResponseObject obj) {
boolean isAsync = false;
if (obj instanceof AsyncJobResponse)
@ -227,26 +228,26 @@ public class ApiResponseSerializer {
serializeResponseObjXML(sb, subObj);
} else if (value instanceof IdentityProxy) {
// Only exception reponses carry a list of IdentityProxy objects.
IdentityProxy idProxy = (IdentityProxy)value;
IdentityProxy idProxy = (IdentityProxy)value;
String id = (idProxy.getValue() != null ? String.valueOf(idProxy.getValue()) : "");
if(!id.isEmpty()) {
IdentityDao identityDao = new IdentityDaoImpl();
id = identityDao.getIdentityUuid(idProxy.getTableName(), id);
}
}
if(id != null && !id.isEmpty()) {
// If this is the first IdentityProxy field encountered, put in a uuidList tag.
if (!usedUuidList) {
sb.append("<").append(serializedName.value()).append(">");
usedUuidList = true;
}
sb.append("<uuid>").append(id).append("</uuid>");
sb.append("<uuid>").append(id).append("</uuid>");
}
// Append the new idFieldName property also.
String idFieldName = idProxy.getidFieldName();
if (idFieldName != null) {
sb.append("<uuidProperty>").append(idFieldName).append("</uuidProperty>");
sb.append("<uuidProperty>").append(idFieldName).append("</uuidProperty>");
}
}
}
}
if (usedUuidList) {
// close the uuidList.
@ -254,8 +255,8 @@ public class ApiResponseSerializer {
}
} else if (fieldValue instanceof Date) {
sb.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date) fieldValue)).
append("</").append(serializedName.value()).append(">");
} else if (fieldValue instanceof IdentityProxy) {
append("</").append(serializedName.value()).append(">");
} else if (fieldValue instanceof IdentityProxy) {
IdentityProxy idProxy = (IdentityProxy)fieldValue;
String id = (idProxy.getValue() != null ? String.valueOf(idProxy.getValue()) : "");
if(!id.isEmpty()) {
@ -273,7 +274,7 @@ public class ApiResponseSerializer {
if (!(obj instanceof ExceptionResponse)) {
resultString = encodeParam(resultString);
}
sb.append("<").append(serializedName.value()).append(">").append(resultString).append("</").append(serializedName.value()).append(">");
}
}
@ -340,10 +341,10 @@ public class ApiResponseSerializer {
resultString.append(singleChar);
}
}
return resultString.toString();
}
private static String encodeParam(String value) {
if (!ApiServer.encodeApiResponse) {
return value;
@ -355,5 +356,5 @@ public class ApiResponseSerializer {
}
return value;
}
}

View File

@ -33,6 +33,7 @@ import com.cloud.api.query.dao.ProjectJoinDaoImpl;
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.async.AsyncJobExecutorContextImpl;
import com.cloud.async.AsyncJobManagerImpl;
import com.cloud.async.SyncQueueManagerImpl;
@ -236,6 +237,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("ProjectJoinDao", ProjectJoinDaoImpl.class);
addDao("ProjectAccountJoinDao", ProjectAccountJoinDaoImpl.class);
addDao("ProjectInvitationJoinDao", ProjectInvitationJoinDaoImpl.class);
addDao("HostJoinDao", HostJoinDaoImpl.class);
ComponentInfo<? extends GenericDao<?, ? extends Serializable>> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class);
info.addParameter("cache.size", "50");
info.addParameter("cache.time.to.live", "600");

View File

@ -181,22 +181,22 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
@Inject
protected ConfigurationDao _configDao;
@Inject
protected HostTagsDao _hostTagsDao;
protected HostTagsDao _hostTagsDao;
@Inject
protected GuestOSCategoryDao _guestOSCategoryDao;
@Inject
@Inject
protected StoragePoolDao _storagePoolDao;
@Inject
protected DataCenterIpAddressDao _privateIPAddressDao;
@Inject
protected IPAddressDao _publicIPAddressDao;
@Inject
protected VirtualMachineManager _vmMgr;
protected VirtualMachineManager _vmMgr;
@Inject
protected VMInstanceDao _vmDao;
protected VMInstanceDao _vmDao;
@Inject
protected HighAvailabilityManager _haMgr;
@Inject
@Inject
protected StorageService _storageSvr;
@Inject(adapter = Discoverer.class)
protected Adapters<? extends Discoverer> _discoverers;
@ -581,7 +581,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
if (pod == null) {
throw new InvalidParameterValueException("Can't find pod by id " + podId);
}
// check if pod belongs to the zone
// check if pod belongs to the zone
if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId);
ex.addProxyObject(pod, podId, "podId");
@ -643,7 +643,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod with specified podId and data center with specified dcID", e);
ex.addProxyObject(pod, podId, "podId");
ex.addProxyObject(zone, dcId, "dcId");
throw ex;
throw ex;
}
}
clusterId = cluster.getId();
@ -744,7 +744,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
// Verify that host exists
HostVO host = _hostDao.findById(hostId);
if (host == null) {
throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
}
_accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId());
@ -752,7 +752,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
* TODO: check current agent status and updateAgentStatus to removed. If it was already removed, that means
* someone is deleting host concurrently, return. And consider the situation of CloudStack shutdown during delete.
* A global lock?
*
*
*/
AgentAttache attache = _agentMgr.findAttache(hostId);
// Get storage pool host mappings here because they can be removed as a part of handleDisconnect later
@ -847,7 +847,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
@DB
public boolean deleteCluster(DeleteClusterCmd cmd) {
Transaction txn = Transaction.currentTxn();
try {
try {
txn.start();
ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
if (cluster == null) {
@ -973,7 +973,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
try {
txn.start();
_clusterDao.update(cluster.getId(), cluster);
txn.commit();
txn.commit();
} catch (Exception e) {
s_logger.error("Unable to update cluster due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support.");
@ -989,12 +989,12 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
_clusterDao.update(cluster.getId(), cluster);
txn.commit();
List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
for( HostVO host : hosts ) {
if(host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected)
if(host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected)
&& !host.getStatus().equals(Status.Up) && !host.getStatus().equals(Status.Alert) ) {
String msg = "host " + host.getPrivateIpAddress() + " should not be in " + host.getStatus().toString() + " status";
throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg);
throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg);
}
}
@ -1011,9 +1011,9 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
Thread.sleep(5 * 1000);
} catch (Exception e) {
}
hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
for( HostVO host : hosts ) {
if ( !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected)
if ( !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected)
&& !host.getStatus().equals(Status.Alert)) {
lsuccess = false;
break;
@ -1025,7 +1025,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
}
if ( success == false ) {
throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
}
} finally {
txn.start();
@ -1033,7 +1033,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
_clusterDao.update(cluster.getId(), cluster);
txn.commit();
}
} else if( newManagedState.equals(Managed.ManagedState.Managed)) {
} else if( newManagedState.equals(Managed.ManagedState.Managed)) {
txn.start();
cluster.setManagedState(Managed.ManagedState.Managed);
_clusterDao.update(cluster.getId(), cluster);
@ -1159,7 +1159,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId());
}
if (_storageMgr.isLocalStorageActiveOnHost(host)) {
if (_storageMgr.isLocalStorageActiveOnHost(host.getId())) {
throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage.");
}
@ -1353,7 +1353,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
public void unregisterResourceStateAdapter(String name) {
synchronized (_resourceStateAdapters) {
_resourceStateAdapters.remove(name);
}
}
}
private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, boolean singleTaker, Object... args) {
@ -1605,7 +1605,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
}
}
if (s_logger.isDebugEnabled()) {
new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
}
@ -1646,7 +1646,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
}
}
if (tempHost != null) {
/* Change agent status to Alert */
_agentMgr.agentStatusTransitTo(tempHost, Status.Event.AgentDisconnected, _nodeId);
@ -1754,7 +1754,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
host.setCpus(ssCmd.getCpus());
host.setTotalMemory(ssCmd.getMemory());
host.setSpeed(ssCmd.getSpeed());
host.setHypervisorType(hyType);
host.setHypervisorType(hyType);
return host;
}

View File

@ -924,23 +924,6 @@ public class ManagementServerImpl implements ManagementServer {
return new Pair<List<? extends Cluster>, Integer>(result.first(), result.second());
}
@Override
public List<HostVO> searchForServers(ListHostsCmd cmd) {
Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId());
Object name = cmd.getHostName();
Object type = cmd.getType();
Object state = cmd.getState();
Object pod = cmd.getPodId();
Object cluster = cmd.getClusterId();
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
Object resourceState = cmd.getResourceState();
Object haHosts = cmd.getHaHost();
return searchForServers(cmd.getStartIndex(), cmd.getPageSizeVal(), name, type, state, zoneId, pod, cluster, id, keyword, resourceState,
haHosts);
}
@Override
public Pair<List<? extends Host>, List<? extends Host>> listHostsForMigrationOfVM(Long vmId, Long startIndex, Long pageSize) {

View File

@ -53,28 +53,28 @@ public interface StorageManager extends StorageService, Manager {
* @return absolute ISO path
*/
public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId);
/**
* Returns the URL of the secondary storage host
* @param zoneId
* @return URL
*/
public String getSecondaryStorageURL(long zoneId);
/**
* Returns a comma separated list of tags for the specified storage pool
* @param poolId
* @return comma separated list of tags
*/
public String getStoragePoolTags(long poolId);
/**
* Returns the secondary storage host
* @param zoneId
* @return secondary storage host
*/
public HostVO getSecondaryStorageHost(long zoneId);
/**
* Returns the secondary storage host
* @param zoneId
@ -89,7 +89,7 @@ public interface StorageManager extends StorageService, Manager {
* @param destPoolPodId
* @param destPoolClusterId
* @return VolumeVO
* @throws ConcurrentOperationException
* @throws ConcurrentOperationException
*/
VolumeVO moveVolume(VolumeVO volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException;
@ -114,10 +114,10 @@ public interface StorageManager extends StorageService, Manager {
/**
* Marks the specified volume as destroyed in the management server database. The expunge thread will delete the volume from its storage pool.
* @param volume
* @return
* @return
*/
boolean destroyVolume(VolumeVO volume) throws ConcurrentOperationException;
/** Create capacity entries in the op capacity table
* @param storagePool
*/
@ -136,7 +136,7 @@ public interface StorageManager extends StorageService, Manager {
Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException;
Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException;
Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
/**
* Checks that one of the following is true:
* 1. The volume is not attached to any VM
@ -145,21 +145,21 @@ public interface StorageManager extends StorageService, Manager {
* @return true if one of the above conditions is true
*/
boolean volumeInactive(VolumeVO volume);
String getVmNameOnVolume(VolumeVO volume);
/**
* Checks if a host has running VMs that are using its local storage pool.
* @return true if local storage is active on the host
*/
boolean isLocalStorageActiveOnHost(Host host);
boolean isLocalStorageActiveOnHost(Long hostId);
/**
* Cleans up storage pools by removing unused templates.
* @param recurring - true if this cleanup is part of a recurring garbage collection thread
*/
void cleanupStorage(boolean recurring);
String getPrimaryStorageNameLabel(VolumeVO volume);
/**
@ -176,16 +176,16 @@ public interface StorageManager extends StorageService, Manager {
*/
<T extends VMInstanceVO> DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, T vm, Account owner);
<T extends VMInstanceVO> DiskProfile allocateTemplatedVolume(Type type, String name, DiskOfferingVO offering, VMTemplateVO template, T vm, Account owner);
void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated);
void prepare(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException;
void release(VirtualMachineProfile<? extends VMInstanceVO> profile);
void cleanupVolumes(long vmId) throws ConcurrentOperationException;
void prepareForMigration(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest);
Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException;
@ -217,7 +217,7 @@ public interface StorageManager extends StorageService, Manager {
boolean stateTransitTo(Volume vol, Event event)
throws NoTransitionException;
VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId);
Host updateSecondaryStorage(long secStorageId, String newUrl);
@ -237,6 +237,6 @@ public interface StorageManager extends StorageService, Manager {
HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException;
}

View File

@ -431,8 +431,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
}
@Override
public boolean isLocalStorageActiveOnHost(Host host) {
List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(host.getId());
public boolean isLocalStorageActiveOnHost(Long hostId) {
List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId);
for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) {
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolHostRef.getPoolId());
if (storagePool.getPoolType() == StoragePoolType.LVM || storagePool.getPoolType() == StoragePoolType.EXT) {
@ -652,7 +652,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
Pair<VolumeVO, String> volumeDetails = createVolumeFromSnapshot(volume, snapshot);
if (volumeDetails != null) {
createdVolume = volumeDetails.first();
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(),
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(),
createdVolume.getDiskOfferingId(), null, createdVolume.getSize());
_usageEventDao.persist(usageEvent);
}
@ -737,21 +737,21 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
@DB
public VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering,
List<StoragePoolVO> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
dskCh.setHyperType(vm.getHypervisorType());
// Find a suitable storage to create volume on
// Find a suitable storage to create volume on
StoragePoolVO destPool = findStoragePool(dskCh, dc, pod, clusterId, null, vm, avoidPools);
// Copy the volume from secondary storage to the destination storage pool
// Copy the volume from secondary storage to the destination storage pool
stateTransitTo(volume, Event.CopyRequested);
VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId());
HostVO secStorage = _hostDao.findById(volumeHostVO.getHostId());
String secondaryStorageURL = secStorage.getStorageUrl();
String[] volumePath = volumeHostVO.getInstallPath().split("/");
String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0];
CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volumeUUID, destPool, secondaryStorageURL, false, _copyvolumewait);
CopyVolumeAnswer cvAnswer;
try {
@ -764,23 +764,23 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
if (cvAnswer == null || !cvAnswer.getResult()) {
stateTransitTo(volume, Event.CopyFailed);
throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool.");
}
}
Transaction txn = Transaction.currentTxn();
txn.start();
txn.start();
volume.setPath(cvAnswer.getVolumePath());
volume.setFolder(destPool.getPath());
volume.setPodId(destPool.getPodId());
volume.setPoolId(destPool.getId());
volume.setPoolId(destPool.getId());
volume.setPodId(destPool.getPodId());
stateTransitTo(volume, Event.CopySucceeded);
stateTransitTo(volume, Event.CopySucceeded);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize());
_usageEventDao.persist(usageEvent);
_volumeHostDao.remove(volumeHostVO.getId());
txn.commit();
return volume;
}
@Override
@DB
public VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering,
@ -975,7 +975,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
value = configDao.getValue(Config.RecreateSystemVmEnabled.key());
_recreateSystemVmEnabled = Boolean.parseBoolean(value);
value = configDao.getValue(Config.StorageTemplateCleanupEnabled.key());
_templateCleanupEnabled = (value == null ? true : Boolean.parseBoolean(value));
@ -1517,7 +1517,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
}
if(sPool.getStatus() != StoragePoolStatus.Maintenance){
s_logger.warn("Unable to delete storage id: " + id +" due to it is not in Maintenance state");
throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
}
if (sPool.getPoolType().equals(StoragePoolType.LVM) || sPool.getPoolType().equals(StoragePoolType.EXT)) {
s_logger.warn("Unable to delete local storage id:" + id);
@ -1546,7 +1546,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
" for this pool");
}
}
// First get the host_id from storage_pool_host_ref for given pool id
StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId());
@ -1740,10 +1740,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
return _volsDao.findById(volume.getId());
}
/*
* Upload the volume to secondary storage.
*
*
*/
@Override
@DB
@ -1755,13 +1755,13 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
String volumeName = cmd.getVolumeName();
String url = cmd.getUrl();
String format = cmd.getFormat();
validateVolume(caller, ownerId, zoneId, volumeName, url, format);
VolumeVO volume = persistVolume(caller, ownerId, zoneId, volumeName, url, cmd.getFormat());
_downloadMonitor.downloadVolumeToStorage(volume, zoneId, url, cmd.getChecksum(), ImageFormat.valueOf(format.toUpperCase()));
return volume;
return volume;
}
private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException{
// permission check
@ -1769,7 +1769,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
// Check that the resource limit for volumes won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume);
// Verify that zone exists
DataCenterVO zone = _dcDao.findById(zoneId);
@ -1781,22 +1781,22 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
}
if (url.toLowerCase().contains("file://")) {
throw new InvalidParameterValueException("File:// type urls are currently unsupported");
}
ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
if (imgfmt == null) {
throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
}
String userSpecifiedName = volumeName;
if (userSpecifiedName == null) {
userSpecifiedName = getRandomVolumeName();
}
if((!url.toLowerCase().endsWith("vhd"))&&(!url.toLowerCase().endsWith("vhd.zip"))
&&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz"))
&&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz"))
&&(!url.toLowerCase().endsWith("qcow2"))&&(!url.toLowerCase().endsWith("qcow2.zip"))
&&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz"))
&&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip"))
@ -1804,7 +1804,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
&&(!url.toLowerCase().endsWith("img"))&&(!url.toLowerCase().endsWith("raw"))){
throw new InvalidParameterValueException("Please specify a valid " + format.toLowerCase());
}
if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(".vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase().endsWith("vhd.gz") ))
|| (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz") ))
|| (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase().endsWith("ova.gz")))
@ -1812,14 +1812,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase());
}
validateUrl(url);
return false;
}
private String validateUrl(String url){
try {
URI uri = new URI(url);
if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http")
if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http")
&& !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) {
throw new IllegalArgumentException("Unsupported scheme for url: " + url);
}
@ -1840,16 +1840,16 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
} catch (UnknownHostException uhe) {
throw new IllegalArgumentException("Unable to resolve " + host);
}
return uri.toString();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid URL " + url);
}
}
private VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) {
Transaction txn = Transaction.currentTxn();
txn.start();
@ -1860,7 +1860,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
volume.setAccountId(ownerId);
volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId()));
long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId();
volume.setDiskOfferingId(diskOfferingId);
volume.setDiskOfferingId(diskOfferingId);
//volume.setSize(size);
volume.setInstanceId(null);
volume.setUpdated(new Date());
@ -1881,8 +1881,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
txn.commit();
return volume;
}
/*
* Just allocate a volume in the database, don't send the createvolume cmd to hypervisor. The volume will be finally
* created
@ -1984,7 +1984,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
* throw new UnsupportedServiceException("operation not supported, snapshot with id " + snapshotId +
* " is created from ROOT volume");
* }
*
*
*/
}
@ -2189,7 +2189,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - "
+ storagePool.getDataCenterId() + ", HostOrPoolId - " + storagePool.getId() + ", PodId " + storagePool.getPodId());
}
@Override
public List<Long> getUpHostsInPool(long poolId) {
SearchCriteria<Long> sc = UpHostsInPoolSearch.create();
@ -2290,7 +2290,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
s_logger.warn("Unable to destroy " + vol.getId(), e);
}
}
// remove snapshots in Error state
List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.Status.Error);
for (SnapshotVO snapshotVO : snapshots) {
@ -2300,7 +2300,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
s_logger.warn("Unable to destroy " + snapshotVO.getId(), e);
}
}
} finally {
scanLock.unlock();
}
@ -2439,7 +2439,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
s_logger.warn("problem cleaning up snapshots in secondary storage " + secondaryStorageHost, e2);
}
}
//CleanUp volumes on Secondary Storage.
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
try {
@ -2467,7 +2467,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
_volumeHostDao.remove(destroyedVolumeHostVO.getId());
}
}
}catch (Exception e2) {
s_logger.warn("problem cleaning up volumes in secondary storage " + secondaryStorageHost, e2);
}
@ -2899,14 +2899,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
}
// Check that volume is completely Uploaded
// Check that volume is completely Uploaded
if (volume.getState() == Volume.State.UploadOp){
VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(volume.getId());
if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){
throw new InvalidParameterValueException("Please specify a volume that is not uploading");
}
}
}
// Check that the volume is not already destroyed
if (volume.getState() != Volume.State.Destroy) {
if (!destroyVolume(volume)) {
@ -3258,7 +3258,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
if (s_logger.isDebugEnabled()) {
s_logger.debug("Checking if we need to prepare " + vols.size() + " volumes for " + vm);
}
boolean recreate = _recreateSystemVmEnabled;
List<VolumeVO> recreateVols = new ArrayList<VolumeVO>(vols.size());
@ -3270,7 +3270,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
}
if (assignedPool == null && recreate) {
assignedPool = _storagePoolDao.findById(vol.getPoolId());
}
if (assignedPool != null || recreate) {
Volume.State state = vol.getState();
@ -3311,7 +3311,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
vm.addDisk(new VolumeTO(vol, pool));
}
}
}
} else {
@ -3333,7 +3333,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
existingPool = _storagePoolDao.findById(vol.getPoolId());
s_logger.debug("existing pool: " + existingPool.getId());
}
if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
newVol = vol;
} else {
@ -3422,7 +3422,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
if (toBeCreated.getTemplateId() != null) {
template = _templateDao.findById(toBeCreated.getTemplateId());
}
StoragePool pool = null;
if (sPool != null) {
pool = sPool;
@ -3506,27 +3506,27 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
if (s_logger.isDebugEnabled()) {
s_logger.debug("Expunging " + vol);
}
//Find out if the volume is present on secondary storage
VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(vol.getId());
if(volumeHost != null){
if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED){
HostVO ssHost = _hostDao.findById(volumeHost.getHostId());
DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath());
DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath());
Answer answer = _agentMgr.sendToSecStorage(ssHost, dtCommand);
if (answer == null || !answer.getResult()) {
s_logger.debug("Failed to delete " + volumeHost + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
return;
}
}else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){
}else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){
s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it.");
throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded.");
}
_volumeHostDao.remove(volumeHost.getId());
_volumeDao.remove(vol.getId());
return;
return;
}
String vmName = null;
if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) {
VirtualMachine vm = _vmInstanceDao.findByIdIncludingRemoved(vol.getInstanceId());
@ -3894,7 +3894,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
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++) {
@ -3924,7 +3924,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
}
sc.setJoinParameters("diskOfferingSearch", "systemUse", 1);
if (tags != null && !tags.isEmpty()) {
int count = 0;
sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.toString());
@ -3957,7 +3957,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
// 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());
@ -3979,14 +3979,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
return null;
}
}
@Override
public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) {
if(format == null) {
return HypervisorType.None;
}
if (format == ImageFormat.VHD) {
return HypervisorType.XenServer;
} else if (format == ImageFormat.OVA) {
@ -4075,5 +4075,5 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
}
return true;
}
}

View File

@ -0,0 +1,189 @@
// 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
// 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;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import com.cloud.utils.exception.CloudRuntimeException;
import com.google.gson.Gson;
/**
* Base class for API Test
*
* @author Min Chen
*
*/
public abstract class APITest {
protected String rootUrl = "http://localhost:8080/client/api";
protected String sessionKey = null;
protected String cookieToSent = null;
/**
* Sending an api request through Http GET
* @param command command name
* @param params command query parameters in a HashMap
* @return http request response string
*/
protected String sendRequest(String command, HashMap<String, String> params){
try {
// Construct query string
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("command=");
sBuilder.append(command);
if ( params != null && params.size() > 0){
Iterator<String> keys = params.keySet().iterator();
while (keys.hasNext()){
String key = keys.next();
sBuilder.append("&");
sBuilder.append(key);
sBuilder.append("=");
sBuilder.append(URLEncoder.encode(params.get(key), "UTF-8"));
}
}
// Construct request url
String reqUrl = rootUrl + "?" + sBuilder.toString();
// Send Http GET request
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if ( !command.equals("login") && cookieToSent != null){
// add the cookie to a request
conn.setRequestProperty("Cookie", cookieToSent);
}
conn.connect();
if ( command.equals("login")){
// if it is login call, store cookie
String headerName=null;
for (int i=1; (headerName = conn.getHeaderFieldKey(i))!=null; i++) {
if (headerName.equals("Set-Cookie")) {
String cookie = conn.getHeaderField(i);
cookie = cookie.substring(0, cookie.indexOf(";"));
String cookieName = cookie.substring(0, cookie.indexOf("="));
String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length());
cookieToSent = cookieName + "=" + cookieValue;
}
}
}
// Get the response
StringBuilder response = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
try {
while ((line = rd.readLine()) != null) {
response.append(line);
}
} catch (EOFException ex) {
// ignore this exception
System.out.println("EOF exception due to java bug");
}
rd.close();
return response.toString();
} catch (Exception e) {
throw new CloudRuntimeException("Problem with sending api request", e);
}
}
protected String createMD5String(String password) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new CloudRuntimeException("Error", e);
}
md5.reset();
BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes()));
// make sure our MD5 hash value is 32 digits long...
StringBuffer sb = new StringBuffer();
String pwStr = pwInt.toString(16);
int padding = 32 - pwStr.length();
for (int i = 0; i < padding; i++) {
sb.append('0');
}
sb.append(pwStr);
return sb.toString();
}
protected Object fromSerializedString(String result, Class<?> repCls) {
try {
if (result != null && !result.isEmpty()) {
// get real content
int start = result.indexOf('{', result.indexOf('{') + 1); // find the second {
if ( start < 0 ){
throw new CloudRuntimeException("Response format is wrong: " + result);
}
int end = result.lastIndexOf('}', result.lastIndexOf('}')-1); // find the second } backwards
if ( end < 0 ){
throw new CloudRuntimeException("Response format is wrong: " + result);
}
String content = result.substring(start, end+1);
Gson gson = ApiGsonHelper.getBuilder().create();
return gson.fromJson(content, repCls);
}
return null;
} catch (RuntimeException e) {
throw new CloudRuntimeException("Caught runtime exception when doing GSON deserialization on: " + result, e);
}
}
/**
* Login call
* @param username user name
* @param password password (plain password, we will do MD5 hash here for you)
* @return login response string
*/
protected void login(String username, String password)
{
//String md5Psw = createMD5String(password);
// send login request
HashMap<String, String> params = new HashMap<String, String>();
params.put("response", "json");
params.put("username", username);
params.put("password", password);
String result = this.sendRequest("login", params);
LoginResponse loginResp = (LoginResponse)fromSerializedString(result, LoginResponse.class);
sessionKey = loginResp.getSessionkey();
}
}

View File

@ -0,0 +1,109 @@
// 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
// 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;
import java.util.HashMap;
import org.junit.Before;
import org.junit.Test;
/**
* Test fixture to do performance test for list command
* Currently we commented out this test suite since it requires a real MS and Db running.
*
* @author Min Chen
*
*/
public class ListPerfTest extends APITest {
@Before
public void setup(){
// always login for each testcase
login("admin", "password");
}
@Test
public void testListVM(){
// issue list VM 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("listVirtualMachines", params);
long after = System.currentTimeMillis();
System.out.println("Time taken to list VM: " + (after - before) + " ms");
}
@Test
public void testListVMXML(){
// issue list VM calls
HashMap<String, String> params = new HashMap<String, String>();
params.put("listAll", "true");
params.put("sessionkey", sessionKey);
long before = System.currentTimeMillis();
String result = this.sendRequest("listVirtualMachines", params);
long after = System.currentTimeMillis();
System.out.println("Time taken to list VM: " + (after - before) + " ms");
}
@Test
public void testListRouter(){
// issue list VM 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("listRouters", params);
long after = System.currentTimeMillis();
System.out.println("Time taken to list Routers: " + (after - before) + " ms");
}
@Test
public void testListRouterXML(){
// issue list VM calls
HashMap<String, String> params = new HashMap<String, String>();
params.put("listAll", "true");
params.put("sessionkey", sessionKey);
long before = System.currentTimeMillis();
String result = this.sendRequest("listRouters", params);
long after = System.currentTimeMillis();
System.out.println("Time taken to list Routers: " + (after - before) + " ms");
}
@Test
public void testListHosts(){
// 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("listHosts", params);
long after = System.currentTimeMillis();
System.out.println("Time taken to list Hosts: " + (after - before) + " ms");
}
}

View File

@ -0,0 +1,142 @@
// 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
// 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;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
/**
* Login Response object
*
* @author Min Chen
*
*/
public class LoginResponse extends BaseResponse {
@SerializedName("timeout")
@Param(description = "session timeout period")
private String timeout;
@SerializedName("sessionkey")
@Param(description = "login session key")
private String sessionkey;
@SerializedName("username")
@Param(description = "login username")
private String username;
@SerializedName("userid")
@Param(description = "login user internal uuid")
private String userid;
@SerializedName("firstname")
@Param(description = "login user firstname")
private String firstname;
@SerializedName("lastname")
@Param(description = "login user lastname")
private String lastname;
@SerializedName("account")
@Param(description = "login user account type")
private String account;
@SerializedName("domainid")
@Param(description = "login user domain id")
private String domainid;
@SerializedName("type")
@Param(description = "login user type")
private int type;
public String getTimeout() {
return timeout;
}
public void setTimeout(String timeout) {
this.timeout = timeout;
}
public String getSessionkey() {
return sessionkey;
}
public void setSessionkey(String sessionkey) {
this.sessionkey = sessionkey;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getDomainid() {
return domainid;
}
public void setDomainid(String domainid) {
this.domainid = domainid;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}