Copilot commented on code in PR #13490:
URL: https://github.com/apache/cloudstack/pull/13490#discussion_r4181831800
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -614,7 +621,6 @@ public DomainResponse createDomainResponse(Domain domain) {
if (domain.getChildCount() > 0) {
domainResponse.setHasChild(true);
}
- populateDomainTags(domain.getUuid(), domainResponse);
domainResponse.setObjectName("domain");
Review Comment:
Direct domain responses no longer include resource tags.
Create/update/move/list-domain-children all call this method, while the
query-based list path still calls `populateDomainTags`, so these APIs now
return inconsistent domain data. Restore the tag population before returning
the response.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -5145,6 +5270,56 @@ public SSHKeyPairResponse
createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolea
return response;
}
+ @Override
+ public ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair) {
+ ApiKeyPairResponse response = new ApiKeyPairResponse();
+ if (keyPair == null) {
+ return response;
+ }
+ response.setId(keyPair.getUuid());
+ response.setName(keyPair.getName());
+ response.setApiKey(keyPair.getApiKey());
+ response.setSecretKey(keyPair.getSecretKey());
+ response.setDescription(keyPair.getDescription());
+ response.setStartDate(keyPair.getStartDate());
+ response.setEndDate(keyPair.getEndDate());
+ response.setCreated(keyPair.getCreated());
+
+ // populate account
+ try {
+ Account account =
ApiDBUtils.findAccountById(keyPair.getAccountId());
+ if (account != null && account.getType() != Account.Type.PROJECT) {
+ response.setAccountName(account.getAccountName());
Review Comment:
This replacement of the existing key-pair mapper drops contract fields
including `state`, `accountid`, `accounttype`, and all role metadata; it also
omits the account name for project accounts. List/register key APIs will
therefore return materially incomplete responses. Preserve the previous
state/account/role population while moving the method.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -2901,10 +2922,7 @@ public NetworkResponse
createNetworkResponse(ResponseView view, Network network)
}
}
- if (CallContext.current().getCallingAccount().getType() ==
Account.Type.ADMIN &&
- network.getVpcId() == null && network.getGuestType() ==
Network.GuestType.Isolated) {
-
response.setKeepMacAddressOnPublicNic(network.getKeepMacAddressOnPublicNic());
- }
+
Review Comment:
Admin responses for isolated, non-VPC networks now omit
`keepmacaddressonpublicnic`, although this remains a documented response field
and is displayed by the UI. Restore the conditional population.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -1684,7 +1706,6 @@ public FirewallRuleResponse
createPortForwardingRuleResponse(PortForwardingRule
Network guestNtwk = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
response.setNetworkId(guestNtwk.getUuid());
- response.setNetworkName(guestNtwk.getName());
Review Comment:
This removal leaves the documented `networkname` field null for every
port-forwarding-rule response even though `guestNtwk` has already been loaded.
Restore the field assignment to avoid an unrelated API response regression.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -3588,7 +3595,7 @@ public VpcResponse createVpcResponse(ResponseView view,
Vpc vpc) {
if (voff != null) {
response.setVpcOfferingId(voff.getUuid());
response.setVpcOfferingName(voff.getName());
- response.setVpcOfferingConserveMode(voff.isConserveMode());
+
Review Comment:
The VPC response no longer reports whether its offering uses conserve mode,
leaving the documented `vpcofferingconservemode` field null for all VPCs.
Restore the assignment from the offering.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -1912,8 +1933,6 @@ public SystemVmResponse
createSystemVmResponse(VirtualMachine vm) {
vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
}
- } else if (network.getTrafficType() ==
TrafficType.Storage) {
-
vmResponse.setStorageIp(singleNicProfile.getIPv4Address());
}
Review Comment:
Storage-network NICs are no longer handled, so `listSystemVms` loses the
`storageip` value that the response contract and UI expose. Restore the storage
traffic branch.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -3684,9 +3691,7 @@ public VpcResponse createVpcResponse(ResponseView view,
Vpc vpc) {
}
}
- if (CallContext.current().getCallingAccount().getType() ==
Account.Type.ADMIN) {
-
response.setKeepMacAddressOnPublicNic(vpc.getKeepMacAddressOnPublicNic());
- }
+
Review Comment:
Admin VPC responses now omit `keepmacaddressonpublicnic`, despite the field
remaining in the response contract and admin UI. Restore the value from the VPC.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -4785,7 +4911,7 @@ public NicSecondaryIpResponse
createSecondaryIPToNicResponse(NicSecondaryIp resu
setResponseIpAddress(result, response);
response.setNicId(nic.getUuid());
response.setNwId(network.getUuid());
- response.setDescription(result.getDescription());
+
Review Comment:
The standalone secondary-IP response now drops its documented description
even when the entity contains one. Restore the mapping so callers of this
response path retain the value.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -4872,7 +4998,7 @@ public NicResponse createNicResponse(Nic result) {
for (NicSecondaryIpVO ip : secondaryIps) {
NicSecondaryIpResponse ipRes = new
NicSecondaryIpResponse();
ipRes.setId(ip.getUuid());
- ipRes.setDescription(ip.getDescription());
+
Review Comment:
Secondary IPs embedded in NIC responses now lose their descriptions because
the mapping was removed. Restore it for parity with the secondary-IP entity and
response contract.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -3981,14 +3986,7 @@ public Site2SiteCustomerGatewayResponse
createSite2SiteCustomerGatewayResponse(S
response.setIkeVersion(result.getIkeVersion());
response.setSplitConnections(result.getSplitConnections());
- Set<String> obsoleteParameters =
site2SiteVpnManager.getObsoleteVpnGatewayParameters(result);
- if (CollectionUtils.isNotEmpty(obsoleteParameters)) {
-
response.setContainsObsoleteParameters(obsoleteParameters.toString());
- }
- Set<String> excludedParameters =
site2SiteVpnManager.getExcludedVpnGatewayParameters(result);
- if (CollectionUtils.isNotEmpty(excludedParameters)) {
-
response.setContainsExcludedParameters(excludedParameters.toString());
- }
+
Review Comment:
Customer-gateway responses no longer populate the documented
obsolete/excluded VPN parameter indicators. This hides compatibility warnings
for every gateway; restore the manager dependency and both response assignments.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -4210,474 +4208,602 @@ public UsageRecordResponse createUsageResponse(Usage
usageRecord, Map<String, Se
}
}
- ResourceTag.ResourceObjectType resourceType = null;
- Long resourceId = null;
+ UsageResourceDetails resourceDetails =
populateUsageTypeSpecificDetails(usageRecord, usageRecResponse, oldFormat,
vmInstance, template);
+ if (resourceTagResponseMap != null && resourceDetails.resourceId !=
null && resourceDetails.resourceType != null) {
+ final String tagKey = resourceDetails.resourceId + ":" +
resourceDetails.resourceType;
+ if (resourceTagResponseMap.get(tagKey) != null) {
+ usageRecResponse.setTags(resourceTagResponseMap.get(tagKey));
+ }
+ }
+
+ if (usageRecord.getRawUsage() != null) {
+ DecimalFormat decimalFormat = new
DecimalFormat("###########.######");
+
usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));
+ }
+
+ if (usageRecord.getStartDate() != null) {
+ usageRecResponse.setStartDate(usageRecord.getStartDate());
+ }
+ if (usageRecord.getEndDate() != null) {
+ usageRecResponse.setEndDate(usageRecord.getEndDate());
+ }
+
+ return usageRecResponse;
+ }
+
+ private UsageResourceDetails populateUsageTypeSpecificDetails(Usage
usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat,
+ VMInstanceVO vmInstance, VMTemplateVO template) {
if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM ||
usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
- ServiceOfferingVO svcOffering =
_entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class,
usageRecord.getOfferingId().toString());
- //Service Offering Id
- if(svcOffering != null) {
- usageRecResponse.setOfferingId(svcOffering.getUuid());
- }
- //VM Instance ID
- VMInstanceVO vm = null;
- if (usageRecord.getUsageId() != null &&
usageRecord.getUsageId().equals(usageRecord.getVmInstanceId())) {
- vm = vmInstance;
- } else {
- vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class,
usageRecord.getUsageId().toString());
+ return populateRunningOrAllocatedVmUsageResponse(usageRecord,
usageRecResponse, oldFormat, vmInstance, template);
+ } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) {
+ return populateIpAddressUsageResponse(usageRecord,
usageRecResponse);
+ } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT
|| usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
+ return populateNetworkBytesUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ ||
usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE
+ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ
|| usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
+ return populateVmDiskUsageResponse(usageRecord, usageRecResponse,
oldFormat, vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) {
+ return populateVolumeUsageResponse(usageRecord, usageRecResponse,
oldFormat, vmInstance, template);
+ } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE ||
usageRecord.getUsageType() == UsageTypes.ISO) {
+ return populateTemplateOrIsoUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) {
+ return populateSnapshotUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() ==
UsageTypes.LOAD_BALANCER_POLICY) {
+ return populateLoadBalancerPolicyUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() ==
UsageTypes.PORT_FORWARDING_RULE) {
+ return populatePortForwardingRuleUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) {
+ return populateNetworkOfferingUsageResponse(usageRecord,
usageRecResponse, oldFormat, vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) {
+ return populateVpnUsersUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) {
+ return populateSecurityGroupUsageResponse(usageRecord,
usageRecResponse, oldFormat, vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.BACKUP) {
+ return populateBackupUsageResponse(usageRecord, usageRecResponse,
vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
+ return populateVmSnapshotUsageResponse(usageRecord,
usageRecResponse, oldFormat, vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.VOLUME_SECONDARY) {
+ return populateVolumeSecondaryUsageResponse(usageRecord,
usageRecResponse, oldFormat);
+ } else if (usageRecord.getUsageType() ==
UsageTypes.VM_SNAPSHOT_ON_PRIMARY) {
+ return populateVmSnapshotOnPrimaryUsageResponse(usageRecord,
usageRecResponse, oldFormat, vmInstance);
+ } else if (usageRecord.getUsageType() == UsageTypes.BUCKET) {
+ return populateBucketUsageResponse(usageRecord, usageRecResponse);
+ }
+
+ return new UsageResourceDetails();
+ }
+
+ private UsageResourceDetails
populateRunningOrAllocatedVmUsageResponse(Usage usageRecord,
UsageRecordResponse usageRecResponse, boolean oldFormat,
+ VMInstanceVO vmInstance, VMTemplateVO template) {
+ UsageResourceDetails resourceDetails = new UsageResourceDetails();
+ ServiceOfferingVO svcOffering =
_entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class,
usageRecord.getOfferingId());
+ //Service Offering Id
+ if(svcOffering != null) {
+ usageRecResponse.setOfferingId(svcOffering.getUuid());
+ }
+ //VM Instance ID
+ VMInstanceVO vm = null;
+ if (usageRecord.getUsageId() != null &&
usageRecord.getUsageId().equals(usageRecord.getVmInstanceId())) {
+ vm = vmInstance;
+ } else {
+ vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class,
usageRecord.getUsageId());
+ }
+ if (vm != null) {
+ resourceDetails.resourceType =
ResourceTag.ResourceObjectType.UserVm;
+ usageRecResponse.setUsageId(vm.getUuid());
+ resourceDetails.resourceId = vm.getId();
+ final GuestOS guestOS = _guestOsDao.findById(vm.getGuestOSId());
+ if (guestOS != null) {
+ usageRecResponse.setOsTypeId(guestOS.getUuid());
+ usageRecResponse.setOsDisplayName(guestOS.getDisplayName());
+ final GuestOsCategory guestOsCategory =
_guestOsCategoryDao.findById(guestOS.getCategoryId());
+ if (guestOsCategory != null) {
+
usageRecResponse.setOsCategoryId(guestOsCategory.getUuid());
+
usageRecResponse.setOsCategoryName(guestOsCategory.getName());
+ }
+ }
+ }
+ //Hypervisor Type
+ usageRecResponse.setType(usageRecord.getType());
+ //Dynamic compute offerings details
+ if (usageRecord.getCpuCores() != null) {
+ usageRecResponse.setCpuNumber(usageRecord.getCpuCores());
+ } else if (svcOffering != null && svcOffering.getCpu() != null) {
+ usageRecResponse.setCpuNumber(svcOffering.getCpu().longValue());
+ }
+ if (usageRecord.getCpuSpeed() != null) {
+ usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed());
+ } else if (svcOffering != null && svcOffering.getSpeed() != null) {
+ usageRecResponse.setCpuSpeed(svcOffering.getSpeed().longValue());
+ }
+ if (usageRecord.getMemory() != null) {
+ usageRecResponse.setMemory(usageRecord.getMemory());
+ } else if (svcOffering != null && svcOffering.getRamSize() != null) {
+ usageRecResponse.setMemory(svcOffering.getRamSize().longValue());
+ }
+ if (!oldFormat) {
+ final StringBuilder builder = new StringBuilder();
+ if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM) {
+ builder.append("Running VM usage ");
+ } else if(usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
+ builder.append("Allocated VM usage ");
}
if (vm != null) {
- resourceType = ResourceTag.ResourceObjectType.UserVm;
- usageRecResponse.setUsageId(vm.getUuid());
- resourceId = vm.getId();
- final GuestOS guestOS =
_guestOsDao.findById(vm.getGuestOSId());
- if (guestOS != null) {
- usageRecResponse.setOsTypeId(guestOS.getUuid());
-
usageRecResponse.setOsDisplayName(guestOS.getDisplayName());
- final GuestOsCategory guestOsCategory =
_guestOsCategoryDao.findById(guestOS.getCategoryId());
- if (guestOsCategory != null) {
-
usageRecResponse.setOsCategoryId(guestOsCategory.getUuid());
-
usageRecResponse.setOsCategoryName(guestOsCategory.getName());
- }
- }
+ builder.append("for ").append(vm.getHostName()).append("
(").append(vm.getInstanceName()).append(") (").append(vm.getUuid()).append(")
");
}
- //Hypervisor Type
- usageRecResponse.setType(usageRecord.getType());
- //Dynamic compute offerings details
- if(usageRecord.getCpuCores() != null) {
- usageRecResponse.setCpuNumber(usageRecord.getCpuCores());
- } else if (svcOffering.getCpu() != null){
-
usageRecResponse.setCpuNumber(svcOffering.getCpu().longValue());
- }
- if(usageRecord.getCpuSpeed() != null) {
- usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed());
- } else if(svcOffering.getSpeed() != null){
-
usageRecResponse.setCpuSpeed(svcOffering.getSpeed().longValue());
- }
- if(usageRecord.getMemory() != null) {
- usageRecResponse.setMemory(usageRecord.getMemory());
- } else if(svcOffering.getRamSize() != null) {
-
usageRecResponse.setMemory(svcOffering.getRamSize().longValue());
- }
- if (!oldFormat) {
- final StringBuilder builder = new StringBuilder();
- if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM) {
- builder.append("Running VM usage ");
- } else if(usageRecord.getUsageType() ==
UsageTypes.ALLOCATED_VM) {
- builder.append("Allocated VM usage ");
- }
- if (vm != null) {
- builder.append("for ").append(vm.getHostName()).append("
(").append(vm.getInstanceName()).append(") (").append(vm.getUuid()).append(")
");
- }
- if (svcOffering != null) {
- builder.append("using service offering
").append(svcOffering.getName()).append("
(").append(svcOffering.getUuid()).append(") ");
- }
- if (template != null) {
- builder.append("and template
").append(template.getName()).append("
(").append(template.getUuid()).append(")");
- }
- usageRecResponse.setDescription(builder.toString());
+ if (svcOffering != null) {
+ builder.append("using service offering
").append(svcOffering.getName()).append("
(").append(svcOffering.getUuid()).append(") ");
}
- } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) {
- //IP Address ID
- IPAddressVO ip =
_entityMgr.findByIdIncludingRemoved(IPAddressVO.class,
usageRecord.getUsageId().toString());
- if (ip != null) {
- Long networkId = ip.getAssociatedWithNetworkId();
- if (networkId == null) {
- networkId = ip.getSourceNetworkId();
- }
- resourceType = ResourceObjectType.PublicIpAddress;
- resourceId = ip.getId();
- usageRecResponse.setUsageId(ip.getUuid());
- }
- //isSourceNAT
-
usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ?
true : false);
- //isSystem
- usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true :
false);
- } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT
|| usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
- //Device Type
- resourceType = ResourceObjectType.UserVm;
- usageRecResponse.setType(usageRecord.getType());
- VMInstanceVO vm = null;
- HostVO host = null;
- if (usageRecord.getType().equals("DomainRouter") ||
usageRecord.getType().equals("UserVm")) {
- //Domain Router Id
- vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class,
usageRecord.getUsageId().toString());
- if (vm != null) {
- resourceId = vm.getId();
- usageRecResponse.setUsageId(vm.getUuid());
- }
- } else {
- //External Device Host Id
- host = _entityMgr.findByIdIncludingRemoved(HostVO.class,
usageRecord.getUsageId().toString());
- if (host != null) {
- usageRecResponse.setUsageId(host.getUuid());
- }
+ if (template != null) {
+ builder.append("and template
").append(template.getName()).append("
(").append(template.getUuid()).append(")");
}
- //Network ID
- NetworkVO network = null;
- if((usageRecord.getNetworkId() != null) &&
(usageRecord.getNetworkId() != 0)) {
- network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class,
usageRecord.getNetworkId().toString());
- if (network != null) {
- resourceType = ResourceObjectType.Network;
- if (network.getTrafficType() == TrafficType.Public) {
- VirtualRouter router =
ApiDBUtils.findDomainRouterById(usageRecord.getUsageId());
- Vpc vpc =
ApiDBUtils.findVpcByIdIncludingRemoved(router.getVpcId());
+ usageRecResponse.setDescription(builder.toString());
+ }
+ return resourceDetails;
+ }
+
+ private UsageResourceDetails populateIpAddressUsageResponse(Usage
usageRecord, UsageRecordResponse usageRecResponse) {
+ UsageResourceDetails resourceDetails = new UsageResourceDetails();
+ //IP Address ID
+ IPAddressVO ip =
_entityMgr.findByIdIncludingRemoved(IPAddressVO.class,
usageRecord.getUsageId());
+ if (ip != null) {
+ resourceDetails.resourceType = ResourceObjectType.PublicIpAddress;
+ resourceDetails.resourceId = ip.getId();
+ usageRecResponse.setUsageId(ip.getUuid());
+ }
+ //isSourceNAT
+
usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ?
true : false);
+ //isSystem
+ usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true :
false);
+ return resourceDetails;
+ }
+
+ private UsageResourceDetails populateNetworkBytesUsageResponse(Usage
usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) {
+ UsageResourceDetails resourceDetails = new UsageResourceDetails();
+ //Device Type
+ resourceDetails.resourceType = ResourceObjectType.UserVm;
+ usageRecResponse.setType(usageRecord.getType());
+ VMInstanceVO vm = null;
+ HostVO host = null;
+ if (usageRecord.getType().equals("DomainRouter") ||
usageRecord.getType().equals("UserVm")) {
+ //Domain Router Id
+ vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class,
usageRecord.getUsageId());
+ if (vm != null) {
+ resourceDetails.resourceId = vm.getId();
+ usageRecResponse.setUsageId(vm.getUuid());
+ }
+ } else {
+ //External Device Host Id
+ host = _entityMgr.findByIdIncludingRemoved(HostVO.class,
usageRecord.getUsageId());
+ if (host != null) {
+ usageRecResponse.setUsageId(host.getUuid());
+ }
+ }
+ //Network ID
+ NetworkVO network = null;
+ if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId()
!= 0)) {
+ network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class,
usageRecord.getNetworkId());
+ if (network != null) {
+ resourceDetails.resourceType = ResourceObjectType.Network;
+ if (network.getTrafficType() == TrafficType.Public) {
+ VirtualRouter router =
ApiDBUtils.findDomainRouterById(usageRecord.getUsageId());
+ Vpc vpc = router != null && router.getVpcId() != null ?
ApiDBUtils.findVpcByIdIncludingRemoved(router.getVpcId()) : null;
+ if (vpc != null) {
usageRecResponse.setVpcId(vpc.getUuid());
- resourceId = vpc.getId();
+ resourceDetails.resourceId = vpc.getId();
} else {
usageRecResponse.setNetworkId(network.getUuid());
- resourceId = network.getId();
+ resourceDetails.resourceId = network.getId();
}
- usageRecResponse.setResourceName(network.getName());
+ } else {
+ usageRecResponse.setNetworkId(network.getUuid());
+ resourceDetails.resourceId = network.getId();
}
+ usageRecResponse.setResourceName(network.getName());
Review Comment:
This new branch changes API behavior for non-public network traffic: it now
sets `networkId`/`resourceName` and changes the tag lookup ID from the
VM/host-derived value to the network ID. That is an observable business-logic
change despite the PR's claim of a strictly structural refactor; either
preserve the original branch semantics or document and isolate this behavior
change.
##########
server/src/main/java/com/cloud/api/ApiResponseHelper.java:
##########
@@ -4903,7 +5029,6 @@ public NicResponse createNicResponse(Nic result) {
response.setVpcName(vpc.getName());
}
Review Comment:
Every NIC response now omits the documented `enabled` state because the
assignment was removed. Restore this mapping to avoid returning incomplete NIC
data.
##########
server/src/test/java/com/cloud/api/ApiResponseHelperTest.java:
##########
@@ -781,23 +809,661 @@ public void
createConsoleSessionResponseTestShouldReturnFullResponse() {
ConsoleSessionResponse response =
apiResponseHelper.createConsoleSessionResponse(consoleSessionMock,
ResponseObject.ResponseView.Full);
- Assert.assertEquals(expected.getId(), response.getId());
- Assert.assertEquals(expected.getCreated(), response.getCreated());
- Assert.assertEquals(expected.getAcquired(),
response.getAcquired());
- Assert.assertEquals(expected.getRemoved(), response.getRemoved());
- Assert.assertEquals(expected.getConsoleEndpointCreatorAddress(),
response.getConsoleEndpointCreatorAddress());
- Assert.assertEquals(expected.getClientAddress(),
response.getClientAddress());
- Assert.assertEquals(expected.getDomain(), response.getDomain());
- Assert.assertEquals(expected.getDomainPath(),
response.getDomainPath());
- Assert.assertEquals(expected.getDomainId(),
response.getDomainId());
- Assert.assertEquals(expected.getUser(), response.getUser());
- Assert.assertEquals(expected.getUserId(), response.getUserId());
- Assert.assertEquals(expected.getAccount(), response.getAccount());
- Assert.assertEquals(expected.getAccountId(),
response.getAccountId());
- Assert.assertEquals(expected.getHostId(), response.getHostId());
- Assert.assertEquals(expected.getHostName(),
response.getHostName());
- Assert.assertEquals(expected.getVmId(), response.getVmId());
- Assert.assertEquals(expected.getVmName(), response.getVmName());
+ Assertions.assertEquals(expected.getId(), response.getId());
+ Assertions.assertEquals(expected.getCreated(),
response.getCreated());
+ Assertions.assertEquals(expected.getAcquired(),
response.getAcquired());
+ Assertions.assertEquals(expected.getRemoved(),
response.getRemoved());
+
Assertions.assertEquals(expected.getConsoleEndpointCreatorAddress(),
response.getConsoleEndpointCreatorAddress());
+ Assertions.assertEquals(expected.getClientAddress(),
response.getClientAddress());
+ Assertions.assertEquals(expected.getDomain(),
response.getDomain());
+ Assertions.assertEquals(expected.getDomainPath(),
response.getDomainPath());
+ Assertions.assertEquals(expected.getDomainId(),
response.getDomainId());
+ Assertions.assertEquals(expected.getUser(), response.getUser());
+ Assertions.assertEquals(expected.getUserId(),
response.getUserId());
+ Assertions.assertEquals(expected.getAccount(),
response.getAccount());
+ Assertions.assertEquals(expected.getAccountId(),
response.getAccountId());
+ Assertions.assertEquals(expected.getHostId(),
response.getHostId());
+ Assertions.assertEquals(expected.getHostName(),
response.getHostName());
+ Assertions.assertEquals(expected.getVmId(), response.getVmId());
+ Assertions.assertEquals(expected.getVmName(),
response.getVmName());
}
}
+
+ @Test
+ @DisplayName("RUNNING_VM usage populates service offering, VM and OS
details")
+ public void populateRunningVmUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ ServiceOfferingVO serviceOffering = mock(ServiceOfferingVO.class);
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ VMTemplateVO template = mock(VMTemplateVO.class);
+ GuestOSVO guestOS = mock(GuestOSVO.class);
+ GuestOSCategoryVO guestOSCategory = mock(GuestOSCategoryVO.class);
+ Long usageId = 11L;
+ Long offeringId = 21L;
+ Long guestOSId = 31L;
+ Long guestOSCategoryId = 41L;
+
+ when(usageRecord.getUsageType()).thenReturn(UsageTypes.RUNNING_VM);
+ when(usageRecord.getOfferingId()).thenReturn(offeringId);
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getVmInstanceId()).thenReturn(usageId);
+ when(usageRecord.getType()).thenReturn("KVM");
+ when(usageRecord.getCpuCores()).thenReturn(null);
+ when(usageRecord.getCpuSpeed()).thenReturn(2400L);
+ when(usageRecord.getMemory()).thenReturn(8192L);
+
when(entityManagerMock.findByIdIncludingRemoved(ServiceOfferingVO.class,
offeringId)).thenReturn(serviceOffering);
+ when(serviceOffering.getUuid()).thenReturn("service-offering-uuid");
+ when(serviceOffering.getName()).thenReturn("Small Instance");
+ when(serviceOffering.getCpu()).thenReturn(4);
+ when(vmInstance.getUuid()).thenReturn("vm-uuid");
+ when(vmInstance.getId()).thenReturn(usageId);
+ when(vmInstance.getHostName()).thenReturn("vm-host");
+ when(vmInstance.getInstanceName()).thenReturn("i-2-11-VM");
+ when(vmInstance.getGuestOSId()).thenReturn(guestOSId);
+ when(guestOSDaoMock.findById(guestOSId)).thenReturn(guestOS);
+ when(guestOS.getUuid()).thenReturn("guest-os-uuid");
+ when(guestOS.getDisplayName()).thenReturn("Ubuntu 22.04");
+ when(guestOS.getCategoryId()).thenReturn(guestOSCategoryId);
+
when(guestOSCategoryDaoMock.findById(guestOSCategoryId)).thenReturn(guestOSCategory);
+ when(guestOSCategory.getUuid()).thenReturn("guest-os-category-uuid");
+ when(guestOSCategory.getName()).thenReturn("Linux");
+ when(template.getUuid()).thenReturn("template-uuid");
+ when(template.getName()).thenReturn("Ubuntu Template");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateRunningOrAllocatedVmUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class, VMTemplateVO.class},
+ usageRecord, response, false, vmInstance, template);
+
+ // Assert
+ assertResponseField(response, "offeringId", "service-offering-uuid");
+ assertResponseField(response, "usageId", "vm-uuid");
+ assertResponseField(response, "type", "KVM");
+ assertResponseField(response, "cpuNumber", 4L);
+ assertResponseField(response, "cpuSpeed", 2400L);
+ assertResponseField(response, "memory", 8192L);
+ assertResponseField(response, "osTypeId", "guest-os-uuid");
+ assertResponseField(response, "osDisplayName", "Ubuntu 22.04");
+ assertResponseField(response, "osCategoryId",
"guest-os-category-uuid");
+ assertResponseField(response, "osCategoryName", "Linux");
+ assertDescriptionContains(response, "Running VM usage for vm-host
(i-2-11-VM) (vm-uuid)");
+ assertDescriptionContains(response, "using service offering Small
Instance (service-offering-uuid)");
+ assertDescriptionContains(response, "and template Ubuntu Template
(template-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.UserVm, usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(ServiceOfferingVO.class,
offeringId);
+ verify(guestOSDaoMock).findById(guestOSId);
+ }
+
+ @Test
+ @DisplayName("ALLOCATED_VM usage falls back to service offering compute
details")
+ public void populateAllocatedVmUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ ServiceOfferingVO serviceOffering = mock(ServiceOfferingVO.class);
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ Long usageId = 12L;
+ Long vmInstanceId = 22L;
+ Long offeringId = 32L;
+
+ when(usageRecord.getUsageType()).thenReturn(UsageTypes.ALLOCATED_VM);
+ when(usageRecord.getOfferingId()).thenReturn(offeringId);
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getVmInstanceId()).thenReturn(vmInstanceId);
+ when(usageRecord.getType()).thenReturn("KVM");
+ when(usageRecord.getCpuCores()).thenReturn(null);
+ when(usageRecord.getCpuSpeed()).thenReturn(null);
+ when(usageRecord.getMemory()).thenReturn(null);
+
when(entityManagerMock.findByIdIncludingRemoved(ServiceOfferingVO.class,
offeringId)).thenReturn(serviceOffering);
+ when(entityManagerMock.findByIdIncludingRemoved(VMInstanceVO.class,
usageId)).thenReturn(vmInstance);
+
when(serviceOffering.getUuid()).thenReturn("allocated-service-offering-uuid");
+ when(serviceOffering.getName()).thenReturn("Medium Instance");
+ when(serviceOffering.getCpu()).thenReturn(2);
+ when(serviceOffering.getSpeed()).thenReturn(1800);
+ when(serviceOffering.getRamSize()).thenReturn(4096);
+ when(vmInstance.getUuid()).thenReturn("allocated-vm-uuid");
+ when(vmInstance.getId()).thenReturn(usageId);
+ when(vmInstance.getHostName()).thenReturn("allocated-vm-host");
+ when(vmInstance.getInstanceName()).thenReturn("i-2-12-VM");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateRunningOrAllocatedVmUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class, VMTemplateVO.class},
+ usageRecord, response, false, null, null);
+
+ // Assert
+ assertResponseField(response, "offeringId",
"allocated-service-offering-uuid");
+ assertResponseField(response, "usageId", "allocated-vm-uuid");
+ assertResponseField(response, "type", "KVM");
+ assertResponseField(response, "cpuNumber", 2L);
+ assertResponseField(response, "cpuSpeed", 1800L);
+ assertResponseField(response, "memory", 4096L);
+ assertDescriptionContains(response, "Allocated VM usage for
allocated-vm-host (i-2-12-VM) (allocated-vm-uuid)");
+ assertDescriptionContains(response, "using service offering Medium
Instance (allocated-service-offering-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.UserVm, usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(ServiceOfferingVO.class,
offeringId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VMInstanceVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("IP_ADDRESS usage populates public IP flags")
+ public void populateIpAddressUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ IPAddressVO ipAddress = mock(IPAddressVO.class);
+ Long usageId = 13L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getType()).thenReturn("SourceNat");
+ when(usageRecord.getSize()).thenReturn(1L);
+ when(entityManagerMock.findByIdIncludingRemoved(IPAddressVO.class,
usageId)).thenReturn(ipAddress);
+ when(ipAddress.getUuid()).thenReturn("ip-address-uuid");
+ when(ipAddress.getId()).thenReturn(usageId);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateIpAddressUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class},
usageRecord, response);
+
+ // Assert
+ assertResponseField(response, "usageId", "ip-address-uuid");
+ assertResponseField(response, "isSourceNat", Boolean.TRUE);
+ assertResponseField(response, "isSystem", Boolean.TRUE);
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.PublicIpAddress, usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(IPAddressVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("NETWORK_BYTES_SENT usage populates VM and network details")
+ public void populateNetworkBytesSentUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ NetworkVO network = mock(NetworkVO.class);
+ Long usageId = 14L;
+ Long networkId = 24L;
+
+
when(usageRecord.getUsageType()).thenReturn(UsageTypes.NETWORK_BYTES_SENT);
+ when(usageRecord.getType()).thenReturn("UserVm");
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getNetworkId()).thenReturn(networkId);
+ when(usageRecord.getRawUsage()).thenReturn(1024D);
+ when(entityManagerMock.findByIdIncludingRemoved(VMInstanceVO.class,
usageId)).thenReturn(vmInstance);
+ when(entityManagerMock.findByIdIncludingRemoved(NetworkVO.class,
networkId)).thenReturn(network);
+ when(vmInstance.getUuid()).thenReturn("network-vm-uuid");
+ when(vmInstance.getId()).thenReturn(usageId);
+ when(vmInstance.getInstanceName()).thenReturn("r-14-VM");
+ when(network.getUuid()).thenReturn("network-uuid");
+ when(network.getId()).thenReturn(networkId);
+ when(network.getName()).thenReturn("guest-network");
+ when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateNetworkBytesUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "type", "UserVm");
+ assertResponseField(response, "usageId", "network-vm-uuid");
+ assertResponseField(response, "networkId", "network-uuid");
+ assertResponseField(response, "resourceName", "guest-network");
+ assertDescriptionContains(response, "Bytes sent by network
guest-network (network-uuid)");
+ assertDescriptionContains(response, "using router r-14-VM
(network-vm-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.Network, networkId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VMInstanceVO.class,
usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(NetworkVO.class,
networkId);
+ }
+
+ @Test
+ @DisplayName("NETWORK_BYTES_RECEIVED usage populates VM and network
details")
+ public void populateNetworkBytesReceivedUsageResponseTest() throws
Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ NetworkVO network = mock(NetworkVO.class);
+ Long usageId = 15L;
+ Long networkId = 25L;
+
+
when(usageRecord.getUsageType()).thenReturn(UsageTypes.NETWORK_BYTES_RECEIVED);
+ when(usageRecord.getType()).thenReturn("DomainRouter");
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getNetworkId()).thenReturn(networkId);
+ when(usageRecord.getRawUsage()).thenReturn(2048D);
+ when(entityManagerMock.findByIdIncludingRemoved(VMInstanceVO.class,
usageId)).thenReturn(vmInstance);
+ when(entityManagerMock.findByIdIncludingRemoved(NetworkVO.class,
networkId)).thenReturn(network);
+ when(vmInstance.getUuid()).thenReturn("network-router-uuid");
+ when(vmInstance.getId()).thenReturn(usageId);
+ when(vmInstance.getInstanceName()).thenReturn("r-15-VM");
+ when(network.getUuid()).thenReturn("received-network-uuid");
+ when(network.getId()).thenReturn(networkId);
+ when(network.getName()).thenReturn("received-network");
+ when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateNetworkBytesUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "type", "DomainRouter");
+ assertResponseField(response, "usageId", "network-router-uuid");
+ assertResponseField(response, "networkId", "received-network-uuid");
+ assertResponseField(response, "resourceName", "received-network");
+ assertDescriptionContains(response, "Bytes received by network
received-network (received-network-uuid)");
+ assertDescriptionContains(response, "using router r-15-VM
(network-router-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.Network, networkId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VMInstanceVO.class,
usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(NetworkVO.class,
networkId);
+ }
+
+ @Test
+ @DisplayName("VOLUME usage populates volume size and offering details")
+ public void populateVolumeUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ VMTemplateVO template = mock(VMTemplateVO.class);
+ VolumeVO volume = mock(VolumeVO.class);
+ DiskOfferingVO diskOffering = mock(DiskOfferingVO.class);
+ Long usageId = 16L;
+ Long offeringId = 26L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getOfferingId()).thenReturn(offeringId);
+ when(usageRecord.getSize()).thenReturn(4096L);
+ when(entityManagerMock.findByIdIncludingRemoved(VolumeVO.class,
usageId)).thenReturn(volume);
+ when(entityManagerMock.findByIdIncludingRemoved(DiskOfferingVO.class,
offeringId)).thenReturn(diskOffering);
+ when(volume.getUuid()).thenReturn("volume-uuid");
+ when(volume.getId()).thenReturn(usageId);
+ when(volume.getName()).thenReturn("data-volume");
+ when(diskOffering.getUuid()).thenReturn("disk-offering-uuid");
+ when(diskOffering.getName()).thenReturn("Small Disk");
+ when(vmInstance.getUuid()).thenReturn("volume-vm-uuid");
+ when(vmInstance.getHostName()).thenReturn("volume-vm");
+ when(template.getUuid()).thenReturn("volume-template-uuid");
+ when(template.getName()).thenReturn("Volume Template");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVolumeUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class, VMTemplateVO.class},
+ usageRecord, response, false, vmInstance, template);
+
+ // Assert
+ assertResponseField(response, "usageId", "volume-uuid");
+ assertResponseField(response, "size", 4096L);
+ assertResponseField(response, "offeringId", "disk-offering-uuid");
+ assertDescriptionContains(response, "Volume usage for data-volume
(volume-uuid)");
+ assertDescriptionContains(response, "attached to VM volume-vm
(volume-vm-uuid)");
+ assertDescriptionContains(response, "with disk offering Small Disk
(disk-offering-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.Volume, usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VolumeVO.class,
usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(DiskOfferingVO.class,
offeringId);
+ }
+
+ @Test
+ @DisplayName("TEMPLATE usage populates template size details")
+ public void populateTemplateUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMTemplateVO template = mock(VMTemplateVO.class);
+ Long usageId = 17L;
+
+ when(usageRecord.getUsageType()).thenReturn(UsageTypes.TEMPLATE);
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getSize()).thenReturn(8192L);
+ when(usageRecord.getVirtualSize()).thenReturn(16384L);
+ when(entityManagerMock.findByIdIncludingRemoved(VMTemplateVO.class,
usageId)).thenReturn(template);
+ when(template.getUuid()).thenReturn("template-usage-uuid");
+ when(template.getId()).thenReturn(usageId);
+ when(template.getName()).thenReturn("CentOS Template");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateTemplateOrIsoUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "template-usage-uuid");
+ assertResponseField(response, "size", 8192L);
+ assertResponseField(response, "virtualSize", 16384L);
+ assertDescriptionContains(response, "Template usage for CentOS
Template (template-usage-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.Template, usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VMTemplateVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("ISO usage populates ISO size details")
+ public void populateIsoUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMTemplateVO iso = mock(VMTemplateVO.class);
+ Long usageId = 18L;
+
+ when(usageRecord.getUsageType()).thenReturn(UsageTypes.ISO);
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getSize()).thenReturn(2048L);
+ when(usageRecord.getVirtualSize()).thenReturn(4096L);
+ when(entityManagerMock.findByIdIncludingRemoved(VMTemplateVO.class,
usageId)).thenReturn(iso);
+ when(iso.getUuid()).thenReturn("iso-usage-uuid");
+ when(iso.getId()).thenReturn(usageId);
+ when(iso.getName()).thenReturn("Installer ISO");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateTemplateOrIsoUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "iso-usage-uuid");
+ assertResponseField(response, "size", 2048L);
+ assertResponseField(response, "virtualSize", 2048L);
+ assertDescriptionContains(response, "ISO usage for Installer ISO
(iso-usage-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.ISO, usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(VMTemplateVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("SNAPSHOT usage populates snapshot size details")
+ public void populateSnapshotUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ SnapshotVO snapshot = mock(SnapshotVO.class);
+ Long usageId = 19L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(usageRecord.getSize()).thenReturn(1024L);
+ when(entityManagerMock.findByIdIncludingRemoved(SnapshotVO.class,
usageId)).thenReturn(snapshot);
+ when(snapshot.getUuid()).thenReturn("snapshot-uuid");
+ when(snapshot.getId()).thenReturn(usageId);
+ when(snapshot.getName()).thenReturn("daily-snapshot");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateSnapshotUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "snapshot-uuid");
+ assertResponseField(response, "size", 1024L);
+ assertDescriptionContains(response, "Snapshot usage for daily-snapshot
(snapshot-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.Snapshot, usageId);
+ verify(entityManagerMock).findByIdIncludingRemoved(SnapshotVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("SECURITY_GROUP usage populates security group details")
+ public void populateSecurityGroupUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ SecurityGroupVO securityGroup = mock(SecurityGroupVO.class);
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ Long usageId = 20L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(entityManagerMock.findByIdIncludingRemoved(SecurityGroupVO.class,
usageId)).thenReturn(securityGroup);
+ when(securityGroup.getUuid()).thenReturn("security-group-uuid");
+ when(securityGroup.getId()).thenReturn(usageId);
+ when(securityGroup.getName()).thenReturn("web-tier");
+ when(vmInstance.getUuid()).thenReturn("security-group-vm-uuid");
+ when(vmInstance.getHostName()).thenReturn("security-group-vm");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateSecurityGroupUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertResponseField(response, "usageId", "security-group-uuid");
+ assertDescriptionContains(response, "Security group web-tier
(security-group-uuid) usage");
+ assertDescriptionContains(response, "for VM security-group-vm
(security-group-vm-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.SecurityGroup, usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(SecurityGroupVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("LOAD_BALANCER_POLICY usage populates load balancer details")
+ public void populateLoadBalancerPolicyUsageResponseTest() throws Exception
{
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ LoadBalancerVO loadBalancer = mock(LoadBalancerVO.class);
+ Long usageId = 21L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(entityManagerMock.findByIdIncludingRemoved(LoadBalancerVO.class,
usageId)).thenReturn(loadBalancer);
+ when(loadBalancer.getUuid()).thenReturn("load-balancer-uuid");
+ when(loadBalancer.getId()).thenReturn(usageId);
+ when(loadBalancer.getName()).thenReturn("public-lb");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateLoadBalancerPolicyUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "load-balancer-uuid");
+ assertDescriptionContains(response, "Loadbalancer policy usage
public-lb (load-balancer-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.LoadBalancer, usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(LoadBalancerVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("PORT_FORWARDING_RULE usage populates port forwarding rule
details")
+ public void populatePortForwardingRuleUsageResponseTest() throws Exception
{
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ PortForwardingRuleVO portForwardingRule =
mock(PortForwardingRuleVO.class);
+ Long usageId = 22L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+
when(entityManagerMock.findByIdIncludingRemoved(PortForwardingRuleVO.class,
usageId)).thenReturn(portForwardingRule);
+
when(portForwardingRule.getUuid()).thenReturn("port-forwarding-rule-uuid");
+ when(portForwardingRule.getId()).thenReturn(usageId);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populatePortForwardingRuleUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "port-forwarding-rule-uuid");
+ assertDescriptionContains(response, "Port forwarding rule usage
(port-forwarding-rule-uuid)");
+ assertUsageResourceDetails(resourceDetails,
ResourceTag.ResourceObjectType.PortForwardingRule, usageId);
+
verify(entityManagerMock).findByIdIncludingRemoved(PortForwardingRuleVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("NETWORK_OFFERING usage populates offering and default flag")
+ public void populateNetworkOfferingUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ NetworkOfferingVO networkOffering = mock(NetworkOfferingVO.class);
+ VMInstanceVO vmInstance = mock(VMInstanceVO.class);
+ Long offeringId = 23L;
+
+ when(usageRecord.getOfferingId()).thenReturn(offeringId);
+ when(usageRecord.getUsageId()).thenReturn(1L);
+
when(entityManagerMock.findByIdIncludingRemoved(NetworkOfferingVO.class,
offeringId)).thenReturn(networkOffering);
+ when(networkOffering.getUuid()).thenReturn("network-offering-uuid");
+ when(networkOffering.getName()).thenReturn("Default Isolated Network");
+ when(vmInstance.getUuid()).thenReturn("network-offering-vm-uuid");
+ when(vmInstance.getHostName()).thenReturn("network-offering-vm");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateNetworkOfferingUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertResponseField(response, "offeringId", "network-offering-uuid");
+ assertResponseField(response, "isDefault", Boolean.TRUE);
+ assertDescriptionContains(response, "Network offering Default Isolated
Network (network-offering-uuid) usage");
+ assertDescriptionContains(response, "for VM network-offering-vm
(network-offering-vm-uuid)");
+ assertUsageResourceDetails(resourceDetails, null, null);
+
verify(entityManagerMock).findByIdIncludingRemoved(NetworkOfferingVO.class,
offeringId);
+ }
+
+ @Test
+ @DisplayName("VPN_USERS usage populates VPN user details")
+ public void populateVpnUsersUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord = mock(UsageVO.class);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VpnUserVO vpnUser = mock(VpnUserVO.class);
+ Long usageId = 24L;
+
+ when(usageRecord.getUsageId()).thenReturn(usageId);
+ when(entityManagerMock.findByIdIncludingRemoved(VpnUserVO.class,
usageId)).thenReturn(vpnUser);
+ when(vpnUser.getUuid()).thenReturn("vpn-user-uuid");
+ when(vpnUser.getUsername()).thenReturn("vpn-user");
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVpnUsersUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class}, usageRecord, response, false);
+
+ // Assert
+ assertResponseField(response, "usageId", "vpn-user-uuid");
+ assertDescriptionContains(response, "VPN usage for user vpn-user
(vpn-user-uuid)");
+ assertUsageResourceDetails(resourceDetails, null, null);
+ verify(entityManagerMock).findByIdIncludingRemoved(VpnUserVO.class,
usageId);
+ }
+
+ @Test
+ @DisplayName("VM_DISK_IO_READ usage populates disk read request details")
+ public void populateVmDiskIoReadUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord =
mockVmDiskUsageRecord(UsageTypes.VM_DISK_IO_READ, 25L, 512D);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mockVmInstance("vm-disk-read-vm",
"vm-disk-read-vm-uuid");
+ VolumeVO volume = mockVolume(25L, "vm-disk-read-volume-uuid",
"vm-disk-read-volume");
+ when(entityManagerMock.findByIdIncludingRemoved(VolumeVO.class,
25L)).thenReturn(volume);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVmDiskUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertVmDiskUsageResponse(response, resourceDetails, "Disk I/O read
requests", "vm-disk-read-volume-uuid", "vm-disk-read-volume", 25L);
+ verify(entityManagerMock).findByIdIncludingRemoved(VolumeVO.class,
25L);
+ }
+
+ @Test
+ @DisplayName("VM_DISK_IO_WRITE usage populates disk write request details")
+ public void populateVmDiskIoWriteUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord =
mockVmDiskUsageRecord(UsageTypes.VM_DISK_IO_WRITE, 26L, 1024D);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mockVmInstance("vm-disk-write-vm",
"vm-disk-write-vm-uuid");
+ VolumeVO volume = mockVolume(26L, "vm-disk-write-volume-uuid",
"vm-disk-write-volume");
+ when(entityManagerMock.findByIdIncludingRemoved(VolumeVO.class,
26L)).thenReturn(volume);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVmDiskUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertVmDiskUsageResponse(response, resourceDetails, "Disk I/O write
requests", "vm-disk-write-volume-uuid", "vm-disk-write-volume", 26L);
+ verify(entityManagerMock).findByIdIncludingRemoved(VolumeVO.class,
26L);
+ }
+
+ @Test
+ @DisplayName("VM_DISK_BYTES_READ usage populates disk read byte details")
+ public void populateVmDiskBytesReadUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord =
mockVmDiskUsageRecord(UsageTypes.VM_DISK_BYTES_READ, 27L, 2048D);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mockVmInstance("vm-disk-bytes-read-vm",
"vm-disk-bytes-read-vm-uuid");
+ VolumeVO volume = mockVolume(27L, "vm-disk-bytes-read-volume-uuid",
"vm-disk-bytes-read-volume");
+ when(entityManagerMock.findByIdIncludingRemoved(VolumeVO.class,
27L)).thenReturn(volume);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVmDiskUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertVmDiskUsageResponse(response, resourceDetails, "Disk I/O read
bytes", "vm-disk-bytes-read-volume-uuid", "vm-disk-bytes-read-volume", 27L);
+ verify(entityManagerMock).findByIdIncludingRemoved(VolumeVO.class,
27L);
+ }
+
+ @Test
+ @DisplayName("VM_DISK_BYTES_WRITE usage populates disk write byte details")
+ public void populateVmDiskBytesWriteUsageResponseTest() throws Exception {
+ // Arrange
+ UsageVO usageRecord =
mockVmDiskUsageRecord(UsageTypes.VM_DISK_BYTES_WRITE, 28L, 4096D);
+ UsageRecordResponse response = new UsageRecordResponse();
+ VMInstanceVO vmInstance = mockVmInstance("vm-disk-bytes-write-vm",
"vm-disk-bytes-write-vm-uuid");
+ VolumeVO volume = mockVolume(28L, "vm-disk-bytes-write-volume-uuid",
"vm-disk-bytes-write-volume");
+ when(entityManagerMock.findByIdIncludingRemoved(VolumeVO.class,
28L)).thenReturn(volume);
+
+ // Act
+ Object resourceDetails =
invokeUsageDetailsHelper("populateVmDiskUsageResponse",
+ new Class<?>[] {Usage.class, UsageRecordResponse.class,
boolean.class, VMInstanceVO.class},
+ usageRecord, response, false, vmInstance);
+
+ // Assert
+ assertVmDiskUsageResponse(response, resourceDetails, "Disk I/O write
bytes", "vm-disk-bytes-write-volume-uuid", "vm-disk-bytes-write-volume", 28L);
+ verify(entityManagerMock).findByIdIncludingRemoved(VolumeVO.class,
28L);
+ }
+
+ private Object invokeUsageDetailsHelper(String methodName, Class<?>[]
parameterTypes, Object... args) throws Exception {
+ Method method = ApiResponseHelper.class.getDeclaredMethod(methodName,
parameterTypes);
+ method.setAccessible(true);
+ return method.invoke(helper, args);
Review Comment:
The new tests invoke private helpers directly, so they never verify
dispatcher routing or tag propagation through `createUsageResponse`; they also
provide no coverage for backup, VM snapshot, secondary-volume, primary
VM-snapshot, or bucket helpers. Add public-method cases for every extracted
branch so structural wiring regressions are detectable.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]