Skip to content

Commit

Permalink
VBV-715 - Useless error message when error creating placements from vRA
Browse files Browse the repository at this point in the history
video: http://engweb.vmware.com/~iilieva/jing/placements-validation.swf

Change-Id: I53e3f77fd4600d8eb6fe93f5bbd2dbec8e01f053
Reviewed-on: http://bellevue-ci.eng.vmware.com:8080/3495
Reviewed-by: Tony Georgiev <[email protected]>
Bellevue-Verified: jenkins <[email protected]>
CS-Verified: jenkins <[email protected]>
  • Loading branch information
iilieva committed Oct 25, 2016
1 parent 03bb20a commit 4d7ecc9
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@
<div class="priorityInput col-lg-8">
<input type="number" placeholder="{{i18n 'app.placement.edit.priorityPlaceholder'}}" />
<i class="fa fa-question-circle" data-toggle="tooltip" data-placement="top" title="{{i18n 'app.placement.edit.priorityHint'}}"></i>
<span class="help-block"></span>
</div>
</div>
<div class="form-group col-md-6">
<label class="col-lg-4 control-label">{{i18n "app.placement.edit.instancesLabel"}}</label>
<div class="maxInstancesInput col-lg-8">
<input type="number" placeholder="{{i18n 'app.placement.edit.instancesPlaceholder'}}"/>
<i class="fa fa-question-circle" data-toggle="tooltip" data-placement="top" title="{{i18n 'app.placement.edit.instancesHint'}}"></i>
<span class="help-block"></span>
</div>
</div>
<div class="form-group col-md-6">
Expand All @@ -72,12 +74,14 @@
<option selected="selected">MB</option>
<option>GB</option>
</select>
<span class="help-block"></span>
</div>
</div>
<div class="form-group col-md-6">
<label class="col-lg-4 control-label">{{i18n "app.placement.edit.cpuSharesLabel"}}</label>
<div class="cpuSharesInput col-lg-8">
<input type="number"/> %
<span class="help-block"></span>
</div>
</div>
</div>
Expand Down
95 changes: 46 additions & 49 deletions ui/app/src/js/components/placements/PlacementsRowEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@ PlacementsRowEditor.prototype.getEl = function() {
return this.$el;
};

PlacementsRowEditor.prototype.setMemoryInputValue = function(valueBytes, selector) {
if (valueBytes && utils.isValidNonNegativeIntValue(valueBytes)) {
let size = utils.calculateMemorySize(valueBytes);

this.$el.find(selector + ' input').val(size.value);
this.$el.find(selector + ' select').val(size.unit);
} else {
this.$el.find(selector + ' input').val('');
this.$el.find(selector + ' select').val('MB');
}
};

PlacementsRowEditor.prototype.getMemoryInputValue = function(selector) {
var memoryLimitVal = this.$el.find(selector + ' input').val();
var memoryLimitUnit = this.$el.find(selector + ' select').val();

if (memoryLimitVal && utils.isValidNonNegativeIntValue(memoryLimitVal)) {
let bytesValue = utils.toBytes(memoryLimitVal, memoryLimitUnit);
if (utils.isValidNonNegativeIntValue(bytesValue)) {
return bytesValue;
}
}

return null;
};

PlacementsRowEditor.prototype.setData = function(data) {
if (this.data !== data) {
var oldData = this.data || {};
Expand All @@ -140,27 +166,7 @@ PlacementsRowEditor.prototype.setData = function(data) {
this.$el.find('.priorityInput input').val(placementObject.priority);
this.$el.find('.nameInput input').val(placementObject.name);

if ($.isNumeric(placementObject.memoryLimit)) {
let size = utils.fromBytes(placementObject.memoryLimit);
normalizeToKB(size);

this.$el.find('.memoryLimitInput input').val(size.value);
this.$el.find('.memoryLimitInput select').val(size.unit);
} else {
this.$el.find('.memoryLimitInput input').val('');
this.$el.find('.memoryLimitInput select').val('MB');
}

if ($.isNumeric(placementObject.storageLimit)) {
let size = utils.fromBytes(placementObject.storageLimit);
normalizeToKB(size);

this.$el.find('.storageLimitInput input').val(size.value);
this.$el.find('.storageLimitInput select').val(size.unit);
} else {
this.$el.find('.storageLimitInput input').val('');
this.$el.find('.storageLimitInput select').val('MB');
}
this.setMemoryInputValue(placementObject.memoryLimit, '.memoryLimitInput');

this.$el.find('.cpuSharesInput input').val(placementObject.cpuShares);
}
Expand Down Expand Up @@ -253,34 +259,26 @@ var getPlacementModel = function() {
toReturn.groupId = this.placementGroupInput.getValue();
toReturn.resourcePool = this.resourcePoolInput.getSelectedOption();
toReturn.deploymentPolicy = this.deploymentPolicyInput.getSelectedOption();

var maxNumberInstances = this.$el.find('.maxInstancesInput input').val();
if ($.isNumeric(maxNumberInstances)) {
if ($.isNumeric(maxNumberInstances) && utils.isValidNonNegativeIntValue(maxNumberInstances)) {
toReturn.maxNumberInstances = maxNumberInstances;
} else if (maxNumberInstances === '') {
toReturn.maxNumberInstances = 0;
}

var priority = this.$el.find('.priorityInput input').val();
if ($.isNumeric(priority)) {
toReturn.priority = priority;
}

var memoryLimitVal = this.$el.find('.memoryLimitInput input').val();
var memoryLimitUnit = this.$el.find('.memoryLimitInput select').val();
if ($.isNumeric(memoryLimitVal)) {
toReturn.memoryLimit = utils.toBytes(memoryLimitVal, memoryLimitUnit);
if ($.isNumeric(priority) && utils.isValidNonNegativeIntValue(priority)) {
toReturn.priority = priority;
}

var cpuLimitVal = this.$el.find('.storageLimitInput input').val();
var cpuLimitUnit = this.$el.find('.storageLimitInput select').val();
if ($.isNumeric(cpuLimitVal)) {
toReturn.storageLimit = utils.toBytes(cpuLimitVal, cpuLimitUnit);
}
toReturn.memoryLimit = this.getMemoryInputValue('.memoryLimitInput');

var cpuShares = this.$el.find('.cpuSharesInput input').val();
if ($.isNumeric(cpuShares)) {
if ($.isNumeric(cpuShares) && utils.isValidNonNegativeIntValue(cpuShares)) {
toReturn.cpuShares = cpuShares;
}

return toReturn;
};

Expand All @@ -298,12 +296,18 @@ var toggleButtonsState = function() {
$saveBtn.removeClass('loading');

var groupClause = !utils.isApplicationEmbedded() || this.placementGroupInput.getValue();
var maxNumberInstancesClause = !maxNumberInstances || $.isNumeric(maxNumberInstances)
&& parseInt(maxNumberInstances, 10) >= 0;
var memoryLimitClause = !memoryLimit
|| $.isNumeric(memoryLimit) && parseInt(memoryLimit, 10) >= 0;
var cpuSharesClause = !cpuShares
|| $.isNumeric(cpuShares) && parseInt(cpuShares, 10) >= 0;
var maxNumberInstancesClause = !maxNumberInstances
|| utils.isValidNonNegativeIntValue(maxNumberInstances);
utils.applyValidationError(this.$el.find('.maxInstancesInput'),
maxNumberInstancesClause ? null : i18n.t('errors.invalidInputValue'));

var memoryLimitClause = !memoryLimit || (this.getMemoryInputValue('.memoryLimitInput') !== null);
utils.applyValidationError(this.$el.find('.memoryLimitInput'),
memoryLimitClause ? null : i18n.t('errors.invalidInputValue'));

var cpuSharesClause = !cpuShares || utils.isValidNonNegativeIntValue(cpuShares);
utils.applyValidationError(this.$el.find('.cpuSharesInput'),
cpuSharesClause ? null : i18n.t('errors.invalidInputValue'));

let notEnoughInfo = !resourcePool || !maxNumberInstancesClause || !groupClause
|| !memoryLimitClause || !cpuSharesClause;
Expand All @@ -318,13 +322,6 @@ var updateAlert = function($el, errors) {
this.alert.toggle($el, constants.ALERTS.TYPE.FAIL, errors && errors._generic);
};

var normalizeToKB = function(size) {
if (size.unit === 'Bytes') {
size.value /= 1024;
size.unit = 'kB';
}
};

/* An adapter that renders group or business group input based on the application type */
class GroupInput {
constructor($containerEl, valueChangeCallback) {
Expand Down
34 changes: 34 additions & 0 deletions ui/app/src/js/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,40 @@ var utils = {
};
},

getIntValue: function(value) {
return $.isNumeric(value) ? parseInt(value, 10) : null;
},

isValidNonNegativeIntValue: function(value) {
let intValue = this.getIntValue(value);
if (intValue === null || intValue === undefined) {
return false;
}

let limitValueRange = {
min: 0,
max: 9007199254740991 // Number.MAX_SAFE_INTEGER
};

return validator.isInt(intValue, limitValueRange);
},

calculateMemorySize: function(bytes) {
let size = utils.fromBytes(bytes);
// KB is the smallest unit shown in the UI
if (size.unit === byteUnits[0]) {
let k = 1024;

let value = (size.value / k);
if (Math.round(value) !== value) {
value = value.toFixed();
}
size.unit = byteUnits[1]; // kB
}

return size;
},

containerStatusDisplay: function(state, timestamp) {
var stateString = '';
if (state) {
Expand Down
3 changes: 2 additions & 1 deletion ui/app/src/messages/admiral.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,8 @@
"serviceNameRequired": "Service name is required.",
"networkRequired": "Network is required.",
"itemNotFound": "Item was not found.",
"networkExists": "Network already exists in template."
"networkExists": "Network already exists in template.",
"invalidInputValue": "Invalid input value"
},
"infoMessages": {
"created": "Created Successfully!",
Expand Down

0 comments on commit 4d7ecc9

Please sign in to comment.