Updated Branches: refs/heads/master 8ce6d5271 -> 414d415db
CLOUDSTACK-5281: Resource limit shouldnt be counted for resources with display flag = 0. Adding functions to resourcelimitmanager and doing it for the volumes at the moment. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/414d415d Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/414d415d Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/414d415d Branch: refs/heads/master Commit: 414d415dba380e655dcd8d8baac621bc2a0db7ab Parents: 8ce6d52 Author: Nitin Mehta <[email protected]> Authored: Tue Nov 26 16:21:45 2013 -0800 Committer: Nitin Mehta <[email protected]> Committed: Tue Nov 26 16:21:45 2013 -0800 ---------------------------------------------------------------------- api/src/com/cloud/storage/VolumeApiService.java | 2 +- .../com/cloud/user/ResourceLimitService.java | 36 ++++++++++++++ .../command/user/volume/UpdateVolumeCmd.java | 2 +- .../com/cloud/storage/dao/VolumeDaoImpl.java | 4 ++ .../resourcelimit/ResourceLimitManagerImpl.java | 47 ++++++++++++++++++ .../com/cloud/storage/VolumeApiServiceImpl.java | 51 +++++++++++--------- .../cloud/vpc/MockResourceLimitManagerImpl.java | 21 ++++++++ 7 files changed, 137 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/api/src/com/cloud/storage/VolumeApiService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 7e9ea62..db23c1b 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -87,7 +87,7 @@ public interface VolumeApiService { Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException; - Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId); + Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner); /** * Extracts the volume to a particular location. http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/api/src/com/cloud/user/ResourceLimitService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java index bec65d5..f8923b7 100644 --- a/api/src/com/cloud/user/ResourceLimitService.java +++ b/api/src/com/cloud/user/ResourceLimitService.java @@ -139,4 +139,40 @@ public interface ResourceLimitService { */ public long getResourceCount(Account account, ResourceType type); + + /** + * Checks if a limit has been exceeded for an account depending on the displayResource flag + * + * @param account + * @param type + * @param displayResource + * @param count + * the number of resources being allocated, count will be added to current allocation and compared + * against maximum allowed allocation + * @throws ResourceAllocationException + */ + void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException; + + + /** + * Increments the resource count depending on the displayResource flag + * + * @param accountId + * @param type + * @param displayResource + * @param delta + */ + void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); + + /** + * Increments/Decrements the resource count depending on the displayResource flag + * + * @param accountId + * @param type + * @param displayResource + * @param delta + */ + void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); + + void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index a47c923..7233b4f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -141,7 +141,7 @@ public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd { @Override public void execute() { CallContext.current().setEventDetails("Volume Id: " + getId()); - Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getCustomId()); + Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getCustomId(), getEntityOwnerId()); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(result); response.setResponseName(getCommandName()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java index c64a253..5120387 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -346,6 +346,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol CountByAccount.select(null, Func.COUNT, null); CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); + CountByAccount.and("displayVolume", CountByAccount.entity().isDisplayVolume(), Op.EQ); CountByAccount.done(); primaryStorageSearch = createSearchBuilder(SumCount.class); @@ -355,6 +356,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol primaryStorageSearch.and().op("path", primaryStorageSearch.entity().getPath(), Op.NNULL); primaryStorageSearch.or("states", primaryStorageSearch.entity().getState(), Op.IN); primaryStorageSearch.cp(); + primaryStorageSearch.and("displayVolume", primaryStorageSearch.entity().isDisplayVolume(), Op.EQ); primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL); primaryStorageSearch.done(); @@ -382,6 +384,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol SearchCriteria<Long> sc = CountByAccount.create(); sc.setParameters("account", accountId); sc.setParameters("state", Volume.State.Destroy); + sc.setParameters("displayVolume", 1); return customSearch(sc, null).get(0); } @@ -393,6 +396,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol sc.setParameters("virtualRouterVmIds", virtualRouters.toArray(new Object[virtualRouters.size()])); } sc.setParameters("states", State.Allocated); + sc.setParameters("displayVolume", 1); List<SumCount> storageSpace = customSearch(sc, null); if (storageSpace != null) { return storageSpace.get(0).sum; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index ed4c480..70e8cdf 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -954,6 +954,53 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type); } + @Override + public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException { + + // By default its always on. + // TODO boilerplate code. + boolean displayflag = (displayResource == null) || (displayResource != null && displayResource); + + if(displayflag){ + checkResourceLimit(account, type, count); + } + } + + @Override + public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // 1. If its null assume displayResource = 1 + // 2. If its not null then increment if displayResource = 1 + if(displayResource == null || (displayResource != null && displayResource)){ + incrementResourceCount(accountId, type, delta); + } + } + + @Override + public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // 1. If its null assume displayResource = 1 + // 2. If its not null then decrement if displayResource = 1 + if(displayResource == null || (displayResource != null && displayResource)){ + decrementResourceCount(accountId, type, delta); + } + } + + @Override + public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + + // meaning that the display flag is not changed so neither increment or decrement + if(displayResource == null) return; + + // Increment because the display is turned on. + if(displayResource){ + // checkResourceLimit((Account)_accountDao.findById(accountId), type, delta); + incrementResourceCount(accountId, type, delta); + }else{ + decrementResourceCount(accountId, type, delta); + } + } + protected class ResourceCountCheckTask extends ManagedContextRunnable { public ResourceCountCheckTask() { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/server/src/com/cloud/storage/VolumeApiServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index aaf0fe3..0fd0ab0 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -458,8 +458,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // permission check _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId)); + if (displayVolumeEnabled == null) { + displayVolumeEnabled = true; + } else { + if (!_accountMgr.isRootAdmin(caller.getType())) { + throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted "); + } + } + // Check that the resource limit for volumes won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume, displayVolumeEnabled); Long zoneId = cmd.getZoneId(); Long diskOfferingId = null; @@ -574,16 +582,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic _accountMgr.checkAccess(caller, null, true, snapshotCheck); } - if (displayVolumeEnabled == null) { - displayVolumeEnabled = true; - } else { - if (!_accountMgr.isRootAdmin(caller.getType())) { - throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted "); - } - } - // Check that the resource limit for primary storage won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage, new Long(size)); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage, displayVolumeEnabled, new Long(size)); // Verify that zone exists DataCenterVO zone = _dcDao.findById(zoneId); @@ -652,8 +652,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // Increment resource count during allocation; if actual creation fails, // decrement it - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolumeEnabled); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolumeEnabled, new Long(volume.getSize())); return volume; } }); @@ -691,8 +691,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } finally { if (!created) { s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume()); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize())); } } } @@ -825,7 +825,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic if (!shrinkOk) { /* Check resource limit for this account on primary storage resource */ - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, new Long(newSize - currentSize)); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize)); } /* @@ -875,9 +875,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic /* Update resource count for the account on primary storage resource */ if (!shrinkOk) { - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(newSize - currentSize)); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize)); } else { - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(currentSize - newSize)); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize)); } return volume; } catch (InterruptedException e) { @@ -928,11 +928,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId); if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { // Decrement the resource count for volumes and primary storage belonging user VM's only - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume()); /* If volume is in primary storage, decrement primary storage count else decrement secondary storage count (in case of upload volume). */ if (volume.getFolder() != null || volume.getPath() != null || volume.getState() == Volume.State.Allocated) { - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(volume.getSize())); } else { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.secondary_storage.getOrdinal()); } @@ -1140,17 +1140,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) - public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId) { + public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId) { + VolumeVO volume = _volumeDao.findById(volumeId); if (path != null) { volume.setPath(path); } - if (displayVolume != null) { - volume.setDisplayVolume(displayVolume); - } - if (state != null) { try { Volume.State volumeState = Volume.State.valueOf(state); @@ -1173,6 +1170,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setUuid(customId); } + if (displayVolume != null && displayVolume != volume.isDisplayVolume()) { // No need to check permissions since only Admin allowed to call this API. + volume.setDisplayVolume(displayVolume); + _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.volume, displayVolume); + _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.primary_storage, displayVolume, new Long(volume.getSize())); + } + _volumeDao.update(volumeId, volume); return volume; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/414d415d/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java index 7756825..aec82fd 100644 --- a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java +++ b/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.configuration.Resource; import org.springframework.stereotype.Component; import com.cloud.configuration.Resource.ResourceType; @@ -148,6 +149,26 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc return 0; } + @Override + public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) { + //To change body of implemented methods use File | Settings | File Templates. + } + /* (non-Javadoc) * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map) */
