ofri masad has uploaded a new change for review. Change subject: core: Quota refactor - QuotaManager step 1 ......................................................................
core: Quota refactor - QuotaManager step 1 Add new public access methods consume() and release() (stabs) which would replace all "validateAndSet...." and "decrease..." methods. Change-Id: Ibb100467a55b26e4219d1a2562da86b81ffdc032 Signed-off-by: Ofri Masad <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManagerAuditLogger.java 3 files changed, 162 insertions(+), 21 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/76/8776/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java index e397a70..e6e3bae 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java @@ -29,6 +29,7 @@ import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameters; import org.ovirt.engine.core.bll.quota.QuotaStorageConsumptionParameter; import org.ovirt.engine.core.bll.quota.Quotable; +import org.ovirt.engine.core.bll.quota.QuotaManager; import org.ovirt.engine.core.bll.session.SessionDataContainer; import org.ovirt.engine.core.bll.tasks.AsyncTaskUtils; import org.ovirt.engine.core.bll.utils.PermissionSubject; @@ -571,8 +572,7 @@ } if (!consumptionParameters.isEmpty()) { - // TODO - implemented in next patch - return QuotaManager.getInstance().consume(quotaConsumptionParameters); - return true; + return QuotaManager.getInstance().consume(quotaConsumptionParameters); } else { return true; } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java index 6484572..8bd8f85 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java @@ -28,7 +28,6 @@ public class QuotaManager { private final static QuotaManager INSTANCE = new QuotaManager(); - public final static Long UNLIMITED = -1L; private final static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final static Log log = LogFactory.getLog(QuotaManager.class); private final static DecimalFormat percentageFormatter = new DecimalFormat("#.##"); @@ -102,7 +101,7 @@ } public void rollbackQuota(storage_pool storagePool, List<Guid> quotaList) { - if (storagePool == null){ + if (storagePool == null) { if (quotaList == null || quotaList.isEmpty()) { return; } @@ -132,7 +131,7 @@ List<StorageQuotaValidationParameter> parameters) { lock.readLock().lock(); try { - if (storagePool == null){ + if (storagePool == null) { log.debug("Null storage pool was passed to 'QuotaManager.decreaseStorageQuota()'"); if (parameters.isEmpty() || parameters.get(0).getQuotaId() == null) { return; @@ -162,7 +161,7 @@ Pair<AuditLogType, AuditLogableBase> logPair = new Pair<AuditLogType, AuditLogableBase>(); lock.readLock().lock(); try { - if (storagePool == null){ + if (storagePool == null) { log.debug("Null storage pool was passed to 'QuotaManager.validateAndSetStorageQuota()'"); if (parameters.isEmpty() || parameters.get(0).getQuotaId() == null) { canDoActionMessages.add(VdcBllMessages.ACTION_TYPE_FAILED_QUOTA_IS_NOT_VALID.toString()); @@ -228,7 +227,7 @@ for (Guid quotaId : desiredStorageSizeQuotaMap.keySet()) { Quota quota = quotaMap.get(quotaId); if (quota.getGlobalQuotaStorage() != null) { // global storage quota - if (quota.getGlobalQuotaStorage().getStorageSizeGB() != UNLIMITED) { + if (quota.getGlobalQuotaStorage().getStorageSizeGB() != QuotaStorage.UNLIMITED) { double sum = 0.0; for (Double size : desiredStorageSizeQuotaMap.get(quotaId).values()) { sum += size; @@ -257,7 +256,7 @@ for (QuotaStorage quotaStorage : quota.getQuotaStorages()) { if (quotaStorage.getStorageId().equals(storageId)) { hasStorageId = true; - if (quotaStorage.getStorageSizeGB() != UNLIMITED) { + if (quotaStorage.getStorageSizeGB() != QuotaStorage.UNLIMITED) { double storageUsagePercentage = quotaStorage.getStorageSizeGBUsage() / quotaStorage.getStorageSizeGB() * 100; double storageRequestPercentage = @@ -339,7 +338,7 @@ Pair<AuditLogType, AuditLogableBase> log) { double storageTotalPercentage = storageUsagePercentage + storageRequestPercentage; - if (limit == UNLIMITED || storageTotalPercentage <= quota.getThresholdStoragePercentage()) { + if (limit == QuotaStorage.UNLIMITED || storageTotalPercentage <= quota.getThresholdStoragePercentage()) { return true; } else if (storageTotalPercentage <= 100) { log.setFirst(AuditLogType.USER_EXCEEDED_QUOTA_STORAGE_THRESHOLD); @@ -389,7 +388,8 @@ long memLimit = quotaVdsGroup.getMemSizeMB(); int cpuLimit = quotaVdsGroup.getVirtualCpu(); - if (memLimit == UNLIMITED && cpuLimit == UNLIMITED) { // if both cpu and mem are unlimited + if (memLimit == QuotaVdsGroup.UNLIMITED_MEM && cpuLimit == QuotaVdsGroup.UNLIMITED_VCPU) { // if both cpu and + // mem are unlimited // cache cacheNewValues(quotaVdsGroup, newMemory, newVcpu); return true; @@ -522,7 +522,7 @@ ArrayList<String> canDoActionMessages) { Pair<AuditLogType, AuditLogableBase> logPair = new Pair<AuditLogType, AuditLogableBase>(); try { - if (storagePool == null){ + if (storagePool == null) { log.debug("Null storage pool was passed to 'QuotaManager.validateAndSetStorageQuota()'"); if (quotaId == null) { canDoActionMessages.add(VdcBllMessages.ACTION_TYPE_FAILED_QUOTA_IS_NOT_VALID.toString()); @@ -620,7 +620,7 @@ /** * Check if the quota exceeded the storage limit (ether for global limit or one of the specific limits). - * + * * @param quotaId * - quota id * @return - true if the quota exceeded the storage limitation. false if quota was not found, limit was not defined @@ -656,21 +656,22 @@ } /** - * This will create a new storage_pool object and set its ID and QuotaEnforcementType. - * If the quota was located in the DB these values will be taken from the quota. If not - * these values will be set ID=Guid.Empty, QuotaEnforcementType=DISABLED. - * - * Notice: The storage_pool object is not the full object obtained from DB but only a synthetic - * object to hold this two fields. - * - * @param quotaId - the id of the quota to locate in DB + * This will create a new storage_pool object and set its ID and QuotaEnforcementType. If the quota was located in + * the DB these values will be taken from the quota. If not these values will be set ID=Guid.Empty, + * QuotaEnforcementType=DISABLED. + * + * Notice: The storage_pool object is not the full object obtained from DB but only a synthetic object to hold this + * two fields. + * + * @param quotaId + * - the id of the quota to locate in DB * @return - the new synthetic storage_pool */ private storage_pool extractStoragePoolFromQuota(Guid quotaId) { storage_pool storagePool; Quota quota = getQuotaDAO().getById(quotaId); storagePool = new storage_pool(); - if (quota != null){ + if (quota != null) { storagePool.setId(quota.getStoragePoolId()); storagePool.setQuotaEnforcementType(quota.getQuotaEnforcementType()); } else { @@ -679,4 +680,75 @@ } return storagePool; } + + /** + * Consume from quota according to the parameters. + * + * @param parameters + * - Quota consumption parameters + * @return - true if the request was validated and set + */ + public boolean consume(QuotaConsumptionParameters parameters) { + if (!validateAndCompleteParameters(parameters)) { + throw new InvalidQuotaParametersException(); + } + + return internalConsumeAndReleaseHandler(parameters); + } + + /** + * Release quota according to the parameters. No need to revert the numbers of the request. for example: in order to + * release 8GB - enter 8 in the requestedStorageGB field + * + * @param parameters + * - Quota consumption parameters + */ + public void release(QuotaConsumptionParameters parameters) { + if (!validateAndCompleteParameters(parameters)) { + throw new InvalidQuotaParametersException(); + } + + QuotaConsumptionParameters revertedParams = revertParametersQuantities(parameters); + internalConsumeAndReleaseHandler(revertedParams); + } + + /** + * This is the start point for all quota consumption and release. This method is called after the parameters were + * validated and competed, and the cache was updated to support all the requests in the parameters. + * + * @param parameters + * - Quota consumption parameters + * @return - true if the request was validated and set + */ + private boolean internalConsumeAndReleaseHandler(QuotaConsumptionParameters parameters) { + + // TODO + return true; + } + + /** + * Revert the quantities of the storage, cpu and mem So that a request for 5GB storage is reverted to (-5)GB request + * + * @param parameters + * the consumption properties. This object would not be mutated. + * @return new QuotaConsumptionParameters object with reverted quantities, + */ + private QuotaConsumptionParameters revertParametersQuantities(QuotaConsumptionParameters parameters) { + QuotaConsumptionParameters revertedParams = parameters.clone(); + revertedParams.revert(); + return revertedParams; + } + + /** + * Validate parameters. Look for null pointers and missing data Complete the missing data in the parameters from DB + * and cache all the needed entities. + * + * @param parameters + * - Quota consumption parameters + */ + private boolean validateAndCompleteParameters(QuotaConsumptionParameters parameters) { + // TODO + return true; + } + } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManagerAuditLogger.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManagerAuditLogger.java new file mode 100644 index 0000000..8aa2434 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManagerAuditLogger.java @@ -0,0 +1,69 @@ +package org.ovirt.engine.core.bll.quota; + + +import org.ovirt.engine.core.common.AuditLogType; +import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; +import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; +import org.ovirt.engine.core.utils.Pair; + +import java.text.DecimalFormat; + +public class QuotaManagerAuditLogger { + private final static DecimalFormat percentageFormatter = new DecimalFormat("#.##"); + private static final QuotaManagerAuditLogger INSTANCE = new QuotaManagerAuditLogger(); + + private QuotaManagerAuditLogger() { + // Empty constructor + } + + public static QuotaManagerAuditLogger getInstance() { + return INSTANCE; + } + + protected synchronized void auditLogStorage(AuditLogableBase auditLogableBase, AuditLogType auditLogType, String quotaName, + double storageUsagePercentage, + double storageRequestedPercentage) { + auditLogableBase.AddCustomValue("QuotaName", quotaName); + auditLogableBase.AddCustomValue("CurrentStorage", percentageFormatter.format(storageUsagePercentage)); + auditLogableBase.AddCustomValue("Requested", percentageFormatter.format(storageRequestedPercentage)); + auditLog(auditLogableBase, auditLogType); + } + + protected synchronized void auditLogVdsGroup(AuditLogableBase auditLogableBase, AuditLogType auditLogType, String quotaName, + double cpuCurrentPercentage, + double cpuRequestPercentage, + double memCurrentPercentage, + double memRequestPercentage, + boolean cpuOverLimit, + boolean memOverLimit) { + + auditLogableBase.AddCustomValue("QuotaName", quotaName); + + StringBuilder currentUtilization = new StringBuilder(); + if (cpuOverLimit) { + currentUtilization.append("vcpu:").append(percentageFormatter.format(cpuCurrentPercentage)).append("% "); + } + if (memOverLimit) { + currentUtilization.append("mem:").append(percentageFormatter.format(memCurrentPercentage)).append("%"); + } + + StringBuilder request = new StringBuilder(); + if (cpuOverLimit) { + request.append("vcpu:").append(percentageFormatter.format(cpuRequestPercentage)).append("% "); + } + if (memOverLimit) { + request.append("mem:").append(percentageFormatter.format(memRequestPercentage)).append("%"); + } + + auditLogableBase.AddCustomValue("Utilization", currentUtilization.toString()); + auditLogableBase.AddCustomValue("Requested", request.toString()); + auditLog(auditLogableBase, auditLogType); + } + + protected void auditLog(AuditLogableBase auditLogableBase, AuditLogType auditLogType) { + if (auditLogType != null) { + AuditLogDirector.log(auditLogableBase, auditLogType); + } + } + +} -- To view, visit http://gerrit.ovirt.org/8776 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibb100467a55b26e4219d1a2562da86b81ffdc032 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: ofri masad <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
