diff options
author | 2017-09-20 14:08:19 +0300 | |
---|---|---|
committer | 2017-09-20 14:14:56 +0300 | |
commit | 1ba64a4a45f26e8bdb58e866e540aa58f32e2e52 (patch) | |
tree | dac3ada662bb141fe986526d13b2436032e5012e /vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler | |
parent | cbdd17f586a4914890bd2b26ee91be135568f38c (diff) |
Change management and PNF support
Issue-ID: VID-44, VID-48, VID-49, VID-50, VID-51, VID-52
Change-Id: I83e940aad2e4e294a0927b546c4c08ca8e539a65
Signed-off-by: Ofir Sonsino <os0695@att.com>
Diffstat (limited to 'vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler')
3 files changed, 701 insertions, 0 deletions
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js new file mode 100644 index 00000000..c8f44c71 --- /dev/null +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js @@ -0,0 +1,455 @@ +(function () { + 'use strict'; + + appDS2.controller("newSchedulerController", ["$scope", "$uibModal", "$uibModalInstance", "AaiService", "SchedulerService", "_", + "$log", "changeManagement", "$timeout", "$interval", "$filter", "VIDCONFIGURATION", "changeManagementService", newSchedulerController]); + + function newSchedulerController($scope, $uibModal, $uibModalInstance, AaiService, SchedulerService, _, $log, changeManagement, $timeout, $interval, $filter, VIDCONFIGURATION, changeManagementService) { + var vm = this; + var pollpromise; + + var init = function () { + vm.scheduler = {}; + vm.schedulingInfo = {}; + var callbackData = extractChangeManagementCallbackDataStr(changeManagement); + vm.vnfObject = changeManagement; + vm.schedulerObj = { + domain: 'ChangeManagement', + scheduleId: '', + scheduleName: 'VnfUpgrade/DWF', + userId: '', + domainData: [{ + 'WorkflowName': vm.scheduler.policy, + 'CallbackUrl': 'http://127.0.0.1:8989/scheduler/v1/loopbacktest/vid', + 'CallbackData': callbackData + }], + + schedulingInfo: { + normalDurationInSeconds: '', + additionalDurationInSeconds: '', + concurrencyLimit: '', + policyId: '', + vnfDetails: [ + { + groupId: "", + node: [], + changeWindow: [{ + startTime: '', + endTime: '' + }] + + } + ] + }, + + } + vm.schedulerObj1 = { + "domain": "ChangeManagement", + "scheduleName": "VnfUpgrade/DWF", + "userId": "su7376", + "domainData": [ + { + "WorkflowName": "HEAT Stack Software Update for vNFs", + "CallbackUrl": "http://127.0.0.1:8989/scheduler/v1/loopbacktest/vid", + "CallbackData": "testing" + } + ], + "schedulingInfo": { + "normalDurationInSeconds": 60, + "additionalDurationInSeconds": 60, + "concurrencyLimit": 60, + "policyId": "SNIRO_CM_1707.Config_MS_Demo_TimeLimitAndVerticalTopology_zone_localTime.1.xml", + "vnfDetails": [ + { + "groupId": "group1", + "node": ["satmo415vbc", "satmo455vbc"], + "changeWindow": [ + { + "startTime": "2017-08-08T16:37:30.521Z", + "endTime": "2017-08-08T16:37:30.521Z" + } + ] + } + ] + } + }; + + + vm.format = 'yyyy/MM/dd'; + vm.todate = new Date(); + vm.checkboxSelection = 'false'; + vm.fromDate = ''; + vm.toDate = ''; + vm.timeSlots = []; + + vm.changeManagement = {}; + + vm.subscribers = []; + + AaiService.getSubscribers(function (response) { + vm.subscribers = response; + }); + + vm.serviceTypes = []; + AaiService.getServices(function (response) { + vm.serviceTypes = response.data.service; + }); + + changeManagementService.getWorkflows() + .then(function (response) { + vm.workflows = response.data; + }) + .catch(function (error) { + $log.error(error); + }); + + //TODO: Get the VNF names from backend dynamically + vm.vnfNames = []; + + //TODO: Get the VNF types from backend dynamically + vm.vnfTypes = []; + + AaiService.getLoggedInUserID(function (response) { + vm.userID = response.data; + }); + vm.policys = []; + + var policyName = JSON.stringify({ + policyName: "SNIRO_1710.*", + configAttributes: { + service: "PlacementOptimizationPolicy" + } + }); + SchedulerService.getPolicyInfo(policyName, function (response) { + vm.policys = response.data.entity; + }); + }; + + vm.radioSelections = function (test) { + if (vm.checkboxSelection == "true") { + vm.fromDate = ''; + vm.toDate = '' + } + } + vm.close = function () { + $uibModalInstance.close(); + }; + + + function convertToSecs(number) { + var totalSecs; + if (vm.selectedOption === 'hours') { + totalSecs = number * 3600; + + } + else if (vm.selectedOption === 'minutes') { + totalSecs = number * 60; + } else { + totalSecs = number; + } + return totalSecs; + } + + vm.submit = function () { + vm.schedulingInfo = { + scheduleId: vm.schedulerID, + approvalDateTime: '2017-08-08T16:37:30.521Z', + approvalUserId: "sy6266", + approvalStatus: 'Accepted', + approvalType: 'Tier 2' + }; + + var approvalObj = JSON.stringify(vm.schedulingInfo); + SchedulerService.getSubmitForapprovedTimeslots(approvalObj, function (response) { + if (response.status == 200) { + openConfirmationModal("Successfully Sent for Approval"); + } + + }); + }; + + vm.reject = function () { + vm.schedulingInfo = { + scheduleId: vm.schedulerID, + approvalDateTime: '2017-08-08T16:37:30.521Z', + approvalUserId: "sy6266", + approvalStatus: 'Rejected', + approvalType: 'Tier 2' + } + + var approvalObj = JSON.stringify(vm.schedulingInfo) + SchedulerService.getSubmitForapprovedTimeslots(approvalObj, function (response) { + if (response.status == 200) { + openConfirmationModal("Successfully sent for Rejection"); + } + + }); + }; + + vm.schedule = function (myForm) { + $scope.$watch('fromDate', validateDates(myForm)); + $scope.$watch('toDate', validateDates(myForm)); + if (myForm.$valid) { + sendSchedulerReq() + } + }; + + + function sendSchedulerReq() { + var changeWindow = [{ + startTime: '', + endTime: '' + }]; + vm.timeSlots = []; + var fromDate = $filter('date')(new Date(vm.fromDate), "yyyy-MM-ddTHH:mmZ", "UTC"); + var toDate = $filter('date')(new Date(vm.toDate), "yyyy-MM-ddTHH:mmZ", "UTC"); + + changeWindow[0].startTime = fromDate; + changeWindow[0].endTime = toDate; + vm.schedulerObj.userId = vm.userID; + vm.schedulerObj.domainData[0].WorkflowName = changeManagement.workflow; + vm.schedulerObj.schedulingInfo.normalDurationInSeconds = convertToSecs(vm.scheduler.duration); + vm.schedulerObj.schedulingInfo.additionalDurationInSeconds = convertToSecs(vm.scheduler.fallbackDuration); + vm.schedulerObj.schedulingInfo.concurrencyLimit = vm.scheduler.concurrency; + vm.schedulerObj.schedulingInfo.policyId = vm.scheduler.policy.policyName; + vm.schedulerObj.schedulingInfo['vnfDetails'][0].groupId = 'groupId'; + vm.schedulerObj.schedulingInfo['vnfDetails'][0].node = getVnfData(changeManagement.vnfNames); + + vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow = changeWindow; + if (vm.checkboxSelection == "true") { //When Scheduled now we remove the changeWindow + delete vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow; + } + vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow = changeWindow; + delete vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow; + + var requestScheduler = JSON.stringify(vm.schedulerObj); + console.log(requestScheduler); + SchedulerService.getStatusSchedulerId(requestScheduler, function (response) { + vm.schedulerID = response.data.uuid; + vm.isSpinnerVisible = true; + if (vm.schedulerID) { + var scheduledID = JSON.stringify({scheduleId: vm.schedulerID}); + seviceCallToGetTimeSlots(); + } + }); + } + + function seviceCallToGetTimeSlots() { + + SchedulerService.getTimeSotsForSchedulerId(vm.schedulerID, function (response) { + if (vm.checkboxSelection == "false") { + if (response.data.entity.schedule) { + var scheduleColl = JSON.parse(response.data.entity.schedule); + if (scheduleColl.length > 0) { + vm.timeSlots = scheduleColl; + vm.isSpinnerVisible = false; + hasvaluereturnd = false; + $scope.stopPoll(); + openConfirmationModal(response.data.entity.scheduleId + " Successfully Returned TimeSlots."); + } + + } + else { + if (vm.timeSlots.length == 0 && hasthresholdreached == false) { + var polltime = VIDCONFIGURATION.SCHEDULER_POLLING_INTERVAL_MSECS; + pollpromise = poll(polltime, function () { + if (vm.timeSlots.length == 0) { + hasvaluereturnd = true; + seviceCallToGetTimeSlots() + } + else { + hasvaluereturnd = false; + } + + }); + + } else { + openConfirmationModal("Timeout error.") + } + } + + } + else { + if (response.data.entity) { + vm.isSpinnerVisible = false; + openConfirmationModal(response.data.entity.scheduleId + " Successfully Ready for Schedule.") + } + } + + }); + + } + + function openConfirmationModal(jobInfo) { + var modalInstance = $uibModal.open({ + templateUrl: 'app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html', + controller: 'alertNewSchedulerController', + controllerAs: 'vm', + resolve: { + jobInfo: function () { + return jobInfo; + } + } + }); + } + + var hasvaluereturnd = true; // Flag to check + var hasthresholdreached = false; + var thresholdvalue = VIDCONFIGURATION.SCHEDULER_MAX_POLLS; // interval threshold value + + function poll(interval, callback) { + return $interval(function () { + if (hasvaluereturnd) { //check flag before start new call + callback(hasvaluereturnd); + } + + thresholdvalue = thresholdvalue - 1; //Decrease threshold value + if (thresholdvalue == 0) { + $scope.stopPoll(); // Stop $interval if it reaches to threshold + } + }, interval) + } + + +// stop interval. + $scope.stopPoll = function () { + $interval.cancel(pollpromise); + thresholdvalue = 0; //reset all flags. + hasvaluereturnd = false; + hasthresholdreached = true; + vm.isSpinnerVisible = false; + } + + function getVnfData(arrColl) { + var vnfcolletion = []; + + for (var i = 0; i < arrColl.length; i++) { + vnfcolletion.push(arrColl[i].name); + } + + return vnfcolletion + } + + function validateDates(form) { + if (vm.checkboxSelection == "false") { + + if (form.startDate.$error.invalidDate || form.endDate.$error.invalidDate) { + form.startDate.$setValidity("endBeforeStart", true); //already invalid (per validDate directive) + } else { + //depending on whether the user used the date picker or typed it, this will be different (text or date type). + //creating a new date object takes care of that. + var endDate = new Date(vm.toDate); + var startDate = new Date(vm.fromDate); + form.startDate.$setValidity("endBeforeStart", endDate >= startDate); + } + } + } + + + function extractChangeManagementCallbackDataStr(changeManagement) { + var result = {}; + + result.requestType = changeManagement.workflow; + result.requestDetails = []; + + _.forEach(changeManagement.vnfNames, function (vnf) { + + var data = { + vnfName: vnf.name, + vnfInstanceId: vnf.id, + modelInfo: { + modelType: 'vnf', + modelInvariantId: vnf.properties['model-invariant-id'], + modelVersionId: vnf.modelVersionId, + modelName: vnf.properties['vnf-name'], + modelVersion: vnf.version, + modelCustomizationName: vnf.properties['model-customization-name'], + modelCustomizationId: vnf.properties['model-customization-id'] + }, + cloudConfiguration: { + lcpCloudRegionId: vnf.availableVersions[0].cloudConfiguration.lcpCloudRegionId, + tenantId: vnf.availableVersions[0].cloudConfiguration.tenantId + }, + requestInfo: { + source: vnf.availableVersions[0].requestInfo.source, + suppressRollback: vnf.availableVersions[0].requestInfo.suppressRollback, + requestorId: vnf.availableVersions[0].requestInfo.requestorId + }, + relatedInstanceList: [], + requestParameters: { + usePreload: vnf.availableVersions[0].requestParameters.usePreload + } + }; + + var serviceInstanceId = ''; + _.forEach(vnf['service-instance-node'], function (instanceNode) { + if(instanceNode['node-type'] === 'service-instance'){ + serviceInstanceId = instanceNode.properties['service-instance-id']; + } + }); + + + _.forEach(vnf.availableVersions[0].relatedInstanceList, function (related) { + + var rel = related.relatedInstance; + + var relatedInstance = { + instanceId: serviceInstanceId, + modelInfo: { + modelType: rel.modelInfo.modelType, + modelInvariantId: rel.modelInfo.modelInvariantId, + modelVersionId: rel.modelInfo.modelVersionId, + modelName: rel.modelInfo.modelName, + modelVersion: rel.modelInfo.modelVersion, + modelCustomizationName: rel.modelInfo.modelCustomizationName, + modelCustomizationId: rel.modelInfo.modelCustomizationId + } + }; + + if (rel.vnfInstanceId) + relatedInstance.instanceId = rel.vnfInstanceId; + + data.relatedInstanceList.push({relatedInstance: relatedInstance}); + }); + + + result.requestDetails.push(data); + } + ); + + + // _.forEach(changeManagement.vnfNames, function (vnfName) { + // if (vnfName && vnfName.version) { + // if (vnfName.selectedFile) { + // vnfName.version.requestParameters.userParams = vnfName.selectedFile; + // } + // result.requestDetails.push(vnfName.version) + // } + // }); + + return JSON.stringify(result); + } + + init(); + }; + + appDS2.directive('validDate', function () { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, element, attrs, control) { + control.$parsers.push(function (viewValue) { + var newDate = model.$viewValue; + control.$setValidity("invalidDate", true); + if (typeof newDate === "object" || newDate == "") return newDate; // pass through if we clicked date from popup + if (!newDate.match(/^\d{1,2}\/\d{1,2}\/((\d{2})|(\d{4}))$/)) + control.$setValidity("invalidDate", false); + return viewValue; + }); + } + }; + }) + + +})(); + diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css new file mode 100644 index 00000000..8da5c55c --- /dev/null +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css @@ -0,0 +1,145 @@ +.btn-white { + font-family: OpenSans; + border-radius: 2px; + border: 1px solid #d8d8d8; + background-color: #ffffff; + width: 94px; + height: 30px; + color: #5a5a5a; + font-size: 13px; + font-weight: 400; + line-height: 36px; + text-align: center; +} + +.btn-primary { + font-family: OpenSans; + border-radius: 2px; + border: 1px solid #0091c8; + background-color: #009fdb; + width: 94px; + height: 30px; + color: #ffffff; + font-size: 13px; + font-weight: 400; + line-height: 36px; + text-align: center; +} + +.modal-header { + border: none!important; + padding: 15px 15px 0px 15px!important; +} + +.modal-header h3 { + font-family: OpenSans; + color: #5a5a5a; + font-size: 22px; + font-weight: 300; + line-height: 16px; + padding-bottom: 20px; + border-bottom: 3px solid #009fdb; + +} + +.modal-footer { + background-color: #eaeaea; +} + +.modal-dialog { + width: 587px; + border-radius: 8px; +} + +.modal-content { + width: 587px; + border-radius: 8px; + background-color: #ffffff; +} +.label-font{ + font-size: 1em; +} +.calender-icon{ + background-image: url(../../../../../app/fusion/external/ebz/images/Calendar.svg); + background-repeat:no-repeat; + background-position:98%; + border-radius: 6px; + border: 1px solid #888; + color: #444; + font-family: clearview_att_regular; + width: 100%; + outline: 0; + padding: 7px 10px; + text-transform: none; + z-index: 0; + height: 40px; + position: relative; + +} + +input.calender-icon:focus{ + background-image: url(../../../../../app/fusion/external/ebz/images/Calendar_blue.svg); + background-repeat:no-repeat; +} + + + +.timeslots-content{ + margin-top: 0px; + margin-bottom: 0px; + height: 10em; +} +.find-block{ + float:5em; +} +.timeslots-block{ +/* margin-top: 1em; */ + height: 85px; + } + .policy-combo{ + background-image: none; + } + + div[ng-controller=newSchedulerController] .schedulerVisible { + visibility: visible; +} +div[ng-controller=newSchedulerController] .schedulerHidden { + visibility: hidden; +} + +.table { + border: 1px solid #eaeaea; + box-sizing: border-box; + background-color: #ffffff; + box-shadow: 0px 2px 7px 0px rgba(34, 31, 31, 0.17); + font-family: OpenSans; + color: #5a5a5a; + font-size: 14px; + font-weight: 400; +} +.table>thead { + background-color: #d2d2d2; + font-family: OpenSans; + color: #191919; + font-size: 13px; + font-weight: 600; + line-height: 40px; +} + +.table-headline-row { + font-family: OpenSans; + color: #5a5a5a; + font-size: 14px; + font-weight: 600; + background-color: #eaeaea; + box-shadow: 0px 1px 1px 0px rgba(34, 31, 31, 0.19); +} + +.table-bordered{border:1px solid #eaeaea;} +.table-bordered>tbody>tr>td, +.table-bordered>tbody>tr>th, +.table-bordered>tfoot>tr>td, +.table-bordered>tfoot>tr>th, +.table-bordered>thead>tr>td, +.table-bordered>thead>tr>th{border:1px solid #eaeaea;} + diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html new file mode 100644 index 00000000..498ff2ec --- /dev/null +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html @@ -0,0 +1,101 @@ +<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-scheduler/new-scheduler.css" /> +<div class="modal-header"> + <h3 class="modal-title" id="modal-title">Scheduler Change</h3> +</div> +<form name="newschedulermodalForm" ng-submit="vm.schedule(newschedulermodalForm)"> + <div class="modal-body"> + + <div class="form-group" > + <label><input type="radio" ng-model="vm.checkboxSelection" ng-change="vm.radioSelections()" value="true">Now</label> + <label><input type="radio" ng-model="vm.checkboxSelection" ng-change="vm.radioSelections()" value="false">Range</label> + </div> +<!-- <div class="form-group"> --> +<!-- <input type="radio" ng-model="checkboxSelection" value="false" ><label>Range</label> --> +<!-- </div> --> + + + <div class="form-group" > + <label class="control-label">From Date</label> + <input ng-disabled="(vm.checkboxSelection=='true')? true:false" valid-date name="startDate" ng-model="vm.fromDate" id="startDate" datetime-picker ng-required="false" hour="23" minute='59' class="calender-icon"/> + + </div> + <div class="form-group" > + <label class="control-label">To Date</label> + <input ng-disabled="(vm.checkboxSelection=='true')? true:false" valid-date name="endDate" ng-model="vm.toDate" id="endDate" datetime-picker ng-required="false" hour="23" minute='59' class="calender-icon" /> + <span ng-show="newschedulermodalForm.startDate.$error.endBeforeStart">To date must be on or after From date.</span> + <span ng-show="newschedulermodalForm.startDate.$error.invalidDate || newschedulermodalForm.endDate.$error.invalidDate">Check dates for validity</span> + <span ng-show="newschedulermodalForm.startDate.$error.required || newschedulermodalForm.endDate.$error.required">A required date is missing</span> + </div> + + <div class="form-group" > + <label>Please Select Option For Duration and FallBack</label> + + <select class="form-control" name="selecttime" data-tests-id="timeUnitSelect" ng-model="vm.selectedOption" ng-change="vm.updateMinMax()"> + <option value="hours">HOURS</option> + <option value="minutes">MINUTES</option> + <option value="seconds">SECONDS</option> + </select> + </div> + <div class="row"> + <div class="form-group col-md-6 col-xs-12"> + <label class="control-label">Duration</label> + <input type="number" style="font-size: 1em;" data-tests-id="durationInput" name="durationinput" ng-model="vm.scheduler.duration" ng-required="true"> + + </div> + <div class="form-group col-md-6 col-xs-12" > + <label class="control-label">Fallback Duration</label> + <input type="number" style="font-size: 1em;" name="fallbackinput" data-tests-id="fallbackInput" ng-model="vm.scheduler.fallbackDuration" ng-required="true"> + + + </div> + </div> + <div class="form-group"> + <label class="control-label">Concurrency Limit</label> + <input type="number" style="font-size: 1em;" name="input" data-tests-id="concurrencyLimitInput" ng-model="vm.scheduler.concurrency" min="1" max="30" ng-required="true"> + </div> + <div class="form-group"> + <label class="control-label">Policy</label> + <select class="policy-combo" ng-model="vm.scheduler.policy" id="policy" ng-options="item.policyName for item in vm.policys"> + <option value="">Select Policy</option> + </select> + </div> + <div class="form-group"> + <button type="submit" id="find" name="Find" ng-disabled="vm.isClicked" class="btn btn-primary find-block">Find</button> + <span class="spinner" ng-show="vm.isSpinnerVisible"> + <img src="app/vid/images/spinner.gif"> + </img> + + </span> + + </div> + + <div class="form-group" ng-show="(vm.checkboxSelection=='false')? true:false"> +<!-- <label class="control-label">Time Slots</label> --> +<!-- <textarea rows="10" cols="50" class="timeslots-block" ></textarea> --> + <table class="table table-bordered"> + <thead class="thead-default"> + <tr> + <th>Start Time</th> + <th>End Time</th> + </tr> + </thead> + <tbody> + + <tr class="table-headline-row" ng-repeat="timeslot in vm.timeSlots"> + <td>{{timeslot.startTime}}</td> + <td>{{timeslot.finishTime}}</td> + </tr> + </tbody> + </table> + </div> + + </div> + <div class="modal-footer"> + <div class="pull-right"> + <button type="button" id="btn" name="submit" class="btn btn-primary" ng-click="vm.submit()">Schedule</button> + <button type="button" id="btn" name="submit" class="btn btn-primary" ng-click="vm.reject()">Reject</button> + <button type="button" id="cancel" name="cancel" class="btn btn-white" ng-click="vm.close()">Cancel</button> + </div> + </div> +</form> + |