diff options
author | demx8as6 <martin.skorupski@highstreet-technologies.com> | 2018-07-10 18:07:44 +0200 |
---|---|---|
committer | Timoney, Dan (dt5972) <dt5972@att.com> | 2018-07-11 16:30:28 -0400 |
commit | 27fb2d06608fbb070ae2c15a5580a4f5b2423d15 (patch) | |
tree | ccd717991b4e556b67f1fd2cacb345b4d174b41f /sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module | |
parent | 60315525ab5e7c12a9f47c409092e8dba6ad656d (diff) |
Add seed code for sdnr app based on ONF Centennial
At this point in time all the Carbon code from ONF Centennial is added to ONAP.
Later it needs to be refactored and modified for ODL Oxygen.
Change-Id: Iff85dd940c05c3827f1c4e6f9542ecd060c58a46
Issue-ID: SDNC-374
Signed-off-by: demx8as6 <martin.skorupski@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module')
10 files changed, 1188 insertions, 0 deletions
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml new file mode 100644 index 00000000..f0d7215d --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>mwtnFault</artifactId> + <groupId>com.highstreet.technologies.odl.dlux</groupId> + <version>0.5.1-SNAPSHOT</version> + </parent> + <artifactId>mwtnFault-module</artifactId> + <name>${prefix} ${project.artifactId}</name> + <packaging>jar</packaging> + +</project>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png Binary files differnew file mode 100755 index 00000000..47bfc70c --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css new file mode 100644 index 00000000..7e959b1e --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css @@ -0,0 +1,100 @@ +/** + * Add your application related css here + */ +.global-alarm-status { + float: left; + margin: 5px; + margin-left: 8px; +} + +.global-alarm-status a { + color:azure; + text-decoration: none; +} + +.global-alarm-status a:visited { + color:azure; + text-decoration: none; +} + +.global-alarm-status a:hover { + color:bisque; +} +s +.mwtn span { + color: white; +} +.mwtn a span { + color: white; +} +.Critical { + color: red; +} +.Major { + color: orange; +} +.Minor { + color: yellow; +} +.Warning { + color: #428bca; +} +.cleared { + color: lightgreen; +} + +.mwtnFaultGrid { + height: 600px; + background-color: white; +} + +.mwtnFaultGrid span { + color: #393939; +} +.ht-pagination span { + color: #393939; +} +.ht-pagination span.dark { + color: #393939; +} +.dark { + color: #393939; +} + + + +.mwtnFaultGrid div.debug { + color: #393939; + background-color: white; +} +.mwtnFaultGrid div.error { + color: #ff0000; + background-color: #ffeeee; + font-weight: bold; +} + +.mwtnFaultGrid div.info { + color: #3276b1; + background-color: #eeeeff; +} + +.mwtnFaultGrid div.warning { + color: #ffa500; + background-color: #ffeedd; +} + +.rotated { + transform: rotate(180deg); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -o-transform: rotate(180deg); +} + +h3.modal-title { + color: #393939; +} + +.modal-body span { + color: #393939; +}
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js new file mode 100644 index 00000000..d29d547d --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +define(['app/mwtnFault/mwtnFault.module', + 'app/mwtnFault/mwtnFault.services', + 'app/mwtnFault/mwtnFault.directives'], + function(mwtnFaultApp) { + + mwtnFaultApp.register.controller('mwtnFaultCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$mwtnFault', '$mwtnLog', '$http', + function(uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $mwtnFault, $mwtnLog, $http) { + + + var COMPONENT = 'mwtnFaultCtrl'; + $mwtnLog.info({component: COMPONENT, message: 'mwtnFaultCtrl started!'}); + + $rootScope.section_logo = 'src/app/mwtnFault/images/mwtnFault.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif' + + $scope.date = new Date().toISOString().toHumanReadableTimeFormat(); + $scope.highlightFilteredHeader = $mwtnFault.highlightFilteredHeader; + $scope.oneATime = true; + + // var rowTemplate = '<div ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ng-class="[\'ui-grid-cell\', row.entity.type]" ui-grid-cell></div>'; + var iconCell = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i class="fa {{COL_FIELD}}" aria-hidden="true"></i></div>'; + var getIconFromSeverity = function(severity) { + var mapping = { + Cleared : '', + NonAlarmed : '', + Critical : 'fa-exclamation-triangle', + Major : 'fa-exclamation-triangle', + Minor : 'fa-exclamation-triangle', + Warning : 'fa-times-circle' + }; + return mapping[severity]; + }; + + // Current Problem List + $scope.gridOptionsCurrentProblemList = JSON.parse(JSON.stringify($mwtnFault.gridOptions)); + $scope.gridOptionsCurrentProblemList.columnDefs = [ + // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true }, + { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell }, + { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: { + direction: uiGridConstants.DESC, + priority: 1 + } }, + { field: 'node', type: 'string', displayName: 'Node name', headerCellClass: $scope.highlightFilteredHeader, width: 200 }, + { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' }, + { field: 'object', type: 'string', displayName: 'Object Id', headerCellClass: $scope.highlightFilteredHeader, width: 300 }, + { field: 'problem', type: 'string', displayName: 'Alarm type', headerCellClass: $scope.highlightFilteredHeader, width : 200 }, + { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 150 } + + ]; + + var processCurrentProblemEntries = function(logEntries) { + if (logEntries.data.hits.hits) { + $scope.gridOptionsCurrentProblemList.data = logEntries.data.hits.hits.map(function(entry){ + return { + id: entry._id, + icon: getIconFromSeverity(entry._source.faultCurrent.severity), + timestamp: $mwtnFault.formatTimeStamp(entry._source.faultCurrent.timeStamp), + node: entry._source.faultCurrent.nodeName, + counter: entry._source.faultCurrent.counter, + object: entry._source.faultCurrent.objectId, + problem: entry._source.faultCurrent.problem, + severity: entry._source.faultCurrent.severity, + }; + }); + $scope.progress.max = logEntries.data.hits.total; + $scope.progress.value = $scope.gridOptionsCurrentProblemList.data.length; + $scope.progress.show = $scope.gridOptionsCurrentProblemList.data.length < logEntries.data.hits.total; + } + }; + + $scope.refreshCurrentProblemList = function() { + // $scope.gridOptionsCurrentProblemList.data = []; + var from = 0; + var size = 10000; + $scope.processing = true; + $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){ + $scope.processing = false; + $scope.spinner.currentProblemList = false; + processCurrentProblemEntries(logEntries); + from = from + size; + while (from < $scope.progress.max) { + $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){ + processCurrentProblemEntries(logEntries); + }, function(error){ + console.error(JSON.stringify(error)); + }); + from = from + size; + } + }, function(error){ + $scope.processing = false; + $scope.spinner.currentProblemList = false; + console.error(JSON.stringify(error)); + }); + }; + + // Alarm Notifications + $scope.gridOptionsAlarmNotifications = JSON.parse(JSON.stringify($mwtnFault.gridOptions)); + $scope.gridOptionsAlarmNotifications.columnDefs = [ + // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true }, + { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell }, + { field: 'timeStamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: { + direction: uiGridConstants.DESC, + priority: 1 + } }, + { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 90 }, + { field: 'nodeName', type: 'string', displayName: 'NetworkElement', headerCellClass: $scope.highlightFilteredHeader, width: 170 }, + { field: 'objectId', type: 'string', displayName: 'Object', headerCellClass: $scope.highlightFilteredHeader, width: 400 }, + + { field: 'problem', type: 'string', displayName: 'Alarm', headerCellClass: $scope.highlightFilteredHeader, width : 140 }, + { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 100 } + ]; + var listenToNotifications = function() { + $mwtnFault.getMwtnWebSocketUrl().then(function(success){ + try { + var notificationSocket = new WebSocket(success); + + notificationSocket.onmessage = function(event) { + // we process our received event here + if (typeof event.data === 'string') { + // console.log("Client Received:\n" + event.data); + // console.log("---------------------------"); + $mwtnFault.formatData(event).then(function(formated) { + switch (formated.notifType) { + case 'ProblemNotification': + formated.icon = getIconFromSeverity(formated.severity); + $scope.gridOptionsAlarmNotifications.data.push(formated); + $timeout(function(){$scope.refreshCurrentProblemList();}, 500); + break; + case 'AttributeValueChangedNotification': + case 'ObjectCreationNotification': + case 'ObjectDeletionNotification': + // ignore + break; + default: + console.error('Missing implementation for', formated.notifType); + } + }, function(error) { + // do nothing + }); + } + }; + + notificationSocket.onerror = function(error) { + console.log("Socket error: " + error); + }; + + notificationSocket.onopen = function(event) { + console.log("Socket connection opened."); + + function subscribe() { + if (notificationSocket.readyState === notificationSocket.OPEN) { + var data = { + 'data' : 'scopes', + 'scopes' : [ "ProblemNotification" ] + }; + notificationSocket.send(JSON.stringify(data)); + } + } + subscribe(); + }; + + notificationSocket.onclose = function(event) { + console.log("Socket connection closed."); + }; + } catch (e) { + console.error("Error when creating WebSocket.\n" + e); + } + }, function(error){ + console.error("Error when creating WebSocket.\n" + error); + }); + }; + listenToNotifications(); + + // Alarm Log + // $scope.gridOptionsAlarmLog = JSON.parse(JSON.stringify($mwtnFault.gridOptions)); + + $scope.paginationOptions = { + pageNumber: 1, + pageSize: 25, + sort: null + }; + + $scope.gridOptionsAlarmLog = { + paginationPageSizes: [25, 100, 1000, 10000], + paginationPageSize: 25, + useExternalPagination: true, + useExternalSorting: true, + enablePaginationControls: false, + enableFiltering: true, + useExternalFiltering: true, + columnDefs : [ + // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true }, + { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell }, + { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: { + direction: uiGridConstants.DESC, + priority: 1 + } }, + { field: 'node', type: 'string', displayName: 'Node name', headerCellClass: $scope.highlightFilteredHeader, width: 200 }, + { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' }, + { field: 'object', type: 'string', displayName: 'Object Id', headerCellClass: $scope.highlightFilteredHeader, width: 300 }, + { field: 'problem', type: 'string', displayName: 'Alarm type', headerCellClass: $scope.highlightFilteredHeader, width : 200 }, + { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 150 } + ], + data: 'data', + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + $scope.gridApi.core.on.filterChanged( $scope, $scope.filter); + $scope.gridApi.core.on.sortChanged( $scope, $scope.sortChanged ); + $scope.sortChanged($scope.gridApi.grid, [ $scope.gridOptionsAlarmLog.columnDefs[1] ] ); + + $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + $scope.paginationOptions.pageNumber = newPage; + $scope.paginationOptions.pageSize = pageSize; + getPage(); + }); + } +}; + + //stateobject + $scope.state={}; + $scope.state.filter=false; + $scope.state.sort=false; + $scope.state.lastfilter=null; + $scope.state.lastSort=null; + + $scope.maxCount=0; //value shown on screen + + + $scope.seekPage= function(page){ + if(!page){ //catch NaN values + page=1; + return; + } + $scope.gridApi.pagination.seek(parseInt(page)); + }; + + $scope.paginationStatusMessage = function() { + + var startnum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1; + var pagenednum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1+$scope.data.length; + if(pagenednum>$scope.gridOptionsAlarmLog.totalItems) pagenednum=pagenednum-1; //reduce by initial added 1 + + if($scope.state.filter){ + var filterTpl = 'Showing {0} to {1} of {2} items (filtered from {3} total items)'; + return filterTpl.format(startnum, pagenednum, $scope.gridOptionsAlarmLog.totalItems, $scope.maxCount); + + } else { + var defaultTpl = 'Showing {0} to {1} of {2} total items'; + return defaultTpl.format( startnum, pagenednum, $scope.maxCount); + } + }; + +//list visible on screen + $scope.data = []; + + var getPage = function() { + //from, how many, sort, filter + getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize, $scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter) + .then(function (data) { + $scope.gridOptionsAlarmLog.totalItems = data.data.hits.total; + processResponseRecreateList(data); + }); + }; + + //filter + $scope.filter = function() + { + var grid = this.grid; + var columns=[]; + + //get all columns where data was typed in + angular.forEach(grid.columns, function(value, key) { + if(value.filters[0].term) { + var col=findColumn(value.displayName); + if(col==="fault.timeStamp"){ + //convert timestamp to db format + var timestamp= $mwtnFault.TimeStampToONFFormat(value.filters[0].term); + columns.push({ column: col ,value: timestamp }); + } + else + columns.push({ column: col ,value: value.filters[0].term }); //create column object + } + }); + + if(columns.length === 0){ //all filter data cleared away + $scope.state.filter=false; + $scope.state.lastfilter=null; + + //get unfiltered data + getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) { + if (response.data.hits.hits) { + processResponseRecreateList(response); + + } + }); + + }else{ + //base filter string + var filter={"query":{"bool":{"must":[]}}}; + + //create filter objects + var prefixs=[]; + for(var obj of columns){ + var prefixObj={}; + prefixObj[obj.column]=obj.value;//add like: {column: "fault.counter", value: "1"} => {"fault.counter":1} + prefixs.push({prefix:prefixObj}); // => {"prefix":{...}} + } + + //add objects to must property + filter.query.bool.must=prefixs; + + //save filter + $scope.state.lastfilter=filter; + $scope.state.filter=true; + + //send data to sdnevents/faultlog/_search + getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) { + if (response.data.hits.total>0) { //only, when hits exist + processResponseRecreateList(response); + $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; + }else{ + //clear data from list + $scope.data=[]; + $scope.gridOptionsAlarmLog.totalItems =0; + $scope.state.filter=false; + $scope.state.lastfilter=null; + } + }); + } +}; + + //sort + + $scope.sortChanged=function(grid, sortColumns){ // sortColumns is an array containing just the column sorted in the grid + + + if(sortColumns.length>0){ + if(sortColumns[0].sort){ + var name = sortColumns[0].displayName; // the name of the column sorted + var direction = sortColumns[0].sort.direction; // the direction of the column sorted: "desc" or "asc" + sort(direction,findColumn(name)); + } + }else{ + $scope.state.sort=false; + $scope.state.lastSort=null; + + //get unsorted data + getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) { + if (response.data.hits.hits) { + processResponseRecreateList(response); + } + }); + } + }; + + function sort(direction, columnName){ + + var sortObj={}; + var sort = [ sortObj]; + switch(direction) { + case uiGridConstants.ASC: + + //create sort object + sortObj[columnName]={order : 'asc'}; + sort = [ sortObj]; + //save last sort + $scope.state.lastSort=sort; + + getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) { + if (response.data.hits.hits) { + processResponseRecreateList(response); + $scope.state.sort=true; + } + }); + + break; + + case uiGridConstants.DESC: + + sortObj[columnName]={order : 'desc'}; + sort = [ sortObj]; + $scope.state.lastSort=sort; + + getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) { + if (response.data.hits.hits) { + processResponseRecreateList(response); + $scope.state.sort=true; + } + }); + break; + + case undefined: + + $scope.state.sort=false; + $scope.state.lastSort=null; + + getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter) + .then(function(response) { + if (response.data.hits.hits) { + processResponseRecreateList(response); + } + }); + + break; + } + } + + var findColumn = function(name) { + + if(name==="Timestamp"){ return "fault.timeStamp"; } + else if(name==="Node name"){ return "fault.nodeName"; } + else if(name==="Counter"){ return "fault.counter"; } + else if(name==="Object Id"){ return "fault.objectId"; } + else if(name==="Alarm type"){return "fault.problem"; } + else if(name==="Severity"){ return "fault.severity"; } + + }; + + var getData = function(from, size, sort, query){ + if(sort === null){ //default sort value + sort = [ { "fault.timeStamp" : {order : 'desc'}}]; + } + if(query === null){ //default filter value + query= {match_all: {}}; + } + return $mwtnFault.getFilteredSortedData(from, size, sort, query); + }; + + var processResponseAddToList=function(response) { + if (response.data.hits.hits) { + response.data.hits.hits.map(function(entry){ + var log = { + id: entry._id, + icon: getIconFromSeverity(entry._source.fault.severity), + timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp), + node: entry._source.fault.nodeName, + counter: entry._source.fault.counter, + object: entry._source.fault.objectId, + problem: entry._source.fault.problem, + severity: entry._source.fault.severity, + }; + + $scope.data.push(log); + }); + + $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update! + if($scope.maxCount<response.data.hits.total){ + $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering) + } + }}; + + function processResponseRecreateList(response){ + var list=[]; + response.data.hits.hits.map(function(entry){ + var log = { + id: entry._id, + icon: getIconFromSeverity(entry._source.fault.severity), + timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp), + node: entry._source.fault.nodeName, + counter: entry._source.fault.counter, + object: entry._source.fault.objectId, + problem: entry._source.fault.problem, + severity: entry._source.fault.severity, + }; + + list.push(log); + }); + $scope.data=list; + $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update! + if($scope.maxCount<response.data.hits.total){ + $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering) + } + } + + $scope.refreshLog = function() { + + var from = ($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize; + var size = $scope.paginationOptions.pageSize; + $scope.processing = true; + getData(from, size,$scope.state.lastSort,$scope.state.lastfilter).then(function(logEntries){ + $scope.processing = false; + $scope.spinner.alarmLog = false; + processResponseRecreateList(logEntries); + + }, function(error){ + $scope.processing = false; + $scope.spinner.alarmLog = false; + console.error(JSON.stringify(error)); + }); + }; + + // [sko] TODO check from here on + $scope.progress = { + show: true + }; + + $scope.clearLog = function () { + + var modalInstance = $uibModal.open({ + animation: true, + ariaLabelledBy: 'modal-title', + ariaDescribedBy: 'modal-body', + templateUrl: 'src/app/mwtnFault/templates/clearLogConfirmation.tpl.html', + controller: 'ClearFaultLogCtrl', + size: 'lg', + resolve: { + now: function () { + var onfDateAndTime = new Date().toISOString().replace(/-/g, '').replace(/T/g, '').replace(/:/g, '').substring(0,16) + 'Z'; + return {timestamp: onfDateAndTime}; + } + } + }); + + modalInstance.result.then(function (now) { + var spec = { + functionId : 'sdnevents', + docType : 'faultlog', + query: { + match_all: {} + } + }; + $mwtnFault.deleteDocType(spec).then(function(deleted){ + //set all to 'null' (empty) + $scope.data = []; + $scope.maxCount=0; + $scope.gridOptionsAlarmLog.totalItems=0; + + $timeout( function() { $scope.refreshLog(); getPage(); }, 1000); + + $mwtnLog.info({component: COMPONENT, message: 'Fault log cleared!'}); + }, function(error){ + $mwtnLog.error({component: COMPONENT, message:JSON.stringify(error)}); + }); + }, function () { + $mwtnLog.info({component: COMPONENT, message: 'Clear fault log dismissed!'}); + }); + }; + + + // UI events + $scope.status = {currentProblemList: true}; + $scope.spinner = {currentProblemList: false}; + $scope.$watch('status', function(status, oldValue) { + Object.keys(status).map(function(key){ + if (status[key] !== oldValue[key]) { + $scope.spinner[key] = status[key]; + + switch (key) { + case 'currentProblemList': + if (status[key]) { + $scope.refreshCurrentProblemList(); + } + break; + case 'alarmNotifications': + $scope.spinner[key] = false; + break; + case 'alarmLog': + $scope.refreshLog(); + break; + default: + $mwtnLog.error({component: COMPONENT, message: key + ' is not implemented!'}); + } + } + }); + }, true); + + // init + $scope.refreshCurrentProblemList(); + + getPage(); + + }]); + + mwtnFaultApp.register.controller('ClearFaultLogCtrl', ['$scope', '$uibModalInstance', '$mwtnFault', 'now', + function ($scope, $uibModalInstance, $mwtnFault, now) { + + $scope.now = $mwtnFault.formatTimeStamp(now.timestamp); + $scope.processing = false; + + $scope.ok = function () { + $uibModalInstance.close(now); + $scope.processing = true; + }; + + $scope.cancel = function () { + $uibModalInstance.dismiss(); + }; + }]); + +}); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js new file mode 100644 index 00000000..ef1c3897 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +define([ 'app/mwtnCommons/mwtnCommons.module'], function(mwtnCommonsApp) { + mwtnCommonsApp.register.directive('alarmStatus', function() { + return { + restrict : 'E', + templateUrl : 'src/app/mwtnFault/templates/alarmStatus.tpl.html', + controller : ['$scope', '$mwtnCommons', '$mwtnDatabase', '$timeout', function($scope, $mwtnCommons, $mwtnDatabase, $timeout){ + + $scope.link = '#/pnfFault/'; + + $scope.nodeCount = 0; + + $scope.alarmStatus = { + Critical:0, + Major:0, + Minor:0, + Warning:0, + }; + + $scope.getAlarmStatusSum = function(){ + var sum = 0; + Object.keys($scope.alarmStatus).map(function(severity) { + sum = sum + $scope.alarmStatus[severity]; + }); + return sum; + }; + + // Update: request the number of alarms in current alarm list per severity + var update = function() { + $mwtnCommons.getMountPoints().then(function(mountpoints) { + $scope.nodeCount = mountpoints.filter(function(mountpoint) { + return mountpoint['netconf-node-topology:connection-status'] === 'connected'; + }).length; + }); + var functionId = 'sdnevents'; + var docType = 'faultcurrent'; + var aggregations = { + "size":0, + "aggregations": { + "severity": { + "terms": { + "field": "faultCurrent.severity" + } + } + } + }; + $mwtnDatabase.getAggregations(functionId, docType, aggregations).then(function (success) { + var found = success.data.aggregations['severity'].buckets.map(function(bucket){ + $scope.alarmStatus[bucket.key] = bucket.doc_count; + return bucket.key; + }); + Object.keys($scope.alarmStatus).map(function(key){ + if (!found.contains(key)) { + $scope.alarmStatus[key] = 0; + } + }); + }, function (error) { + console.error(error); + $scope.alarmStatus = { + Critical:0, + Major:0, + Minor:0, + Warning:0, + }; + }); + + + // Object.keys($scope.alarmStatus).map(function(severity) { + // // usage of the ElasticSearch Count API + // $mwtnDatabase.getBase('sdnevents').then(function(success) { + // var databaseRequest = { + // base : success.base, + // method : 'POST', + // command: '_count', + // index: success.index, + // docType: 'faultcurrent', + // query: { + // match: { + // 'faultCurrent.severity': severity + // } + // } + // }; + // $mwtnDatabase.genericRequest(databaseRequest).then(function(success){ + // $scope.alarmStatus[severity] = success.data.count; + // }, function(error){ + // console.error('severity', severity, error); + // }); + // }, function(error) { + // console.error('severity', severity, error); + // }); + // }); + }; + update(); + + var listenToNotifications = function() { + $mwtnCommons.getMwtnWebSocketUrl().then(function(success){ + try { + var notificationSocket = new WebSocket(success); + + notificationSocket.onmessage = function(event) { + // we process our received event here + if (typeof event.data === 'string') { + // console.log('Client Received:\n', event.data); + $mwtnCommons.formatData(event).then(function(formated) { + switch (formated.notifType) { + case 'ProblemNotification': + $timeout(function(){update();}, 500); + break; + case 'AttributeValueChangedNotification': + case 'ObjectCreationNotification': + case 'ObjectDeletionNotification': + // ignore + break; + default: + console.error('Missing implementation for', formated.notifType); + } + }, function(error) { + // do nothing + }); + } + }; + + notificationSocket.onerror = function(error) { + console.log("Socket error: " + error); + }; + + notificationSocket.onopen = function(event) { + console.log("Socket connection opened."); + function subscribe() { + if (notificationSocket.readyState === notificationSocket.OPEN) { + var data = { + 'data' : 'scopes', + 'scopes' : [ "ProblemNotification" ] + }; + notificationSocket.send(JSON.stringify(data)); + } + } + subscribe(); + }; + + notificationSocket.onclose = function(event) { + console.log("Socket connection closed."); + }; + } catch (e) { + console.error("Error when creating WebSocket.\n" + e); + } + }, function(error){ + console.error("Error when creating WebSocket.\n" + error); + }); + }; + listenToNotifications(); + }] + }; + }); + +});
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js new file mode 100644 index 00000000..0da8e76d --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +define(['angularAMD', + 'app/routingConfig', + 'app/core/core.services', + 'common/config/env.module', + 'app/mwtnCommons/mwtnCommons.module'], function(ng) { + var mwtnFaultApp = angular.module('app.mwtnFault', ['ui.grid', 'ui.bootstrap', 'app.core', + 'ui.router.state', 'config', 'ui.grid.exporter', + 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection', + 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]); + + mwtnFaultApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) { + mwtnFaultApp.register = { + controller : $controllerProvider.register, + directive : $compileProvider.directive, + factory : $provide.factory, + service : $provide.service + }; + + + NavHelperProvider.addControllerUrl('app/mwtnFault/mwtnFault.controller'); + NavHelperProvider.addToMenu('mwtnFault', { + "link" : "#/pnfFault/", + "active" : "main.mwtnFault", + "title" : "pnf Fault", + "icon" : "fa fa-bell", // Add navigation icon css class here + "page" : { + "title" : "pnf Fault", + "description" : "mwtnFault" + } + }); + + var access = routingConfig.accessLevels; + + $stateProvider.state('main.mwtnFault', { + url: 'pnfFault/:nodeId', + access: access.admin, + views : { + 'content' : { + templateUrl: 'src/app/mwtnFault/mwtnFault.tpl.html', + controller: 'mwtnFaultCtrl' + } + } + }); + + }); + + return mwtnFaultApp; +}); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js new file mode 100644 index 00000000..f07e4d04 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +define(['app/mwtnFault/mwtnFault.module','app/mwtnCommons/mwtnCommons.services'],function(mwtnFaultApp) { + + mwtnFaultApp.register.factory('$mwtnFault', function($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) { + + var service = {}; + + service.checkModules = $mwtnCommons.checkModules; + service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl; + service.gridOptions = $mwtnCommons.gridOptions; + service.formatData = $mwtnCommons.formatData; + service.formatTimeStamp = $mwtnCommons.formatTimeStamp; + service.deleteDocType = $mwtnDatabase.deleteDocType; + + + service.TimeStampToONFFormat=function(timestamp){ + + timestamp=timestamp.split('-').join(''); + timestamp=timestamp.split(':').join(''); + timestamp=timestamp.split(' ').join(''); + timestamp=timestamp.replace('UTC','Z'); + return timestamp; + }; + + service.getAllLogEntries = function(from, size) { + var sort = [ { + "fault.timeStamp" : { + order : 'desc' + } + }]; + var deferred = $q.defer(); + $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){ + deferred.resolve(success); + }, function(error){ + $mwtnLog.error({component: '$mwtnFault.getAllLogEntries', message: JSON.stringify(error.data)}); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getAllLogEntriesWithSort= function(from, size, sort){ + var deferred = $q.defer(); + $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){ + deferred.resolve(success); + }, function(error){ + $mwtnLog.error({component: '$mwtnFault.getAllLogEntries', message: JSON.stringify(error.data)}); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getFilteredSortedData=function(from, size, sort,query){ + var deferred = $q.defer(); + $mwtnDatabase.getFilteredSortedData('sdnevents', 'faultlog', from, size,sort, query).then(function(success){ + deferred.resolve(success); + }, function(error){ + $mwtnLog.error({component: '$mwtnFault.getFilteredSortedData', message: JSON.stringify(error.data)}); + deferred.reject(error); + }); + return deferred.promise; + + }; + + service.getFilteredData= function(from, size, query){ + var deferred = $q.defer(); + $mwtnDatabase.getFilteredData('sdnevents', 'faultlog', from, size, query).then(function(success){ + deferred.resolve(success); + }, function(error){ + $mwtnLog.error({component: '$mwtnFault.getFilteredData', message: JSON.stringify(error.data)}); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getAllCurrentProblemEntries = function(from, size) { + var sort = [ { + "faultCurrent.timeStamp" : { + order : 'desc' + } + }]; + var deferred = $q.defer(); + $mwtnDatabase.getAllData('sdnevents', 'faultcurrent', from, size, sort).then(function(success){ + deferred.resolve(success); + }, function(error){ + $mwtnLog.error({component: '$mwtnFault.getAllCurrentLogEntries', message: JSON.stringify(error.data)}); + deferred.reject(error); + }); + return deferred.promise; + }; + + return service; + }); +}); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html new file mode 100644 index 00000000..dd23d262 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html @@ -0,0 +1,119 @@ +<ht-header help-link='sdnr/pnfFault/0.4.0/README.md'></ht-header> +<div class="mwtnError">{{error}}</div> + +<uib-accordion close-others="oneATime"> + +<div uib-accordion-group class="panel-primary" is-open="status.currentProblemList"> + <uib-accordion-heading> <i class="pull-left fa" + ng-class="{'fa-chevron-down': status.currentProblemList, 'fa-chevron-right': !status.currentProblemList}"></i> + <span>{{'MWTN_CURRENT_PROBLEM_LIST' | translate}} + ({{gridOptionsCurrentProblemList.data.length}})</span> + <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.currentProblemList"></i> + </uib-accordion-heading> + + + <div id="mwtnFaultGridCurrentProblemList" ui-grid="gridOptionsCurrentProblemList" ui-grid-exporter + ui-grid-selection ui-grid-pinning ui-grid-resize-columns + ui-grid-move-columns class="mwtnFaultGrid"></div> +</div> + +<div uib-accordion-group class="panel-primary" is-open="status.alarmNotifications"> + <uib-accordion-heading> <i class="pull-left fa" + ng-class="{'fa-chevron-down': status.alarmNotifications, 'fa-chevron-right': !status.alarmNotifications}"></i> + <span>{{'MWTN_ALARM_NOTIFICATIONS' | translate}} + ({{gridOptionsAlarmNotifications.data.length}} since {{date}})</span> + <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.alarmNotifications"></i> + </uib-accordion-heading> + + + <div id="mwtnFaultGridAlarmNotifications" ui-grid="gridOptionsAlarmNotifications" + ui-grid-exporter ui-grid-selection ui-grid-pinning + ui-grid-resize-columns ui-grid-move-columns class="mwtnFaultGrid"></div> +</div> + +<div uib-accordion-group class="panel-primary" is-open="status.alarmLog"> + <uib-accordion-heading> <i class="pull-left fa" + ng-class="{'fa-chevron-down': status.alarmLog, 'fa-chevron-right': !status.alarmLog}"></i> + <span>{{'MWTN_ALARM_LOG' | translate}} + ({{maxCount}})</span> + <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.alarmLog"></i> + </uib-accordion-heading> + + <div id="mwtnFaultGridAlarmLog" + ui-grid="gridOptionsAlarmLog" + ui-grid-pagination + ui-grid-exporter + ui-grid-selection + ui-grid-pinning + ui-grid-resize-columns + ui-grid-move-columns class="mwtnFaultGrid"> + </div> + + <div class="ht-pagination"> + <button class="btn btn-default" + ng-disabled="paginationOptions.pageNumber === 1" + ng-click="gridApi.pagination.seek(1)" + ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}" + role="menuitem" type="button" title="Page to first" aria-label="Page to first"> + <i class="fa fa-step-backward "></i> + </button> + <button class="btn btn-default" + ng-disabled="paginationOptions.pageNumber === 1" + ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}" + ng-click="gridApi.pagination.previousPage()" + + role="menuitem" type="button" title="Previous Page" aria-label="Previous Page"> + <i class="fa fa-play fa-rotate-180 "></i> + </button> + <input class="btn btn-default" style="text-align:right;" border="1" + ng-model="gridOptionsAlarmLog.paginationCurrentPage" + ng-change="seekPage(gridOptionsAlarmLog.paginationCurrentPage)" + type="number" style="width:20px;"/> + <span class="dark"> / {{ gridApi.pagination.getTotalPages() }}</span> + + <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page" + ng-disabled="gridOptionsAlarmLog.paginationCurrentPage === gridApi.pagination.getTotalPages()" + ng-click="gridApi.pagination.nextPage()"> + <i class="fa fa-play "></i> + </button> + <button class="btn btn-default" ng-disabled="gridOptionsAlarmLog.paginationCurrentPage === gridApi.pagination.getTotalPages()" + ng-click="gridApi.pagination.seek(gridApi.pagination.getTotalPages())" + role="menuitem" type="button" title="Page to last" aria-label="Page to last"> + <i class="fa fa-step-forward "></i> + </button> + + <select + class="btn btn-default" name="repeatSelect" id="repeatSelect" + ng-init="gridOptionsAlarmLog.paginationPageSize = gridOptionsAlarmLog.paginationPageSizes[0]" + ng-model="gridOptionsAlarmLog.paginationPageSize" + ng-options="option for option in gridOptionsAlarmLog.paginationPageSizes"></select> + + <span class="dark"> items per page </span> + + <span class="pull-right dark">{{ paginationStatusMessage() }}</span> + + </div> + + <div class="text-right"> + <button type="button" id="clearLog" class="btn btn-warning" ng-click="clearLog()"> + <i class="fa fa-times" aria-hidden="true"></i> + <span>Clear log...</span> + </button> + <!-- + see gird menu Export ... + <button type="button" id="saveLog" class="btn btn-default" ng-click="saveLog()"> + <i class="fa fa-save" aria-hidden="true"></i> + <span>Save...</span> + </button> --> + <button type="button" id="refreshLog" class="btn btn-primary" ng-click="refreshLog()"> + <span>{{'MWTN_REFRESH' | translate}}</span> + </button> + </div> + + </div> +</uib-accordion> + +<hr /> +<div class="owl"> + <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html new file mode 100644 index 00000000..b57a614c --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html @@ -0,0 +1,21 @@ +<div class="text-right margin5 mwtn global-alarm-status"> + <a href="{{link}}" title="{{'MWTN_NODES' | translate}}"> + <span>{{ 'MWTN_NODES' | translate }}:</span> + <i class="fa fa-link cleared" aria-hidden="true"></i> + <span> {{nodeCount}} </span> + <span> || </span> + </a> + <a href="{{link}}" title="{{'MWTN_NODES' | translate}}"> + <span>{{ 'MWTN_ALARM_STATUS' | translate }}:</span> + </a> + <a href="{{link}}" ng-repeat="(key, value) in alarmStatus" title="{{key}}"> + <span ng-show="$index !== 0"> | </span> + <i class="fa fa-exclamation-triangle" ng-class="{ {{key}} : value !== 0, 'cleared': value === 0}" aria-hidden="true" ></i> + <span> {{value}} </span> + </a> + <a href="{{link}}" title="{{key}}"> + <span> | </span> + <span>{{ 'MWTN_SUM' | translate }}: </span> + <span> {{getAlarmStatusSum()}} </span> + </a> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html new file mode 100644 index 00000000..3e58a3a4 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html @@ -0,0 +1,17 @@ + +<div class="modal-header"> + <h3 class="modal-title" id="modal-title">{{'Clear Log Confirmation' | translate}}</h3> +</div> +<div class="modal-body" id="modal-body"> + <p> + <span>All alarm log entries will be deleted.</span> + </p> + <p>Please make sure, you have exported the log entries, otherwise they will get lost.</p> +</div> +<div class="modal-footer"> + <button class="btn btn-primary" type="button" ng-click="ok()"> + <i class="pull-left fa fa-spinner fa-pulse" ng-show="processing"></i> + <span>{{'Clear log' | translate}}</span> + </button> + <button class="btn btn-warning" type="button" ng-click="cancel()">{{'Cancel' | translate}}</button> +</div>
\ No newline at end of file |