/** * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * * It is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ package com.cloud.api.commands; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import org.apache.log4j.Logger; import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.capacity.CapacityVO; import com.cloud.server.Criteria; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePoolVO; import com.cloud.utils.Pair; public class ListCapacityCmd extends BaseCmd{ public static final Logger s_logger = Logger.getLogger(ListCapacityCmd.class.getName()); private static final DecimalFormat s_percentFormat = new DecimalFormat("####.##"); private static final String s_name = "listcapacityresponse"; private static final List> s_properties = new ArrayList>(); public String getName() { return s_name; } public List> getProperties() { return s_properties; } static { s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.POD_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.HOST_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.TYPE, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.PAGE, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.PAGESIZE, Boolean.FALSE)); } public List> execute(Map params) { Long zoneId = (Long)params.get(BaseCmd.Properties.ZONE_ID.getName()); Long podId = (Long)params.get(BaseCmd.Properties.POD_ID.getName()); Long hostId = (Long)params.get(BaseCmd.Properties.HOST_ID.getName()); String type = (String)params.get(BaseCmd.Properties.TYPE.getName()); Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName()); Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName()); Long startIndex = Long.valueOf(0); int pageSizeNum = 1000000; if (pageSize != null) { pageSizeNum = pageSize.intValue(); } if (page != null) { int pageNum = page.intValue(); if (pageNum > 0) { startIndex = Long.valueOf(pageSizeNum * (pageNum-1)); } } Criteria c = new Criteria ("capacityType", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.DATACENTERID, zoneId); c.addCriteria(Criteria.PODID, podId); c.addCriteria(Criteria.HOSTID, hostId); c.addCriteria(Criteria.TYPE, type); List capacities = getManagementServer().listCapacities(c); if (capacities == null ) { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "unable to get capacity statistic"); } List summedCapacities = sumCapacities(capacities); List> capacitiesTags = new ArrayList>(); Object[] cTag = new Object[summedCapacities.size()]; int i=0; for (CapacityVO capacity : summedCapacities) { List> capacityData = new ArrayList>(); capacityData.add(new Pair(BaseCmd.Properties.TYPE.getName(), capacity.getCapacityType())); capacityData.add(new Pair(BaseCmd.Properties.ZONE_ID.getName(), capacity.getDataCenterId())); capacityData.add(new Pair(BaseCmd.Properties.ZONE_NAME.getName(), getManagementServer().getDataCenterBy(capacity.getDataCenterId()).getName())); if (capacity.getPodId() != null) { capacityData.add(new Pair(BaseCmd.Properties.POD_ID.getName(), capacity.getPodId())); capacityData.add(new Pair(BaseCmd.Properties.POD_NAME.getName(), (capacity.getPodId() > 0) ? getManagementServer().findHostPodById(capacity.getPodId()).getName() : "All")); } capacityData.add(new Pair(BaseCmd.Properties.CAPACITY_USED.getName(), Long.valueOf(capacity.getUsedCapacity()).toString())); capacityData.add(new Pair(BaseCmd.Properties.CAPACITY_TOTAL.getName(), Long.valueOf(capacity.getTotalCapacity()).toString())); try { if (capacity.getTotalCapacity() != 0) { float percent = (float)capacity.getUsedCapacity()/(float)capacity.getTotalCapacity()*100; capacityData.add(new Pair(BaseCmd.Properties.PERCENT_USED.getName(), s_percentFormat.format(percent))); } else { capacityData.add(new Pair(BaseCmd.Properties.PERCENT_USED.getName(), s_percentFormat.format(0))); } } catch (Exception ex) { throw new ServerApiException (BaseCmd.INTERNAL_ERROR, "unable to get capacity statistic"); } cTag[i++] = capacityData; } Pair capacityTag = new Pair("capacity", cTag); capacitiesTags.add(capacityTag); return capacitiesTags; } public List sumCapacities(List hostCapacities) { Map totalCapacityMap = new HashMap(); Map usedCapacityMap = new HashMap(); Set poolIdsToIgnore = new HashSet(); Criteria c = new Criteria(); List allStoragePools = getManagementServer().searchForStoragePools(c); for (StoragePoolVO pool : allStoragePools) { StoragePoolType poolType = pool.getPoolType(); if (!(poolType.equals(StoragePoolType.NetworkFilesystem) || poolType.equals(StoragePoolType.IscsiLUN))) { poolIdsToIgnore.add(pool.getId()); } } // collect all the capacity types, sum allocated/used and sum total...get one capacity number for each for (CapacityVO capacity : hostCapacities) { if (poolIdsToIgnore.contains(capacity.getHostOrPoolId())) { continue; } String key = capacity.getCapacityType() + "_" + capacity.getDataCenterId(); String keyForPodTotal = key + "_-1"; boolean sumPodCapacity = false; if (capacity.getPodId() != null) { key += "_" + capacity.getPodId(); sumPodCapacity = true; } Long totalCapacity = totalCapacityMap.get(key); Long usedCapacity = usedCapacityMap.get(key); if (totalCapacity == null) { totalCapacity = new Long(capacity.getTotalCapacity()); } else { totalCapacity = new Long(capacity.getTotalCapacity() + totalCapacity.longValue()); } if (usedCapacity == null) { usedCapacity = new Long(capacity.getUsedCapacity()); } else { usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity.longValue()); } totalCapacityMap.put(key, totalCapacity); usedCapacityMap.put(key, usedCapacity); if (sumPodCapacity) { totalCapacity = totalCapacityMap.get(keyForPodTotal); usedCapacity = usedCapacityMap.get(keyForPodTotal); if (totalCapacity == null) { totalCapacity = new Long(capacity.getTotalCapacity()); } else { totalCapacity = new Long(capacity.getTotalCapacity() + totalCapacity.longValue()); } if (usedCapacity == null) { usedCapacity = new Long(capacity.getUsedCapacity()); } else { usedCapacity = new Long(capacity.getUsedCapacity() + usedCapacity.longValue()); } totalCapacityMap.put(keyForPodTotal, totalCapacity); usedCapacityMap.put(keyForPodTotal, usedCapacity); } } List summedCapacities = new ArrayList(); for (String key : totalCapacityMap.keySet()) { CapacityVO summedCapacity = new CapacityVO(); StringTokenizer st = new StringTokenizer(key, "_"); summedCapacity.setCapacityType(Short.parseShort(st.nextToken())); summedCapacity.setDataCenterId(Long.parseLong(st.nextToken())); if (st.hasMoreTokens()) { summedCapacity.setPodId(Long.parseLong(st.nextToken())); } summedCapacity.setTotalCapacity(totalCapacityMap.get(key)); summedCapacity.setUsedCapacity((usedCapacityMap.get(key) > totalCapacityMap.get(key)) ? totalCapacityMap.get(key):usedCapacityMap.get(key)); summedCapacities.add(summedCapacity); } return summedCapacities; } }