ofri masad has posted comments on this change.
Change subject: core: Quota refactor - QuotaManager
......................................................................
Patch Set 15: (27 inline comments)
....................................................
File
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java
Line 640: QuotaConsumptionParametersWrapper
quotaConsumptionParametersWrapper = new QuotaConsumptionParametersWrapper(this,
Line 641: getReturnValue().getCanDoActionMessages());
Line 642:
quotaConsumptionParametersWrapper.setParameters(getQuotaConsumptionParameters());
Line 643:
Line 644: return
quotaConsumptionParametersWrapper.getParameters().isEmpty() ||
getQuotaManager().consume(quotaConsumptionParametersWrapper);
Done
Line 645: }
Line 646:
Line 647: /**
Line 648: * @return true if all parameters class and its inner members
passed
....................................................
File
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManagerAuditLogger.java
Line 6: import
org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;
Line 7:
Line 8: import java.text.DecimalFormat;
Line 9:
Line 10: public class QuotaManagerAuditLogger {
Done
Line 11: private final DecimalFormat percentageFormatter = new
DecimalFormat("#.##");
Line 12:
Line 13: protected void auditLogStorage(AuditLogableBase auditLogableBase,
AuditLogType auditLogType, String quotaName,
Line 14: double
storageUsagePercentage,
Line 50: auditLog(auditLogableBase, auditLogType);
Line 51: }
Line 52:
Line 53: protected void auditLog(AuditLogableBase auditLogableBase,
AuditLogType auditLogType) {
Line 54: if (auditLogType != null) {
Done
Line 55: AuditLogDirector.log(auditLogableBase, auditLogType);
Line 56: }
Line 57: }
Line 58:
....................................................
File
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/quota/QuotaManager.java
Line 31: private final static QuotaManager INSTANCE = new QuotaManager();
Line 32: private final static ReentrantReadWriteLock lock = new
ReentrantReadWriteLock();
Line 33: private final static Log log =
LogFactory.getLog(QuotaManager.class);
Line 34: private final static DecimalFormat percentageFormatter = new
DecimalFormat("#.##");
Line 35: private static QuotaManagerAuditLogger quotaManagerAuditLogger =
new QuotaManagerAuditLogger();
QuotaManagerAuditLogger is not final and have setter in order to allow mock
inject in the test. I'll add a comment here and on line 43
Line 36: private final ConcurrentHashMap<Guid, Map<Guid, Quota>>
storagePoolQuotaMap =
Line 37: new ConcurrentHashMap<Guid, Map<Guid, Quota>>();
Line 38: private final ConcurrentMap<Guid, Quota> directQuotaMap = new
ConcurrentHashMap<Guid, Quota>();
Line 39:
Line 39:
Line 40: public static QuotaManager getInstance() {
Line 41: return INSTANCE;
Line 42: }
Line 43:
Done
Line 44: public static QuotaManagerAuditLogger getQuotaManagerAuditLogger()
{
Line 45: return quotaManagerAuditLogger;
Line 46: }
Line 47:
Line 331: }
Line 332: }
Line 333:
Line 334: private boolean
validateAndSetStorageQuotaHelper(QuotaConsumptionParametersWrapper parameters) {
Line 335: lock.readLock().lock();
I'm editing an object from the map and not the map itself. to avoid data
corruption of the object itself - synchronized is used.
Line 336: try {
Line 337: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Line 338: if
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId())
== null) {
Line 339: return false;
Line 332: }
Line 333:
Line 334: private boolean
validateAndSetStorageQuotaHelper(QuotaConsumptionParametersWrapper parameters) {
Line 335: lock.readLock().lock();
Line 336: try {
Done
Line 337: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Line 338: if
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId())
== null) {
Line 339: return false;
Line 340: }
Line 333:
Line 334: private boolean
validateAndSetStorageQuotaHelper(QuotaConsumptionParametersWrapper parameters) {
Line 335: lock.readLock().lock();
Line 336: try {
Line 337: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Done
Line 338: if
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId())
== null) {
Line 339: return false;
Line 340: }
Line 341: Map<Guid, Quota> quotaMap =
storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId());
Line 334: private boolean
validateAndSetStorageQuotaHelper(QuotaConsumptionParametersWrapper parameters) {
Line 335: lock.readLock().lock();
Line 336: try {
Line 337: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Line 338: if
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId())
== null) {
Done
Line 339: return false;
Line 340: }
Line 341: Map<Guid, Quota> quotaMap =
storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId());
Line 342: Map<Guid, Map<Guid, Double>>
desiredStorageSizeQuotaMap = new HashMap<Guid, Map<Guid, Double>>();
Line 337: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Line 338: if
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId())
== null) {
Line 339: return false;
Line 340: }
Line 341: Map<Guid, Quota> quotaMap =
storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId());
Done
Line 342: Map<Guid, Map<Guid, Double>>
desiredStorageSizeQuotaMap = new HashMap<Guid, Map<Guid, Double>>();
Line 343:
Line 344: Map<Guid, Double> newUsedGlobalStorageSize = new
HashMap<Guid, Double>();
Line 345: Map<Guid, Map<Guid, Double>>
newUsedSpecificStorageSize = new HashMap<Guid, Map<Guid, Double>>();
Line 346:
Line 347: generateDesiredStorageSizeQuotaMap(parameters,
desiredStorageSizeQuotaMap);
Line 348:
Line 349: for (Guid quotaId :
desiredStorageSizeQuotaMap.keySet()) {
Line 350: Quota quota = quotaMap.get(quotaId);
quotaId is taken from desiredStorageSizeQuotaMap.keySet() while Quota is taken
from quotaMap.valueSet(). (not same Map)
Line 351: if (quota.getGlobalQuotaStorage() != null) {
Line 352: if
(checkConsumptionForGlobalStorageQuota(parameters,
Line 353: desiredStorageSizeQuotaMap,
Line 354: newUsedGlobalStorageSize,
Line 408: }
Line 409: if (!hasStorageId) {
Line 410: parameters.getCanDoActionMessages()
Line 411:
.add(VdcBllMessages.ACTION_TYPE_FAILED_NO_QUOTA_SET_FOR_DOMAIN.toString());
Line 412: return true;
Done
Line 413: }
Line 414: }
Line 415: return false;
Line 416: }
Line 436: quota.getGlobalQuotaStorage().getStorageSizeGB(),
Line 437: storageUsagePercentage, storageRequestPercentage,
Line 438: parameters.getCanDoActionMessages(),
Line 439: parameters.getAuditLogable())) {
Line 440: return true;
Done
Line 441: }
Line 442: newUsedGlobalStorageSize.put(quotaId, sum
Line 443: +
quota.getGlobalQuotaStorage().getStorageSizeGBUsage());
Line 444: }
Line 565: double storageRequestPercentage,
Line 566: List<String> canDoActionMessages,
Line 567: AuditLogableBase auditLogableBase) {
Line 568: double storageTotalPercentage = storageUsagePercentage +
storageRequestPercentage;
Line 569:
Done
Line 570: if (limit == QuotaStorage.UNLIMITED || storageTotalPercentage
<= quota.getThresholdStoragePercentage()) {
Line 571: return true;
Line 572: } else if (storageTotalPercentage <= 100) {
Line 573: quotaManagerAuditLogger.auditLogStorage(auditLogableBase,
Line 582: storageUsagePercentage + storageRequestPercentage,
Line 583: storageRequestPercentage);
Line 584: } else {
Line 585: quotaManagerAuditLogger.auditLogStorage(auditLogableBase,
Line 586:
AuditLogType.USER_EXCEEDED_QUOTA_STORAGE_GRACE_LIMIT,
Done
Line 587: quota.getQuotaName(),
Line 588: storageUsagePercentage,
Line 589: storageRequestPercentage);
Line 590: if
(QuotaEnforcementTypeEnum.HARD_ENFORCEMENT.equals(quotaEnforcementTypeEnum)) {
Line 693: int newVcpu = vcpuToAdd + quotaVdsGroup.getVirtualCpuUsage();
Line 694:
Line 695: long memLimit = quotaVdsGroup.getMemSizeMB();
Line 696: int cpuLimit = quotaVdsGroup.getVirtualCpu();
Line 697:
Done
Line 698: if (memLimit == QuotaVdsGroup.UNLIMITED_MEM && cpuLimit ==
QuotaVdsGroup.UNLIMITED_VCPU) { // if both cpu and
Line 699: // mem are unlimited
Line 700: // cache
Line 701: cacheNewValues(quotaVdsGroup, newMemory, newVcpu);
Line 823: }
Line 824:
Line 825: }
Line 826:
Line 827: public boolean
validateAndSetClusterQuota(QuotaConsumptionParametersWrapper parameters) {
Done
Line 828: List<QuotaVdsGroupConsumptionParameter>
vdsGroupConsumptionParameters =
Line 829:
filterQuotaVdsGroupConsumptionParameter(parameters.getParameters());
Line 830: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Line 831: for (QuotaVdsGroupConsumptionParameter parameter :
vdsGroupConsumptionParameters) {
Line 826:
Line 827: public boolean
validateAndSetClusterQuota(QuotaConsumptionParametersWrapper parameters) {
Line 828: List<QuotaVdsGroupConsumptionParameter>
vdsGroupConsumptionParameters =
Line 829:
filterQuotaVdsGroupConsumptionParameter(parameters.getParameters());
Line 830: synchronized
(storagePoolQuotaMap.get(parameters.getAuditLogable().getStoragePool().getId()))
{
Done
Line 831: for (QuotaVdsGroupConsumptionParameter parameter :
vdsGroupConsumptionParameters) {
Line 832: Quota quota = parameter.getQuota();
Line 833: QuotaVdsGroup quotaVdsGroup = null;
Line 834:
Line 1038: * @return - true if the request was validated and set
Line 1039: */
Line 1040: public boolean consume(QuotaConsumptionParametersWrapper
parameters) {
Line 1041: if (!validateAndCompleteParameters(parameters)) {
Line 1042: throw new InvalidQuotaParametersException();
Done
Line 1043: }
Line 1044:
Line 1045: return internalConsumeAndReleaseHandler(parameters);
Line 1046: }
Line 1116: * - Quota consumption parameters
Line 1117: */
Line 1118:
Line 1119: private boolean
validateAndCompleteParameters(QuotaConsumptionParametersWrapper parameters) {
Line 1120:
Done
Line 1121: if
(QuotaEnforcementTypeEnum.DISABLED.equals(parameters.getAuditLogable().getStoragePool().getQuotaEnforcementType()))
{
Line 1122: return true;
Line 1123: }
Line 1124:
Line 1127:
Line 1128: // for each parameter - check and complete
Line 1129: for (QuotaConsumptionParameter param :
parameters.getParameters()) {
Line 1130: // check that quota id is valid and fetch the quota from
db (or cache). add the quota to the param
Line 1131: boolean validQuotaId = checkAndFetchQuota(parameters,
param);
Done
Line 1132:
Line 1133: // In case this param is a QuotaVdsConsumptionParameter
- check that it has a valid
Line 1134: // vds group id which is handled by this quota
Line 1135: boolean validVdsGroup = true;
Line 1181: return true;
Line 1182: }
Line 1183:
Line 1184: // In case this param is a QuotaVdsConsumptionParameter - check
that it has a valid
Line 1185: // vds group id which is handled by this quota
Done
Line 1186: private boolean
checkVdsGroupMatchQuota(QuotaConsumptionParametersWrapper parameters,
QuotaConsumptionParameter param) {
Line 1187: Quota quota = param.getQuota();
Line 1188: QuotaVdsGroupConsumptionParameter paramVds =
(QuotaVdsGroupConsumptionParameter) param;
Line 1189:
Line 1185: // vds group id which is handled by this quota
Line 1186: private boolean
checkVdsGroupMatchQuota(QuotaConsumptionParametersWrapper parameters,
QuotaConsumptionParameter param) {
Line 1187: Quota quota = param.getQuota();
Line 1188: QuotaVdsGroupConsumptionParameter paramVds =
(QuotaVdsGroupConsumptionParameter) param;
Line 1189:
The parameters are passed from the Command. the
getVdsGroupConsumptionParameters() method is implemented by the command and
thus getVdsGroupId() can be null.
Line 1190: if (paramVds.getVdsGroupId() == null) {
Line 1191:
parameters.getCanDoActionMessages().add(VdcBllMessages.ACTION_TYPE_FAILED_QUOTA_IS_NOT_VALID.toString());
Line 1192: log.errorFormat("Quota Vds parameters from command: {0}
are missing vds group id",
Line 1193:
parameters.getAuditLogable().getClass().getName());
Line 1218: // storage domain id which is handled by this quota
Line 1219: private boolean
checkStoragePoolMatchQuota(QuotaConsumptionParametersWrapper parameters,
QuotaConsumptionParameter param) {
Line 1220: Quota quota = param.getQuota();
Line 1221: QuotaStorageConsumptionParameter paramstorage =
(QuotaStorageConsumptionParameter) param;
Line 1222:
The parameters are passed from the Command. the
getStorageConsumptionParameters() method is implemented by the command and thus
getStorageDomainId() can be null.
Line 1223: if (paramstorage.getStorageDomainId() == null) {
Line 1224:
parameters.getCanDoActionMessages().add(VdcBllMessages.ACTION_TYPE_FAILED_QUOTA_IS_NOT_VALID.toString());
Line 1225: log.errorFormat("Quota storage parameters from command:
{0} are missing storage domain id",
Line 1226:
parameters.getAuditLogable().getClass().getName());
Line 1252: * @param quotaId - quota id
Line 1253: * @return - found quota. null if not found.
Line 1254: */
Line 1255: private Quota fetchQuotaFromDB(Guid quotaId) {
Line 1256: // if the id is valid
Done
Line 1257: if (quotaId != null && quotaId != Guid.Empty) {
Line 1258: if (!directQuotaMap.containsKey(quotaId)) {
Line 1259: // cache in direct quota map
Line 1260: Quota quota = getQuotaDAO().getById(quotaId);
Line 1253: * @return - found quota. null if not found.
Line 1254: */
Line 1255: private Quota fetchQuotaFromDB(Guid quotaId) {
Line 1256: // if the id is valid
Line 1257: if (quotaId != null && quotaId != Guid.Empty) {
Done
Line 1258: if (!directQuotaMap.containsKey(quotaId)) {
Line 1259: // cache in direct quota map
Line 1260: Quota quota = getQuotaDAO().getById(quotaId);
Line 1261: if (quota == null) {
Line 1264: }
Line 1265: lock.readLock().lock();
Line 1266: try {
Line 1267: directQuotaMap.put(quotaId, quota);
Line 1268: // cache in storage-pool->quota map
Done.
added a warning about locks in the documentation
Line 1269:
storagePoolQuotaMap.putIfAbsent(quota.getStoragePoolId(), new HashMap<Guid,
Quota>());
Line 1270:
storagePoolQuotaMap.get(quota.getStoragePoolId()).put(quotaId, quota);
Line 1271: } finally {
Line 1272: lock.readLock().unlock();
--
To view, visit http://gerrit.ovirt.org/8776
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: Ibb100467a55b26e4219d1a2562da86b81ffdc032
Gerrit-PatchSet: 15
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: ofri masad <[email protected]>
Gerrit-Reviewer: Allon Mureinik <[email protected]>
Gerrit-Reviewer: Doron Fediuck <[email protected]>
Gerrit-Reviewer: Gilad Chaplik <[email protected]>
Gerrit-Reviewer: Laszlo Hornyak <[email protected]>
Gerrit-Reviewer: Michael Kublin <[email protected]>
Gerrit-Reviewer: Sharad Mishra <[email protected]>
Gerrit-Reviewer: Yair Zaslavsky <[email protected]>
Gerrit-Reviewer: ofri masad <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches