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.
This commit is contained in:
Nitin Mehta 2013-11-26 16:21:45 -08:00
parent 8ce6d5271c
commit 414d415dba
7 changed files with 137 additions and 26 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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());

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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)
*/