Skip to content

Commit 6a0fce3

Browse files
committed
Adding UI and API responses
1 parent 4b94afb commit 6a0fce3

7 files changed

Lines changed: 236 additions & 22 deletions

File tree

api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import java.util.Date;
20-
19+
import com.cloud.offering.DiskOffering;
20+
import com.cloud.serializer.Param;
2121
import com.google.gson.annotations.SerializedName;
22-
2322
import org.apache.cloudstack.api.ApiConstants;
2423
import org.apache.cloudstack.api.BaseResponse;
2524
import org.apache.cloudstack.api.EntityReference;
2625

27-
import com.cloud.offering.DiskOffering;
28-
import com.cloud.serializer.Param;
26+
import java.util.Date;
2927

3028
@EntityReference(value = DiskOffering.class)
3129
public class DiskOfferingResponse extends BaseResponse {
@@ -112,6 +110,21 @@ public class DiskOfferingResponse extends BaseResponse {
112110
@Param(description = "whether to display the offering to the end user or not.")
113111
private Boolean displayOffering;
114112

113+
@SerializedName(ApiConstants.MIN_IOPS_PER_GB)
114+
@Param(description = "IOPS/GB rate for min IOPS. miniops = size * miniopspergb")
115+
private Long minIopsPerGb;
116+
@SerializedName(ApiConstants.MAX_IOPS_PER_GB)
117+
@Param(description = "IOPS/GB rate for max IOPS. miniops = size * miniopspergb")
118+
private Long maxIopsPerGb;
119+
120+
@SerializedName(ApiConstants.HIGHEST_MIN_IOPS)
121+
@Param(description = "Highest Min IOPS value that is allowed for this offering")
122+
private Long highestMinIops;
123+
124+
@SerializedName(ApiConstants.HIGHEST_MAX_IOPS)
125+
@Param(description = "Highest Max IOPS value that is allowed for this offering")
126+
private Long highestMaxIops;
127+
115128
public Boolean getDisplayOffering() {
116129
return displayOffering;
117130
}
@@ -221,6 +234,38 @@ public Integer getHypervisorSnapshotReserve() {
221234
return hypervisorSnapshotReserve;
222235
}
223236

237+
public Long getMinIopsPerGb() {
238+
return minIopsPerGb;
239+
}
240+
241+
public void setMinIopsPerGb(Long minIopsPerGb) {
242+
this.minIopsPerGb = minIopsPerGb;
243+
}
244+
245+
public Long getMaxIopsPerGb() {
246+
return maxIopsPerGb;
247+
}
248+
249+
public void setMaxIopsPerGb(Long maxIopsPerGb) {
250+
this.maxIopsPerGb = maxIopsPerGb;
251+
}
252+
253+
public Long getHighestMinIops() {
254+
return highestMinIops;
255+
}
256+
257+
public void setHighestMinIops(Long highestMinIops) {
258+
this.highestMinIops = highestMinIops;
259+
}
260+
261+
public Long getHighestMaxIops() {
262+
return highestMaxIops;
263+
}
264+
265+
public void setHighestMaxIops(Long highestMaxIops) {
266+
this.highestMaxIops = highestMaxIops;
267+
}
268+
224269
public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
225270
this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
226271
}
@@ -264,4 +309,5 @@ public void setIopsReadRate(Long iopsReadRate) {
264309
public void setIopsWriteRate(Long iopsWriteRate) {
265310
this.iopsWriteRate = iopsWriteRate;
266311
}
312+
267313
}

server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,18 @@
1616
// under the License.
1717
package com.cloud.api.query.dao;
1818

19-
import java.util.List;
20-
21-
22-
import org.apache.log4j.Logger;
23-
import org.springframework.stereotype.Component;
24-
25-
import org.apache.cloudstack.api.response.DiskOfferingResponse;
26-
2719
import com.cloud.api.query.vo.DiskOfferingJoinVO;
2820
import com.cloud.offering.DiskOffering;
2921
import com.cloud.offering.ServiceOffering;
3022
import com.cloud.utils.db.Attribute;
3123
import com.cloud.utils.db.GenericDaoBase;
3224
import com.cloud.utils.db.SearchBuilder;
3325
import com.cloud.utils.db.SearchCriteria;
26+
import org.apache.cloudstack.api.response.DiskOfferingResponse;
27+
import org.apache.log4j.Logger;
28+
import org.springframework.stereotype.Component;
29+
30+
import java.util.List;
3431

3532
@Component
3633
public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO, Long> implements DiskOfferingJoinDao {
@@ -62,6 +59,10 @@ public DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO offering)
6259
diskOfferingResponse.setDiskSize(offering.getDiskSize() / (1024 * 1024 * 1024));
6360
diskOfferingResponse.setMinIops(offering.getMinIops());
6461
diskOfferingResponse.setMaxIops(offering.getMaxIops());
62+
diskOfferingResponse.setMinIopsPerGb(offering.getMinIopsPerGb());
63+
diskOfferingResponse.setMaxIopsPerGb(offering.getMaxIopsPerGb());
64+
diskOfferingResponse.setHighestMinIops(offering.getHighestMinIops());
65+
diskOfferingResponse.setHighestMaxIops(offering.getHighestMaxIops());
6566

6667
diskOfferingResponse.setDomain(offering.getDomainName());
6768
diskOfferingResponse.setDomainId(offering.getDomainUuid());

server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,17 @@
1616
// under the License.
1717
package com.cloud.api.query.vo;
1818

19-
import java.util.Date;
19+
import com.cloud.offering.DiskOffering.Type;
20+
import com.cloud.storage.Storage;
21+
import com.cloud.utils.db.GenericDao;
22+
import org.apache.cloudstack.api.Identity;
23+
import org.apache.cloudstack.api.InternalIdentity;
2024

2125
import javax.persistence.Column;
2226
import javax.persistence.Entity;
2327
import javax.persistence.Id;
2428
import javax.persistence.Table;
25-
26-
import com.cloud.storage.Storage;
27-
import org.apache.cloudstack.api.Identity;
28-
import org.apache.cloudstack.api.InternalIdentity;
29-
30-
import com.cloud.offering.DiskOffering.Type;
31-
import com.cloud.utils.db.GenericDao;
29+
import java.util.Date;
3230

3331
@Entity
3432
@Table(name = "disk_offering_view")
@@ -119,6 +117,18 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
119117
@Column(name = "display_offering")
120118
boolean displayOffering;
121119

120+
@Column(name = "min_iops_per_gb")
121+
Long minIopsPerGb;
122+
123+
@Column(name = "max_iops_per_gb")
124+
Long maxIopsPerGb;
125+
126+
@Column(name = "highest_min_iops")
127+
Long highestMinIops;
128+
129+
@Column(name = "highest_max_iops")
130+
Long highestMaxIops;
131+
122132
public DiskOfferingJoinVO() {
123133
}
124134

@@ -239,4 +249,20 @@ public Long getIopsReadRate() {
239249
public Long getIopsWriteRate() {
240250
return iopsWriteRate;
241251
}
252+
253+
public Long getMinIopsPerGb() {
254+
return minIopsPerGb;
255+
}
256+
257+
public Long getMaxIopsPerGb() {
258+
return maxIopsPerGb;
259+
}
260+
261+
public Long getHighestMinIops() {
262+
return highestMinIops;
263+
}
264+
265+
public Long getHighestMaxIops() {
266+
return highestMaxIops;
267+
}
242268
}

server/test/com/cloud/storage/VolumeApiServiceImplTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,66 @@ public void testResizeVolumeFromCustomSizeIopsPerGbToFixedSizeFixedIops() throws
688688
}
689689
}
690690

691+
@Test
692+
public void testResizeVolumeFromCustomSizeIopsPerGbToCustomSizeIopsPerGb() throws NoSuchFieldException, IllegalAccessException {
693+
Long oldSize = 10L * 1024 * 1024 * 1024;
694+
Long oldSizeGb = 10L;
695+
Long oldMinIopsPerGb = 10L;
696+
Long oldMaxIopsPerGb = 30L;
697+
698+
Long newSize = 10L * 1024 * 1024 * 1024;
699+
Long newSizeGb = 10L;
700+
Long newMinIopsPerGb = 20L;
701+
Long newMaxIopsPerGb = 50L;
702+
703+
ResizeVolumeCmd resizeVolumeCmd = Mockito.mock(ResizeVolumeCmd.class);
704+
when(resizeVolumeCmd.getNewDiskOfferingId()).thenReturn(2L);
705+
when(resizeVolumeCmd.getEntityId()).thenReturn(1L);
706+
707+
VolumeVO volumeVO = new VolumeVO(Volume.Type.DATADISK, "test-vol", 1, 1, 1, 1, Storage.ProvisioningType.THIN,
708+
oldSize, oldSizeGb * oldMinIopsPerGb, oldSizeGb * oldMaxIopsPerGb, null);
709+
710+
Field IdField = VolumeVO.class.getDeclaredField("id");
711+
IdField.setAccessible(true);
712+
IdField.set(volumeVO, 1L);
713+
714+
Field maxVolSizeField = _svc.getClass().getDeclaredField("_maxVolumeSizeInGb");
715+
maxVolSizeField.setAccessible(true);
716+
maxVolSizeField.setLong(_svc, 2 * 1024); // 2 TB max vol size
717+
718+
DiskOfferingVO diskOfferingVO = new DiskOfferingVO(1L, "custom-size-iopspergb-old", "custom-size-iopspergb-old", Storage.ProvisioningType.THIN,
719+
0L, "", true, false, null, null, null);
720+
diskOfferingVO.setMinIopsPerGb(oldMinIopsPerGb);
721+
diskOfferingVO.setMaxIopsPerGb(oldMaxIopsPerGb);
722+
723+
DiskOfferingVO newDiskOfferingVO = new DiskOfferingVO(1L,"custom-size-iopspergb-new","custom-size-iopspergb-new",
724+
Storage.ProvisioningType.THIN, newSize, "", false, false, null, null, null);
725+
newDiskOfferingVO.setMinIopsPerGb(newMinIopsPerGb);
726+
newDiskOfferingVO.setMaxIopsPerGb(newMaxIopsPerGb);
727+
728+
VolumeVO newVolume;
729+
730+
when(_svc._volsDao.findById(1L)).thenReturn(volumeVO);
731+
when(_svc._volsDao.getHypervisorType(1L)).thenReturn(HypervisorType.XenServer);
732+
when(_svc._volsDao.update(anyLong(), any(VolumeVO.class))).thenReturn(true);
733+
734+
when(_svc._vmSnapshotDao.findByVm(anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
735+
736+
when(_svc._diskOfferingDao.findById(1L)).thenReturn(diskOfferingVO);
737+
when(_svc._diskOfferingDao.findById(2L)).thenReturn(newDiskOfferingVO);
738+
doNothing().when(_svc._configMgr).checkDiskOfferingAccess(any(Account.class), any(DiskOffering.class));
739+
740+
try {
741+
newVolume = _svc.resizeVolume(resizeVolumeCmd);
742+
Assert.assertEquals(new Long(newMinIopsPerGb * newSizeGb), newVolume.getMinIops());
743+
Assert.assertEquals(new Long(newMaxIopsPerGb * newSizeGb), newVolume.getMaxIops());
744+
Assert.assertEquals(newSize, newVolume.getSize());
745+
Assert.assertEquals(Volume.State.Allocated, newVolume.getState());
746+
} catch (ResourceAllocationException e) {
747+
fail(e.getMessage());
748+
}
749+
}
750+
691751
@After
692752
public void tearDown() {
693753
CallContext.unregister();

setup/db/db/schema-41000to41100.sql

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,45 @@ CALL `cloud`.`ADD_COLUMN_TO_TABLE_IDEMPOTENT`('disk_offering', 'highest_min_iops
153153
CALL `cloud`.`ADD_COLUMN_TO_TABLE_IDEMPOTENT`('disk_offering', 'highest_max_iops', 'int unsigned', 'Highest Max IOPS value for this offering');
154154

155155
DROP PROCEDURE `cloud`.`ADD_COLUMN_TO_TABLE_IDEMPOTENT`;
156+
157+
DROP VIEW IF EXISTS `cloud`.`disk_offering_view`;
158+
CREATE VIEW `cloud`.`disk_offering_view` AS
159+
select
160+
disk_offering.id,
161+
disk_offering.uuid,
162+
disk_offering.name,
163+
disk_offering.display_text,
164+
disk_offering.provisioning_type,
165+
disk_offering.disk_size,
166+
disk_offering.min_iops,
167+
disk_offering.max_iops,
168+
disk_offering.created,
169+
disk_offering.tags,
170+
disk_offering.customized,
171+
disk_offering.customized_iops,
172+
disk_offering.removed,
173+
disk_offering.use_local_storage,
174+
disk_offering.system_use,
175+
disk_offering.hv_ss_reserve,
176+
disk_offering.bytes_read_rate,
177+
disk_offering.bytes_write_rate,
178+
disk_offering.iops_read_rate,
179+
disk_offering.iops_write_rate,
180+
disk_offering.min_iops_per_gb,
181+
disk_offering.max_iops_per_gb,
182+
disk_offering.highest_min_iops,
183+
disk_offering.highest_max_iops,
184+
disk_offering.cache_mode,
185+
disk_offering.sort_key,
186+
disk_offering.type,
187+
disk_offering.display_offering,
188+
domain.id domain_id,
189+
domain.uuid domain_uuid,
190+
domain.name domain_name,
191+
domain.path domain_path
192+
from
193+
`cloud`.`disk_offering`
194+
left join
195+
`cloud`.`domain` ON disk_offering.domain_id = domain.id
196+
where
197+
disk_offering.state='ACTIVE';

ui/scripts/configuration.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,45 @@
23512351
diskIopsWriteRate: {
23522352
label: 'label.disk.iops.write.rate'
23532353
},
2354+
miniopspergb: {
2355+
label: 'label.disk.iops.pergb.min',
2356+
converter: function(args) {
2357+
if (args > 0)
2358+
return args;
2359+
else
2360+
return "N/A";
2361+
}
2362+
2363+
},
2364+
maxiopspergb: {
2365+
label: 'label.disk.iops.pergb.max',
2366+
converter: function(args) {
2367+
if (args > 0)
2368+
return args;
2369+
else
2370+
return "N/A";
2371+
}
2372+
2373+
},
2374+
highestminiops: {
2375+
label: 'label.disk.iops.highest.min',
2376+
converter: function(args) {
2377+
if (args > 0)
2378+
return args;
2379+
else
2380+
return "N/A";
2381+
}
2382+
2383+
},
2384+
highestmaxiops: {
2385+
label: 'label.disk.iops.highest.max',
2386+
converter: function(args) {
2387+
if (args > 0)
2388+
return args;
2389+
else
2390+
return "N/A";
2391+
}
2392+
},
23542393
cacheMode: {
23552394
label: 'label.cache.mode'
23562395
},

ui/scripts/storage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1667,7 +1667,7 @@
16671667
action: function(args) {
16681668
var array1 = [];
16691669
var newSize;
1670-
if (selectedDiskOfferingObj == null || selectedDiskOfferingObj.iscustomized == true) {
1670+
if (selectedDiskOfferingObj == null) {
16711671
newSize = args.data.newsize;
16721672
if (newSize != null && newSize.length > 0) {
16731673
array1.push("&size=" + todb(newSize));

0 commit comments

Comments
 (0)