From 61cb4ea0663a737e5a5cb27177c50907f9bad02e Mon Sep 17 00:00:00 2001 From: PrashantBhanage Date: Thu, 25 Jun 2026 13:54:18 +0530 Subject: [PATCH 01/10] Refactor: Modularize ApiResponseHelper#createUsageResponse Fixes #11635 - Extracted the 500+ line switch/if-else block into a main dispatcher method `populateUsageTypeSpecificDetails`. - Created 18 individual private helper methods for each specific `UsageType` to improve maintainability and readability. - Introduced a `UsageResourceDetails` container class to safely manage and return `resourceId` and `resourceType` state for tag lookups. - Verified zero business logic changes; strictly structural refactoring. --- .../java/com/cloud/api/ApiResponseHelper.java | 950 ++++++++++-------- 1 file changed, 530 insertions(+), 420 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 8c51d9926841..f309196442ea 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -4184,474 +4184,584 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord, Map Date: Fri, 26 Jun 2026 10:03:44 +0530 Subject: [PATCH 02/10] test: Add unit tests for 18 extracted UsageType helper methods --- server/pom.xml | 18 + .../com/cloud/api/ApiResponseHelperTest.java | 821 ++++++++++++++++-- 2 files changed, 763 insertions(+), 76 deletions(-) diff --git a/server/pom.xml b/server/pom.xml index 2b35a0f42ac8..fc27f97fbd43 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -118,6 +118,24 @@ test-jar test + + org.junit.jupiter + junit-jupiter + ${cs.junit.jupiter.version} + test + + + org.junit.vintage + junit-vintage-engine + ${cs.junit.jupiter.version} + test + + + org.mockito + mockito-junit-jupiter + ${cs.mockito.version} + test + org.reflections reflections diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java index c0c019f6dbd8..73f9ed612621 100644 --- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java +++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.api; -import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -29,17 +29,20 @@ import java.util.TimeZone; import java.util.UUID; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import org.springframework.test.util.ReflectionTestUtils; import org.apache.cloudstack.annotation.dao.AnnotationDao; @@ -57,7 +60,9 @@ import org.apache.cloudstack.api.response.UsageRecordResponse; import org.apache.cloudstack.api.response.TrafficTypeResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.usage.Usage; import org.apache.cloudstack.usage.UsageService; +import org.apache.cloudstack.usage.UsageTypes; import org.apache.cloudstack.vm.UnmanagedInstanceTO; import com.cloud.capacity.Capacity; @@ -67,6 +72,7 @@ import com.cloud.network.Networks; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.network.PublicIpQuarantine; +import com.cloud.network.VpnUserVO; import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.network.as.AutoScaleVmGroupVO; import com.cloud.network.as.AutoScaleVmProfileVO; @@ -78,12 +84,23 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; +import com.cloud.network.rules.PortForwardingRuleVO; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.offerings.NetworkOfferingVO; import com.cloud.resource.icon.ResourceIconVO; +import com.cloud.service.ServiceOfferingVO; import com.cloud.server.ResourceIcon; import com.cloud.server.ResourceIconManager; import com.cloud.server.ResourceTag; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOsCategory; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.storage.dao.GuestOSDao; import com.cloud.usage.UsageVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -93,22 +110,25 @@ import com.cloud.user.UserDataVO; import com.cloud.user.UserVO; import com.cloud.user.dao.UserDataDao; +import com.cloud.utils.db.EntityManager; import com.cloud.utils.net.Ip; import com.cloud.vm.ConsoleSessionVO; import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.VMInstanceVO; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class ApiResponseHelperTest { @Mock @@ -137,6 +157,15 @@ public class ApiResponseHelperTest { @Mock ResourceIconManager resourceIconManager; + @Mock + EntityManager entityManagerMock; + + @Mock + GuestOSDao guestOSDaoMock; + + @Mock + GuestOSCategoryDao guestOSCategoryDaoMock; + @Mock private ConsoleSessionVO consoleSessionMock; @Mock @@ -168,17 +197,16 @@ public class ApiResponseHelperTest { static long autoScaleUserId = 7L; - @Before - public void injectMocks() throws SecurityException, NoSuchFieldException, - IllegalArgumentException, IllegalAccessException { - Field usageSvcField = ApiResponseHelper.class - .getDeclaredField("_usageSvc"); - usageSvcField.setAccessible(true); + @BeforeEach + public void injectMocks() { helper = new ApiResponseHelper(); - usageSvcField.set(helper, usageService); + ReflectionTestUtils.setField(helper, "_usageSvc", usageService); + ReflectionTestUtils.setField(helper, "_entityMgr", entityManagerMock); + ReflectionTestUtils.setField(helper, "_guestOsDao", guestOSDaoMock); + ReflectionTestUtils.setField(helper, "_guestOsCategoryDao", guestOSCategoryDaoMock); } - @Before + @BeforeEach public void setup() { AccountVO account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid"); account.setId(1); @@ -188,7 +216,7 @@ public void setup() { CallContext.register(user, account); } - @After + @AfterEach public void cleanup() { CallContext.unregister(); } @@ -479,8 +507,8 @@ private UnmanagedInstanceTO getUnmanagedInstanceForTests() { public void testCreateUnmanagedInstanceResponseVmwareDcVms() { UnmanagedInstanceTO instance = getUnmanagedInstanceForTests(); UnmanagedInstanceResponse response = apiResponseHelper.createUnmanagedInstanceResponse(instance, null, null); - Assert.assertEquals(1, response.getDisks().size()); - Assert.assertEquals(1, response.getNics().size()); + Assertions.assertEquals(1, response.getDisks().size()); + Assertions.assertEquals(1, response.getNics().size()); } @Test @@ -521,16 +549,16 @@ public void createQuarantinedIpsResponseTestReturnsObject() { IpQuarantineResponse result = apiResponseHelper.createQuarantinedIpsResponse(quarantinedIpMock); - Assert.assertEquals(quarantinedIpUuid, result.getId()); - Assert.assertEquals(publicIpAddress, result.getPublicIpAddress()); - Assert.assertEquals(previousOwnerUuid, result.getPreviousOwnerId()); - Assert.assertEquals(previousOwnerName, result.getPreviousOwnerName()); - Assert.assertEquals(created, result.getCreated()); - Assert.assertEquals(removed, result.getRemoved()); - Assert.assertEquals(endDate, result.getEndDate()); - Assert.assertEquals(removalReason, result.getRemovalReason()); - Assert.assertEquals(removerAccountUuid, result.getRemoverAccountId()); - Assert.assertEquals("quarantinedip", result.getResponseName()); + Assertions.assertEquals(quarantinedIpUuid, result.getId()); + Assertions.assertEquals(publicIpAddress, result.getPublicIpAddress()); + Assertions.assertEquals(previousOwnerUuid, result.getPreviousOwnerId()); + Assertions.assertEquals(previousOwnerName, result.getPreviousOwnerName()); + Assertions.assertEquals(created, result.getCreated()); + Assertions.assertEquals(removed, result.getRemoved()); + Assertions.assertEquals(endDate, result.getEndDate()); + Assertions.assertEquals(removalReason, result.getRemovalReason()); + Assertions.assertEquals(removerAccountUuid, result.getRemoverAccountId()); + Assertions.assertEquals("quarantinedip", result.getResponseName()); } @Test @@ -542,9 +570,9 @@ public void testCapacityListingForSingleTag() { Capacity c3 = Mockito.mock(Capacity.class); Mockito.when(c3.getTag()).thenReturn("tag2"); Capacity c4 = Mockito.mock(Capacity.class); - Assert.assertTrue(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2))); - Assert.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2, c3))); - Assert.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c4, c2, c3))); + Assertions.assertTrue(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2))); + Assertions.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c1, c2, c3))); + Assertions.assertFalse(apiResponseHelper.capacityListingForSingleTag(List.of(c4, c2, c3))); } @Test @@ -556,8 +584,8 @@ public void testCapacityListingForSingleNonGpuType() { Capacity c3 = Mockito.mock(Capacity.class); Mockito.when(c3.getCapacityType()).thenReturn((short)Resource.ResourceType.volume.getOrdinal()); Capacity c4 = Mockito.mock(Capacity.class); - Assert.assertTrue(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2))); - Assert.assertFalse(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2, c3))); + Assertions.assertTrue(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2))); + Assertions.assertFalse(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2, c3))); } @Test @@ -575,17 +603,17 @@ public void testCreateGuestOSCategoryResponse_WithResourceIcon() { Mockito.when(ApiDBUtils.getResourceIconByResourceUUID(uuid, ResourceTag.ResourceObjectType.GuestOsCategory)).thenReturn(resourceIconVO); Mockito.when(ApiDBUtils.newResourceIconResponse(resourceIconVO)).thenReturn(mockIconResponse); GuestOSCategoryResponse response = apiResponseHelper.createGuestOSCategoryResponse(guestOsCategory); - Assert.assertNotNull(response); - Assert.assertEquals(uuid, response.getId()); - Assert.assertEquals(name, response.getName()); + Assertions.assertNotNull(response); + Assertions.assertEquals(uuid, response.getId()); + Assertions.assertEquals(name, response.getName()); Object obj = ReflectionTestUtils.getField(response, "featured"); if (obj == null) { - Assert.fail("Invalid featured value"); + Assertions.fail("Invalid featured value"); } - Assert.assertTrue((Boolean)obj); + Assertions.assertTrue((Boolean)obj); obj = ReflectionTestUtils.getField(response, "resourceIconResponse"); - Assert.assertNotNull(obj); - Assert.assertEquals("oscategory", response.getObjectName()); + Assertions.assertNotNull(obj); + Assertions.assertEquals("oscategory", response.getObjectName()); } } @@ -601,17 +629,17 @@ public void testCreateGuestOSCategoryResponse_WithoutResourceIcon() { try (MockedStatic ignored = Mockito.mockStatic(ApiDBUtils.class)) { when(ApiDBUtils.getResourceIconByResourceUUID(uuid, ResourceTag.ResourceObjectType.GuestOsCategory)).thenReturn(null); GuestOSCategoryResponse response = apiResponseHelper.createGuestOSCategoryResponse(guestOsCategory); - Assert.assertNotNull(response); - Assert.assertEquals(uuid, response.getId()); - Assert.assertEquals(name, response.getName()); + Assertions.assertNotNull(response); + Assertions.assertEquals(uuid, response.getId()); + Assertions.assertEquals(name, response.getName()); Object obj = ReflectionTestUtils.getField(response, "featured"); if (obj == null) { - Assert.fail("Invalid featured value"); + Assertions.fail("Invalid featured value"); } - Assert.assertFalse((Boolean)obj); + Assertions.assertFalse((Boolean)obj); obj = ReflectionTestUtils.getField(response, "resourceIconResponse"); - Assert.assertNull(obj); - Assert.assertEquals("oscategory", response.getObjectName()); + Assertions.assertNull(obj); + Assertions.assertEquals("oscategory", response.getObjectName()); } } @@ -621,7 +649,7 @@ public void testCreateGuestOSCategoryResponse_WithShowIconFalse() { Mockito.when(guestOsCategory.getUuid()).thenReturn(UUID.randomUUID().toString()); try (MockedStatic mockedStatic = Mockito.mockStatic(ApiDBUtils.class)) { GuestOSCategoryResponse response = apiResponseHelper.createGuestOSCategoryResponse(guestOsCategory, false); - Assert.assertNotNull(response); + Assertions.assertNotNull(response); mockedStatic.verify(() -> ApiDBUtils.getResourceIconByResourceUUID(Mockito.any(), Mockito.any()), Mockito.never()); } @@ -732,12 +760,12 @@ public void createConsoleSessionResponseTestShouldReturnRestrictedResponse() { ConsoleSessionResponse response = apiResponseHelper.createConsoleSessionResponse(consoleSessionMock, ResponseObject.ResponseView.Restricted); - 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()); + 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()); } } @@ -781,23 +809,664 @@ 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.toString())).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.toString()); + 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.toString())).thenReturn(serviceOffering); + when(entityManagerMock.findByIdIncludingRemoved(VMInstanceVO.class, usageId.toString())).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.toString()); + verify(entityManagerMock).findByIdIncludingRemoved(VMInstanceVO.class, usageId.toString()); + } + + @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.toString())).thenReturn(ipAddress); + when(ipAddress.getUuid()).thenReturn("ip-address-uuid"); + when(ipAddress.getId()).thenReturn(usageId); + when(ipAddress.getAssociatedWithNetworkId()).thenReturn(null); + when(ipAddress.getSourceNetworkId()).thenReturn(23L); + + // 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.toString()); + verify(ipAddress).getSourceNetworkId(); + } + + @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.toString())).thenReturn(vmInstance); + when(entityManagerMock.findByIdIncludingRemoved(NetworkVO.class, networkId.toString())).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.toString()); + verify(entityManagerMock).findByIdIncludingRemoved(NetworkVO.class, networkId.toString()); + } + + @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.toString())).thenReturn(vmInstance); + when(entityManagerMock.findByIdIncludingRemoved(NetworkVO.class, networkId.toString())).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.toString()); + verify(entityManagerMock).findByIdIncludingRemoved(NetworkVO.class, networkId.toString()); + } + + @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.toString())).thenReturn(volume); + when(entityManagerMock.findByIdIncludingRemoved(DiskOfferingVO.class, offeringId.toString())).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.toString()); + verify(entityManagerMock).findByIdIncludingRemoved(DiskOfferingVO.class, offeringId.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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.toString())).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.toString()); + } + + @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, "25")).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, "25"); + } + + @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, "26")).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, "26"); + } + + @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, "27")).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, "27"); + } + + @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, "28")).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, "28"); + } + + 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); + } + + private void assertResponseField(UsageRecordResponse response, String fieldName, Object expectedValue) { + assertEquals(expectedValue, ReflectionTestUtils.getField(response, fieldName)); + } + + private void assertDescriptionContains(UsageRecordResponse response, String expectedText) { + Object description = ReflectionTestUtils.getField(response, "description"); + Assertions.assertNotNull(description); + assertTrue(description.toString().contains(expectedText), + String.format("Expected description [%s] to contain [%s]", description, expectedText)); + } + + private void assertUsageResourceDetails(Object resourceDetails, ResourceTag.ResourceObjectType expectedResourceType, Long expectedResourceId) { + assertEquals(expectedResourceType, ReflectionTestUtils.getField(resourceDetails, "resourceType")); + assertEquals(expectedResourceId, ReflectionTestUtils.getField(resourceDetails, "resourceId")); + } + + private UsageVO mockVmDiskUsageRecord(int usageType, Long usageId, Double rawUsage) { + UsageVO usageRecord = mock(UsageVO.class); + when(usageRecord.getUsageType()).thenReturn(usageType); + when(usageRecord.getUsageId()).thenReturn(usageId); + when(usageRecord.getType()).thenReturn("UserVm"); + when(usageRecord.getRawUsage()).thenReturn(rawUsage); + return usageRecord; + } + + private VMInstanceVO mockVmInstance(String hostName, String uuid) { + VMInstanceVO vmInstance = mock(VMInstanceVO.class); + when(vmInstance.getHostName()).thenReturn(hostName); + when(vmInstance.getUuid()).thenReturn(uuid); + return vmInstance; + } + + private VolumeVO mockVolume(Long id, String uuid, String name) { + VolumeVO volume = mock(VolumeVO.class); + when(volume.getId()).thenReturn(id); + when(volume.getUuid()).thenReturn(uuid); + when(volume.getName()).thenReturn(name); + return volume; + } + + private void assertVmDiskUsageResponse(UsageRecordResponse response, Object resourceDetails, String descriptionPrefix, String volumeUuid, String volumeName, Long volumeId) { + assertResponseField(response, "type", "UserVm"); + assertResponseField(response, "usageId", volumeUuid); + assertDescriptionContains(response, descriptionPrefix); + assertDescriptionContains(response, "volume " + volumeName + " (" + volumeUuid + ")"); + assertUsageResourceDetails(resourceDetails, ResourceTag.ResourceObjectType.Volume, volumeId); + } } From c6225bd0dff78f857feaff994d076fad0169f9eb Mon Sep 17 00:00:00 2001 From: prrssshhhh Date: Sat, 4 Jul 2026 18:10:05 +0530 Subject: [PATCH 03/10] fix: Apply Copilot null-check suggestions and remove unused variable Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../java/com/cloud/api/ApiResponseHelper.java | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index f309196442ea..14e8d765f609 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -4185,8 +4185,11 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord, Map Date: Sat, 4 Jul 2026 23:05:52 +0530 Subject: [PATCH 04/10] Fix: Replace internal X509CertImpl with standard Java API and remove unused imports --- .../java/com/cloud/api/ApiResponseHelper.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 14e8d765f609..801dd40edb89 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -18,8 +18,7 @@ import static com.cloud.utils.NumbersUtil.toHumanReadableSize; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; + import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; @@ -460,7 +459,7 @@ import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; -import sun.security.x509.X509CertImpl; + public class ApiResponseHelper implements ResponseGenerator, ResourceIdSupport { @@ -5440,18 +5439,18 @@ public NetworkPermissionsResponse createNetworkPermissionsResponse(NetworkPermis return response; } - protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) { +protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) { try { - Certificate cert = CertificateHelper.buildCertificate(certStr); - if (cert instanceof X509CertImpl) { - X509CertImpl certificate = (X509CertImpl) cert; + java.security.cert.Certificate cert = CertificateHelper.buildCertificate(certStr); + if (cert instanceof java.security.cert.X509Certificate) { + java.security.cert.X509Certificate certificate = (java.security.cert.X509Certificate) cert; response.setVersion(String.valueOf(certificate.getVersion())); response.setSubject(certificate.getSubjectDN().toString()); response.setIssuer(certificate.getIssuerDN().toString()); - response.setSerialNum(certificate.getSerialNumberObject().toString()); + response.setSerialNum(certificate.getSerialNumber().toString()); response.setValidity(String.format("From: [%s] - To: [%s]", certificate.getNotBefore(), certificate.getNotAfter())); } - } catch (CertificateException e) { + } catch (java.security.cert.CertificateException e) { logger.error("Error parsing direct download certificate: " + certStr, e); } } From 6c3b5972aa789e31974ece90af668e365981400a Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Sun, 5 Jul 2026 19:47:36 +0530 Subject: [PATCH 05/10] test: Fix populateIpAddressUsageResponseTest after Copilot refactor --- .../src/test/java/com/cloud/api/ApiResponseHelperTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java index 73f9ed612621..dbfb48e78ff0 100644 --- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java +++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java @@ -962,20 +962,17 @@ public void populateIpAddressUsageResponseTest() throws Exception { when(entityManagerMock.findByIdIncludingRemoved(IPAddressVO.class, usageId.toString())).thenReturn(ipAddress); when(ipAddress.getUuid()).thenReturn("ip-address-uuid"); when(ipAddress.getId()).thenReturn(usageId); - when(ipAddress.getAssociatedWithNetworkId()).thenReturn(null); - when(ipAddress.getSourceNetworkId()).thenReturn(23L); // Act Object resourceDetails = invokeUsageDetailsHelper("populateIpAddressUsageResponse", new Class[] {Usage.class, UsageRecordResponse.class}, usageRecord, response); - // Assert + // 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.toString()); - verify(ipAddress).getSourceNetworkId(); } @Test @@ -1469,4 +1466,4 @@ private void assertVmDiskUsageResponse(UsageRecordResponse response, Object reso assertDescriptionContains(response, "volume " + volumeName + " (" + volumeUuid + ")"); assertUsageResourceDetails(resourceDetails, ResourceTag.ResourceObjectType.Volume, volumeId); } -} +} \ No newline at end of file From a54428bc108eb8e7fe4dd075c3d3c13baa98402e Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Mon, 6 Jul 2026 20:06:21 +0530 Subject: [PATCH 06/10] Fix: Add missing EOF newline to ApiResponseHelperTest --- server/src/test/java/com/cloud/api/ApiResponseHelperTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java index dbfb48e78ff0..9361c08b82e9 100644 --- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java +++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java @@ -1466,4 +1466,4 @@ private void assertVmDiskUsageResponse(UsageRecordResponse response, Object reso assertDescriptionContains(response, "volume " + volumeName + " (" + volumeUuid + ")"); assertUsageResourceDetails(resourceDetails, ResourceTag.ResourceObjectType.Volume, volumeId); } -} \ No newline at end of file +} From b08293486a003c6f209a1bb38c99375c7ab48c69 Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Tue, 14 Jul 2026 08:03:33 +0530 Subject: [PATCH 07/10] fix: pre-commit end-of-file fixes --- .github/workflows/sonar-check.yml | 26 +++++++++++--- .../unit/components/widgets/Status.spec.js | 35 +++++++++++-------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/.github/workflows/sonar-check.yml b/.github/workflows/sonar-check.yml index fbb3cb9f540d..41822a8ae376 100644 --- a/.github/workflows/sonar-check.yml +++ b/.github/workflows/sonar-check.yml @@ -47,6 +47,8 @@ jobs: - name: Install Non-OSS uses: ./.github/actions/install-nonoss - name: Run Build and Tests with Coverage + env: + NODE_OPTIONS: "--max-old-space-size=4096" run: mvn -B -T$(nproc) -P developer,systemvm,quality -Dsimulator -Dnoredist clean install - name: Upload to SonarQube if: github.repository == 'apache/cloudstack' && github.event.pull_request.head.repo.full_name == github.repository @@ -56,7 +58,15 @@ jobs: PR_ID: ${{ github.event.pull_request.number }} HEADREF: ${{ github.event.pull_request.head.ref }} run: | - mvn -B -P quality org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=apache_cloudstack -Dsonar.pullrequest.key="$PR_ID" -Dsonar.pullrequest.branch="$HEADREF" -Dsonar.pullrequest.github.repository=apache/cloudstack -Dsonar.pullrequest.provider=GitHub -Dsonar.pullrequest.github.summary_comment=true + mvn -B -P quality org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \ + -Dsonar.projectKey=apache_cloudstack \ + -Dsonar.pullrequest.key="$PR_ID" \ + -Dsonar.pullrequest.branch="$HEADREF" \ + -Dsonar.pullrequest.base=main \ + -Dsonar.sources=. \ + -Dsonar.projectBaseDir=/home/runner/work/cloudstack/cloudstack \ + -Dsonar.java.binaries=/home/runner/work/cloudstack/cloudstack/target/classes \ + -Dsonar.exclusions=**/*.js - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: files: ./client/target/site/jacoco-aggregate/jacoco.xml @@ -69,18 +79,24 @@ jobs: id: grade run: bash scripts/coverage-grade.sh client/target/site/jacoco-aggregate/jacoco.xml - name: Post Coverage Grade Comment on PR + if: github.repository == 'apache/cloudstack' && github.event.pull_request.head.repo.full_name == github.repository && steps.grade.outputs.coverage_grade != '' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const grade = '${{ steps.grade.outputs.coverage_grade }}'; - const label = '${{ steps.grade.outputs.coverage_grade_label }}'; - const linePct = '${{ steps.grade.outputs.line_coverage }}'; - const branchPct = '${{ steps.grade.outputs.branch_coverage }}'; + const grade = '${{ steps.grade.outputs.coverage_grade || 'N/A' }}'; + const label = '${{ steps.grade.outputs.coverage_grade_label || 'Unknown' }}'; + const linePct = '${{ steps.grade.outputs.line_coverage || 'N/A' }}'; + const branchPct = '${{ steps.grade.outputs.branch_coverage || 'N/A' }}'; const emojiMap = { A: '🟢', B: '🟡', C: '🟠', D: '🔴', F: '⛔' }; const emoji = emojiMap[grade] ?? '❓'; const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + if (!grade || grade === 'N/A') { + console.log('Coverage grade not available, skipping comment'); + return; + } + const branchRow = branchPct !== 'N/A' ? `| Branch coverage | **${branchPct}%** |` : ''; diff --git a/ui/tests/unit/components/widgets/Status.spec.js b/ui/tests/unit/components/widgets/Status.spec.js index dc5a48d1a7db..b854b7e010b9 100644 --- a/ui/tests/unit/components/widgets/Status.spec.js +++ b/ui/tests/unit/components/widgets/Status.spec.js @@ -212,8 +212,9 @@ describe('Components > Widgets > Status.vue', () => { displayText: true } }) - router.push({ name: 'testRouter1' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter1' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Allocated' @@ -228,8 +229,9 @@ describe('Components > Widgets > Status.vue', () => { displayText: true } }) - router.push('/') - await router.isReady() + await wrapper.vm.$router.push('/') + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Allocated' @@ -241,8 +243,9 @@ describe('Components > Widgets > Status.vue', () => { describe('getTooltip()', () => { it('getTooltip() is called with `$route.path` equal `/vmsnapshot`', async () => { const wrapper = factory({ props: { text: 'Active', displayText: true } }) - router.push({ name: 'testRouter2' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter2' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Active' @@ -252,8 +255,9 @@ describe('Components > Widgets > Status.vue', () => { it('getTooltip() is called with `$route.path` equal `/vm`', async () => { const wrapper = factory({ props: { text: 'Active', displayText: true } }) - router.push({ name: 'testRouter3' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter3' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Active' @@ -263,8 +267,9 @@ describe('Components > Widgets > Status.vue', () => { it('getTooltip() is called with `$route.path` equal `/volume`', async () => { const wrapper = factory({ props: { text: 'Active', displayText: true } }) - router.push({ name: 'testRouter4' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter4' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Active' @@ -274,8 +279,9 @@ describe('Components > Widgets > Status.vue', () => { it('getTooltip() is called with `$route.path` equal `/guestnetwork`', async () => { const wrapper = factory({ props: { text: 'Active', displayText: true } }) - router.push({ name: 'testRouter5' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter5' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Active' @@ -285,8 +291,9 @@ describe('Components > Widgets > Status.vue', () => { it('getTooltip() is called with `$route.path` equal `/publicip`', async () => { const wrapper = factory({ props: { text: 'Active', displayText: true } }) - router.push({ name: 'testRouter1' }) - await router.isReady() + await wrapper.vm.$router.push({ name: 'testRouter1' }) + await wrapper.vm.$router.isReady() + await wrapper.vm.$nextTick() await flushPromises() const received = wrapper.html() const expected = 'Active' From e7843779daddaf3352543324c6100669cc9ebf97 Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Wed, 22 Jul 2026 10:03:35 +0530 Subject: [PATCH 08/10] fix: add proper imports for java.security.cert classes and fix indentation --- .../main/java/com/cloud/api/ApiResponseHelper.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 801dd40edb89..0eb85483ab5b 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -37,6 +37,9 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import javax.inject.Inject; import org.apache.cloudstack.acl.ControlledEntity; @@ -5439,18 +5442,18 @@ public NetworkPermissionsResponse createNetworkPermissionsResponse(NetworkPermis return response; } -protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) { + protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) { try { - java.security.cert.Certificate cert = CertificateHelper.buildCertificate(certStr); - if (cert instanceof java.security.cert.X509Certificate) { - java.security.cert.X509Certificate certificate = (java.security.cert.X509Certificate) cert; + Certificate cert = CertificateHelper.buildCertificate(certStr); + if (cert instanceof X509Certificate) { + X509Certificate certificate = (X509Certificate) cert; response.setVersion(String.valueOf(certificate.getVersion())); response.setSubject(certificate.getSubjectDN().toString()); response.setIssuer(certificate.getIssuerDN().toString()); response.setSerialNum(certificate.getSerialNumber().toString()); response.setValidity(String.format("From: [%s] - To: [%s]", certificate.getNotBefore(), certificate.getNotAfter())); } - } catch (java.security.cert.CertificateException e) { + } catch (CertificateException e) { logger.error("Error parsing direct download certificate: " + certStr, e); } } From a9ebdd2d7e8f6a5d092fad43a94b6a0cabb6f5d9 Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Fri, 24 Jul 2026 20:20:59 +0530 Subject: [PATCH 09/10] Fix: Remove invalid .toString() type mismatch in usage entity lookups --- .../java/com/cloud/api/ApiResponseHelper.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 0eb85483ab5b..8cb06af4245b 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -4254,7 +4254,7 @@ private UsageResourceDetails populateUsageTypeSpecificDetails(Usage usageRecord, 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().toString()); + ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId()); //Service Offering Id if(svcOffering != null) { usageRecResponse.setOfferingId(svcOffering.getUuid()); @@ -4264,7 +4264,7 @@ private UsageResourceDetails populateRunningOrAllocatedVmUsageResponse(Usage usa if (usageRecord.getUsageId() != null && usageRecord.getUsageId().equals(usageRecord.getVmInstanceId())) { vm = vmInstance; } else { - vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId()); } if (vm != null) { resourceDetails.resourceType = ResourceTag.ResourceObjectType.UserVm; @@ -4323,7 +4323,7 @@ private UsageResourceDetails populateRunningOrAllocatedVmUsageResponse(Usage usa private UsageResourceDetails populateIpAddressUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //IP Address ID - IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString()); + IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId()); if (ip != null) { resourceDetails.resourceType = ResourceObjectType.PublicIpAddress; resourceDetails.resourceId = ip.getId(); @@ -4345,14 +4345,14 @@ private UsageResourceDetails populateNetworkBytesUsageResponse(Usage usageRecord HostVO host = null; if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) { //Domain Router Id - vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + 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().toString()); + host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId()); if (host != null) { usageRecResponse.setUsageId(host.getUuid()); } @@ -4360,7 +4360,7 @@ private UsageResourceDetails populateNetworkBytesUsageResponse(Usage usageRecord //Network ID NetworkVO network = null; if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId() != 0)) { - network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString()); + network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId()); if (network != null) { resourceDetails.resourceType = ResourceObjectType.Network; if (network.getTrafficType() == TrafficType.Public) { @@ -4412,7 +4412,7 @@ private UsageResourceDetails populateVmDiskUsageResponse(Usage usageRecord, Usag usageRecResponse.setType(usageRecord.getType()); resourceDetails.resourceType = ResourceObjectType.Volume; //Volume ID - VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId()); if (volume != null) { usageRecResponse.setUsageId(volume.getUuid()); resourceDetails.resourceId = volume.getId(); @@ -4446,7 +4446,7 @@ private UsageResourceDetails populateVolumeUsageResponse(Usage usageRecord, Usag VMInstanceVO vmInstance, VMTemplateVO template) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Volume ID - VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId()); resourceDetails.resourceType = ResourceObjectType.Volume; if (volume != null) { usageRecResponse.setUsageId(volume.getUuid()); @@ -4457,7 +4457,7 @@ private UsageResourceDetails populateVolumeUsageResponse(Usage usageRecord, Usag //Disk Offering Id DiskOfferingVO diskOff = null; if (usageRecord.getOfferingId() != null) { - diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString()); + diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId()); if (diskOff != null) { usageRecResponse.setOfferingId(diskOff.getUuid()); } @@ -4488,7 +4488,7 @@ private UsageResourceDetails populateVolumeUsageResponse(Usage usageRecord, Usag private UsageResourceDetails populateTemplateOrIsoUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Template/ISO ID - VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString()); + VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId()); if (tmpl != null) { usageRecResponse.setUsageId(tmpl.getUuid()); resourceDetails.resourceId = tmpl.getId(); @@ -4521,7 +4521,7 @@ private UsageResourceDetails populateTemplateOrIsoUsageResponse(Usage usageRecor private UsageResourceDetails populateSnapshotUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Snapshot ID - SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString()); + SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId()); resourceDetails.resourceType = ResourceObjectType.Snapshot; if (snap != null) { usageRecResponse.setUsageId(snap.getUuid()); @@ -4544,7 +4544,7 @@ private UsageResourceDetails populateSnapshotUsageResponse(Usage usageRecord, Us private UsageResourceDetails populateLoadBalancerPolicyUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Load Balancer Policy ID - LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString()); + LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId()); resourceDetails.resourceType = ResourceObjectType.LoadBalancer; if (lb != null) { usageRecResponse.setUsageId(lb.getUuid()); @@ -4564,7 +4564,7 @@ private UsageResourceDetails populateLoadBalancerPolicyUsageResponse(Usage usage private UsageResourceDetails populatePortForwardingRuleUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Port Forwarding Rule ID - PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString()); + PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId()); resourceDetails.resourceType = ResourceObjectType.PortForwardingRule; if (pf != null) { usageRecResponse.setUsageId(pf.getUuid()); @@ -4583,7 +4583,7 @@ private UsageResourceDetails populatePortForwardingRuleUsageResponse(Usage usage private UsageResourceDetails populateNetworkOfferingUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat, VMInstanceVO vmInstance) { //Network Offering Id - NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString()); + NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId()); if (netOff != null) { usageRecResponse.setOfferingId(netOff.getUuid()); } @@ -4605,7 +4605,7 @@ private UsageResourceDetails populateNetworkOfferingUsageResponse(Usage usageRec private UsageResourceDetails populateVpnUsersUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { //VPN User ID - VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString()); + VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId()); if (vpnUser != null) { usageRecResponse.setUsageId(vpnUser.getUuid()); } @@ -4623,7 +4623,7 @@ private UsageResourceDetails populateVpnUsersUsageResponse(Usage usageRecord, Us private UsageResourceDetails populateSecurityGroupUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat, VMInstanceVO vmInstance) { UsageResourceDetails resourceDetails = new UsageResourceDetails(); //Security Group Id - SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString()); + SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId()); resourceDetails.resourceType = ResourceObjectType.SecurityGroup; if (sg != null) { resourceDetails.resourceId = sg.getId(); @@ -4690,12 +4690,12 @@ private UsageResourceDetails populateVmSnapshotUsageResponse(Usage usageRecord, usageRecResponse.setVirtualSize(usageRecord.getVirtualSize()); } if (usageRecord.getOfferingId() != null) { - usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString()); + usageRecResponse.setOfferingId(usageRecord.getOfferingId()); } if (!oldFormat) { VolumeVO volume = null; if (vmSnapshotVO == null && usageRecord.getUsageId() != null) { - volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId()); } DiskOfferingVO diskOff = null; @@ -4725,7 +4725,7 @@ private UsageResourceDetails populateVmSnapshotUsageResponse(Usage usageRecord, } private UsageResourceDetails populateVolumeSecondaryUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse, boolean oldFormat) { - VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId()); if (!oldFormat) { final StringBuilder builder = new StringBuilder(); builder.append("Volume on secondary storage usage"); @@ -4771,7 +4771,7 @@ private UsageResourceDetails populateVmSnapshotOnPrimaryUsageResponse(Usage usag } private UsageResourceDetails populateBucketUsageResponse(Usage usageRecord, UsageRecordResponse usageRecResponse) { - BucketVO bucket = _entityMgr.findByIdIncludingRemoved(BucketVO.class, usageRecord.getUsageId().toString()); + BucketVO bucket = _entityMgr.findByIdIncludingRemoved(BucketVO.class, usageRecord.getUsageId()); if (bucket != null) { usageRecResponse.setUsageId(bucket.getUuid()); usageRecResponse.setResourceName(bucket.getName()); From da39c453f61358783635870d152d29f2d0b8a56b Mon Sep 17 00:00:00 2001 From: Prashant Bhanage Date: Fri, 24 Jul 2026 22:42:13 +0530 Subject: [PATCH 10/10] Refactor: modularize ApiResponseHelper#createUsageResponse (4.22 backport) --- .../java/com/cloud/api/ApiResponseHelper.java | 159 ++---------------- 1 file changed, 18 insertions(+), 141 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 8cb06af4245b..7d7f9288ea3e 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -44,10 +44,7 @@ import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.RoleVO; -import org.apache.cloudstack.acl.apikeypair.ApiKeyPair; -import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission; -import org.apache.cloudstack.acl.dao.RoleDao; + import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.annotation.AnnotationService; @@ -74,7 +71,7 @@ import org.apache.cloudstack.api.response.BackupOfferingResponse; import org.apache.cloudstack.api.response.BackupRepositoryResponse; import org.apache.cloudstack.api.response.BackupScheduleResponse; -import org.apache.cloudstack.api.response.BaseRolePermissionResponse; + import org.apache.cloudstack.api.response.BgpPeerResponse; import org.apache.cloudstack.api.response.BucketResponse; import org.apache.cloudstack.api.response.CapabilityResponse; @@ -122,7 +119,6 @@ import org.apache.cloudstack.api.response.Ipv4RouteResponse; import org.apache.cloudstack.api.response.Ipv6RouteResponse; import org.apache.cloudstack.api.response.IsolationMethodResponse; -import org.apache.cloudstack.api.response.ApiKeyPairResponse; import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; @@ -306,7 +302,7 @@ import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; -import com.cloud.domain.dao.DomainDao; + import com.cloud.event.Event; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -381,7 +377,7 @@ import com.cloud.network.vpc.VpcOffering; import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcOfferingDao; -import com.cloud.network.vpn.Site2SiteVpnManager; + import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Detail; @@ -424,14 +420,13 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.ApiKeyPairState; + import com.cloud.user.SSHKeyPair; import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.user.UserData; import com.cloud.user.UserStatisticsVO; -import com.cloud.user.dao.AccountDao; + import com.cloud.user.dao.UserDataDao; import com.cloud.user.dao.UserStatisticsDao; import com.cloud.uservm.UserVm; @@ -544,8 +539,7 @@ public class ApiResponseHelper implements ResponseGenerator, ResourceIdSupport { BgpPeerDao bgpPeerDao; @Inject RoutedIpv4Manager routedIpv4Manager; - @Inject - Site2SiteVpnManager site2SiteVpnManager; + @Inject ResourceIconManager resourceIconManager; @Inject @@ -560,14 +554,7 @@ public static String getPrettyDomainPath(String path) { return domainPath.toString(); } - @Inject - private RoleDao roleDao; - - @Inject - private AccountDao accountDao; - @Inject - private DomainDao domainDao; @Override public UserResponse createUserResponse(User user) { @@ -613,7 +600,6 @@ public DomainResponse createDomainResponse(Domain domain) { if (domain.getChildCount() > 0) { domainResponse.setHasChild(true); } - populateDomainTags(domain.getUuid(), domainResponse); domainResponse.setObjectName("domain"); return domainResponse; } @@ -1683,7 +1669,6 @@ public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule Network guestNtwk = ApiDBUtils.findNetworkById(fwRule.getNetworkId()); response.setNetworkId(guestNtwk.getUuid()); - response.setNetworkName(guestNtwk.getName()); IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); @@ -1911,8 +1896,6 @@ public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask()); vmResponse.setGateway(singleNicProfile.getIPv4Gateway()); } - } else if (network.getTrafficType() == TrafficType.Storage) { - vmResponse.setStorageIp(singleNicProfile.getIPv4Address()); } } } @@ -1937,11 +1920,7 @@ public UserVm findUserVmById(Long vmId) { } - @Override - public UserVm findUserVmByNicId(Long nicId) { - NicVO nic = ApiDBUtils.findNicById(nicId); - return ApiDBUtils.findUserVmById(nic.getInstanceId()); - } + @Override public VolumeVO findVolumeById(Long volumeId) { @@ -2892,10 +2871,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()); - } + response.setObjectName("network"); return response; @@ -3099,19 +3075,7 @@ public static void populateOwner(ControlledViewEntityResponse response, Controll response.setDomainPath(getPrettyDomainPath(object.getDomainPath())); } - public static void populateDomainTags(String domainUuid, DomainResponse domainResponse) { - List tags = ApiDBUtils.listResourceTagViewByResourceUUID(domainUuid, - ResourceTag.ResourceObjectType.Domain); - if (CollectionUtils.isEmpty(tags)) { - return; - } - Set tagResponses = new HashSet<>(); - for (ResourceTagJoinVO tag : tags) { - ResourceTagResponse tagResponse = ApiDBUtils.newResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - domainResponse.setTags(tagResponses); - } + private void populateAccount(ControlledEntityResponse response, long accountId) { Account account = ApiDBUtils.findAccountById(accountId); @@ -3324,9 +3288,7 @@ public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId()); if (pnet != null) { response.setPhysicalNetworkId(pnet.getUuid()); - if (!pnet.getIsolationMethods().isEmpty()) { - response.setIsolationMethods(String.join(",", pnet.getIsolationMethods())); - } + } if (result.getTrafficType() != null) { response.setTrafficType(result.getTrafficType().toString()); @@ -3337,7 +3299,7 @@ public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType response.setVmwareLabel(result.getVmwareNetworkLabel()); response.setHypervLabel(result.getHypervNetworkLabel()); response.setOvm3Label(result.getOvm3NetworkLabel()); - response.setVlan(result.getVlan()); + response.setObjectName("traffictype"); return response; @@ -3564,7 +3526,7 @@ public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) { if (voff != null) { response.setVpcOfferingId(voff.getUuid()); response.setVpcOfferingName(voff.getName()); - response.setVpcOfferingConserveMode(voff.isConserveMode()); + } response.setCidr(vpc.getCidr()); response.setRestartRequired(vpc.isRestartRequired()); @@ -3660,9 +3622,7 @@ public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) { } } - if (CallContext.current().getCallingAccount().getType() == Account.Type.ADMIN) { - response.setKeepMacAddressOnPublicNic(vpc.getKeepMacAddressOnPublicNic()); - } + response.setObjectName("vpc"); return response; } @@ -3957,14 +3917,7 @@ public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(S response.setIkeVersion(result.getIkeVersion()); response.setSplitConnections(result.getSplitConnections()); - Set obsoleteParameters = site2SiteVpnManager.getObsoleteVpnGatewayParameters(result); - if (CollectionUtils.isNotEmpty(obsoleteParameters)) { - response.setContainsObsoleteParameters(obsoleteParameters.toString()); - } - Set excludedParameters = site2SiteVpnManager.getExcludedVpnGatewayParameters(result); - if (CollectionUtils.isNotEmpty(excludedParameters)) { - response.setContainsExcludedParameters(excludedParameters.toString()); - } + response.setObjectName("vpncustomergateway"); response.setHasAnnotation(annotationDao.hasAnnotations(result.getUuid(), AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(), @@ -4690,7 +4643,7 @@ private UsageResourceDetails populateVmSnapshotUsageResponse(Usage usageRecord, usageRecResponse.setVirtualSize(usageRecord.getVirtualSize()); } if (usageRecord.getOfferingId() != null) { - usageRecResponse.setOfferingId(usageRecord.getOfferingId()); + usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString()); } if (!oldFormat) { VolumeVO volume = null; @@ -4889,7 +4842,7 @@ public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp resu setResponseIpAddress(result, response); response.setNicId(nic.getUuid()); response.setNwId(network.getUuid()); - response.setDescription(result.getDescription()); + response.setObjectName("nicsecondaryip"); return response; } @@ -4976,7 +4929,7 @@ public NicResponse createNicResponse(Nic result) { for (NicSecondaryIpVO ip : secondaryIps) { NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse(); ipRes.setId(ip.getUuid()); - ipRes.setDescription(ip.getDescription()); + setResponseIpAddress(ip, ipRes); ipList.add(ipRes); } @@ -5007,7 +4960,6 @@ public NicResponse createNicResponse(Nic result) { response.setVpcName(vpc.getName()); } - response.setEnabled(result.isEnabled()); return response; } @@ -5923,81 +5875,6 @@ public ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consol return consoleSessionResponse; } - @Override - public ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair) { - ApiKeyPairResponse apiKeyPairResponse = new ApiKeyPairResponse(); - - populateApiKeyPairInApiKeyPairResponse(keyPair, apiKeyPairResponse); - populateUserInApiKeyPairResponse(keyPair, apiKeyPairResponse); - - AccountVO account = accountDao.findByIdIncludingRemoved(keyPair.getAccountId()); - apiKeyPairResponse.setAccountId(account.getUuid()); - apiKeyPairResponse.setAccountName(account.getAccountName()); - apiKeyPairResponse.setAccountType(account.getType().toString()); - - populateDomainInApiKeyPairResponse(account.getDomainId(), apiKeyPairResponse); - populateRoleInApiKeyPairResponse(account.getRoleId(), apiKeyPairResponse); - - return apiKeyPairResponse; - } - - protected void populateRoleInApiKeyPairResponse(Long roleId, ApiKeyPairResponse apiKeyPairResponse) { - RoleVO roleVO = roleDao.findById(roleId); - apiKeyPairResponse.setRoleId(roleVO.getUuid()); - apiKeyPairResponse.setRoleName(roleVO.getName()); - apiKeyPairResponse.setRoleType(roleVO.getRoleType().name()); - } - - protected static void populateApiKeyPairInApiKeyPairResponse(ApiKeyPair keyPair, ApiKeyPairResponse apiKeyPairResponse) { - apiKeyPairResponse.setName(keyPair.getName()); - apiKeyPairResponse.setApiKey(keyPair.getApiKey()); - apiKeyPairResponse.setSecretKey(keyPair.getSecretKey()); - apiKeyPairResponse.setDescription(keyPair.getDescription()); - apiKeyPairResponse.setId(keyPair.getUuid()); - apiKeyPairResponse.setCreated(keyPair.getCreated()); - apiKeyPairResponse.setStartDate(keyPair.getStartDate()); - apiKeyPairResponse.setEndDate(keyPair.getEndDate()); - - ApiKeyPairState state = ApiKeyPairState.ENABLED; - if (keyPair.getRemoved() != null) { - state = ApiKeyPairState.REMOVED; - } else if (keyPair.hasEndDatePassed()) { - state = ApiKeyPairState.EXPIRED; - } - apiKeyPairResponse.setState(state); - } - - protected void populateUserInApiKeyPairResponse(ApiKeyPair keyPair, ApiKeyPairResponse apiKeyPairResponse) { - User user = ApiDBUtils.findUserById(keyPair.getUserId()); - apiKeyPairResponse.setUserId(user.getUuid()); - apiKeyPairResponse.setUsername(user.getUsername()); - } - - protected void populateDomainInApiKeyPairResponse(Long domainId, ApiKeyPairResponse apiKeyPairResponse) { - DomainVO domainVO = domainDao.findById(domainId); - apiKeyPairResponse.setDomainId(domainVO.getUuid()); - apiKeyPairResponse.setDomainName(domainVO.getName()); - StringBuilder domainPath = new StringBuilder("ROOT"); - (domainPath.append(domainVO.getPath())).deleteCharAt(domainPath.length() - 1); - apiKeyPairResponse.setDomainPath(domainPath.toString()); - } - - @Override - public ListResponse createKeypairPermissionsResponse(final List permissions) { - final ListResponse response = new ListResponse<>(); - final List permissionResponses = new ArrayList<>(); - for (final ApiKeyPairPermission permission : permissions) { - BaseRolePermissionResponse permissionResponse = new BaseRolePermissionResponse(); - permissionResponse.setRule(permission.getRule()); - permissionResponse.setRulePermission(permission.getPermission()); - permissionResponse.setDescription(permission.getDescription()); - permissionResponse.setObjectName("keypermission"); - permissionResponses.add(permissionResponse); - } - response.setResponses(permissionResponses); - return response; - } - @Override public EntityManager getEntityManager() { return _entityMgr;