CLOUDSTACK-9997: Add cpu cores information in CapacityResponse

This commit contains following changes
(1) add CPU CORE information in op_host_capacity
(2) add capacity name in the CapacityResponse
(3) add allocatedCapacity for CPU/MEMORY/CPU CORE for zones
(4) sort CapacityResponse by zonename and CapacityType
This commit is contained in:
Wei Zhou 2017-07-13 02:36:58 +02:00 committed by Rohit Yadav
parent 829965771a
commit 088cca2b28
11 changed files with 207 additions and 5 deletions

View File

@ -32,6 +32,8 @@ public interface Capacity extends InternalIdentity, Identity {
public static final short CAPACITY_TYPE_LOCAL_STORAGE = 9;
public static final short CAPACITY_TYPE_GPU = 19;
public static final short CAPACITY_TYPE_CPU_CORE = 90;
public Long getHostOrPoolId();
public Long getDataCenterId();
@ -49,4 +51,6 @@ public interface Capacity extends InternalIdentity, Identity {
public long getReservedCapacity();
public Float getUsedPercentage();
public Long getAllocatedCapacity();
}

View File

@ -17,6 +17,8 @@
package org.apache.cloudstack.api.command.admin.resource;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.log4j.Logger;
@ -65,7 +67,8 @@ public class ListCapacityCmd extends BaseListCmd {
@Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "lists capacity by type" + "* CAPACITY_TYPE_MEMORY = 0" + "* CAPACITY_TYPE_CPU = 1"
+ "* CAPACITY_TYPE_STORAGE = 2" + "* CAPACITY_TYPE_STORAGE_ALLOCATED = 3" + "* CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = 4" + "* CAPACITY_TYPE_PRIVATE_IP = 5"
+ "* CAPACITY_TYPE_SECONDARY_STORAGE = 6" + "* CAPACITY_TYPE_VLAN = 7" + "* CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8" + "* CAPACITY_TYPE_LOCAL_STORAGE = 9.")
+ "* CAPACITY_TYPE_SECONDARY_STORAGE = 6" + "* CAPACITY_TYPE_VLAN = 7" + "* CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8" + "* CAPACITY_TYPE_LOCAL_STORAGE = 9"
+ "* CAPACITY_TYPE_GPU = 19" + "* CAPACITY_TYPE_CPU_CORE = 90.")
private Integer type;
@Parameter(name = ApiConstants.SORT_BY, type = CommandType.STRING, since = "3.0.0", description = "Sort the results. Available values: Usage")
@ -127,6 +130,17 @@ public class ListCapacityCmd extends BaseListCmd {
ListResponse<CapacityResponse> response = new ListResponse<CapacityResponse>();
List<CapacityResponse> capacityResponses = _responseGenerator.createCapacityResponse(result, s_percentFormat);
Collections.sort(capacityResponses, new Comparator<CapacityResponse>() {
public int compare(CapacityResponse resp1, CapacityResponse resp2) {
int res = resp1.getZoneName().compareTo(resp2.getZoneName());
if (res != 0) {
return res;
} else {
return resp1.getCapacityType().compareTo(resp2.getCapacityType());
}
}
});
response.setResponses(capacityResponses);
response.setResponseName(getCommandName());
this.setResponseObject(response);

View File

@ -28,6 +28,10 @@ public class CapacityResponse extends BaseResponse {
@Param(description = "the capacity type")
private Short capacityType;
@SerializedName(ApiConstants.NAME)
@Param(description="the capacity name")
private String capacityName;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "the Zone ID")
private String zoneId;
@ -52,6 +56,10 @@ public class CapacityResponse extends BaseResponse {
@Param(description = "the Cluster name")
private String clusterName;
@SerializedName("capacityallocated")
@Param(description="the capacity currently in allocated")
private Long capacityAllocated;
@SerializedName("capacityused")
@Param(description = "the capacity currently in use")
private Long capacityUsed;
@ -72,6 +80,14 @@ public class CapacityResponse extends BaseResponse {
this.capacityType = capacityType;
}
public String getCapacityName() {
return capacityName;
}
public void setCapacityName(String capacityName) {
this.capacityName = capacityName;
}
public String getZoneId() {
return zoneId;
}
@ -120,6 +136,14 @@ public class CapacityResponse extends BaseResponse {
this.clusterName = clusterName;
}
public Long getCapacityAllocated() {
return capacityAllocated;
}
public void setCapacityAllocated(Long capacityAllocated) {
this.capacityAllocated = capacityAllocated;
}
public Long getCapacityUsed() {
return capacityUsed;
}

View File

@ -17,6 +17,8 @@
package com.cloud.capacity;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -75,6 +77,9 @@ public class CapacityVO implements Capacity {
@Transient
private Float usedPercentage;
@Transient
private Long allocatedCapacity;
public CapacityVO() {
}
@ -208,8 +213,37 @@ public class CapacityVO implements Capacity {
this.usedPercentage = usedPercentage;
}
public Long getAllocatedCapacity() {
return allocatedCapacity;
}
public void setAllocatedCapacity(Long allocatedCapacity) {
this.allocatedCapacity = allocatedCapacity;
}
@Override
public String getUuid() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
private static Map<Short, String> capacityNames = null;
static {
capacityNames = new HashMap<Short, String>();
capacityNames.put(CAPACITY_TYPE_MEMORY, "MEMORY");
capacityNames.put(CAPACITY_TYPE_CPU, "CPU");
capacityNames.put(CAPACITY_TYPE_STORAGE, "STORAGE");
capacityNames.put(CAPACITY_TYPE_STORAGE_ALLOCATED, "STORAGE_ALLOCATED");
capacityNames.put(CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, "VIRTUAL_NETWORK_PUBLIC_IP");
capacityNames.put(CAPACITY_TYPE_PRIVATE_IP, "PRIVATE_IP");
capacityNames.put(CAPACITY_TYPE_SECONDARY_STORAGE, "SECONDARY_STORAGE");
capacityNames.put(CAPACITY_TYPE_VLAN, "VLAN");
capacityNames.put(CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, "DIRECT_ATTACHED_PUBLIC_IP");
capacityNames.put(CAPACITY_TYPE_LOCAL_STORAGE, "LOCAL_STORAGE");
capacityNames.put(CAPACITY_TYPE_GPU, "GPU");
capacityNames.put(CAPACITY_TYPE_CPU_CORE, "CPU_CORE");
}
public static String getCapacityName (Short capacityType) {
return capacityNames.get(capacityType);
}
}

View File

@ -187,6 +187,17 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
+
"from op_host_capacity capacity where cluster_id = ? and capacity_type = ?;";
private static final String LIST_ALLOCATED_CAPACITY_GROUP_BY_CAPACITY_AND_ZONE = "SELECT v.data_center_id, SUM(cpu) AS cpucore, " +
"SUM(cpu * speed) AS cpu, SUM(ram_size * 1024 * 1024) AS memory " +
"FROM (SELECT vi.data_center_id, (CASE WHEN ISNULL(service_offering.cpu) THEN custom_cpu.value ELSE service_offering.cpu end) AS cpu, " +
"(CASE WHEN ISNULL(service_offering.speed) THEN custom_speed.value ELSE service_offering.speed end) AS speed, " +
"(CASE WHEN ISNULL(service_offering.ram_size) THEN custom_ram_size.value ELSE service_offering.ram_size end) AS ram_size " +
"FROM (((vm_instance vi LEFT JOIN service_offering ON(((vi.service_offering_id = service_offering.id))) " +
"LEFT JOIN user_vm_details custom_cpu ON(((custom_cpu.vm_id = vi.id) AND (custom_cpu.name = 'CpuNumber')))) " +
"LEFT JOIN user_vm_details custom_speed ON(((custom_speed.vm_id = vi.id) AND (custom_speed.name = 'CpuSpeed')))) " +
"LEFT JOIN user_vm_details custom_ram_size ON(((custom_ram_size.vm_id = vi.id) AND (custom_ram_size.name = 'memory')))) " +
"WHERE ISNULL(vi.removed) AND vi.state NOT IN ('Destroyed', 'Error', 'Expunging')";
public CapacityDaoImpl() {
_hostIdTypeSearch = createSearchBuilder();
_hostIdTypeSearch.and("hostId", _hostIdTypeSearch.entity().getHostOrPoolId(), SearchCriteria.Op.EQ);
@ -407,6 +418,33 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
PreparedStatement pstmt = null;
List<SummedCapacity> results = new ArrayList<SummedCapacity>();
StringBuilder allocatedSql = new StringBuilder(LIST_ALLOCATED_CAPACITY_GROUP_BY_CAPACITY_AND_ZONE);
HashMap<Long, Long> sumCpuCore = new HashMap<Long, Long>();
HashMap<Long, Long> sumCpu = new HashMap<Long, Long>();
HashMap<Long, Long> sumMemory = new HashMap<Long, Long>();
if (zoneId != null){
allocatedSql.append(" AND vi.data_center_id = ?");
}
allocatedSql.append(" ) AS v GROUP BY v.data_center_id");
try {
if (podId == null && clusterId == null) {
// add allocated capacity of zone in result
pstmt = txn.prepareAutoCloseStatement(allocatedSql.toString());
if (zoneId != null){
pstmt.setLong(1, zoneId);
}
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
sumCpuCore.put(rs.getLong(1), rs.getLong(2));
sumCpu.put(rs.getLong(1), rs.getLong(3));
sumMemory.put(rs.getLong(1), rs.getLong(4));
}
}
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + allocatedSql, e);
}
StringBuilder sql = new StringBuilder(LIST_CAPACITY_GROUP_BY_CAPACITY_PART1);
List<Long> resourceIdList = new ArrayList<Long>();
@ -427,7 +465,11 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
resourceIdList.add(capacityType.longValue());
}
sql.append(LIST_CAPACITY_GROUP_BY_CAPACITY_DATA_CENTER_POD_CLUSTER);
if (podId == null && clusterId == null) {
sql.append(" GROUP BY capacity_type, data_center_id");
} else {
sql.append(LIST_CAPACITY_GROUP_BY_CAPACITY_DATA_CENTER_POD_CLUSTER);
}
try {
pstmt = txn.prepareAutoCloseStatement(sql.toString());
@ -438,6 +480,7 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Long capacityZoneId = rs.getLong(6);
Long capacityPodId = null;
Long capacityClusterId = null;
@ -450,6 +493,16 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
(short)rs.getLong(5), rs.getLong(6),
capacityPodId, capacityClusterId);
if (podId == null && clusterId == null) {
Short sumCapacityType = summedCapacity.getCapacityType();
if (sumCapacityType == CapacityVO.CAPACITY_TYPE_MEMORY) {
summedCapacity.setAllocatedCapacity(sumMemory.get(capacityZoneId));
} else if (sumCapacityType == CapacityVO.CAPACITY_TYPE_CPU) {
summedCapacity.setAllocatedCapacity(sumCpu.get(capacityZoneId));
} else if (sumCapacityType == CapacityVO.CAPACITY_TYPE_CPU_CORE) {
summedCapacity.setAllocatedCapacity(sumCpuCore.get(capacityZoneId));
}
}
results.add(summedCapacity);
}
HashMap<String, SummedCapacity> capacityMap = new HashMap<String, SummedCapacity>();
@ -460,7 +513,7 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
}
else {
// sum the values based on the zoneId.
key=String.valueOf(result.getDataCenterId())+String.valueOf(result.getCapacityType());
key=String.valueOf(result.getDataCenterId()) + "-" + String.valueOf(result.getCapacityType());
}
SummedCapacity tempCapacity=null;
if (capacityMap.containsKey(key)) {
@ -589,6 +642,7 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
}
public static class SummedCapacity {
public Long sumAllocated;
public long sumUsed;
public long sumReserved;
public long sumTotal;
@ -679,6 +733,12 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
public void setClusterId(Long clusterId) {
this.clusterId=clusterId;
}
public Long getAllocatedCapacity() {
return sumAllocated;
}
public void setAllocatedCapacity(Long sumAllocated) {
this.sumAllocated = sumAllocated;
}
}
@Override

View File

@ -958,6 +958,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (SummedCapacity capacity : capacities) {
CapacityResponse capacityResponse = new CapacityResponse();
capacityResponse.setCapacityType(capacity.getCapacityType());
capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null);
@ -994,6 +995,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (SummedCapacity capacity : capacities) {
CapacityResponse capacityResponse = new CapacityResponse();
capacityResponse.setCapacityType(capacity.getCapacityType());
capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null);
@ -1026,6 +1028,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (CapacityVO capacity : capacities) {
CapacityResponse capacityResponse = new CapacityResponse();
capacityResponse.setCapacityType(capacity.getCapacityType());
capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
if (capacityResponse.getCapacityTotal() != 0) {
@ -1110,6 +1113,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (SummedCapacity capacity : capacities) {
CapacityResponse capacityResponse = new CapacityResponse();
capacityResponse.setCapacityType(capacity.getCapacityType());
capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
@ -1606,7 +1610,11 @@ public class ApiResponseHelper implements ResponseGenerator {
for (Capacity summedCapacity : result) {
CapacityResponse capacityResponse = new CapacityResponse();
capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity());
if (summedCapacity.getAllocatedCapacity() != null) {
capacityResponse.setCapacityAllocated(summedCapacity.getAllocatedCapacity());
}
capacityResponse.setCapacityType(summedCapacity.getCapacityType());
capacityResponse.setCapacityName(CapacityVO.getCapacityName(summedCapacity.getCapacityType()));
capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity());
if (summedCapacity.getPodId() != null) {
capacityResponse.setPodId(ApiDBUtils.findPodById(summedCapacity.getPodId()).getUuid());
@ -1677,6 +1685,7 @@ public class ApiResponseHelper implements ResponseGenerator {
capacityResponse.setClusterName(cluster.getName());
}
capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU);
capacityResponse.setCapacityName(CapacityVO.getCapacityName(Capacity.CAPACITY_TYPE_GPU));
capacityResponse.setCapacityUsed((long)Math.ceil(capacityUsed));
capacityResponse.setCapacityTotal(capacityMax);
if (capacityMax > 0) {

View File

@ -591,6 +591,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
offeringsMap.put(offering.getId(), offering);
}
long usedCpuCore = 0;
long reservedCpuCore = 0;
long usedCpu = 0;
long usedMemory = 0;
long reservedMemory = 0;
@ -626,9 +628,11 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
usedCpu +=
((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
clusterCpuOvercommitRatio;
usedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
} else {
usedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
usedCpu += ((so.getCpu() * so.getSpeed()) / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
usedCpuCore += so.getCpu();
}
}
@ -655,9 +659,11 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
reservedCpu +=
((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
clusterCpuOvercommitRatio;
reservedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
} else {
reservedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
reservedCpu += (so.getCpu() * so.getSpeed() / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
reservedCpuCore += so.getCpu();
}
} else {
// signal if not done already, that the VM has been stopped for skip.counting.hours,
@ -678,6 +684,53 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU);
CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
CapacityVO cpuCoreCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU_CORE);
if (cpuCoreCap != null) {
long hostTotalCpuCore = host.getCpus().longValue();
if (cpuCoreCap.getTotalCapacity() != hostTotalCpuCore) {
s_logger.debug("Calibrate total cpu for host: " + host.getId() + " old total CPU:"
+ cpuCoreCap.getTotalCapacity() + " new total CPU:" + hostTotalCpuCore);
cpuCoreCap.setTotalCapacity(hostTotalCpuCore);
}
if (cpuCoreCap.getUsedCapacity() == usedCpuCore && cpuCoreCap.getReservedCapacity() == reservedCpuCore) {
s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpuCore: " + cpuCoreCap.getUsedCapacity()
+ " reservedCpuCore: " + cpuCoreCap.getReservedCapacity());
} else {
if (cpuCoreCap.getReservedCapacity() != reservedCpuCore) {
s_logger.debug("Calibrate reserved cpu core for host: " + host.getId() + " old reservedCpuCore:"
+ cpuCoreCap.getReservedCapacity() + " new reservedCpuCore:" + reservedCpuCore);
cpuCoreCap.setReservedCapacity(reservedCpuCore);
}
if (cpuCoreCap.getUsedCapacity() != usedCpuCore) {
s_logger.debug("Calibrate used cpu core for host: " + host.getId() + " old usedCpuCore:"
+ cpuCoreCap.getUsedCapacity() + " new usedCpuCore:" + usedCpuCore);
cpuCoreCap.setUsedCapacity(usedCpuCore);
}
}
try {
_capacityDao.update(cpuCoreCap.getId(), cpuCoreCap);
} catch (Exception e) {
s_logger.error("Caught exception while updating cpucore capacity for the host " +host.getId(), e);
}
} else {
final long usedCpuCoreFinal = usedCpuCore;
final long reservedCpuCoreFinal = reservedCpuCore;
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
CapacityVO capacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedCpuCoreFinal, host.getCpus().longValue(),
CapacityVO.CAPACITY_TYPE_CPU_CORE);
capacity.setReservedCapacity(reservedCpuCoreFinal);
capacity.setCapacityState(capacityState);
_capacityDao.persist(capacity);
}
});
}
if (cpuCap != null && memCap != null) {
if (host.getTotalMemory() != null) {
memCap.setTotalCapacity(host.getTotalMemory());

View File

@ -2505,6 +2505,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
for (final SummedCapacity summedCapacity : summedCapacities) {
final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(),summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getUsedCapacity()
+ summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType());
capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity());
capacities.add(capacity);
}

View File

@ -246,8 +246,6 @@
data: {
fetchLatest: data.fetchLatest,
sortBy: 'usage',
page: 0,
pageSize: (pageSize > 8? 8: pageSize)
},
success: function(json) {
var capacities = json.listcapacityresponse.capacity ?

View File

@ -1225,6 +1225,8 @@ cloudStack.converters = {
return _l('label.secondary.storage.vm');
case 19:
return _l('label.gpu');
case 90:
return _l('label.num.cpu.cores');
}
},

View File

@ -386,6 +386,9 @@
},
19: {
name: _l('GPU')
},
90: {
name: _l('label.num.cpu.cores')
}
};