From a093f00ab52bfb70f758db96f3830c8855dd7231 Mon Sep 17 00:00:00 2001 From: Lucas Martins <56271185+lucas-a-martins@users.noreply.github.com> Date: Fri, 14 Feb 2025 08:28:06 -0300 Subject: [PATCH] Add IOPS and bytes preset variables to `VOLUME` usage type (#10326) * Add bytes and iops preset variables to volume usage type * Add new line at the end of file Co-authored-by: dahn * Change disk offering preset variable class name --------- Co-authored-by: Lucas Martins Co-authored-by: dahn --- .../DiskOfferingPresetVariables.java | 165 ++++++++++++++++++ .../presetvariables/PresetVariableHelper.java | 17 +- .../activationrule/presetvariables/Value.java | 20 ++- .../PresetVariableHelperTest.java | 24 ++- 4 files changed, 216 insertions(+), 10 deletions(-) create mode 100644 framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/DiskOfferingPresetVariables.java diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/DiskOfferingPresetVariables.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/DiskOfferingPresetVariables.java new file mode 100644 index 00000000000..b2f5f69502f --- /dev/null +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/DiskOfferingPresetVariables.java @@ -0,0 +1,165 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.quota.activationrule.presetvariables; + +public class DiskOfferingPresetVariables extends GenericPresetVariable { + + @PresetVariableDefinition(description = "A long informing the bytes read rate of the disk offering.") + private Long bytesReadRate; + + @PresetVariableDefinition(description = "A long informing the burst bytes read rate of the disk offering.") + private Long bytesReadBurst; + + @PresetVariableDefinition(description = "The length (in seconds) of the bytes read burst.") + private Long bytesReadBurstLength; + + @PresetVariableDefinition(description = "A long informing the bytes write rate of the disk offering.") + private Long bytesWriteRate; + + @PresetVariableDefinition(description = "A long informing the burst bytes write rate of the disk offering.") + private Long bytesWriteBurst; + + @PresetVariableDefinition(description = "The length (in seconds) of the bytes write burst.") + private Long bytesWriteBurstLength; + + @PresetVariableDefinition(description = "A long informing the I/O requests read rate of the disk offering.") + private Long iopsReadRate; + + @PresetVariableDefinition(description = "A long informing the burst I/O requests read rate of the disk offering.") + private Long iopsReadBurst; + + @PresetVariableDefinition(description = "The length (in seconds) of the IOPS read burst.") + private Long iopsReadBurstLength; + + @PresetVariableDefinition(description = "A long informing the I/O requests write rate of the disk offering.") + private Long iopsWriteRate; + + @PresetVariableDefinition(description = "A long informing the burst I/O requests write rate of the disk offering.") + private Long iopsWriteBurst; + + @PresetVariableDefinition(description = "The length (in seconds) of the IOPS write burst.") + private Long iopsWriteBurstLength; + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + fieldNamesToIncludeInToString.add("bytesReadRate"); + } + + public Long getBytesReadBurst() { + return bytesReadBurst; + } + + public void setBytesReadBurst(Long bytesReadBurst) { + this.bytesReadBurst = bytesReadBurst; + fieldNamesToIncludeInToString.add("bytesReadBurst"); + } + + public Long getBytesReadBurstLength() { + return bytesReadBurstLength; + } + + public void setBytesReadBurstLength(Long bytesReadBurstLength) { + this.bytesReadBurstLength = bytesReadBurstLength; + fieldNamesToIncludeInToString.add("bytesReadBurstLength"); + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + fieldNamesToIncludeInToString.add("bytesWriteRate"); + } + + public Long getBytesWriteBurst() { + return bytesWriteBurst; + } + + public void setBytesWriteBurst(Long bytesWriteBurst) { + this.bytesWriteBurst = bytesWriteBurst; + fieldNamesToIncludeInToString.add("bytesWriteBurst"); + } + + public Long getBytesWriteBurstLength() { + return bytesWriteBurstLength; + } + + public void setBytesWriteBurstLength(Long bytesWriteBurstLength) { + this.bytesWriteBurstLength = bytesWriteBurstLength; + fieldNamesToIncludeInToString.add("bytesWriteBurstLength"); + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + fieldNamesToIncludeInToString.add("iopsReadRate"); + } + + public Long getIopsReadBurst() { + return iopsReadBurst; + } + + public void setIopsReadBurst(Long iopsReadBurst) { + this.iopsReadBurst = iopsReadBurst; + fieldNamesToIncludeInToString.add("iopsReadBurst"); + } + + public Long getIopsReadBurstLength() { + return iopsReadBurstLength; + } + + public void setIopsReadBurstLength(Long iopsReadBurstLength) { + this.iopsReadBurstLength = iopsReadBurstLength; + fieldNamesToIncludeInToString.add("iopsReadBurstLength"); + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + fieldNamesToIncludeInToString.add("iopsWriteRate"); + } + + public Long getIopsWriteBurst() { + return iopsWriteBurst; + } + + public void setIopsWriteBurst(Long iopsWriteBurst) { + this.iopsWriteBurst = iopsWriteBurst; + fieldNamesToIncludeInToString.add("iopsWriteBurst"); + } + + public Long getIopsWriteBurstLength() { + return iopsWriteBurstLength; + } + + public void setIopsWriteBurstLength(Long iopsWriteBurstLength) { + this.iopsWriteBurstLength = iopsWriteBurstLength; + fieldNamesToIncludeInToString.add("iopsWriteBurstLength"); + } +} diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java index 1e84ba27e02..b94b7de1b7b 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java @@ -492,6 +492,7 @@ public class PresetVariableHelper { value.setId(volumeVo.getUuid()); value.setName(volumeVo.getName()); value.setProvisioningType(volumeVo.getProvisioningType()); + value.setVolumeType(volumeVo.getVolumeType()); Long poolId = volumeVo.getPoolId(); if (poolId == null) { @@ -510,13 +511,25 @@ public class PresetVariableHelper { } } - protected GenericPresetVariable getPresetVariableValueDiskOffering(Long diskOfferingId) { + protected DiskOfferingPresetVariables getPresetVariableValueDiskOffering(Long diskOfferingId) { DiskOfferingVO diskOfferingVo = diskOfferingDao.findByIdIncludingRemoved(diskOfferingId); validateIfObjectIsNull(diskOfferingVo, diskOfferingId, "disk offering"); - GenericPresetVariable diskOffering = new GenericPresetVariable(); + DiskOfferingPresetVariables diskOffering = new DiskOfferingPresetVariables(); diskOffering.setId(diskOfferingVo.getUuid()); diskOffering.setName(diskOfferingVo.getName()); + diskOffering.setBytesReadRate(diskOfferingVo.getBytesReadRate()); + diskOffering.setBytesReadBurst(diskOfferingVo.getBytesReadRateMax()); + diskOffering.setBytesReadBurstLength(diskOfferingVo.getBytesReadRateMaxLength()); + diskOffering.setBytesWriteRate(diskOfferingVo.getBytesWriteRate()); + diskOffering.setBytesWriteBurst(diskOfferingVo.getBytesWriteRateMax()); + diskOffering.setBytesWriteBurstLength(diskOfferingVo.getBytesWriteRateMaxLength()); + diskOffering.setIopsReadRate(diskOfferingVo.getIopsReadRate()); + diskOffering.setIopsReadBurst(diskOfferingVo.getIopsReadRateMax()); + diskOffering.setIopsReadBurstLength(diskOfferingVo.getIopsReadRateMaxLength()); + diskOffering.setIopsWriteRate(diskOfferingVo.getIopsWriteRate()); + diskOffering.setIopsWriteBurst(diskOfferingVo.getIopsWriteRateMax()); + diskOffering.setIopsWriteBurstLength(diskOfferingVo.getIopsWriteRateMaxLength()); return diskOffering; } diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java index d87146d8798..77e539db0f3 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java @@ -22,6 +22,7 @@ import java.util.Map; import com.cloud.storage.Snapshot; import com.cloud.storage.Storage.ProvisioningType; +import com.cloud.storage.Volume; import com.cloud.vm.snapshot.VMSnapshot; import org.apache.cloudstack.quota.constant.QuotaTypes; @@ -75,7 +76,7 @@ public class Value extends GenericPresetVariable { private GenericPresetVariable template; @PresetVariableDefinition(description = "Disk offering of the volume.", supportedTypes = {QuotaTypes.VOLUME}) - private GenericPresetVariable diskOffering; + private DiskOfferingPresetVariables diskOffering; @PresetVariableDefinition(description = "Storage where the volume or snapshot is. While handling with snapshots, this value can be from the primary storage if the global " + "setting 'snapshot.backup.to.secondary' is false, otherwise it will be from secondary storage.", supportedTypes = {QuotaTypes.VOLUME, QuotaTypes.SNAPSHOT}) @@ -93,6 +94,10 @@ public class Value extends GenericPresetVariable { @PresetVariableDefinition(description = "The volume format. Values can be: RAW, VHD, VHDX, OVA and QCOW2.", supportedTypes = {QuotaTypes.VOLUME, QuotaTypes.VOLUME_SECONDARY}) private String volumeFormat; + + @PresetVariableDefinition(description = "The volume type. Values can be: UNKNOWN, ROOT, SWAP, DATADISK and ISO.", supportedTypes = {QuotaTypes.VOLUME}) + private Volume.Type volumeType; + private String state; public Host getHost() { @@ -194,11 +199,11 @@ public class Value extends GenericPresetVariable { fieldNamesToIncludeInToString.add("template"); } - public GenericPresetVariable getDiskOffering() { + public DiskOfferingPresetVariables getDiskOffering() { return diskOffering; } - public void setDiskOffering(GenericPresetVariable diskOffering) { + public void setDiskOffering(DiskOfferingPresetVariables diskOffering) { this.diskOffering = diskOffering; fieldNamesToIncludeInToString.add("diskOffering"); } @@ -257,6 +262,15 @@ public class Value extends GenericPresetVariable { return volumeFormat; } + public Volume.Type getVolumeType() { + return volumeType; + } + + public void setVolumeType(Volume.Type volumeType) { + this.volumeType = volumeType; + fieldNamesToIncludeInToString.add("volumeType"); + } + public String getState() { return state; } diff --git a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java index 7f64939f7bb..660bf8ba205 100644 --- a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java +++ b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java @@ -76,6 +76,7 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ProvisioningType; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; @@ -208,7 +209,7 @@ public class PresetVariableHelperTest { value.setComputeOffering(getComputeOfferingForTests()); value.setTags(Collections.singletonMap("tag1", "value1")); value.setTemplate(getGenericPresetVariableForTests()); - value.setDiskOffering(getGenericPresetVariableForTests()); + value.setDiskOffering(getDiskOfferingForTests()); value.setProvisioningType(ProvisioningType.THIN); value.setStorage(getStorageForTests()); value.setSize(ByteScaleUtils.GiB); @@ -216,6 +217,7 @@ public class PresetVariableHelperTest { value.setTag("tag_test"); value.setVmSnapshotType(VMSnapshot.Type.Disk); value.setComputingResources(getComputingResourcesForTests()); + value.setVolumeType(Volume.Type.DATADISK); return value; } @@ -308,6 +310,13 @@ public class PresetVariableHelperTest { return backupOffering; } + private DiskOfferingPresetVariables getDiskOfferingForTests() { + DiskOfferingPresetVariables diskOffering = new DiskOfferingPresetVariables(); + diskOffering.setId("disk_offering_id"); + diskOffering.setName("disk_offering_name"); + return diskOffering; + } + private void mockMethodValidateIfObjectIsNull() { Mockito.doNothing().when(presetVariableHelperSpy).validateIfObjectIsNull(Mockito.any(), Mockito.anyLong(), Mockito.anyString()); } @@ -698,6 +707,7 @@ public class PresetVariableHelperTest { Mockito.doReturn(expected.getName()).when(volumeVoMock).getName(); Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong()); Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType(); + Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType(); Mockito.doReturn(expected.getStorage()).when(presetVariableHelperSpy).getPresetVariableValueStorage(Mockito.anyLong(), Mockito.anyInt()); Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class)); Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize(); @@ -713,12 +723,13 @@ public class PresetVariableHelperTest { assertPresetVariableIdAndName(expected, result); Assert.assertEquals(expected.getDiskOffering(), result.getDiskOffering()); Assert.assertEquals(expected.getProvisioningType(), result.getProvisioningType()); + Assert.assertEquals(expected.getVolumeType(), result.getVolumeType()); Assert.assertEquals(expected.getStorage(), result.getStorage()); Assert.assertEquals(expected.getTags(), result.getTags()); Assert.assertEquals(expectedSize, result.getSize()); Assert.assertEquals(imageFormat.name(), result.getVolumeFormat()); - validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "storage", "tags", "size", "volumeFormat"), result); + validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "storage", "tags", "size", "volumeFormat"), result); } Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(), @@ -740,6 +751,7 @@ public class PresetVariableHelperTest { Mockito.doReturn(expected.getName()).when(volumeVoMock).getName(); Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong()); Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType(); + Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType(); Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class)); Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize(); Mockito.doReturn(imageFormat).when(volumeVoMock).getFormat(); @@ -754,12 +766,13 @@ public class PresetVariableHelperTest { assertPresetVariableIdAndName(expected, result); Assert.assertEquals(expected.getDiskOffering(), result.getDiskOffering()); Assert.assertEquals(expected.getProvisioningType(), result.getProvisioningType()); + Assert.assertEquals(expected.getVolumeType(), result.getVolumeType()); Assert.assertNull(result.getStorage()); Assert.assertEquals(expected.getTags(), result.getTags()); Assert.assertEquals(expectedSize, result.getSize()); Assert.assertEquals(imageFormat.name(), result.getVolumeFormat()); - validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "tags", "size", "volumeFormat"), result); + validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "tags", "size", "volumeFormat"), result); } Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(), @@ -772,14 +785,15 @@ public class PresetVariableHelperTest { Mockito.doReturn(diskOfferingVoMock).when(diskOfferingDaoMock).findByIdIncludingRemoved(Mockito.anyLong()); mockMethodValidateIfObjectIsNull(); - GenericPresetVariable expected = getGenericPresetVariableForTests(); + DiskOfferingPresetVariables expected = getDiskOfferingForTests(); Mockito.doReturn(expected.getId()).when(diskOfferingVoMock).getUuid(); Mockito.doReturn(expected.getName()).when(diskOfferingVoMock).getName(); GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueDiskOffering(1l); assertPresetVariableIdAndName(expected, result); - validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result); + validateFieldNamesToIncludeInToString(Arrays.asList("bytesReadBurst", "bytesReadBurstLength", "bytesReadRate", "bytesWriteBurst", "bytesWriteBurstLength", "bytesWriteRate", + "id", "iopsReadBurst", "iopsReadBurstLength", "iopsReadRate", "iopsWriteBurst", "iopsWriteBurstLength", "iopsWriteRate", "name"), result); } @Test