diff options
Diffstat (limited to 'sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main')
17 files changed, 6863 insertions, 0 deletions
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/README.md b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/README.md new file mode 100644 index 00000000..3c254917 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/README.md @@ -0,0 +1,34 @@ +# MTWN Comments + +This component offers services for MTWN specific ODL DLUX application development. +It should ensure, that common functionality of ODL DLUX applications is implemented and tested only once, but reused by several applications. + +All MWTN ODL DLUX application should have a dependency to 'mtwnCommons'. +However, it is a case by case decision by developers, whether such dependency is needed for their application of not. + +Common functions are: +* A centralized service ($mwtnLog), which stores application logs in a centralized database. It should simplify failure analysis and debugging. +* Communication with the RestConf API of OpenDaylight. +* WebSocket subscription for notification handling +* Implementation of common object classes as defined by the Microwave Information model (e.g. NetConfServer, NetworkElement, LogicalTerminationPoint, LayerProtocol, MW_AirInterface_Pac, MW_PureEthernetStructure_Pac, MW_EthernetContainer_Pac) +* Enhanced [angular.js](https://angularjs.org/) features for web development, which are not native in [ODL DLUX](https://wiki.opendaylight.org/view/OpenDaylight_dlux:Main). + +## Installation + +Additional [angular.js](https://angularjs.org/) feature and implementations are listed in the file [bower.json](./bower.json). + +``` +bower install +``` +Please see [bower.io](https://bower.io/) for further information about bower. + +## angular-chart.js + +* Open app/mwtnCommons/bower_components/angular-chart.js/dist/angular-chart +* Locate + else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['angular', 'chart'], factory); + } + + * change define(['angular', 'chart'], factory); to define(['angular', 'app/mwtnCommons/bower_components/chart.js/dist/Chart'], factory); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower.json b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower.json new file mode 100644 index 00000000..77aed945 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower.json @@ -0,0 +1,39 @@ +{ + "name": "mwtn-commons", + "homepage": "https://github.com/OpenNetworkingFoundation/CENTENNIAL/tree/master/03-WTP-PoC/code", + "authors": [ + "Martin Skorupski <martin.skorupski@highstreet-technologies.com>" + ], + "description": "bower components for microwave transport network specific opendaylight dlux applications", + "main": "", + "version": "0.5.1-SNAPSHOT", + "dependencies": { + "bootstrap": "~3.3.7", + "font-awesome": "~4.6.3", + "angular-ui-grid": "3.2.9", + "angular-clipboard": "~1.5.0", + "angular-chart.js": "~1.1.1", + "chart.js": "^2.5.0", + "lodash": "^4.17.4", + "json-formatter": "^0.6.0", + "cytoscape": "^3.1.1" + }, + "keywords": [ + "Microwave", + "Millimeterwave", + "MWTN", + "ONF", + "SDN", + "Transport", + "Wireless", + "xHaul" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bowerInstall.sh b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bowerInstall.sh new file mode 100755 index 00000000..054cf683 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bowerInstall.sh @@ -0,0 +1,18 @@ +echo "---------------------------------" +echo "Install bower and adapt to ODL UX" +echo "---------------------------------" +echo "Step1: Install bower" +bower install -q + +echo "Step2: Install Bower patches to adapt to ODL-DLUX" + +FileToPatch="angular-chart.js" +FileToPatchDestination="bower_components/angular-chart.js/dist" +FileToPatchOrigination="bower_components_patches" + +echo "- File to handle: $FileToPatch" +mv $FileToPatchDestination/$FileToPatch $FileToPatchDestination/$FileToPatch.orig +cp $FileToPatchOrigination/$FileToPatch.patch $FileToPatchDestination +mv $FileToPatchDestination/$FileToPatch.patch $FileToPatchDestination/$FileToPatch + +echo "Install bower script ends" diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower_components_patches/angular-chart.js.patch b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower_components_patches/angular-chart.js.patch new file mode 100644 index 00000000..23a4b361 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower_components_patches/angular-chart.js.patch @@ -0,0 +1,400 @@ +/*! + * angular-chart.js - An angular.js wrapper for Chart.js + * http://jtblin.github.io/angular-chart.js/ + * Version: 1.1.1 + * + * Copyright 2016 Jerome Touffe-Blin + * Released under the BSD-2-Clause license + * https://github.com/jtblin/angular-chart.js/blob/master/LICENSE + */ +(function (factory) { + 'use strict'; + if (typeof exports === 'object') { + // Node/CommonJS + module.exports = factory( + typeof angular !== 'undefined' ? angular : require('angular'), + typeof Chart !== 'undefined' ? Chart : require('chart.js')); + } else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['angular', 'app/mwtnCommons/bower_components/chart.js/dist/Chart'], factory); + } else { + // Browser globals + if (typeof angular === 'undefined') { + throw new Error('AngularJS framework needs to be included, see https://angularjs.org/'); + } else if (typeof Chart === 'undefined') { + throw new Error('Chart.js library needs to be included, see http://jtblin.github.io/angular-chart.js/'); + } + factory(angular, Chart); + } +}(function (angular, Chart) { + 'use strict'; + + Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>'; + Chart.defaults.global.tooltips.mode = 'label'; + Chart.defaults.global.elements.line.borderWidth = 2; + Chart.defaults.global.elements.rectangle.borderWidth = 2; + Chart.defaults.global.legend.display = false; + Chart.defaults.global.colors = [ + '#97BBCD', // blue + '#DCDCDC', // light grey + '#F7464A', // red + '#46BFBD', // green + '#FDB45C', // yellow + '#949FB1', // grey + '#4D5360' // dark grey + ]; + + var useExcanvas = typeof window.G_vmlCanvasManager === 'object' && + window.G_vmlCanvasManager !== null && + typeof window.G_vmlCanvasManager.initElement === 'function'; + + if (useExcanvas) Chart.defaults.global.animation = false; + + return angular.module('chart.js', []) + .provider('ChartJs', ChartJsProvider) + .factory('ChartJsFactory', ['ChartJs', '$timeout', ChartJsFactory]) + .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }]) + .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('line'); }]) + .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bar'); }]) + .directive('chartHorizontalBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('horizontalBar'); }]) + .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('radar'); }]) + .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('doughnut'); }]) + .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('pie'); }]) + .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('polarArea'); }]) + .directive('chartBubble', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bubble'); }]) + .name; + + /** + * Wrapper for chart.js + * Allows configuring chart js using the provider + * + * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) { + * ChartJsProvider.setOptions({ responsive: false }); + * ChartJsProvider.setOptions('Line', { responsive: true }); + * }))) + */ + function ChartJsProvider () { + var options = { responsive: true }; + var ChartJs = { + Chart: Chart, + getOptions: function (type) { + var typeOptions = type && options[type] || {}; + return angular.extend({}, options, typeOptions); + } + }; + + /** + * Allow to set global options during configuration + */ + this.setOptions = function (type, customOptions) { + // If no type was specified set option for the global object + if (! customOptions) { + customOptions = type; + options = angular.merge(options, customOptions); + } else { + // Set options for the specific chart + options[type] = angular.merge(options[type] || {}, customOptions); + } + + angular.merge(ChartJs.Chart.defaults, options); + }; + + this.$get = function () { + return ChartJs; + }; + } + + function ChartJsFactory (ChartJs, $timeout) { + return function chart (type) { + return { + restrict: 'CA', + scope: { + chartGetColor: '=?', + chartType: '=', + chartData: '=?', + chartLabels: '=?', + chartOptions: '=?', + chartSeries: '=?', + chartColors: '=?', + chartClick: '=?', + chartHover: '=?', + chartDatasetOverride: '=?' + }, + link: function (scope, elem/*, attrs */) { + if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]); + + // Order of setting "watch" matter + scope.$watch('chartData', watchData, true); + scope.$watch('chartSeries', watchOther, true); + scope.$watch('chartLabels', watchOther, true); + scope.$watch('chartOptions', watchOther, true); + scope.$watch('chartColors', watchOther, true); + scope.$watch('chartDatasetOverride', watchOther, true); + scope.$watch('chartType', watchType, false); + + scope.$on('$destroy', function () { + destroyChart(scope); + }); + + scope.$on('$resize', function () { + if (scope.chart) scope.chart.resize(); + }); + + function watchData (newVal, oldVal) { + if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) { + destroyChart(scope); + return; + } + var chartType = type || scope.chartType; + if (! chartType) return; + + if (scope.chart && canUpdateChart(newVal, oldVal)) + return updateChart(newVal, scope); + + createChart(chartType, scope, elem); + } + + function watchOther (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + var chartType = type || scope.chartType; + if (! chartType) return; + + // chart.update() doesn't work for series and labels + // so we have to re-create the chart entirely + createChart(chartType, scope, elem); + } + + function watchType (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + createChart(newVal, scope, elem); + } + } + }; + }; + + function createChart (type, scope, elem) { + var options = getChartOptions(type, scope); + if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return; + + var cvs = elem[0]; + var ctx = cvs.getContext('2d'); + + scope.chartGetColor = getChartColorFn(scope); + var data = getChartData(type, scope); + // Destroy old chart if it exists to avoid ghost charts issue + // https://github.com/jtblin/angular-chart.js/issues/187 + destroyChart(scope); + + scope.chart = new ChartJs.Chart(ctx, { + type: type, + data: data, + options: options + }); + scope.$emit('chart-create', scope.chart); + bindEvents(cvs, scope); + } + + function canUpdateChart (newVal, oldVal) { + if (newVal && oldVal && newVal.length && oldVal.length) { + return Array.isArray(newVal[0]) ? + newVal.length === oldVal.length && newVal.every(function (element, index) { + return element.length === oldVal[index].length; }) : + oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false; + } + return false; + } + + function sum (carry, val) { + return carry + val; + } + + function getEventHandler (scope, action, triggerOnlyOnChange) { + var lastState = { + point: void 0, + points: void 0 + }; + return function (evt) { + var atEvent = scope.chart.getElementAtEvent || scope.chart.getPointAtEvent; + var atEvents = scope.chart.getElementsAtEvent || scope.chart.getPointsAtEvent; + if (atEvents) { + var points = atEvents.call(scope.chart, evt); + var point = atEvent ? atEvent.call(scope.chart, evt)[0] : void 0; + + if (triggerOnlyOnChange === false || + (! angular.equals(lastState.points, points) && ! angular.equals(lastState.point, point)) + ) { + lastState.point = point; + lastState.points = points; + scope[action](points, evt, point); + } + } + }; + } + + function getColors (type, scope) { + var colors = angular.copy(scope.chartColors || + ChartJs.getOptions(type).chartColors || + Chart.defaults.global.colors + ); + var notEnoughColors = colors.length < scope.chartData.length; + while (colors.length < scope.chartData.length) { + colors.push(scope.chartGetColor()); + } + // mutate colors in this case as we don't want + // the colors to change on each refresh + if (notEnoughColors) scope.chartColors = colors; + return colors.map(convertColor); + } + + function convertColor (color) { + // Allows RGB and RGBA colors to be input as a string: e.g.: "rgb(159,204,0)", "rgba(159,204,0, 0.5)" + if (typeof color === 'string' && color[0] === 'r') return getColor(rgbStringToRgb(color)); + // Allows hex colors to be input as a string. + if (typeof color === 'string' && color[0] === '#') return getColor(hexToRgb(color.substr(1))); + // Allows colors to be input as an object, bypassing getColor() entirely + if (typeof color === 'object' && color !== null) return color; + return getRandomColor(); + } + + function getRandomColor () { + var color = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)]; + return getColor(color); + } + + function getColor (color) { + var alpha = color[3] || 1; + color = color.slice(0, 3); + return { + backgroundColor: rgba(color, 0.2), + pointBackgroundColor: rgba(color, alpha), + pointHoverBackgroundColor: rgba(color, 0.8), + borderColor: rgba(color, alpha), + pointBorderColor: '#fff', + pointHoverBorderColor: rgba(color, alpha) + }; + } + + function getRandomInt (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function rgba (color, alpha) { + // rgba not supported by IE8 + return useExcanvas ? 'rgb(' + color.join(',') + ')' : 'rgba(' + color.concat(alpha).join(',') + ')'; + } + + // Credit: http://stackoverflow.com/a/11508164/1190235 + function hexToRgb (hex) { + var bigint = parseInt(hex, 16), + r = (bigint >> 16) & 255, + g = (bigint >> 8) & 255, + b = bigint & 255; + + return [r, g, b]; + } + + function rgbStringToRgb (color) { + var match = color.match(/^rgba?\(([\d,.]+)\)$/); + if (! match) throw new Error('Cannot parse rgb value'); + color = match[1].split(','); + return color.map(Number); + } + + function hasData (scope) { + return scope.chartData && scope.chartData.length; + } + + function getChartColorFn (scope) { + return typeof scope.chartGetColor === 'function' ? scope.chartGetColor : getRandomColor; + } + + function getChartData (type, scope) { + var colors = getColors(type, scope); + return Array.isArray(scope.chartData[0]) ? + getDataSets(scope.chartLabels, scope.chartData, scope.chartSeries || [], colors, scope.chartDatasetOverride) : + getData(scope.chartLabels, scope.chartData, colors, scope.chartDatasetOverride); + } + + function getDataSets (labels, data, series, colors, datasetOverride) { + return { + labels: labels, + datasets: data.map(function (item, i) { + var dataset = angular.extend({}, colors[i], { + label: series[i], + data: item + }); + if (datasetOverride && datasetOverride.length >= i) { + angular.merge(dataset, datasetOverride[i]); + } + return dataset; + }) + }; + } + + function getData (labels, data, colors, datasetOverride) { + var dataset = { + labels: labels, + datasets: [{ + data: data, + backgroundColor: colors.map(function (color) { + return color.pointBackgroundColor; + }), + hoverBackgroundColor: colors.map(function (color) { + return color.backgroundColor; + }) + }] + }; + if (datasetOverride) { + angular.merge(dataset.datasets[0], datasetOverride); + } + return dataset; + } + + function getChartOptions (type, scope) { + return angular.extend({}, ChartJs.getOptions(type), scope.chartOptions); + } + + function bindEvents (cvs, scope) { + cvs.onclick = scope.chartClick ? getEventHandler(scope, 'chartClick', false) : angular.noop; + cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop; + } + + function updateChart (values, scope) { + if (Array.isArray(scope.chartData[0])) { + scope.chart.data.datasets.forEach(function (dataset, i) { + dataset.data = values[i]; + }); + } else { + scope.chart.data.datasets[0].data = values; + } + + scope.chart.update(); + scope.$emit('chart-update', scope.chart); + } + + function isEmpty (value) { + return ! value || + (Array.isArray(value) && ! value.length) || + (typeof value === 'object' && ! Object.keys(value).length); + } + + function canDisplay (type, scope, elem, options) { + // TODO: check parent? + if (options.responsive && elem[0].clientHeight === 0) { + $timeout(function () { + createChart(type, scope, elem); + }, 50, false); + return false; + } + return true; + } + + function destroyChart(scope) { + if(! scope.chart) return; + scope.chart.destroy(); + scope.$emit('chart-destroy', scope.chart); + } + } +})); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/locale/locale-en_US.json b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/locale/locale-en_US.json new file mode 100644 index 00000000..eb0ef3b5 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/locale/locale-en_US.json @@ -0,0 +1,924 @@ +{ + + "PNF_NAME": "Name", + "PNF_IDENTIFIER":"Identifier", + "PNF_EQUIPMENT_TYPE":"Equipment type", + "PNF_EQUIPMENT_MODEL": "Equipment model", + "PNF_EQUIPMENT_VENDOR": "Equipment vendor", + "PNF_IPv4ADDRESS": "IPv4 address", + "PNF_MAINTENANCE_MODE": "Maintenace mode", + "PNF_CREATE_IN_AAI": "Create PNF in Active and Available Inventory", + "PNF_DELETE_IN_AAI": "Delete PNF in Active and Available Inventory", + "PNF_RESOURCE_VERSION": "Resource version", + + "MWTN_AMSL_GRD": "Above mean sea level (ground)", + "MWTN_APPCOMMAND": "Application command", + "MWTN_AIR_INTERFACE_LINKS": "Air interface links", + "MWTN_BAND": "Band", + "MWTN_CLIADDRESS": "CLI address", + "MWTN_CONNECTED_LTP_REF": "Connected LTP", + "MWTN_CURRENT_PROBLEMS": "Current problem list", + "MWTN_CURRENT_PERFORMANCE": "Current performance", + "MWTN_DURATION": "Duration", + "MWTN_END_TIME": "End time", + "MWTN_FORWARDING_DOMAIN": "Forwarding domain (ETH switch)", + "MWTN_FORWARDING_CONSTRUCTS":"Forwarding constructs", + "MWTN_FC": "Forwarding constructs", + "MWTN_FC_PORT#1": "Port #1", + "MWTN_FC_PORT#2": "Port #2", + "MWTN_FC_UUID": "Forwarding construct UUID", + "MWTN_FD_EX":"Extension", + "MWTN_HISTORICAL_PERFORMANCES": "Performance history", + "MWTN_HTMEDIATOR": "Has mediator", + "MWTN_INFORMATION_RATE_CUR":"Current infromation rate", + "MWTN_LAT_LON":"Lat/Lon", + "MWTN_LTP1":"LTP#1", + "MWTN_LTP2":"LTP#2", + "MWTN_LTPEXTENSION": "Extension", + "MWTN_LINK_IDENTIFIER": "Link identifier", + "MWTN_LINKS": "Links", + "MWTN_LOWER_LEVEL_LINK": "Lower level link", + "MWTN_LOOP_BACK_IS_AVAIL": "Loopback support", + "MWTN_LOOP_BACK_IS_ON": "Loop-back is on", + "MWTN_LOOP_BACK_IS_UP": "Loopback", + "MWTN_MED_ADD": "Add", + "MWTN_MED_START":"Start", + "MWTN_MED_STOP":"Stop", + "MWTN_MED_CLOSE":"Close", + "MWTN_MED_DELETE":"Delete", + "MWTN_NEIPADDRESS": "IP address", + "MWTN_NEEXTENSION": "Extension", + "MWTN_NE_EXTENSION":"Extension", + "MWTN_NETYPE": "Network element type", + "MWTN_ONF_PTP_DATASET:MULTICAST_MAC_ADDRESS": "Multicast MAC address", + "MWTN_ONF_PTP_DATASET:MAX_STEPS_REMOVED": "Max. steps removed", + "MWTN_PEER_LTP_REF": "Peer LTP", + "MWTN_PHYSICAL_PORT_REFERENCE": "Physical port", + "MWTN_PTP_DEFAULT_DS_CONFIGURATION": "PTP default dataset configuration", + "MWTN_PTP_PORT_CONFIGURATION":"PTP port configuration", + "MWTN_RADIO": "Radio", + "MWTN_REQUIRED_NETWORK_ELEMENTS": "Required network elements", + "MWTN_REVISION": "Revision", + "MWTN_ROOTEQUIPMENT": "Equipment", + "MWTN_SERVICE_ID":"Service ID", + "MWTN_SCANNING": "Scanning...", + "MWTN_SCAN_NETWORK": "Scan network", + "MWTN_START_TIME": "Start time", + "MWTN_SITE_ID": "Site identifier", + "MWTN_SITE_NAME": "Site-name", + "MWTN_SUPPORTED_LOOP_BACK_KIND_LIST":"Supported loopback types", + "MWTN_STATUS": "Status", + "MWTN_TOP_LEVEL_EQUIPMENT":"Main equipment", + "MWTN_TYPE": "Type", + "MWTN_UNKNOWN_NETWORK_ELEMENTS": "Unknown network elements", + "MWTN_VEXTENSION": "Extension", + "MWTN_WEBURI": "Web UI", + + "MWTN_$$HASHKEY": "Key", + "MWTN_ACTION_VERB": "action-verb", + "MWTN_ACTUAL_EQUIPMENT": "actual-equipment", + "MWTN_ACTUAL_HOLDER": "actual-holder", + "MWTN_ADAPTIVEMODULATIONISAVAIL": "adaptiveModulationIsAvail", + "MWTN_ADAPTIVEMODULATIONISON": "adaptiveModulationIsOn", + "MWTN_ADAPTIVE_MODULATION_IS_AVAIL": "adaptive-modulation-is-avail", + "MWTN_ADAPTIVE_MODULATION_IS_ON": "adaptive-modulation-is-on", + "MWTN_ADDRESS_ELEMENT": "address-element", + "MWTN_ADDRESS_ELEMENT_NAME": "address-element-name", + "MWTN_ADDRESS_NAME": "address-name", + "MWTN_ADD_TO_REQUIRED_NETWORKELEMENTS": "Add to required Network Elements", + "MWTN_ADMINISTRATIVECONTROL": "administrativeControl", + "MWTN_ADMINISTRATIVESTATE": "administrativeState", + "MWTN_ADMINISTRATIVE_CONTROL": "administrative-control", + "MWTN_ADMINISTRATIVE_STATE": "administrative-state", + "MWTN_AGGREGATE_FUNCTION": "aggregate-function", + "MWTN_AIRINTERFACECAPABILITY": "airInterfaceCapability", + "MWTN_AIRINTERFACECONFIGURATION": "AirInterfaceConfiguration", + "MWTN_AIRINTERFACECURRENTPERFORMANCE": "AirInterfaceCurrentPerformance", + "MWTN_AIRINTERFACECURRENTPROBLEMS": "airInterfaceCurrentProblems", + "MWTN_AIRINTERFACEDIVERSITY": "airInterfaceDiversity", + "MWTN_AIRINTERFACEDIVERSITYCAPABILITY": "airInterfaceDiversityCapability", + "MWTN_AIRINTERFACEDIVERSITYCONFIGURATION": "airInterfaceDiversityConfiguration", + "MWTN_AIRINTERFACEDIVERSITYCURRENTPERFORMANCE": "AirInterfaceDiversityCurrentPerformance", + "MWTN_AIRINTERFACEDIVERSITYCURRENTPROBLEMS": "AirInterfaceDiversityCurrentProblems", + "MWTN_AIRINTERFACEDIVERSITYHISTORICALPERFORMANCES": "airInterfaceDiversityHistoricalPerformances", + "MWTN_AIRINTERFACEDIVERSITYSTATUS": "AirInterfaceDiversityStatus", + "MWTN_AIRINTERFACEHISTORICALPERFORMANCES": "airInterfaceHistoricalPerformances", + "MWTN_AIRINTERFACEHSBCONFIGURATIONISFAULTYSEVERITY": "airInterfaceHsbConfigurationIsFaultySeverity", + "MWTN_AIRINTERFACEHSBISDOWNSEVERITY": "airInterfaceHsbIsDownSeverity", + "MWTN_AIRINTERFACEHSBISPARTLYDOWNSEVERITY": "airInterfaceHsbIsPartlyDownSeverity", + "MWTN_AIRINTERFACEID": "Air interface identifier", + "MWTN_AIRINTERFACELIST": "airInterfaceList", + "MWTN_AIRINTERFACELTPLIST": "airInterfaceLtpList", + "MWTN_AIRINTERFACENAME": "Air interface name", + "MWTN_AIRINTERFACESTATUS": "airInterfaceStatus", + "MWTN_AIR_INTERFACE": "Air interface", + "MWTN_AIR_INTERFACES": "Air interfaces", + "MWTN_AIR_INTERFACE_CAPABILITY": "air-interface-capability", + "MWTN_AIR_INTERFACE_CONFIGURATION": "air-interface-configuration", + "MWTN_AIR_INTERFACE_CURRENT_PERFORMANCE": "air-interface-current-performance", + "MWTN_AIR_INTERFACE_CURRENT_PROBLEMS": "air-interface-current-problems", + "MWTN_AIR_INTERFACE_DIVERSITY": "air-interface-diversity", + "MWTN_AIR_INTERFACE_DIVERSITY_CAPABILITY": "air-interface-diversity-capability", + "MWTN_AIR_INTERFACE_DIVERSITY_CONFIGURATION": "air-interface-diversity-configuration", + "MWTN_AIR_INTERFACE_DIVERSITY_CURRENT_PERFORMANCE": "air-interface-diversity-current-performance", + "MWTN_AIR_INTERFACE_DIVERSITY_CURRENT_PROBLEMS": "air-interface-diversity-current-problems", + "MWTN_AIR_INTERFACE_DIVERSITY_HISTORICAL_PERFORMANCES": "air-interface-diversity-historical-performances", + "MWTN_AIR_INTERFACE_DIVERSITY_STATUS": "air-interface-diversity-status", + "MWTN_AIR_INTERFACE_HISTORICAL_PERFORMANCES": "air-interface-historical-performances", + "MWTN_AIR_INTERFACE_HSB_CONFIGURATION_IS_FAULTY_SEVERITY": "air-interface-hsb-configuration-is-faulty-severity", + "MWTN_AIR_INTERFACE_HSB_IS_DOWN_SEVERITY": "air-interface-hsb-is-down-severity", + "MWTN_AIR_INTERFACE_HSB_IS_PARTLY_DOWN_SEVERITY": "air-interface-hsb-is-partly-down-severity", + "MWTN_AIR_INTERFACE_NAME": "air-interface-name", + "MWTN_AIR_INTERFACE_STATUS": "air-interface-status", + "MWTN_ALARMS": "Alarms", + "MWTN_ALARM_LOG": "Alarm log", + "MWTN_ALARM_NOTIFICATIONS": "Alarm notifications", + "MWTN_ALARM_STATUS": "Alarm status", + "MWTN_ALICISAVAIL": "alicIsAvail", + "MWTN_ALICISON": "alicIsOn", + "MWTN_ALICISUP": "alicIsUp", + "MWTN_ALIC_IS_AVAIL": "alic-is-avail", + "MWTN_ALIC_IS_ON": "alic-is-on", + "MWTN_ALIC_IS_UP": "alic-is-up", + "MWTN_AMDOWNSHIFTLEVEL": "AM downshift level", + "MWTN_AMUPSHIFTLEVEL": "AM upshift level", + "MWTN_AM_DOWNSHIFT_LEVEL": "am-downshift-level", + "MWTN_AM_UPSHIFT_LEVEL": "am-upshift-level", + "MWTN_ANNOUNCE_RECEIPT_TIMEOUT": "announce-receipt-timeout", + "MWTN_APPLY": "Apply", + "MWTN_ARBITRARY_ELEMENT": "arbitrary-element", + "MWTN_ASSET_INSTANCE_IDENTIFIER": "asset-instance-identifier", + "MWTN_ASSET_TYPE_IDENTIFIER": "asset-type-identifier", + "MWTN_ATPCISAVAIL": "atpcIsAvail", + "MWTN_ATPCISON": "atpcIsOn", + "MWTN_ATPCISUP": "atpcIsUp", + "MWTN_ATPCRANGE": "atpcRange", + "MWTN_ATPCTHRESHLOWER": "atpcThreshLower", + "MWTN_ATPCTHRESHUPPER": "atpcThreshUpper", + "MWTN_ATPC_IS_AVAIL": "atpc-is-avail", + "MWTN_ATPC_IS_ON": "atpc-is-on", + "MWTN_ATPC_IS_UP": "atpc-is-up", + "MWTN_ATPC_RANGE": "atpc-range", + "MWTN_ATPC_THRESH_LOWER": "atpc-thresh-lower", + "MWTN_ATPC_THRESH_UPPER": "atpc-thresh-upper", + "MWTN_ATTRIBUTE": "Attribute", + "MWTN_ATTRIBUTE_NAME": "attribute-name", + "MWTN_ATTRIBUTE_VALUE_CHANGED": "Attribute value changed", + "MWTN_AUTOFREQSELECTISAVAIL": "Automatic frequency selection", + "MWTN_AUTOFREQSELECTISON": "autoFreqSelectIsOn", + "MWTN_AUTOFREQSELECTISUP": "autoFreqSelectIsUp", + "MWTN_AUTOFREQSELECTRANGE": "autoFreqSelectRange", + "MWTN_AUTO_FREQ_SELECT_IS_AVAIL": "auto-freq-select-is-avail", + "MWTN_AUTO_FREQ_SELECT_IS_ON": "auto-freq-select-is-on", + "MWTN_AUTO_FREQ_SELECT_IS_UP": "auto-freq-select-is-up", + "MWTN_AUTO_FREQ_SELECT_RANGE": "auto-freq-select-range", + "MWTN_AVAILABLEKINDSOFCONTAINERLIST": "Supported clients", + "MWTN_AVAILABLEKINDSOFDIVERSITY": "availableKindsOfDiversity", + "MWTN_AVAILABLE_KINDS_OF_DIVERSITY": "available-kinds-of-diversity", + "MWTN_BUNDLINGISAVAIL": "bundlingIsAvail", + "MWTN_BUNDLING_IS_AVAIL": "bundling-is-avail", + "MWTN_CANCEL": "Cancel", + "MWTN_CAPABILITY": "Capability", + "MWTN_CATEGORY": "category", + "MWTN_CHANNELBANDWIDTH": "Channel bandwidth", + "MWTN_CHANNEL_BANDWIDTH": "channel-bandwidth", + "MWTN_CLASS_OF_INSTANCE": "class-of-instance", + "MWTN_CLEAR": "Clear", + "MWTN_CLIENT_LTP": "Client LTPs", + "MWTN_CLOCK": "Clock (IEEE 1588v2)", + "MWTN_CLOCK_ACCURACY": "clock-accuracy", + "MWTN_CLOCK_CLASS": "clock-class", + "MWTN_CLOCK_IDENTITY": "clock-identity", + "MWTN_CLOCK_QUALITY": "clock-quality", + "MWTN_CLOSE": "Close", + "MWTN_COCHANNELGROUP": "CoChannelGroup", + "MWTN_COCHANNELGROUPID": "coChannelGroupId", + "MWTN_CODE_RATE": "code-rate", + "MWTN_CODE_RATE_CUR": "code-rate-cur", + "MWTN_COLLAPSE_ALL": "Collapse all", + "MWTN_CONDITIONALPACKAGE": "Conditional package", + "MWTN_CONDITIONAL_PACKAGE": "Conditional package", + "MWTN_CONFIGURATION": "Configuration", + "MWTN_CONFIGUREDCLIENTCAPACITY": "configuredClientCapacity", + "MWTN_CONFIGURED_CLIENT_CAPACITY": "configured-client-capacity", + "MWTN_CONFIG_AND_SWITCH_CONTROLLER": "config-and-switch-controller", + "MWTN_CONNECTED_LTP": "connected-ltp", + "MWTN_CONNECTIONSTATUS": "Connection status", + "MWTN_CONNECTION_STATUS_LOG": "Connection status log", + "MWTN_CONNECTOR": "connector", + "MWTN_CONNECTOR_CABLE_END": "connector-cable-end", + "MWTN_CONNECTOR_CAPABILITY": "connector-capability", + "MWTN_CONNECTOR_CONFIGURATION": "connector-configuration", + "MWTN_CONNECTOR_CURRENT_PROBLEMS": "connector-current-problems", + "MWTN_CONNECTOR_IN_HOLDER": "connector-in-holder", + "MWTN_CONNECTOR_ON_EQUIPMENT_FOR_CABLE": "connector-on-equipment-for-cable", + "MWTN_CONNECTOR_ON_EQUIPMENT_FOR_HOLDER": "connector-on-equipment-for-holder", + "MWTN_CONNECTOR_PAC": "connector-pac", + "MWTN_CONNECTOR_STATUS": "connector-status", + "MWTN_CONNECTOR_TYPE": "connector-type", + "MWTN_CONTAINED_HOLDER": "contained-holder", + "MWTN_CONTAINER": "Client", + "MWTN_CONTAINERID": "containerID", + "MWTN_CONTAINERTYPE": "containerType", + "MWTN_CONTAINER_ID": "container-id", + "MWTN_CONTAINER_NAME": "container-name", + "MWTN_CONTAINER_TYPE": "container-type", + "MWTN_CONTROL_PARAMETERS": "control-parameters", + "MWTN_COUNTER": "counter", + "MWTN_CO_CHANNEL_GROUP": "co-channel-group", + "MWTN_CO_CHANNEL_GROUP_ID": "co-channel-group-id", + "MWTN_CREATE": "Create", + "MWTN_CRYPTOGRAPHICKEY": "cryptographicKey", + "MWTN_CRYPTOGRAPHIC_KEY": "cryptographic-key", + "MWTN_CSES": "CSES", + "MWTN_CURRENTPERFORMANCEDATALIST": "currentPerformanceDataList", + "MWTN_CURRENTPROBLEMLIST": "currentProblemList", + "MWTN_CURRENT_DS": "current-ds", + "MWTN_CURRENT_PERFORMANCE_DATA_LIST": "current-performance-data", + "MWTN_CURRENT_PROBLEM_LIST": "Current problem list", + "MWTN_CURRENT_UTC_OFFSET": "current-utc-offset", + "MWTN_CURRENT_UTC_OFFSET_VALID": "current-utc-offset-valid", + "MWTN_CUT_THROUGH_COMMANDS": "Cut-through commands", + "MWTN_DEFAULT_DS": "default-ds", + "MWTN_DEFECTBLOCKSSUM": "Defect blocks (sum)", + "MWTN_DEFECT_BLOCKS_SUM": "defect-blocks-sum", + "MWTN_DELAY_ASYMMETRY": "delay-asymmetry", + "MWTN_ONF_PTP_DATASET:DELAY_ASYMMETRY": "delay-asymmetry", + "MWTN_DELAY_MECHANISM": "delay-mechanism", + "MWTN_DELETE": "Delete", + "MWTN_DESCRIPTION": "description", + "MWTN_DESIGNATED_ENABLED": "designated-enabled", + "MWTN_ONF_PTP_DATASET:DESIGNATED_ENABLED": "designated-enabled", + "MWTN_DIRECTIONALITY": "Directionality", + "MWTN_DIVERSITY_NAME": "diversity-name", + "MWTN_DOMAIN_NUMBER": "domain-number", + "MWTN_DUPLEXDISTANCE": "Duplex distance", + "MWTN_DUPLEXDISTANCEISVARIABLE": "Variable duplex distance", + "MWTN_DUPLEX_DISTANCE": "duplex-distance", + "MWTN_DUPLEX_DISTANCE_IS_VARIABLE": "duplex-distance-is-variable", + "MWTN_EFFORT_AND_ACTION": "effort-and-action", + "MWTN_ELAPSEDTIME": "elapsedTime", + "MWTN_ELAPSED_TIME": "elapsed-time", + "MWTN_ENCRYPTIONISAVAIL": "encryptionIsAvail", + "MWTN_ENCRYPTIONISON": "encryptionIsOn", + "MWTN_ENCRYPTION_IS_AVAIL": "encryption-is-avail", + "MWTN_ENCRYPTION_IS_ON": "encryption-is-on", + "MWTN_ENDPOINT": "endpoint", + "MWTN_EQUIPMENT": "equipment", + "MWTN_EQUIPMENT_CAPABILITY": "equipment-capability", + "MWTN_EQUIPMENT_CONFIGURATION": "equipment-configuration", + "MWTN_EQUIPMENT_CURRENT_PROBLEMS": "equipment-current-problems", + "MWTN_EQUIPMENT_INSTANCE": "equipment-instance", + "MWTN_EQUIPMENT_LOCATION": "equipment-location", + "MWTN_EQUIPMENT_PAC": "equipment-pac", + "MWTN_EQUIPMENT_STATUS": "equipment-status", + "MWTN_EQUIPMENT_TYPE": "equipment-type", + "MWTN_ES": "ES", + "MWTN_ETH": "Ethernet (ETH)", + "MWTN_ETH-CTP": "Ethernet connection termination point (ETH-CTP)", + "MWTN_ETHERNETCONTAINERCAPABILITY": "EthernetContainerCapability", + "MWTN_ETHERNETCONTAINERCONFIGURATION": "ethernetContainerConfiguration", + "MWTN_ETHERNETCONTAINERCURRENTPERFORMANCE": "ethernetContainerCurrentPerformance", + "MWTN_ETHERNETCONTAINERCURRENTPROBLEMS": "ethernetContainerCurrentProblems", + "MWTN_ETHERNETCONTAINERHISTORICALPERFORMANCES": "ethernetContainerHistoricalPerformances", + "MWTN_ETHERNETCONTAINERSTATUS": "ethernetContainerStatus", + "MWTN_ETHERNET_CAPABILITY": "ethernet-capability", + "MWTN_ETHERNET_CONFIGURATION": "ethernet-configuration", + "MWTN_ETHERNET_CONTAINER_CAPABILITY": "ethernet-container-capability", + "MWTN_ETHERNET_CONTAINER_CONFIGURATION": "ethernet-container-configuration", + "MWTN_ETHERNET_CONTAINER_CURRENT_PERFORMANCE": "ethernet-container-current-performance", + "MWTN_ETHERNET_CONTAINER_CURRENT_PROBLEMS": "ethernet-container-current-problems", + "MWTN_ETHERNET_CONTAINER_HISTORICAL_PERFORMANCES": "ethernet-container-historical-performances", + "MWTN_ETHERNET_CONTAINER_STATUS": "ethernet-container-status", + "MWTN_ETHERNET_CURRENT_PERFORMANCE": "ethernet-current-performance", + "MWTN_ETHERNET_CURRENT_PROBLEMS": "ethernet-current-problems", + "MWTN_ETHERNET_HISTORICAL_PERFORMANCES": "ethernet-historical-performances", + "MWTN_ETHERNET_PAC": "ethernet-pac", + "MWTN_ETHERNET_STATUS": "ethernet-status", + "MWTN_EXPECTED_EQUIPMENT": "expected-equipment", + "MWTN_EXPECTED_HOLDER": "expected-holder", + "MWTN_EXPOSED_CABLE": "exposed-cable", + "MWTN_EXTENSION": "Extension", + "MWTN_EXTENSIONLIST": "extensionList", + "MWTN_FAULTY_FLAG": "faulty-flag", + "MWTN_FCPORT": "FcPort", + "MWTN_FCPORTDIRECTION": "fcPortDirection", + "MWTN_FCSWITCH": "fcswitch", + "MWTN_FC_BLOCKS_SIGNAL_TO_LP": "fc-blocks-signal-to-lp", + "MWTN_FC_PORT": "fc-port", + "MWTN_FC_PORT_DIRECTION": "fc-port-direction", + "MWTN_FC_SWITCH": "fc-switch", + "MWTN_FD": "fd", + "MWTN_FIRE_CHARACTERISTICS": "fire-characteristics", + "MWTN_FORWARDINGCONSTRUCT": "ForwardingConstruct", + "MWTN_FORWARDINGDIRECTION": "forwardingDirection", + "MWTN_FORWARDINGDOMAIN": "ForwardingDomain", + "MWTN_FORWARDING_CONSTRUCT": "forwarding-construct", + "MWTN_FORWARDING_DIRECTION": "forwarding-direction", + "MWTN_FREQUENCY_TRACEABLE": "frequency-traceable", + "MWTN_FUNCTION_ENABLERS": "function-enablers", + "MWTN_GENERALDIRECTIVES": "generaldirectives", + "MWTN_GEOGRAPHICAL_LOCATION": "geographical-location", + "MWTN_GLOBALCLASS": "GlobalClass", + "MWTN_GLOBAL_PAC": "global-pac", + "MWTN_GRAPH": "Graph", + "MWTN_GRANDMASTER_CLOCK_QUALITY": "grandmaster-clock-quality", + "MWTN_GRANDMASTER_IDENTITY": "grandmaster-identity", + "MWTN_GRANDMASTER_PRIORITY1": "grandmaster-priority1", + "MWTN_GRANDMASTER_PRIORITY2": "grandmaster-priority2", + "MWTN_GRANULARITYPERIOD": "granularityPeriod", + "MWTN_GRANULARITY_PERIOD": "granularity-period", + "MWTN_HEIGHT": "height", + "MWTN_HIDE": "Hide", + "MWTN_HISTORICALPERFORMANCEDATALIST": "historicalPerformanceDataList", + "MWTN_HISTORICAL_PERFORMANCE_DATA_LIST": "historical-performance-data", + "MWTN_HISTORYDATAID": "historyDataId", + "MWTN_HISTORY_DATA_ID": "history-data-id", + "MWTN_HOLDER": "holder", + "MWTN_HOLDER_CAPABILITY": "holder-capability", + "MWTN_HOLDER_CATEGORY": "holder-category", + "MWTN_HOLDER_CONFIGURATION": "holder-configuration", + "MWTN_HOLDER_CURRENT_PROBLEMS": "holder-current-problems", + "MWTN_HOLDER_LOCATION": "holder-location", + "MWTN_HOLDER_MONITORS": "holder-monitors", + "MWTN_HOLDER_PAC": "holder-pac", + "MWTN_HOLDER_STATUS": "holder-status", + "MWTN_HOLDER_STRUCTURE": "holder-structure", + "MWTN_HOLDOFFTIME": "holdOffTime", + "MWTN_HOLD_OFF_TIME": "hold-off-time", + "MWTN_HYBRIDMWSTRUCTURECAPABILITY": "hybridMwStructureCapability", + "MWTN_HYBRIDMWSTRUCTURECONFIGURATION": "HybridMwStructureConfiguration", + "MWTN_HYBRIDMWSTRUCTURECURRENTPERFORMANCE": "HybridMwStructureCurrentPerformance", + "MWTN_HYBRIDMWSTRUCTURECURRENTPROBLEMS": "hybridMwStructureCurrentProblems", + "MWTN_HYBRIDMWSTRUCTUREHISTORICALPERFORMANCES": "hybridMwStructureHistoricalPerformances", + "MWTN_HYBRIDMWSTRUCTURESTATUS": "hybridMwStructureStatus", + "MWTN_HYBRID_MW_STRUCTURE_CAPABILITY": "hybrid-mw-structure-capability", + "MWTN_HYBRID_MW_STRUCTURE_CONFIGURATION": "hybrid-mw-structure-configuration", + "MWTN_HYBRID_MW_STRUCTURE_CURRENT_PERFORMANCE": "hybrid-mw-structure-current-performance", + "MWTN_HYBRID_MW_STRUCTURE_CURRENT_PROBLEMS": "hybrid-mw-structure-current-problems", + "MWTN_HYBRID_MW_STRUCTURE_HISTORICAL_PERFORMANCES": "hybrid-mw-structure-historical-performances", + "MWTN_HYBRID_MW_STRUCTURE_STATUS": "hybrid-mw-structure-status", + "MWTN_ID": "Identifier", + "MWTN_INFORMATIONRATE": "Information rate", + "MWTN_INFORMATIONRATECUR": "informationRateCur", + "MWTN_INSTANCE_LIST": "instances", + "MWTN_INSTANCE_NUMBER": "instance-number", + "MWTN_INTERFACE": "Interface", + "MWTN_INTERFERENCE_ALARM!": "INTERFERENCE ALARM!!!", + "MWTN_INTERFERENCE_ALARM?": "Interference alarm?", + "MWTN_INTERFERENCE_ALARM_STATUS": "Interferance alarm status", + "MWTN_INTERNAL_CONFIGURATION_AND_SWITCH_CONTROL": "internal-configuration-and-switch-control", + "MWTN_IPADDRESS": "IP address", + "MWTN_IPV4COMPRESSIONISAVAIL": "ipv4CompressionIsAvail", + "MWTN_IPV4COMPRESSIONISON": "ipv4CompressionIsOn", + "MWTN_IPV4_COMPRESSION_IS_AVAIL": "ipv4-compression-is-avail", + "MWTN_IPV4_COMPRESSION_IS_ON": "ipv4-compression-is-on", + "MWTN_IPV6COMPRESSIONISAVAIL": "ipv6CompressionIsAvail", + "MWTN_IPV6COMPRESSIONISON": "ipv6CompressionIsOn", + "MWTN_IPV6_COMPRESSION_IS_AVAIL": "ipv6-compression-is-avail", + "MWTN_IPV6_COMPRESSION_IS_ON": "ipv6-compression-is-on", + "MWTN_IS_ACTIVE": "is-active", + "MWTN_IS_ACTUAL_MISMATCH_WITH_EXPECTED": "is-actual-mismatch-with-expected", + "MWTN_IS_CAPTIVE": "is-captive", + "MWTN_IS_COORDINATED_SWITCHING_BOTH_ENDS": "is-coordinated-switching-both-ends", + "MWTN_IS_FIELD_REPLACEABLE": "is-field-replaceable", + "MWTN_IS_FROZEN": "is-frozen", + "MWTN_IS_GUIDED": "is-guided", + "MWTN_IS_HOT_SWAPPABLE": "is-hot-swappable", + "MWTN_IS_INTERNAL_PORT": "is-internal-port", + "MWTN_IS_NOT": "is-not", + "MWTN_IS_PROTECTION_LOCK_OUT": "is-protection-lock-out", + "MWTN_IS_QUANTIZED_SPACE": "is-quantized-space", + "MWTN_IS_SHORT_LIVED": "is-short-lived", + "MWTN_ITEMS": "items", + "MWTN_LABEL": "Label", + "MWTN_LABELLIST": "labelList", + "MWTN_LASTSTATUSCHANGE": "lastStatusChange", + "MWTN_LAST_STATUS_CHANGE": "last-status-change", + "MWTN_LAYER": "Layer", + "MWTN_LAYER2COMPRESSIONISAVAIL": "layer2CompressionIsAvail", + "MWTN_LAYER2COMPRESSIONISON": "layer2CompressionIsOn", + "MWTN_LAYER2_COMPRESSION_IS_AVAIL": "layer2-compression-is-avail", + "MWTN_LAYER2_COMPRESSION_IS_ON": "layer2-compression-is-on", + "MWTN_LAYER4COMPRESSIONISAVAIL": "layer4CompressionIsAvail", + "MWTN_LAYER4COMPRESSIONISON": "layer4CompressionIsOn", + "MWTN_LAYER4_COMPRESSION_IS_AVAIL": "layer4-compression-is-avail", + "MWTN_LAYER4_COMPRESSION_IS_ON": "layer4-compression-is-on", + "MWTN_LAYERPROTOCOL": "LayerProtocol", + "MWTN_LAYERPROTOCOLNAME": "layerProtocolName", + "MWTN_LAYERPROTOCOLNAMELIST": "layerProtocolNameList", + "MWTN_LAYER_PROTOCOL": "layer-protocol", + "MWTN_LAYER_PROTOCOL_NAME": "layer-protocol-name", + "MWTN_LEAP59": "leap59", + "MWTN_LEAP61": "leap61", + "MWTN_LENGTH": "length", + "MWTN_LIFECYCLESTATE": "lifecycleState", + "MWTN_LIFECYCLE_STATE": "lifecycle-state", + "MWTN_LINKISUP": "linkIsUp", + "MWTN_LINK_IS_UP": "link-is-up", + "MWTN_LOADING": "Loading...", + "MWTN_LOCALCLASS": "LocalClass", + "MWTN_LOCALENDPOINTID": "localEndPointId", + "MWTN_LOCALIDLIST": "localIdList", + "MWTN_LOCAL_END_POINT": "local-end-point", + "MWTN_LOCAL_END_POINT_ID": "local-end-point-id", + "MWTN_LOCAL_ID": "local-id", + "MWTN_LOCAL_PAC": "local-pac", + "MWTN_LOCAL_PRIORITY": "local-priority", + "MWTN_ONF_PTP_DATASET:LOCAL_PRIORITY": "local-priority", + "MWTN_LOCATION": "location", + "MWTN_LOGICALTERMINATIONPOINT": "LogicalTerminationPoint", + "MWTN_LOGICAL_TERMINATION_POINT": "logical-termination-point", + "MWTN_ONF_PTP_DATASET:LOGICAL_TERMINATION_POINT": "logical-termination-point", + "MWTN_LOG_ANNOUNCE_INTERVAL": "log-announce-interval", + "MWTN_LOG_MIN_DELAY_REQ_INTERVAL": "log-min-delay-req-interval", + "MWTN_LOG_MIN_PDELAY_REQ_INTERVAL": "log-min-pdelay-req-interval", + "MWTN_LOG_SYNC_INTERVAL": "log-sync-interval", + "MWTN_LOOPBACKISAVAIL": "loopBackIsAvail", + "MWTN_LOOPBACKISON": "loopBackIsOn", + "MWTN_LOOPBACKISUP": "loopBackIsUp", + "MWTN_LOOP_BACK_KIND_ON": "loop-back-kind-on", + "MWTN_LOOP_BACK_KIND_UP": "loop-back-kind-up", + "MWTN_LP": "Layer protocol", + "MWTN_LPDIRECTION": "lpDirection", + "MWTN_LP_DIRECTION": "lp-direction", + "MWTN_LTP": "LTP", + "MWTN_LTPS": "LTPs", + "MWTN_LTPDIRECTION": "ltpDirection", + "MWTN_LTP_DIRECTION": "ltp-direction", + "MWTN_MAINTENANCETIMER": "maintenanceTimer", + "MWTN_MAINTENANCETIMERRANGE": "maintenanceTimerRange", + "MWTN_MAINTENANCE_TIMER": "maintenance-timer", + "MWTN_MAINTENANCE_TIMER_RANGE": "maintenance-timer-range", + "MWTN_MAKE_KNOWN": "To required NEs...", + "MWTN_MANUFACTURED_THING": "manufactured-thing", + "MWTN_MANUFACTURER_IDENTIFIER": "manufacturer-identifier", + "MWTN_MANUFACTURER_NAME": "manufacturer-name", + "MWTN_MANUFACTURER_PROPERTIES": "manufacturer-properties", + "MWTN_MANUFACTURE_DATE": "manufacture-date", + "MWTN_MASTER_ONLY": "master-only", + "MWTN_ONF_PTP_DATASET:MASTER_ONLY": "master-only", + "MWTN_MATERIALS": "materials", + "MWTN_MAX_NUMBER_OF_SEGMENTS_RESERVABLE": "max-number-of-segments-reservable", + "MWTN_MAX_STEPS_REMOVED": "max-steps-removed", + "MWTN_MEAN_PATH_DELAY": "mean-path-delay", + "MWTN_MECHANICAL_FEATURES": "mechanical-features", + "MWTN_MECHANICAL_FUNCTIONS": "mechanical-functions", + "MWTN_MESSAGE": "Message", + "MWTN_MICROWAVEMODEL_OBJECTCLASSES_AIRINTERFACE:MW_AIRINTERFACE_PAC": "Airinterface", + "MWTN_MICROWAVEMODEL_OBJECTCLASSES_ETHERNETCONTAINER:MW_ETHERNETCONTAINER_PAC": "Ethernet container", + "MWTN_MICROWAVEMODEL_OBJECTCLASSES_PUREETHERNETSTRUCTURE:MW_PUREETHERNETSTRUCTURE_PAC": "Structure (pure ethernet)", + "MWTN_MICROWAVE_MODEL:MW_AIR_INTERFACE_DIVERISTY_PAC": "Diversity", + "MWTN_MICROWAVE_MODEL:MW_AIR_INTERFACE_PAC": "Airinterface", + "MWTN_MICROWAVE_MODEL:MW_ETHERNET_CONTAINER_PAC": "Ethernet container", + "MWTN_MICROWAVE_MODEL:MW_HYBRID_MW_STRUCTURE_PAC": "Structure (hybrid)", + "MWTN_MICROWAVE_MODEL:MW_PURE_ETHERNET_STRUCTURE_PAC": "Structure (pure ethernet)", + "MWTN_MICROWAVE_MODEL:MW_TDM_CONTAINER_PAC": "TDM container", + "MWTN_MIMOCHANNELS": "mimoChannels", + "MWTN_MIMOISAVAIL": "mimoIsAvail", + "MWTN_MIMOISON": "mimoIsOn", + "MWTN_MIMOISUP": "mimoIsUp", + "MWTN_MIMO_CHANNELS": "mimo-channels", + "MWTN_MIMO_IS_AVAIL": "mimo-is-avail", + "MWTN_MIMO_IS_ON": "mimo-is-on", + "MWTN_MIMO_IS_UP": "mimo-is-up", + "MWTN_MODEL_IDENTIFIER": "model-identifier", + "MWTN_MODULATIONCUR": "modulationCur", + "MWTN_MODULATIONISON": "modulationIsOn", + "MWTN_MODULATIONMAX": "modulationMax", + "MWTN_MODULATIONMIN": "modulationMin", + "MWTN_MODULATIONSCHEME": "Modulation scheme", + "MWTN_MODULATION_CUR": "modulation-cur", + "MWTN_MODULATION_IS_ON": "modulation-is-on", + "MWTN_MODULATION_MAX": "modulation-max", + "MWTN_MODULATION_MIN": "modulation-min", + "MWTN_MODULATION_SCHEME": "modulation-scheme", + "MWTN_MOUNT": "Mount", + "MWTN_MOUNTPOINT": "Mountpoint", + "MWTN_MPLSCOMPRESSIONISAVAIL": "mplsCompressionIsAvail", + "MWTN_MPLSCOMPRESSIONISON": "mplsCompressionIsOn", + "MWTN_MPLS_COMPRESSION_IS_AVAIL": "mpls-compression-is-avail", + "MWTN_MPLS_COMPRESSION_IS_ON": "mpls-compression-is-on", + "MWTN_MULTICAST_MAC_ADDRESS": "multicast-mac-address", + "MWTN_MWCURRENTPROBLEM": "MwCurrentProblem", + "MWTN_MWPS": "Microwave Physical Section (MWPS)", + "MWTN_MWS": "Microwave Section (MWS)", + "MWTN_MW_AIRINTERFACEDIVERSITY_PAC": "MW_AirInterfaceDiversity_Pac", + "MWTN_MW_AIRINTERFACEHSBENDPOINT_PAC": "MW_AirInterfaceHsbEndPoint_Pac", + "MWTN_MW_AIRINTERFACEHSBFCSWITCH_PAC": "MW_AirInterfaceHsbFcSwitch_Pac", + "MWTN_MW_AIRINTERFACE_PAC": "MW_AirInterface_Pac", + "MWTN_MW_AIR_INTERFACE_DIVERSITY_PAC": "mw-air-interface-diversity-pac", + "MWTN_MW_AIR_INTERFACE_HSB_END_POINT_PAC": "mw-air-interface-hsb-end-point-pac", + "MWTN_MW_AIR_INTERFACE_HSB_FC_SWITCH_PAC": "mw-air-interface-hsb-fc-switch-pac", + "MWTN_MW_AIR_INTERFACE_PAC": "mw-air-interface-pac", + "MWTN_MW_ETHERNETCONTAINER_PAC": "MW_EthernetContainer_Pac", + "MWTN_MW_ETHERNET_CONTAINER_PAC": "mw-ethernet-container-pac", + "MWTN_MW_HYBRIDMWSTRUCTURE_PAC": "MW_HybridMwStructure_Pac", + "MWTN_MW_HYBRID_MW_STRUCTURE_PAC": "mw-hybrid-mw-structure-pac", + "MWTN_MW_PUREETHERNETSTRUCTURE_PAC": "MW_PureEthernetStructure_Pac", + "MWTN_MW_PURE_ETHERNET_STRUCTURE_PAC": "mw-pure-ethernet-structure-pac", + "MWTN_MW_TDMCONTAINER_PAC": "MW_TdmContainer_Pac", + "MWTN_MW_TDM_CONTAINER_PAC": "mw-tdm-container-pac", + "MWTN_NAME": "Name", + "MWTN_NAMEANDVALUEAUTHORITY": "NameAndValueAuthority", + "MWTN_NAMEBINDING": "nameBinding", + "MWTN_NAMELIST": "nameList", + "MWTN_NAME_BINDING": "name-binding", + "MWTN_NECESSARY_INITIALCONDITION_CONSTRAINTS": "necessary-initialcondition-constraints", + "MWTN_NETCONF_PORT": "NetConf port", + "MWTN_NETWORKELEMENT": "Network element", + "MWTN_NETWORK_ELEMENT": "network-element", + "MWTN_NETWORK_ELEMENT_CAPABILITY": "network-element-capability", + "MWTN_NETWORK_ELEMENT_CONFIGURATION": "network-element-configuration", + "MWTN_NETWORK_ELEMENT_CURRENT_PROBLEMS": "network-element-current-problems", + "MWTN_NETWORK_ELEMENT_PAC": "network-element-pac", + "MWTN_NETWORK_ELEMENT_STATUS": "network-element-status", + "MWTN_NETWORK_SCHEME_SPECIFICATION": "network-scheme-specification", + "MWTN_NEW_VALUE": "new-value", + "MWTN_NICKNAME": "Nickname", + "MWTN_NODES": "Nodes", + "MWTN_NO_DEVICES_CONNECTED": "Sorry, no Microwave devices connected to OpenDaylight.", + "MWTN_NUMBEROFLTPS": "# of LTPs", + "MWTN_NUMBEROFTDMSEGMENTSTOBERESERVED": "numberOfTdmSegmentsToBeReserved", + "MWTN_NUMBER_OF_AIR_INTERFACES_MAX": "number-of-air-interfaces-max", + "MWTN_NUMBER_OF_TDM_SEGMENTS_TO_BE_RESERVED": "number-of-tdm-segments-to-be-reserved", + "MWTN_NUMBER_OF_TIME_SLOTS_REQUIRED": "number-of-time-slots-required", + "MWTN_NUMBER_PORTS": "number-ports", + "MWTN_OBJECTCLASS": "objectClass", + "MWTN_OBJECTIDREF": "Object", + "MWTN_OBJECT_CLASS": "object-class", + "MWTN_OBJECT_DELETION_CREATION": "Object deletion or creation", + "MWTN_OBJECT_ID_REF": "object-id-ref", + "MWTN_OBJECT_REFERENCE": "object-reference", + "MWTN_OBJECT_TYPE": "object-type", + "MWTN_OBSERVED_PARENT_CLOCK_PHASE_CHANGE_RATE": "observed-parent-clock-phase-change-rate", + "MWTN_OBSERVED_PARENT_OFFSET_SCALED_LOG_VARIANCE": "observed-parent-offset-scaled-log-variance", + "MWTN_OBSOLETE_DROP_ORDER_RANK": "obsolete-drop-order-rank", + "MWTN_OBSOLETE_PRIORITY_CLASS": "obsolete-priority-class", + "MWTN_OCCUPYING_FRU": "occupying-fru", + "MWTN_OFFSET_FROM_MASTER": "offset-from-master", + "MWTN_OFFSET_SCALED_LOG_VARIANCE": "offset-scaled-log-variance", + "MWTN_OK": "Ok", + "MWTN_ONF_ETHERNET_CONDITIONAL_PACKAGES:ETHERNET_PAC": "Ethernet", + "MWTN_OPERATIONALSTATE": "operationalState", + "MWTN_OPERATIONALSTATUS": "Operational status", + "MWTN_OPERATIONAL_STATE": "operational-state", + "MWTN_OPERATIONAL_STATUS": "operational-status", + "MWTN_OPERATIONIDENTIFIERS": "operationidentifiers", + "MWTN_OPERATION_DETAILS": "operation-details", + "MWTN_OPERATION_ENVELOPE": "operation-envelope", + "MWTN_OPERATION_SET": "operation-set", + "MWTN_OPERATOR_AUGMENTED_EQUIPMENT_TYPE": "operator-augmented-equipment-type", + "MWTN_OPERTYPE": "operType", + "MWTN_ORIENTATION": "orientation", + "MWTN_OTN_CURRENTDATA": "OTN_CurrentData", + "MWTN_OTN_HISTORYDATA": "OTN_HistoryData", + "MWTN_PACKETCOMPRESSIONISAVAIL": "packetCompressionIsAvail", + "MWTN_PACKETCOMPRESSIONISON": "packetCompressionIsOn", + "MWTN_PACKET_COMPRESSION_IS_AVAIL": "packet-compression-is-avail", + "MWTN_PACKET_COMPRESSION_IS_ON": "packet-compression-is-on", + "MWTN_PARENT_DS": "parent-ds", + "MWTN_PARENT_PORT_IDENTITY": "parent-port-identity", + "MWTN_PARENT_STATS": "parent-stats", + "MWTN_PART_TYPE_IDENTIFIER": "part-type-identifier", + "MWTN_PASSWORD": "Password", + "MWTN_PAUSE_RESUME_RULE": "pause-resume-rule", + "MWTN_PEER_LTP": "peer-ltp", + "MWTN_PEER_MEAN_PATH_DELAY": "peer-mean-path-delay", + "MWTN_PERFORMANCEDATA": "Performance data", + "MWTN_PERFORMANCE_DATA": "Performance-data", + "MWTN_PERIODENDTIME": "period-end-time", + "MWTN_PERIOD_END_TIME": "period-end-time", + "MWTN_PHYSICALPORTREFERENCE": "physical-port-reference", + "MWTN_PHYSICAL_CHARACTERISTICS": "physical-characteristics", + "MWTN_PHYSICAL_PROPERTIES": "physical-properties", + "MWTN_PHYSICAL_RATING": "physical-rating", + "MWTN_PIN": "pin", + "MWTN_PIN_GROUP": "pin-group", + "MWTN_PIN_LAYOUT": "pin-layout", + "MWTN_POLARIZATION": "Polarization", + "MWTN_PORT": "Port", + "MWTN_PORT_DS_LIST": "ptp-ports", + "MWTN_PORT_IDENTITY": "port-identity", + "MWTN_PORT_NUMBER": "port-number", + "MWTN_PORT_STATE": "port-state", + "MWTN_POSITION": "position", + "MWTN_POWERISON": "powerIsOn", + "MWTN_POWER_IS_ON": "power-is-on", + "MWTN_POWER_RATING": "power-rating", + "MWTN_POWER_STATE": "power-state", + "MWTN_PRIMARY_DOMAIN": "primary-domain", + "MWTN_PRIORITY1": "priority1", + "MWTN_PRIORITY2": "priority2", + "MWTN_PROBLEM": "problem", + "MWTN_PROBLEMKINDNAME": "Alarm", + "MWTN_PROBLEMKINDSEVERITY": "Severity", + "MWTN_PROBLEMKINDSEVERITYLIST": "Severity list", + "MWTN_PROBLEMNAME": "Problem name", + "MWTN_PROBLEMSEVERITY": "Severity", + "MWTN_PROBLEM_KIND_NAME": "problem-type", + "MWTN_PROBLEM_KIND_SEVERITY": "severity", + "MWTN_PROBLEM_KIND_SEVERITY_LIST": "severities", + "MWTN_PROBLEM_NAME": "problem-name", + "MWTN_PROBLEM_SEVERITY": "problem-severity", + "MWTN_PROBLEM_TYPE_NAME": "problem-type-name", + "MWTN_PROBLEM_TYPE_SEVERITY": "problem-type-severity", + "MWTN_PROBLEM_TYPE_SEVERITY_LIST": "problem-severities", + "MWTN_PROTTYPE": "protType", + "MWTN_PROT_TYPE": "prot-type", + "MWTN_PTP_TIMESCALE": "ptp-timescale", + "MWTN_PUREETHERNETSTRUCTURECAPABILITY": "pureEthernetStructureCapability", + "MWTN_PUREETHERNETSTRUCTURECONFIGURATION": "pureEthernetStructureConfiguration", + "MWTN_PUREETHERNETSTRUCTURECURRENTPERFORMANCE": "PureEthernetStructureCurrentPerformance", + "MWTN_PUREETHERNETSTRUCTURECURRENTPROBLEMS": "PureEthernetStructureCurrentProblems", + "MWTN_PUREETHERNETSTRUCTUREHISTORICALPERFORMANCES": "PureEthernetStructureHistoricalPerformances", + "MWTN_PUREETHERNETSTRUCTURESTATUS": "PureEthernetStructureStatus", + "MWTN_PURE_ETHERNET_STRUCTURE_CAPABILITY": "pure-ethernet-structure-capability", + "MWTN_PURE_ETHERNET_STRUCTURE_CONFIGURATION": "pure-ethernet-structure-configuration", + "MWTN_PURE_ETHERNET_STRUCTURE_CURRENT_PERFORMANCE": "pure-ethernet-structure-current-performance", + "MWTN_PURE_ETHERNET_STRUCTURE_CURRENT_PROBLEMS": "pure-ethernet-structure-current-problems", + "MWTN_PURE_ETHERNET_STRUCTURE_HISTORICAL_PERFORMANCES": "pure-ethernet-structure-historical-performances", + "MWTN_PURE_ETHERNET_STRUCTURE_STATUS": "pure-ethernet-structure-status", + "MWTN_QINQCOMPRESSIONISAVAIL": "qInQCompressionIsAvail", + "MWTN_QINQCOMPRESSIONISON": "qInQCompressionIsOn", + "MWTN_Q_IN_Q_COMPRESSION_IS_AVAIL": "q-in-q-compression-is-avail", + "MWTN_Q_IN_Q_COMPRESSION_IS_ON": "q-in-q-compression-is-on", + "MWTN_RADIOPOWERISUP": "radioPowerIsUp", + "MWTN_RADIOSIGNALID": "Radio signal identifier", + "MWTN_RADIOSIGNALIDS": "Radio signal identifiers", + "MWTN_RADIO_POWER_IS_UP": "radio-power-is-up", + "MWTN_RADIO_SIGNAL_ID": "radio-signal-id", + "MWTN_RECEIVERISON": "receiverIsOn", + "MWTN_RECEIVER_IS_ON": "receiver-is-on", + "MWTN_REFRESH": "Refresh", + "MWTN_REFRESH_STATUS": "refresh-status", + "MWTN_RELATIVE_POSITION": "relative-position", + "MWTN_REMOTEENDPOINTID": "remoteEndPointId", + "MWTN_REMOTE_END_POINT": "remote-end-point", + "MWTN_REMOTE_END_POINT_ID": "remote-end-point-id", + "MWTN_REVERSION_MODE": "reversion-mode", + "MWTN_REVISON": "Revision", + "MWTN_RFTEMPAVG": "Temerature (avg)", + "MWTN_RFTEMPCUR": "rfTempCur", + "MWTN_RFTEMPMAX": "Temerature (max)", + "MWTN_RFTEMPMIN": "Temerature (min)", + "MWTN_RF_TEMP_AVG": "rf-temp-avg", + "MWTN_RF_TEMP_CUR": "rf-temp-cur", + "MWTN_RF_TEMP_MAX": "rf-temp-max", + "MWTN_RF_TEMP_MIN": "rf-temp-min", + "MWTN_ROLE": "role", + "MWTN_ROTATION_SPEED": "rotation-speed", + "MWTN_RXCHANNELBANDWIDTH": "rxChannelBandwidth", + "MWTN_RXFREQUENCY": "Receive frequency", + "MWTN_RXFREQUENCYCUR": "rxFrequencyCur", + "MWTN_RXFREQUENCYMAX": "rxFrequencyMax", + "MWTN_RXFREQUENCYMIN": "rxFrequencyMin", + "MWTN_RXLEVELAVG": "Receive level (avg)", + "MWTN_RXLEVELCUR": "rxLevelCur", + "MWTN_RXLEVELMAX": "Receive level (min)", + "MWTN_RXLEVELMIN": "Receive level (max)", + "MWTN_RXTHRESHOLD": "RX threshold", + "MWTN_RX_CHANNEL_BANDWIDTH": "rx-channel-bandwidth", + "MWTN_RX_FREQUENCY": "rx-frequency", + "MWTN_RX_FREQUENCY_CUR": "rx-frequency-cur", + "MWTN_RX_FREQUENCY_MAX": "rx-frequency-max", + "MWTN_RX_FREQUENCY_MIN": "rx-frequency-min", + "MWTN_RX_LEVEL_AVG": "rx-level-avg", + "MWTN_RX_LEVEL_CUR": "rx-level-cur", + "MWTN_RX_LEVEL_MAX": "rx-level-max", + "MWTN_RX_LEVEL_MIN": "rx-level-min", + "MWTN_RX_THRESHOLD": "rx-threshold", + "MWTN_SCANNERID": "scannerId", + "MWTN_SCANNER_ID": "scanner-id", + "MWTN_SCRIPTID": "Script id", + "MWTN_SCRIPTLIST": "Scripts", + "MWTN_SEGMENTID": "segmentID", + "MWTN_SEGMENTSIDLIST": "segmentsIDList", + "MWTN_SEGMENTSTATUSLIST": "segmentStatusList", + "MWTN_SEGMENTS_ID_LIST": "segments-ids", + "MWTN_SEGMENT_ID": "segment-id", + "MWTN_SEGMENT_ID_REF": "segment-id-ref", + "MWTN_SEGMENT_IS_RESERVED_FOR_TDM": "segment-is-reserved-for-tdm", + "MWTN_SEGMENT_STATUS_LIST": "segment-status", + "MWTN_SEGMENT_STATUS_TYPE_ID": "segment-status-type-id", + "MWTN_SELECTION_PRIORITY": "selection-priority", + "MWTN_SELECT_LTP": "Select LTP", + "MWTN_SELECT_NETWORK_ELEMENT": "Select network element", + "MWTN_SEND": "Send", + "MWTN_SEQUENCENUMBER": "sequenceNumber", + "MWTN_SEQUENCE_NUMBER": "sequence-number", + "MWTN_SERIAL_NUMBER": "serial-number", + "MWTN_SERVERID": "Server identifier", + "MWTN_SERVER_LTP": "Server LTPs", + "MWTN_SERVICE_PRIORITY": "service-priority", + "MWTN_SES": "SES", + "MWTN_SEVERITY": "severity", + "MWTN_SHOWLIST": "Show list", + "MWTN_SHOWOBJECT": "Show object", + "MWTN_SINR": "Signal-to-interference-plus-noise ratio (SINR)", + "MWTN_SITE": "Site", + "MWTN_SLAVE_ONLY": "slave-only", + "MWTN_SNIRAVG": "SINR (avg)", + "MWTN_SNIRCUR": "SINR (current)", + "MWTN_SNIRMAX": "SINR (max)", + "MWTN_SNIRMIN": "SINR (min)", + "MWTN_SNIR_AVG": "SINR (avg)", + "MWTN_SNIR_CUR": "SINR (current)", + "MWTN_SNIR_MAX": "SINR (max)", + "MWTN_SNIR_MIN": "SINR (min)", + "MWTN_SORTOFCOCHANNELGROUP": "sortOfCoChannelGroup", + "MWTN_SORT_OF_CO_CHANNEL_GROUP": "sort-of-co-channel-group", + "MWTN_SPATIAL_PROPERTIES_OF_TYPE": "spatial-properties-of-type", + "MWTN_STATE_PAC": "State_Pac", + "MWTN_STEPS_REMOVED": "steps-removed", + "MWTN_STRUCTUREID": "structureId", + "MWTN_STRUCTURETYPE": "structureType", + "MWTN_STRUCTURE_ID": "structure-id", + "MWTN_STRUCTURE_ID_REF": "structure-id-ref", + "MWTN_STRUCTURE_TYPE": "structure-type", + "MWTN_SUBOBJECT": "Subobject", + "MWTN_SUM": "Sum", + "MWTN_SUPPORTEDALARMS": "supportedAlarms", + "MWTN_SUPPORTEDCHANNELPLAN": "Channnel plan", + "MWTN_SUPPORTEDCHANNELPLANLIST": "supportedChannelPlanList", + "MWTN_SUPPORTEDCHANNELPLANS": "Supported channel plans", + "MWTN_SUPPORTEDTDMCONTAINERTYPESLIST": "supportedTdmContainerTypesList", + "MWTN_SUPPORTEDTDMSTRUCTURETYPESLIST": "supportedTdmStructureTypesList", + "MWTN_SUPPORTED_ALARMS": "supported-alarms", + "MWTN_SUPPORTED_CHANNEL_PLAN": "supported-channel-plan", + "MWTN_SUPPORTED_CHANNEL_PLAN_LIST": "supported-channel-plans", + "MWTN_SUPPORTED_TDM_CONTAINER_TYPES_LIST": "supported-tdm-container-types", + "MWTN_SUPPORTED_TDM_STRUCTURE_TYPES_LIST": "supported-tdm-structure-types", + "MWTN_SUSPECTINTERVALFLAG": "suspectIntervalFlag", + "MWTN_SUSPECT_INTERVAL_FLAG": "suspect-interval-flag", + "MWTN_SWAPABILITY": "swapability", + "MWTN_SWITCH_CONTROL": "switch-control", + "MWTN_SWITCH_RULE": "switch-rule", + "MWTN_SWITCH_SELECTION_REASON": "switch-selection-reason", + "MWTN_SWITCH_SELECTS_PORTS": "switch-selects-ports", + "MWTN_TDMCONTAINERCAPABILITY": "tdmContainerCapability", + "MWTN_TDMCONTAINERCONFIGURATION": "tdmContainerConfiguration", + "MWTN_TDMCONTAINERCURRENTPERFORMANCE": "TdmContainerCurrentPerformance", + "MWTN_TDMCONTAINERCURRENTPROBLEMS": "tdmContainerCurrentProblems", + "MWTN_TDMCONTAINERHISTORICALPERFORMANCES": "TdmContainerHistoricalPerformances", + "MWTN_TDMCONTAINERSTATUS": "tdmContainerStatus", + "MWTN_TDM_CONTAINER_CAPABILITY": "tdm-container-capability", + "MWTN_TDM_CONTAINER_CONFIGURATION": "tdm-container-configuration", + "MWTN_TDM_CONTAINER_CURRENT_PERFORMANCE": "tdm-container-current-performance", + "MWTN_TDM_CONTAINER_CURRENT_PROBLEMS": "tdm-container-current-problems", + "MWTN_TDM_CONTAINER_HISTORICAL_PERFORMANCES": "tdm-container-historical-performances", + "MWTN_TDM_CONTAINER_NAME": "tdm-container-name", + "MWTN_TDM_CONTAINER_SIZE": "tdm-container-size", + "MWTN_TDM_CONTAINER_STATUS": "tdm-container-status", + "MWTN_TDM_SEGMENT_SIZE": "tdm-segment-size", + "MWTN_TDM_STRUCTURE_NAME": "tdm-structure-name", + "MWTN_TDM_TIME_SLOTS_IS_REQUIRED": "tdm-time-slots-is-required", + "MWTN_TEMPERATURE": "temperature", + "MWTN_TERMINATIONSTATE": "terminationState", + "MWTN_TERMINATION_STATE": "Termination state", + "MWTN_THERMAL_RATING": "thermal-rating", + "MWTN_TIME1024SYMBOLS": "Time 1024 QAM", + "MWTN_TIME1024SYMBOLSL": "Time 1024 QAM (light)", + "MWTN_TIME1024_STATES": "time1024-states", + "MWTN_TIME1024_STATES_L": "time1024-states-l", + "MWTN_TIME128SYMBOLS": "Time 128 QAM", + "MWTN_TIME128_STATES": "time128-states", + "MWTN_TIME16SYMBOLS": "Time 16 QAM", + "MWTN_TIME16SYMBOLSS": "Time 16 QAM (strong)", + "MWTN_TIME16_STATES": "time16-states", + "MWTN_TIME16_STATES_S": "time16-states-s", + "MWTN_TIME2048SYMBOLS": "Time 2048 QAM", + "MWTN_TIME2048SYMBOLSL": "Time 2048 QAM (light)", + "MWTN_TIME2048_STATES": "time2048-states", + "MWTN_TIME2048_STATES_L": "time2048-states-l", + "MWTN_TIME256SYMBOLS": "Time 256 QAM", + "MWTN_TIME256_STATES": "time256-states", + "MWTN_TIME2SYMBOLS": "Time 2 QAM", + "MWTN_TIME2_STATES": "time2-states", + "MWTN_TIME32SYMBOLS": "Time 32 QAM", + "MWTN_TIME32_STATES": "time32-states", + "MWTN_TIME4096SYMBOLS": "Time 4096 QAM", + "MWTN_TIME4096SYMBOLSL": "Time 4096 QAM (light)", + "MWTN_TIME4096_STATES": "time4096-states", + "MWTN_TIME4096_STATES_L": "time4096-states-l", + "MWTN_TIME4SYMBOLS": "Time 4 QAM", + "MWTN_TIME4SYMBOLSS": "Time 4 QAM (strong)", + "MWTN_TIME4_STATES": "time4-states", + "MWTN_TIME4_STATES_S": "time4-states-s", + "MWTN_TIME512SYMBOLS": "Time 512 QAM", + "MWTN_TIME512SYMBOLSL": "Time 512 QAM (light)", + "MWTN_TIME512_STATES": "time512-states", + "MWTN_TIME512_STATES_L": "time512-states-l", + "MWTN_TIME64SYMBOLS": "Time 64 QAM", + "MWTN_TIME64_STATES": "time64-states", + "MWTN_TIME8192SYMBOLS": "Time 8192 QAM", + "MWTN_TIME8192SYMBOLSL": "Time 8192 QAM (light)", + "MWTN_TIME8192_STATES": "time8192-states", + "MWTN_TIME8192_STATES_L": "time8192-states-l", + "MWTN_TIME8SYMBOLS": "Time 8 QAM", + "MWTN_TIME8_STATES": "time8-states", + "MWTN_TIMEPERIOD": "Period", + "MWTN_TIMESLOTCAPACITY": "Time slot capacity", + "MWTN_TIMESLOTID": "Time slot", + "MWTN_TIMESLOTIDLIST": "Time slot identifiers", + "MWTN_TIMESLOTSTATUSLIST": "Time slot status list", + "MWTN_TIMESTAMP": "timestamp", + "MWTN_TIME_PERIOD": "time-period", + "MWTN_TIME_PROPERTIES_DS": "time-properties-ds", + "MWTN_TIME_SOURCE": "time-source", + "MWTN_TIME_STAMP": "time-stamp", + "MWTN_TIME_TRACEABLE": "time-traceable", + "MWTN_TOTALNUMBEROFTIMESLOTS": "Total number of time slots", + "MWTN_TRAFFIC": "Traffic (Logical termination points)", + "MWTN_TRANSMISSIONMODEID": "Transmission mode identifier", + "MWTN_TRANSMISSIONMODELIST": "Transmission modes", + "MWTN_TRANSMISSION_MODE_ID": "transmission-mode-id", + "MWTN_TRANSMISSION_MODE_LIST": "transmission-mode", + "MWTN_TRANSMITTERISON": "transmitterIsOn", + "MWTN_TRANSMITTER_IS_ON": "transmitter-is-on", + "MWTN_TRANSPARENT_CLOCK_DEFAULT_DS": "transparent-clock-default-ds", + "MWTN_TRANSPARENT_CLOCK_PORT_DS_LIST": "transparent-clock-port", + "MWTN_TRIGGER_REFRESH": "trigger-refresh", + "MWTN_TWO_STEP_FLAG": "two-step-flag", + "MWTN_TXCHANNELBANDWIDTH": "txChannelBandwidth", + "MWTN_TXFREQUENCY": "Transmit frequency", + "MWTN_TXFREQUENCYCUR": "txFrequencyCur", + "MWTN_TXFREQUENCYMAX": "txFrequencyMax", + "MWTN_TXFREQUENCYMIN": "txFrequencyMin", + "MWTN_TXLEVELAVG": "Transmit level (avg)", + "MWTN_TXLEVELCUR": "txLevelCur", + "MWTN_TXLEVELMAX": "Transmit level (max)", + "MWTN_TXLEVELMIN": "Transmit level (min)", + "MWTN_TXPOWER": "txPower", + "MWTN_TXPOWERMAX": "Max tx power", + "MWTN_TXPOWERMIN": "Min tx power", + "MWTN_TX_CHANNEL_BANDWIDTH": "tx-channel-bandwidth", + "MWTN_TX_ETHERNET_BYTES_MAX_M": "tx-ethernet-bytes-max-m", + "MWTN_TX_ETHERNET_BYTES_MAX_S": "tx-ethernet-bytes-max-s", + "MWTN_TX_ETHERNET_BYTES_SUM": "tx-ethernet-bytes-sum", + "MWTN_TX_FREQUENCY": "tx-frequency", + "MWTN_TX_FREQUENCY_CUR": "tx-frequency-cur", + "MWTN_TX_FREQUENCY_MAX": "tx-frequency-max", + "MWTN_TX_FREQUENCY_MIN": "tx-frequency-min", + "MWTN_TX_LEVEL_AVG": "tx-level-avg", + "MWTN_TX_LEVEL_CUR": "tx-level-cur", + "MWTN_TX_LEVEL_MAX": "tx-level-max", + "MWTN_TX_LEVEL_MIN": "tx-level-min", + "MWTN_TX_POWER": "tx-power", + "MWTN_TX_POWER_MAX": "tx-power-max", + "MWTN_TX_POWER_MIN": "tx-power-min", + "MWTN_TYPEOFEQUIPMENT": "typeOfEquipment", + "MWTN_TYPE_NAME": "type-name", + "MWTN_TYPE_OF_EQUIPMENT": "type-of-equipment", + "MWTN_UNAVAILABILITY": "unavailability", + "MWTN_UNIVERSALIDAUTHORITY": "UniversalIdAuthority", + "MWTN_USERNAME": "User name", + "MWTN_UUID": "UUID", + "MWTN_VALUE": "value", + "MWTN_VALUE_NAME": "value-name", + "MWTN_VERSION": "version", + "MWTN_VERSION_NUMBER": "version-number", + "MWTN_VLANCOMPRESSIONISAVAIL": "vlanCompressionIsAvail", + "MWTN_VLANCOMPRESSIONISON": "vlanCompressionIsOn", + "MWTN_VLAN_COMPRESSION_IS_AVAIL": "vlan-compression-is-avail", + "MWTN_VLAN_COMPRESSION_IS_ON": "vlan-compression-is-on", + "MWTN_VLAN_ID": "vlan-id", + "MWTN_WAITTORESTORETIME": "waitToRestoreTime", + "MWTN_WAIT_TO_RESTORE_TIME": "wait-to-restore-time", + "MWTN_WAIT_TO_REVERT_TIME": "wait-to-revert-time", + "MWTN_WEIGHT_CHARACTERISTICS": "weight-characteristics", + "MWTN_WIDTH": "width", + "MWTN_X_CONNECTIONS": "Cross connections", + "MWTN_XPDAVG": "Cross polarization discrimination (avg)", + "MWTN_XPDCUR": "xpdCur", + "MWTN_XPDMAX": "Cross polarization discrimination (max)", + "MWTN_XPDMIN": "Cross polarization discrimination (min)", + "MWTN_XPD_AVG": "xpd-avg", + "MWTN_XPD_CUR": "xpd-cur", + "MWTN_XPD_MAX": "xpd-max", + "MWTN_XPD_MIN": "xpd-min", + "MWTN_XPICISAVAIL": "xPic", + "MWTN_XPICISON": "xpicIsOn", + "MWTN_XPICISUP": "xpicIsUp", + "MWTN_XPIC_IS_AVAIL": "xpic-is-avail", + "MWTN_XPIC_IS_ON": "xpic-is-on", + "MWTN_XPIC_IS_UP": "xpic-is-up", + "MWTN_YANG_CAPABILITIES": "Yang capabilities", + "MWTN__CLIENTLTPREFLIST": "_clientLtpRefList", + "MWTN__CONNECTEDLTPREF": "_connectedLtpRef", + "MWTN__FCPORTLIST": "_fcPortList", + "MWTN__FCREFLIST": "_fcRefList", + "MWTN__FCSWITCHLIST": "_fcSwitchList", + "MWTN__FDREFLIST": "_fdRefList", + "MWTN__LOWERLEVELFCREFLIST": "_lowerLevelFcRefList", + "MWTN__LOWERLEVELFDREFLIST": "_lowerLevelFdRefList", + "MWTN__LPLIST": "_lpList", + "MWTN__LTPREFLIST": "_ltpRefList", + "MWTN__PEERLTPREF": "_peerLtpRef", + "MWTN__SELECTEDFCPORTREFLIST": "_selectedFcPortRefList", + "MWTN__SERVERLTPREFLIST": "_serverLtpRefList", + "MWTN_«Q.822»-CURRENTDATA": "«Q.822»-CurrentData", + "MWTN_«Q.822»-HISTORYDATA": "«Q.822»-HistoryData", + "MWTN_«X.721»-TOP": "«X.721»-Top", + "MWTN_«X.739»-SCANNER": "«X.739»-Scanner" +}
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons-custom.css new file mode 100644 index 00000000..cf22c146 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons-custom.css @@ -0,0 +1,108 @@ +/** + * Add your application related css here + */ + .ht-header { + display: block; + height: 32px; +} +.ht-header-right { + float: right; +} + +.owl { + padding:5px; +} +.owl-dark { + color: #414042; +} + +.owl .owl-dark { + color: #414042; +} + +.owl span { + color: white; +} + +.owl a span { + color: white; +} + +.owl .panel-default span { + color: #414042; +} + +.owl .panel-default a span.owl-dark { + color: #414042; +} + +.owl .panel-default .mwtn-json-viewer span.owl-dark { + color: #414042; +} + +.owl .panel-default .json-formatter-row .string{color:green;white-space:pre;word-wrap:break-word} +.owl .panel-default .json-formatter-row .number{color:#00f} +.owl .panel-default .json-formatter-row .boolean{color:red} +.owl .panel-default .json-formatter-row .null{color:#855A00} +.owl .panel-default .json-formatter-row .undefined{color:#ca0b69} +.owl .panel-default .json-formatter-row .function{color:#FF20ED} +.owl .panel-default .json-formatter-row .date{background-color:rgba(0,0,0,.05)} +.owl .panel-default .json-formatter-row .url{text-decoration:underline;color:#00f;cursor:pointer} +.owl .panel-default .json-formatter-row a span.bracket{color:#00f} +.owl .panel-default .json-formatter-row a span.key{color:#00008B;cursor:pointer} +.owl .panel-default .json-formatter-row a span.constructor-name{color: #888888; cursor:pointer} + +.mwtn-grid { + background-color: white; + color:black; +} + +@media (min-width: 1296px) { + .modal-huge { + width: 1200px; + } +} + + +.form-group span.mwtnError { + color: red; +} + +.mwtnLight { + color: white; +} + +.panel-group .panel-default span .mwtnError { + color: red; +} + +.mwtnSuccess { + color: darkgreen; +} + +.panel-group .panel-default span .mwtnSuccess { + color: darkgreen; +} + +.number { + text-align: right; +} + +.rotated { + transform: rotate(180deg); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -o-transform: rotate(180deg); +} + +.vCenter { + margin: 5px 30px 5px 0px; + display: inline-block; + vertical-align: middle; + float: none; +} + +a.vCenter { + text-decoration: none; +} diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.controller.js new file mode 100644 index 00000000..872c2aa8 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.controller.js @@ -0,0 +1,25 @@ +/* + * 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/mwtnCommons/mwtnCommons.module', + 'app/mwtnCommons/mwtnCommons.services'], function(mwtnCommonsApp) { + + mwtnCommonsApp.register.controller('mwtnCommonsCtrl', ['$scope', '$rootScope', '$mwtnCommons', '$mwtnLog', 'FileReader', + function($scope, $rootScope, $mwtnCommons, $mwtnLog, FileReader) { + + $rootScope.section_logo = ''; // Add your topbar logo location here such as 'assets/images/logo_topology.gif' + + $scope.mwtnCommonsInfo = {}; + + $mwtnCommons.getData(function(data){ + $scope.data = data; + }); + + }]); + +}); diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.module.js new file mode 100755 index 00000000..ebc515ca --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.module.js @@ -0,0 +1,622 @@ +/* + * 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/bower_components/angular-ui-grid/ui-grid.min', + 'app/mwtnCommons/bower_components/chart.js/dist/Chart', + 'app/mwtnCommons/bower_components/angular-chart.js/dist/angular-chart', + 'app/mwtnCommons/bower_components/angular-clipboard/angular-clipboard', + 'ui-bootstrap', + 'app/mwtnCommons/bower_components/json-formatter/dist/json-formatter.min'], + function(ng) { + var mwtnCommonsApp = angular.module('app.mwtnCommons', ['app.core','chart.js', 'ui.router.state', 'ui.grid', 'ui.bootstrap', 'jsonFormatter', 'config', 'pascalprecht.translate', 'angular-clipboard']); + + mwtnCommonsApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) { + mwtnCommonsApp.register = { + controller : $controllerProvider.register, + directive : $compileProvider.directive, + factory : $provide.factory, + service : $provide.service + }; + + $translatePartialLoaderProvider.addPart('app/mwtnCommons/locale/locale'); + + var access = routingConfig.accessLevels; + + }); + + mwtnCommonsApp.directive('htHeader', [ '$injector' ,function ($injector) { + return { + template: '<div class="ht-header"><div class="ht-header-right"><alarm-status ng-if="mwtnFaultExists"></alarm-status><help ng-if="helpExists" link="{{helpLink}}" ></help></div></div>', + controller: ['$scope', function ($scope) { + $scope.helpExists = $injector.has('helpDirective'); + $scope.mwtnFaultExists = $injector.has('alarmStatusDirective'); + }], + restict: "EA", + replace: true, + scope: { + helpLink: "@" + } + }; + }]); + + + return mwtnCommonsApp; +}); + + +/* + Copyright 2011-2013 Abdulla Abdurakhmanov + Original sources are available at https://code.google.com/p/x2js/ + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function X2JS(config) { + 'use strict'; + + var VERSION = "1.1.5"; + + config = config || {}; + initConfigDefaults(); + initRequiredPolyfills(); + + function initConfigDefaults() { + if(config.escapeMode === undefined) { + config.escapeMode = true; + } + config.attributePrefix = config.attributePrefix || "_"; + config.arrayAccessForm = config.arrayAccessForm || "none"; + config.emptyNodeForm = config.emptyNodeForm || "text"; + if(config.enableToStringFunc === undefined) { + config.enableToStringFunc = true; + } + config.arrayAccessFormPaths = config.arrayAccessFormPaths || []; + if(config.skipEmptyTextNodesForObj === undefined) { + config.skipEmptyTextNodesForObj = true; + } + if(config.stripWhitespaces === undefined) { + config.stripWhitespaces = true; + } + config.datetimeAccessFormPaths = config.datetimeAccessFormPaths || []; + } + + var DOMNodeTypes = { + ELEMENT_NODE : 1, + TEXT_NODE : 3, + CDATA_SECTION_NODE : 4, + COMMENT_NODE : 8, + DOCUMENT_NODE : 9 + }; + + function initRequiredPolyfills() { + function pad(number) { + var r = String(number); + if ( r.length === 1 ) { + r = '0' + r; + } + return r; + } + // Hello IE8- + if(typeof String.prototype.trim !== 'function') { + String.prototype.trim = function() { + return this.replace(/^\s+|^\n+|(\s|\n)+$/g, ''); + } + } + if(typeof Date.prototype.toISOString !== 'function') { + // Implementation from http://stackoverflow.com/questions/2573521/how-do-i-output-an-iso-8601-formatted-string-in-javascript + Date.prototype.toISOString = function() { + return this.getUTCFullYear() + + '-' + pad( this.getUTCMonth() + 1 ) + + '-' + pad( this.getUTCDate() ) + + 'T' + pad( this.getUTCHours() ) + + ':' + pad( this.getUTCMinutes() ) + + ':' + pad( this.getUTCSeconds() ) + + '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 ) + + 'Z'; + }; + } + } + + function getNodeLocalName( node ) { + var nodeLocalName = node.localName; + if(nodeLocalName == null) // Yeah, this is IE!! + nodeLocalName = node.baseName; + if(nodeLocalName == null || nodeLocalName=="") // =="" is IE too + nodeLocalName = node.nodeName; + return nodeLocalName; + } + + function getNodePrefix(node) { + return node.prefix; + } + + function escapeXmlChars(str) { + if(typeof(str) == "string") + return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/'); + else + return str; + } + + function unescapeXmlChars(str) { + return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(///g, '\/'); + } + + function toArrayAccessForm(obj, childName, path) { + switch(config.arrayAccessForm) { + case "property": + if(!(obj[childName] instanceof Array)) + obj[childName+"_asArray"] = [obj[childName]]; + else + obj[childName+"_asArray"] = obj[childName]; + break; + /*case "none": + break;*/ + } + + if(!(obj[childName] instanceof Array) && config.arrayAccessFormPaths.length > 0) { + var idx = 0; + for(; idx < config.arrayAccessFormPaths.length; idx++) { + var arrayPath = config.arrayAccessFormPaths[idx]; + if( typeof arrayPath === "string" ) { + if(arrayPath == path) + break; + } + else + if( arrayPath instanceof RegExp) { + if(arrayPath.test(path)) + break; + } + else + if( typeof arrayPath === "function") { + if(arrayPath(obj, childName, path)) + break; + } + } + if(idx!=config.arrayAccessFormPaths.length) { + obj[childName] = [obj[childName]]; + } + } + } + + function fromXmlDateTime(prop) { + // Implementation based up on http://stackoverflow.com/questions/8178598/xml-datetime-to-javascript-date-object + // Improved to support full spec and optional parts + var bits = prop.split(/[-T:+Z]/g); + + var d = new Date(bits[0], bits[1]-1, bits[2]); + var secondBits = bits[5].split("\."); + d.setHours(bits[3], bits[4], secondBits[0]); + if(secondBits.length>1) + d.setMilliseconds(secondBits[1]); + + // Get supplied time zone offset in minutes + if(bits[6] && bits[7]) { + var offsetMinutes = bits[6] * 60 + Number(bits[7]); + var sign = /\d\d-\d\d:\d\d$/.test(prop)? '-' : '+'; + + // Apply the sign + offsetMinutes = 0 + (sign == '-'? -1 * offsetMinutes : offsetMinutes); + + // Apply offset and local timezone + d.setMinutes(d.getMinutes() - offsetMinutes - d.getTimezoneOffset()) + } + else + if(prop.indexOf("Z", prop.length - 1) !== -1) { + d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds())); + } + + // d is now a local time equivalent to the supplied time + return d; + } + + function checkFromXmlDateTimePaths(value, childName, fullPath) { + if(config.datetimeAccessFormPaths.length > 0) { + var path = fullPath.split("\.#")[0]; + var idx = 0; + for(; idx < config.datetimeAccessFormPaths.length; idx++) { + var dtPath = config.datetimeAccessFormPaths[idx]; + if( typeof dtPath === "string" ) { + if(dtPath == path) + break; + } + else + if( dtPath instanceof RegExp) { + if(dtPath.test(path)) + break; + } + else + if( typeof dtPath === "function") { + if(dtPath(obj, childName, path)) + break; + } + } + if(idx!=config.datetimeAccessFormPaths.length) { + return fromXmlDateTime(value); + } + else + return value; + } + else + return value; + } + + function parseDOMChildren( node, path ) { + if(node.nodeType == DOMNodeTypes.DOCUMENT_NODE) { + var result = new Object; + var nodeChildren = node.childNodes; + // Alternative for firstElementChild which is not supported in some environments + for(var cidx=0; cidx <nodeChildren.length; cidx++) { + var child = nodeChildren.item(cidx); + if(child.nodeType == DOMNodeTypes.ELEMENT_NODE) { + var childName = getNodeLocalName(child); + result[childName] = parseDOMChildren(child, childName); + } + } + return result; + } + else + if(node.nodeType == DOMNodeTypes.ELEMENT_NODE) { + var result = new Object; + result.__cnt=0; + + var nodeChildren = node.childNodes; + + // Children nodes + for(var cidx=0; cidx <nodeChildren.length; cidx++) { + var child = nodeChildren.item(cidx); // nodeChildren[cidx]; + var childName = getNodeLocalName(child); + + if(child.nodeType!= DOMNodeTypes.COMMENT_NODE) { + result.__cnt++; + if(result[childName] == null) { + result[childName] = parseDOMChildren(child, path+"."+childName); + toArrayAccessForm(result, childName, path+"."+childName); + } + else { + if(result[childName] != null) { + if( !(result[childName] instanceof Array)) { + result[childName] = [result[childName]]; + toArrayAccessForm(result, childName, path+"."+childName); + } + } + (result[childName])[result[childName].length] = parseDOMChildren(child, path+"."+childName); + } + } + } + + // Attributes + for(var aidx=0; aidx <node.attributes.length; aidx++) { + var attr = node.attributes.item(aidx); // [aidx]; + result.__cnt++; + result[config.attributePrefix+attr.name]=attr.value; + } + + // Node namespace prefix + var nodePrefix = getNodePrefix(node); + if(nodePrefix!=null && nodePrefix!="") { + result.__cnt++; + result.__prefix=nodePrefix; + } + + if(result["#text"]!=null) { + result.__text = result["#text"]; + if(result.__text instanceof Array) { + result.__text = result.__text.join("\n"); + } + if(config.escapeMode) + result.__text = unescapeXmlChars(result.__text); + if(config.stripWhitespaces) + result.__text = result.__text.trim(); + delete result["#text"]; + if(config.arrayAccessForm=="property") + delete result["#text_asArray"]; + result.__text = checkFromXmlDateTimePaths(result.__text, childName, path+"."+childName); + } + if(result["#cdata-section"]!=null) { + result.__cdata = result["#cdata-section"]; + delete result["#cdata-section"]; + if(config.arrayAccessForm=="property") + delete result["#cdata-section_asArray"]; + } + + if( result.__cnt == 1 && result.__text!=null ) { + result = result.__text; + } + else + if( result.__cnt == 0 && config.emptyNodeForm=="text" ) { + result = ''; + } + else + if ( result.__cnt > 1 && result.__text!=null && config.skipEmptyTextNodesForObj) { + if( (config.stripWhitespaces && result.__text=="") || (result.__text.trim()=="")) { + delete result.__text; + } + } + delete result.__cnt; + + if( config.enableToStringFunc && (result.__text!=null || result.__cdata!=null )) { + result.toString = function() { + return (this.__text!=null? this.__text:'')+( this.__cdata!=null ? this.__cdata:''); + }; + } + + return result; + } + else + if(node.nodeType == DOMNodeTypes.TEXT_NODE || node.nodeType == DOMNodeTypes.CDATA_SECTION_NODE) { + return node.nodeValue; + } + } + + function startTag(jsonObj, element, attrList, closed) { + var resultStr = "<"+ ( (jsonObj!=null && jsonObj.__prefix!=null)? (jsonObj.__prefix+":"):"") + element; + if(attrList!=null) { + for(var aidx = 0; aidx < attrList.length; aidx++) { + var attrName = attrList[aidx]; + var attrVal = jsonObj[attrName]; + if(config.escapeMode) + attrVal=escapeXmlChars(attrVal); + resultStr+=" "+attrName.substr(config.attributePrefix.length)+"='"+attrVal+"'"; + } + } + if(!closed) + resultStr+=">"; + else + resultStr+="/>"; + return resultStr; + } + + function endTag(jsonObj,elementName) { + return "</"+ (jsonObj.__prefix!=null? (jsonObj.__prefix+":"):"")+elementName+">"; + } + + function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function jsonXmlSpecialElem ( jsonObj, jsonObjField ) { + if((config.arrayAccessForm=="property" && endsWith(jsonObjField.toString(),("_asArray"))) + || jsonObjField.toString().indexOf(config.attributePrefix)==0 + || jsonObjField.toString().indexOf("__")==0 + || (jsonObj[jsonObjField] instanceof Function) ) + return true; + else + return false; + } + + function jsonXmlElemCount ( jsonObj ) { + var elementsCnt = 0; + if(jsonObj instanceof Object ) { + for( var it in jsonObj ) { + if(jsonXmlSpecialElem ( jsonObj, it) ) + continue; + elementsCnt++; + } + } + return elementsCnt; + } + + function parseJSONAttributes ( jsonObj ) { + var attrList = []; + if(jsonObj instanceof Object ) { + for( var ait in jsonObj ) { + if(ait.toString().indexOf("__")== -1 && ait.toString().indexOf(config.attributePrefix)==0) { + attrList.push(ait); + } + } + } + return attrList; + } + + function parseJSONTextAttrs ( jsonTxtObj ) { + var result =""; + + if(jsonTxtObj.__cdata!=null) { + result+="<![CDATA["+jsonTxtObj.__cdata+"]]>"; + } + + if(jsonTxtObj.__text!=null) { + if(config.escapeMode) + result+=escapeXmlChars(jsonTxtObj.__text); + else + result+=jsonTxtObj.__text; + } + return result; + } + + function parseJSONTextObject ( jsonTxtObj ) { + var result =""; + + if( jsonTxtObj instanceof Object ) { + result+=parseJSONTextAttrs ( jsonTxtObj ); + } + else + if(jsonTxtObj!=null) { + if(config.escapeMode) + result+=escapeXmlChars(jsonTxtObj); + else + result+=jsonTxtObj; + } + + return result; + } + + function parseJSONArray ( jsonArrRoot, jsonArrObj, attrList ) { + var result = ""; + if(jsonArrRoot.length == 0) { + result+=startTag(jsonArrRoot, jsonArrObj, attrList, true); + } + else { + for(var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) { + result+=startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false); + result+=parseJSONObject(jsonArrRoot[arIdx]); + result+=endTag(jsonArrRoot[arIdx],jsonArrObj); + } + } + return result; + } + + function parseJSONObject ( jsonObj ) { + var result = ""; + + var elementsCnt = jsonXmlElemCount ( jsonObj ); + + if(elementsCnt > 0) { + for( var it in jsonObj ) { + + if(jsonXmlSpecialElem ( jsonObj, it) ) + continue; + + var subObj = jsonObj[it]; + + var attrList = parseJSONAttributes( subObj ) + + if(subObj == null || subObj == undefined) { + result+=startTag(subObj, it, attrList, true); + } + else + if(subObj instanceof Object) { + + if(subObj instanceof Array) { + result+=parseJSONArray( subObj, it, attrList ); + } + else if(subObj instanceof Date) { + result+=startTag(subObj, it, attrList, false); + result+=subObj.toISOString(); + result+=endTag(subObj,it); + } + else { + var subObjElementsCnt = jsonXmlElemCount ( subObj ); + if(subObjElementsCnt > 0 || subObj.__text!=null || subObj.__cdata!=null) { + result+=startTag(subObj, it, attrList, false); + result+=parseJSONObject(subObj); + result+=endTag(subObj,it); + } + else { + result+=startTag(subObj, it, attrList, true); + } + } + } + else { + result+=startTag(subObj, it, attrList, false); + result+=parseJSONTextObject(subObj); + result+=endTag(subObj,it); + } + } + } + result+=parseJSONTextObject(jsonObj); + + return result; + } + + this.parseXmlString = function(xmlDocStr) { + var isIEParser = window.ActiveXObject || "ActiveXObject" in window; + if (xmlDocStr === undefined) { + return null; + } + var xmlDoc; + if (window.DOMParser) { + var parser=new window.DOMParser(); + var parsererrorNS = null; + // IE9+ now is here + if(!isIEParser) { + try { + parsererrorNS = parser.parseFromString("INVALID", "text/xml").childNodes[0].namespaceURI; + } + catch(err) { + parsererrorNS = null; + } + } + try { + xmlDoc = parser.parseFromString( xmlDocStr, "text/xml" ); + if( parsererrorNS!= null && xmlDoc.getElementsByTagNameNS(parsererrorNS, "parsererror").length > 0) { + //throw new Error('Error parsing XML: '+xmlDocStr); + xmlDoc = null; + } + } + catch(err) { + xmlDoc = null; + } + } + else { + // IE :( + if(xmlDocStr.indexOf("<?")==0) { + xmlDocStr = xmlDocStr.substr( xmlDocStr.indexOf("?>") + 2 ); + } + xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.async="false"; + xmlDoc.loadXML(xmlDocStr); + } + return xmlDoc; + }; + + this.asArray = function(prop) { + if(prop instanceof Array) + return prop; + else + return [prop]; + }; + + this.toXmlDateTime = function(dt) { + if(dt instanceof Date) + return dt.toISOString(); + else + if(typeof(dt) === 'number' ) + return new Date(dt).toISOString(); + else + return null; + }; + + this.asDateTime = function(prop) { + if(typeof(prop) == "string") { + return fromXmlDateTime(prop); + } + else + return prop; + }; + + this.xml2json = function (xmlDoc) { + return parseDOMChildren ( xmlDoc ); + }; + + this.xml_str2json = function (xmlDocStr) { + var xmlDoc = this.parseXmlString(xmlDocStr); + if(xmlDoc!=null) + return this.xml2json(xmlDoc); + else + return null; + }; + + this.json2xml_str = function (jsonObj) { + return parseJSONObject ( jsonObj ); + }; + + this.json2xml = function (jsonObj) { + var xmlDocStr = this.json2xml_str (jsonObj); + return this.parseXmlString(xmlDocStr); + }; + + this.getVersion = function () { + return VERSION; + }; + +}
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.services.js new file mode 100644 index 00000000..9a713436 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.services.js @@ -0,0 +1,3826 @@ +/* + * @copyright 2017 highstreet technologies GmbH and others. All rights reserved. + * + * @license + * 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 {@link http://www.eclipse.org/legal/epl-v10.html} + */ + +if (!String.prototype.toHumanReadableTimeFormat) { + String.prototype.toHumanReadableTimeFormat = function () { + return this.replace(/T/g, ' ').replace(/Z/g, ' UTC').replace(/\+00:00/g, ' UTC'); + }; +} + +if (!String.prototype.base64ToHex) { + String.prototype.base64ToHex = function () { + var raw = atob(this); + var result = []; + for ( i = 0; i < raw.length; i++ ) { + var _hex = raw.charCodeAt(i).toString(16) + result.push('0x' + ( _hex.length === 2 ? _hex:'0' + _hex)); + } + return result.join(' '); + }; +} + +if (!String.prototype.contains) { + /** + * An extension to String, which checks whether another string is contained. + * @param {string} find A string to be checked, whether it is contained in 'this'. + * @return {boolean} True, if 'this' contains param 'find', otherwise false. + */ + String.prototype.contains = function (find) { + return this.indexOf(find) > -1; + }; +} + +if (!String.prototype.format) { + /** + * An extension to String, which replaces certain patterns by arguments. + * @see {@link https://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format|javascript-equivalent-to-printf-string-format} + * @return {string} Formated string. + */ + String.prototype.format = function () { + var args = arguments; + return this.replace(/{(\d+)}/g, function (match, number) { + return typeof args[number] !== 'undefined' ? args[number] : match + ; + }); + }; +} + +if (!String.prototype.replaceAll) { + /** + * An extension to String, which replaces certain patterns by arguments. + * @see {@link https://stackoverflow.com/questions/1144783/how-to-replace-all-occurrences-of-a-string-in-javascript|how-to-replace-all-occurrences-of-a-string-in-javascript} + * @param {string} find - The string which should be replaced. + * @param {string} replace - The string which should replace 'find'. + * @return {string} String where 'find' is replaced by 'replace'. + */ + String.prototype.replaceAll = function (find, replace) { + return this.replace(new RegExp(find, 'g'), replace); + } +} + +if (!Array.prototype.contains) { + /** + * An extension to Array checking whether an array of primitive types contains a given value. + * @param {string|number|boolean|null|undefined} find An object which should be removed from the array. + * @return {boolean} True, if 'this' contains param 'find', otherwise false.. + */ + Array.prototype.contains = function (find) { + return this.indexOf(find) > -1; + }; +} + +if (!Array.prototype.clean) { + /** + * An extension to Array removing defined values from an array. + * @see {@link https://gist.github.com/waynegraham/3684627|Array.clean()} + * @param {Object} deleteValue An object which should be removed from the array. + * @return {Array} An array without 'deleteValue'. + */ + Array.prototype.clean = function (deleteValue) { + for (var i = 0; i < this.length; i++) { // TODO swtich to .map() ? + if (this[i] === deleteValue) { + this.splice(i, 1); + i--; + } + } + return this; + }; +} + +define( + ['app/mwtnCommons/mwtnCommons.module'], + function (mwtnCommonsApp) { + + mwtnCommonsApp.register.controller('mwtnFooterController', ['$scope', function ($scope) { + var vm = this; + $scope.prefix = 'ONF Wireless for OpenDaylight Boron-SR3'; + }]); + + mwtnCommonsApp.register.directive('mwtnFooter', function () { + return { + restrict: 'E', + controller: 'mwtnFooterController', + controllerAs: 'vm', + templateUrl: 'src/app/mwtnCommons/templates/mwtnFooter.tpl.html' + }; + }); + + mwtnCommonsApp.register.controller('openConfigViewController', ['$scope', '$uibModalInstance', '$mwtnGlobal', '$mwtnCommons', '$mwtnDatabase', '$mwtnLog', 'valueData', + function ($scope, $uibModalInstance, $mwtnGlobal, $mwtnCommons, $mwtnDatabase, $mwtnLog, data) { + + var vm = this; + var COMPONENT = 'openConfigViewController'; + + $scope.getType = $mwtnGlobal.getType; + $scope.spec = data.spec; + $mwtnCommons.getConditionalPackagePart($scope.spec).then(function (success) { + + var getControlType = function(type) { + var result = 'text' + switch (type) { + case 'boolean': + result = 'checkbox'; + break; + case 'number': + result = 'number'; + break; + case 'string': + case 'array': + case 'object': + break; + default: + var message = 'Check control type for ' + type; + $mwtnLog.warning({ component: COMPONENT, message: message }); + } + return result; + }; + + success.layerProtocol = $scope.spec.layerProtocolId; + $scope.configuredData = success; + $scope.newData = $scope.configuredData[$scope.spec.partId]; + + $scope.viewData = $mwtnGlobal.getViewData($scope.configuredData[$scope.spec.partId], $scope.ne); + $mwtnDatabase.getSchema().then(function(schema){ + var ordered = {}; + var clone = JSON.parse(JSON.stringify($scope.viewData)); + var keys = Object.keys(clone).map(function(key){ + if ($mwtnGlobal.getType(key) !== 'string') { + console.log('key', key); + return; + } + var item = clone[key]; + if (!schema[key]) { + + var message = 'No schema information for ' + key; + console.error(key, schema[key]); + $mwtnLog.warning({ component: COMPONENT, message: message }); + item['order-number'] = $mwtnCommons.getOrderNumber(97, item); + item.description = 'No description available.'; + item.visible = true; + return key; + } + if (schema[key].controlType === undefined) { + item.controlType = getControlType(item.type); + } else { + item.controlType = schema[key].controlType; + } + item.unit = schema[key].unit; + item.description = schema[key].description; + item['order-number'] = $mwtnCommons.getOrderNumber(schema[key]['order-number'], item); + if (item.description === undefined || item.description === '') { + item.description = 'No description available.'; + } + // hide complex types for now -> TODO + if (item.type === 'array' || item.type === 'object') { + item.visible = false; + } + return key; + }).sort(function(a,b){ + if (clone[a]['order-number'] < clone[b]['order-number']) return -1; + if (clone[a]['order-number'] > clone[b]['order-number']) return 1; + return 0; + }).map(function(key){ + ordered[key] = clone[key]; + }); + $scope.viewData = ordered; + }, function(error){ + $scope.empty = true; + }); + + }, function (error) { + $scope.configuredData = undefined; + $mwtnLog.error({ component: COMPONENT, message: 'Requesting conditional package of ' + JSON.stringify($scope.spec) + ' failed!' }); + }); + + $scope.ok = function () { + $scope.processing = true; + Object.keys($scope.viewData).map(function(key){ + $scope.newData[key] = $scope.viewData[key].value; + }); + + $mwtnCommons.setConditionalPackagePart($scope.spec, $scope.newData).then(function(success){ + $scope.applied = {text: 'Applied: ' + new Date().toISOString(), class:'mwtnSuccess'}; + $scope.processing = false; + }, function(error){ + $scope.applied = {text: 'Error: ' + new Date().toISOString(), class:'mwtnError'}; + $scope.processing = false; + $mwtnLog.error({component: COMPONENT, message: JSON.stringify(error)}); + }); + + }; + + $scope.cancel = function () { + $uibModalInstance.close($scope.newData); + }; + + }]); + + mwtnCommonsApp.register.controller('mwtnJsonViewerController', ['$scope', '$uibModal', '$mwtnGlobal', '$mwtnCommons', '$mwtnDatabase', '$mwtnLog', + function ($scope, $uibModal, $mwtnGlobal, $mwtnCommons, $mwtnDatabase, $mwtnLog) { + var vm = this; + var COMPONENT = 'mwtnJsonViewerController'; + $scope.getType = $mwtnGlobal.getType; + + if ($scope.data) { + $scope.replace = false; + if ($scope.path && $scope.path.endsWith('-configuration') ) { + $scope.replace = true; + } + $scope.viewData = $mwtnGlobal.getViewData($scope.data, $scope.ne); + var path = [undefined, undefined, undefined]; + if ($scope.path) { + path = $scope.path.split($mwtnCommons.separator); + } + $scope.spec = { + nodeId: $scope.networkElement, + revision: '2017-03-20', + pacId: path[0], + layer: '???', + layerProtocolId: path[1], + partId: path[2], + config: true + }; + + $scope.openConfigView = function(){ + var modalInstance = $uibModal.open({ + animation: true, + ariaLabelledBy: 'modal-title', + ariaDescribedBy: 'modal-body', + templateUrl: 'src/app/mwtnCommons/templates/openConfigView.html', + controller: 'openConfigViewController', + size: 'huge', + resolve: { + valueData: function () { + return {spec:$scope.spec}; + } + } + }); + modalInstance.result.then(function(object) { + // update fetch new data from ODL + $mwtnCommons.getPacParts($scope.spec).then(function(success){ + // intermedite step to display something, even processing fails or takes time + $scope.viewData = $mwtnGlobal.getViewData(success[$scope.spec.partId], $scope.ne); + // now the nice way ;) + $scope.viewData = processData($scope.schema); + }, function(error){ + // ignore; + }); + }, function () { + // ignore; + }); + }; + + $scope.myClipboard = { + data: [$scope.data], + supported: true, + getJson: function () { + return JSON.stringify(this.data, null, ' '); + }, + copyToClipboard: function () { + var message = 'Copied to clipboard! ' + this.getJson(); + $mwtnLog.info({ component: COMPONENT, message: message }); + }, + error: function (err) { + $mwtnLog.error({ component: COMPONENT, message: err }); + } + }; + + var processData = function(schema) { + var ordered = {}; + var clone = JSON.parse(JSON.stringify($scope.viewData)); + var keys = Object.keys(clone).map(function(key){ + if ($mwtnGlobal.getType(key) !== 'string') { + console.log('key', key); + return; + } + var item = clone[key]; + if (!schema[key]) { + var message = 'No schema information for ' + key; + $mwtnLog.warning({ component: COMPONENT, message: message }); + item['order-number'] = $mwtnCommons.getOrderNumber(97, item); + item.description = 'No description available.'; + item.visible = true; + return key; + } + item.unit = schema[key].unit; + item.description = schema[key].description; + item['order-number'] = $mwtnCommons.getOrderNumber(schema[key]['order-number'], item); + if (item.description === undefined || item.description === '') { + item.description = 'No description available.'; + } + return key; + }).sort(function(a,b){ + if (clone[a]['order-number'] < clone[b]['order-number']) return -1; + if (clone[a]['order-number'] > clone[b]['order-number']) return 1; + return 0; + }).map(function(key){ + ordered[key] = clone[key]; + }); + $scope.info = false; + if (Object.keys(ordered).length === 0) { + $scope.info = 'An empty object is displayed. Please check if the NetConf server has send an empty object.'; + } + return ordered; + }; + + $mwtnDatabase.getSchema().then(function(schema){ + $scope.schema = schema; + $scope.viewData = processData($scope.schema); + }, function(error){ + // ignore; + }); + } + }]); + + mwtnCommonsApp.register.directive('mwtnJsonViewer', function () { + return { + restrict: 'E', + scope: { + data: '=', + path: '=', + ne: '=', // flag if ne class + networkElement: '=', + noButtons: '=' + }, + controller: 'mwtnJsonViewerController', + controllerAs: 'vm', + templateUrl: 'src/app/mwtnCommons/templates/mwtnJsonViewer.tpl.html' + }; + }); + + mwtnCommonsApp.register.controller('showGridCellDetailController', ['$scope', '$uibModalInstance', '$mwtnGlobal', 'valueData', + function ($scope, $uibModalInstance, $mwtnGlobal, valueData) { + + $scope.networkElement = valueData.networkElement; + $scope.path = valueData.path; + $scope.type = $mwtnGlobal.getType(valueData.value); + $scope.value = valueData.value; + // $scope.gridOptions = JSON.parse(JSON.stringify($mwtnCommons.gridOptions)); + // $scope.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader; + + console.log('valueData', JSON.stringify(valueData)); + + // $scope.ok = function () { + // $scope.processing = true; + // $mwtnCommons.setPacPartLists($scope.path, $scope.listData).then(function(success){ + // $scope.applied = {text: 'Applied: ' + new Date().toISOString(), class:'mwtnSuccess'}; + // $scope.processing = false; + // }, function(error){ + // $scope.applied = {text: 'Error: ' + new Date().toISOString(), class:'mwtnError'}; + // $scope.processing = false; + // $mwtnLog.error({component: COMPONENT, message: JSON.stringify(error)}); + // }); + + // }; + + $scope.cancel = function () { + $uibModalInstance.dismiss('cancel'); + }; + + }]); + + mwtnCommonsApp.register.controller('mwtnGridController', ['$scope', '$filter', '$uibModal', '$mwtnGlobal', '$mwtnCommons', '$mwtnLog', + function ($scope, $filter, $uibModal, $mwtnGlobal, $mwtnCommons, $mwtnLog) { + var vm = this; + var COMPONENT = 'mwtnGridController'; + + $scope.info = false; + + var data = JSON.parse(JSON.stringify($scope.data)); + if (!data) { + var message = 'No data to be displayed!";' + $mwtnLog.info({ component: COMPONENT, message: message }); + data = [{'message':message}]; + } + + if ($mwtnGlobal.getType(data) !== 'array') { + var message = 'Data must be of type "array"!'; + $mwtnLog.info({ component: COMPONENT, message: message }); + data = [{'message':message}]; + } + + if (data.length === 0) { + var message = 'Data list must have at least one entry!'; + $mwtnLog.info({ component: COMPONENT, message: message }); + data = [{'message':message}]; + } + + if ($mwtnGlobal.getType(data[0]) !== 'object') { + data = data.map(function(item){ + return {value: item}; + }); + } + + $scope.gridOptions = JSON.parse(JSON.stringify($mwtnCommons.gridOptions)); + $scope.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader; + + $scope.getTableHeight = function() { + var rowHeight = 30; + var headerHeight = 40; + var maxCount = 12; + var rowCount = $scope.gridOptions.data.length + 2; + var count = rowCount; + if (rowCount > maxCount) { + count = maxCount; + headerHeight = 31; + } + return { + height: (count * rowHeight + headerHeight) + 'px' + }; + }; + + var getCellTemplate = function(field) { + var object = ['transmission-mode-list', 'performance-data']; + if (object.contains(field)) { + console.warn(JSON.stringify(field)); + return ['<div class="ui-grid-cell-contents">', + '<i class="fa fa-info-circle" aria-hidden="true"', + ' ng-click="grid.appScope.show(grid.getCellValue(row, col))"', + ' style="color: rgb(66, 139, 202); cursor: pointer;"></i> ', + '{{grid.getCellValue(row, col)}}</div>'].join(''); + } + return '<div class="ui-grid-cell-contents">{{grid.getCellValue(row, col)}}</div>'; + }; + $scope.show = function(value){ + // console.warn(JSON.stringify(value)); + var type = $mwtnGlobal.getType(value); + // if (type === 'object') + var modalInstance = $uibModal.open({ + animation: true, + ariaLabelledBy: 'modal-title', + ariaDescribedBy: 'modal-body', + templateUrl: 'src/app/mwtnCommons/templates/showGridCellDetail.html', + controller: 'showGridCellDetailController', + size: 'huge', + resolve: { + valueData: function () { + return {networkElement: $scope.networkElement, path:$scope.path, value:value}; + } + } + }); + }; + var enable = data.length > 10; + $scope.gridOptions.columnDefs = Object.keys(data[0]).map(function (field) { + var type = $mwtnGlobal.getType(data[0][field]); + var labelId = $mwtnGlobal.getLabelId(field); + var displayName = $filter('translate')(labelId); + var visible = $mwtnGlobal.getVisibilityOf(field); + if (labelId.contains('$$') || labelId === 'MWTN_SPEC') { + visible = false; + } + return { + field: field, + type: type, + displayName: displayName, + enableSorting: true, + enableFiltering: enable, + headerCellClass: $scope.highlightFilteredHeader, + cellTemplate: getCellTemplate(field), + cellClass: type, + visible: visible + }; + }); + if ($scope.gridOptions.data.length < 10) { + $scope.gridOptions.minRowsToShow = data.length; // 10 is default + } + $scope.gridOptions.data = data; + // .sort(function(a, b){ + // if (a.type === 'object') return -1; + // if (a.type === 'array' ) return -2; + // return 0; + // }) + + $scope.myClipboard = { + data: $scope.data, + supported: true, + getJson: function () { + return JSON.stringify(this.data, null, ' '); + }, + copyToClipboard: function () { + var message = 'Copied to clipboard! ' + this.getJson(); + $mwtnLog.info({ component: COMPONENT, message: message }); + }, + error: function (err) { + $mwtnLog.error({ component: COMPONENT, message: err }); + } + }; + }]); + + mwtnCommonsApp.register.directive('mwtnGrid', function () { + return { + restrict: 'E', + scope: { + data: '=', + path: '=', + networkElement: '=' + }, + controller: 'mwtnGridController', + controllerAs: 'vm', + templateUrl: 'src/app/mwtnCommons/templates/mwtnGrid.tpl.html' + }; + }); + + mwtnCommonsApp.register.controller('mwtnSelectNetworkElementController', ['$scope', '$state','$mwtnCommons', function ($scope, $state, $mwtnCommons) { + var vm = this; + + /** + * A function which scanns the mountpoints for connected network-elements and adds it to networkElements. + * @param {{"onfAirInterfaceRevision": string, "node-id": string, "netconf-node-topology:connection-status": string}[]} mountpoints An array of mountpoints from OpenDaylight. + */ + var initNodeList = function (mountpoints) { + $scope.loading = true; + $scope.mountPoints = mountpoints; + $scope.networkElements = mountpoints.filter(function (mountpoint) { + return mountpoint['netconf-node-topology:connection-status'] === 'connected'; + }).map(function (mountpoint) { + return { id: mountpoint['node-id'], revision: mountpoint.onfAirInterfaceRevision }; + }).sort(function (a, b) { + if (a.id < b.id) return -1; + if (a.id > b.id) return 1; + return 0; + }); + + + $scope.networkElement = undefined; + if ($state.params.nodeId) { + + } + + console.error('nodeId', $state.params.nodeId); + + // select one of the nodes + /* dont do it in field applications!!!! + var select = parseInt(Math.random() * $scope.networkElements.length); + if (select !== undefined && $scope.networkElements[select]) { + $scope.networkElement = $scope.networkElements[select].id; + $scope.mountpoint = $scope.mountPoints.filter(function (mountpoint) { + return mountpoint['node-id'] === $scope.networkElement; + })[0]; + } + */ + $scope.loading = false; + }; + + $mwtnCommons.getMountPoints().then(function (mountpoints) { + initNodeList(mountpoints); + }, function (error) { + $scope.networkElements = []; + }); + }]); + + mwtnCommonsApp.register.directive('mwtnSelectNetworkElement', function () { + return { + restrict: 'E', + controller: 'mwtnSelectNetworkElementController', + controllerAs: 'vm', + templateUrl: 'src/app/mwtnCommons/templates/mwtnSelectNetworkElement.tpl.html' + }; + }); + + // mwtnCommonsApp.register.factory('$notifying', function($rootScope) { + // return { + // subscribe: function(scope, callback) { + // var handler = $rootScope.$on('notifying-service-event', callback); + // scope.$on('$destroy', handler); + // }, + + // notify: function(text) { + // $rootScope.$emit('notifying-service-event', text); + // } + // }; + // }); + + mwtnCommonsApp.register.factory('$mwtnGlobal', function () { + var service = {}; + + /** + * Returns false, if parameter/attribute should be in visible + * @param {string} field - a json to be analyzed + * @return {boolean} true, if the parameter should be visible, otherwise false. + */ + service.getVisibilityOf = function(field) { + var hide = ['name-binding', 'object-class']; + return !hide.contains(field); + }; + + /** + * Returns the (json) type of a value + * @param {*} value - a json to be analyzed + * @return type of json + */ + service.getType = function (value) { + var result = typeof value; + if (result === 'object' && JSON.stringify(value).substring(0, 1) === '[') { + result = 'array'; + } else if (result === 'object' && value === null) { + result = 'null'; + } else if (result === 'object' && value['value-name'] && value.value) { + result = 'name-value'; + } + return result; + }; + + service.getLabelId = function (string) { + return ['mwtn', string].join('_').replaceAll('-', '_').toUpperCase(); + }; + + var isIntesting = function(key) { + var instesting = ['name', 'local-id', 'label', 'extension', 'physical-port-reference', 'lp', 'server-ltp', 'client-ltp', 'layer-protocol-name']; + return instesting.contains(key); + } + /** + * Returns a simplfies json for display + * @param {*} data - the json to be simplified + * @param {boolean} ne - control parameter for finetuning + * @return a simplfied json for display + */ + service.getViewData = function (data, ne) { + var viewData = JSON.parse(JSON.stringify(data)); + if (ne) { + viewData.ltp = undefined; + viewData.fd = undefined; + } + Object.keys(viewData).map(function (key) { + var type = service.getType(viewData[key]); + var viewValue = { + value: viewData[key], + type: type, + labelId: service.getLabelId(key), + visible: service.getVisibilityOf(key) + }; + viewData[key] = viewValue; + if (type === 'array') { + if (key === 'extension') { + viewValue.value.map(function (item) { + viewData[item['value-name']] = { value: item.value, type: 'string', labelId:service.getLabelId(item['value-name']) }; + }); + viewData[key] = undefined; + } else if (viewValue.value.length === 1 && isIntesting(key)) { + // console.warn(key, JSON.stringify(viewData[key])); + var valueType = service.getType(viewValue.value[0]); + viewData[key].value = viewValue.value[0]; + viewData[key].type = valueType; + + if (valueType === 'object') { + viewData[key].value = service.getViewData(viewValue.value); + } else if (valueType === 'name-value') { + viewData[key].value = viewValue.value.value; + //viewData[key].type = 'string'; + } + } else if (type === 'object') { + viewData[key].value = service.getViewData(viewValue.value); + } + } + }); + return viewData; + }; + return service; + }); + + /** + * Process an array of data synchronously. + * Please see https://gist.github.com/KevinTCoughlin/6901825 + * @param {Array} data An array of data. + * @param {function} processData A function that processes an item of data. + * Signature: function(item, i, callback), where {@code item} is the i'th item, + * {@code i} is the loop index value and {@code calback} is the + * parameterless function to call on completion of processing an item. + * @param {function} done A callback function indecating that all items are processed. + */ + var doSynchronousLoop = function (data, processData, done) { + if (data && data.length > 0) { + var loop = function (data, i, processData, done) { + processData(data[i], i, function () { + if (++i < data.length) { + loop(data, i, processData, done); + } else { + done(); + } + }); + }; + loop(data, 0, processData, done); + } else { + done(); + } + }; + + mwtnCommonsApp.register.factory('$mwtnCommons', function ($http, $q, $mwtnGlobal, $mwtnLog, $mwtnDatabase, LogicalTerminationPoint, PtpClock) { + + var COMPONENT = '$mwtnCommons'; + + var service = { + base: window.location.origin + "/restconf/", + database: {}, + 'sdn-controller': [], + modules: {}, + layerProtocolNameOrder: { + 'MWPS': 6, + 'MWS': 5, + 'ETC': 4, + 'TDM': 3, + 'ETY': 2, + 'ETH-CTP': 1, + 'ETH': 1, + } + }; + + service.getOrderNumber = function(proposal, item){ + var result = proposal; + if (item.type === 'array') { + proposal = 99; + } else if (item.type === 'object') { + proposal = 98; + } else if (item.labelId === 'MWTN_LOCAL_ID') { + proposal = -1; + } else if (item.labelId === 'MWTN_LABEL') { + proposal = -2; + } else if (item.labelId === 'MWTN_NAME') { + proposal = -3; + } else if (item.labelId === 'MWTN_UUID') { + proposal = -4; + } + return proposal; + } + + /** + * A function to get the global-identifier of a condtional package subClass by a specifcation object of such subClass and a local-name. + * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass. + * @param {string} local-name (e.g. current-problems) + * @return {string} globel-identifier of a conditional packages subClass (e.g. 'air-interface-diversity-current-problems') + */ + service.getPartGlobalId = function (spec, localName) { + var address = spec.pacId.split(':'); + var module = address[0]; + var pacName = address[1]; + + // check for unexpected issues + if (!module) { + console.error('not module', module, JSON.stringify(spec)); + return; + } + if (!pacName) { + console.error('not pacName', pacName, JSON.stringify(spec)); + return; + } + if (!service.modules[module]) { + console.error('not service.modules[module]', service.modules[module], JSON.stringify(spec)); + return; + } + if (!service.modules[module][pacName]) { + console.error('not service.modules[module][pacName]', service.modules[module][pacName], JSON.stringify(spec)); + return; + } + if (!service.modules[module]) { + console.error('not ervice.modules[module][pacName][subClass]', service.modules[module][pacName][subClass], JSON.stringify(spec)); + return; + } + + return Object.keys(service.modules[module][pacName]).filter(function (subClass) { + return service.modules[module][pacName][subClass]['local-name'] === localName; + }).map(function (subClass) { + return service.modules[module][pacName][subClass].name; + })[0]; + + }; + + /** + * A function to get the local-name of a condtional package subClass by a specifcation object of such subClass. + * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass + * @return {string} local-name of a conditional packages subClass (e.g. 'current-problems') + */ + service.getPartLocalId = function (spec) { + var result; + Object.keys(service.modules).map(function (module) { + Object.keys(service.modules[module]).filter(function (pacName) { + return spec.pacId === [module, pacName].join(':') && service.modules[module][pacName][spec.partId].name === spec.partId; + }).map(function (pacName) { + result = service.modules[module][pacName][spec.partId]['local-name']; + }); + }); + return result; + }; + + var init = function () { + var deferred = $q.defer(); + var databaseRequest = { + base: $mwtnDatabase.base, + index: 'config', + docType: 'sdn-controller', + command: '_search', + method: 'GET', + from: 0, + size: 10 + }; + $mwtnDatabase.genericRequest(databaseRequest).then(function (success) { + // console.log('sc', JSON.stringify(success.data.hits.hits)); + service['sdn-controller'] = success.data.hits.hits; + $mwtnDatabase.getModules().then(function (success) { + service.modules = success; + }, function (error) { + service.modules = []; + console.error('modules', JSON.stringify(error)); + deferred.reject(error); + }); + deferred.resolve(); + }, function (error) { + service['sdn-controller'] = []; + console.error('sc', JSON.stringify(error)); + deferred.reject(error); + }); + + return deferred.promise; + }; + + service.getMainConroller = function () { + var deferred = $q.defer(); + if (service['sdn-controller'].length === 0) { + init().then(function (success) { + service['sdn-controller'].map(function (controller) { + result = controller; + }); + deferred.resolve(result); + }, function (error) { + deferred.reject(error); + }); + } else { + service['sdn-controller'].map(function (controller) { + result = controller; + }); + deferred.resolve(result); + } + return deferred.promise; + }; + + var createStream = function (streamName, callback) { + service.getMainConroller().then(function (success) { + var src = success._source; + var ip = src.host; + if (ip === 'localhost') { + ip = service.base.split('//')[1].split(':')[0]; + } + var url = [src['transport-protocol'], '://', ip, ':', src.port, '/restconf/streams/stream/', streamName].join(''); + var request = { + method: 'GET', + url: url + }; + $http(request).then(function (response) { + // console.log(response.headers('Location')); + callback(response.headers('Location')); + }, function errorCallback(response) { + console.error(JSON.stringify(response)); + callback(); + }); + }, function (error) { + console.error('mainController', error); + callback(); + }); + }; + + service.getMwtnWebSocketUrl = function () { + var deferred = $q.defer(); + service.getMainConroller().then(function (success) { + + var protocol = window.location.protocol.replace(/http/g, 'ws'); + var host = window.location.hostname; + var user = window.localStorage.odlUser; + if (user === undefined) user = 'admin' // ODL default user + var pw = window.localStorage.odlPass; + if (pw === undefined) pw = 'admin' // ODL default password + + var url = [protocol, '//', user, ':',pw, '@', host, ':8085/websocket'].join(''); + console.info('url', url); + + deferred.resolve(url); + }, function (error) { + console.error('mainController', error); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.formatTimeStamp = function (t) { + // t: time in ONF format, e.g. 20161020081633.7Z, 20161025235946.0+0000 + if (t.length !== '20161020081633.7Z'.length || t.length !== '20161025221822.0+0000') { + if (t.endsWith('Z') || t.endsWith('+0000')) { + if (!t.contains('-')) { + return [[t.slice(0, 4), t.slice(4, 6), t.slice(6, 8)].join('-'), + [t.slice(8, 10), t.slice(10, 12), t.slice(12, 16)].join(':')].join(' ') + ' UTC'; + } + } + } + // console.info('check', t); + // return new Date().toISOString().toHumanReadableTimeFormat(); + return t.toHumanReadableTimeFormat(); + }; + + service.formatData = function (event) { + var deferred = $q.defer(); + + var x2js = new X2JS(); + var jsonObj = x2js.xml_str2json(event.data); + // console.info('a', service.getType(jsonObj), JSON.stringify(jsonObj)); + if (jsonObj === null || service.getType(jsonObj) !== 'object') { + deferred.reject('ignore'); + } else { + notifType = Object.keys(jsonObj)[0]; + var formated = jsonObj[notifType]; + formated.timeStamp = service.formatTimeStamp(formated.timeStamp); + formated.notifType = notifType; + formated.myMessage = 'someMessage'; + formated.time = new Date().toISOString(); + deferred.resolve(formated); + } + + return deferred.promise; + }; + + service.getData = function (callback) { + return callback('$mwtnCommons registered to this application.'); + }; + + service.getType = $mwtnGlobal.getType; + service.getViewData = $mwtnGlobal.getViewData; + + service.getLayer = function (pacId) { + console.warn('@depricated', '$mwtnCommons.getLayer()'); + switch (pacId) { + case 'airinterface': + case 'air-interface': + return 'MWPS'; + case 'structure': + case 'pureEthernetStructure': + case 'hybridStructure': + case 'pure-ethernet-structure': + case 'hybrid-structure': + return 'MWS'; + case 'container': + case 'ethernetContainer': + case 'ethernet-container': + return 'ETC'; + case 'tdmContainer': + case 'tdm-container': + return 'TDM'; + default: + return (pacId); + } + }; + + /** @deprecated */ + service.parts = ['Capability', 'Configuration', 'Status', 'CurrentProblems', 'CurrentPerformance', 'HistoricalPerformances']; + + service.getLabelId = function (key, callback) { + return callback(['mwtn', key].join('_').toUpperCase()); + }; + + service.checkModules = function (names) { + // accepts a list of module names and + // attempts to load them, in order. + // attempt to load the module into m + var m; + var result = {}; + names.map(function (name) { + try { + m = angular.module(name); + result[name] = true; + } catch (err) { + result[name] = false; + } + }); + return result; + }; + + service.mount = function (mp) { + // mp: mounting point + var url = [service.base, service.url.mount(mp.name)].join(''); + /* deprecated + var xml = [ + '<module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">', + '<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>', + '<name>{0}</name>', + '<address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">{1}</address>', + '<port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">{2}</port>', + '<username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">{3}</username>', + '<password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">{4}</password>', + '<tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>', + '<event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>', + ' <name>global-event-executor</name>', + '</event-executor>', + '<binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>', + ' <name>binding-osgi-broker</name>', + '</binding-registry>', + '<dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>', + ' <name>dom-broker</name>', + '</dom-registry>', + '<client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>', + ' <name>global-netconf-dispatcher</name>', + '</client-dispatcher>', + '<processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>', + ' <name>global-netconf-processing-executor</name>', + '</processing-executor>', + '<keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">', + ' <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>', + ' <name>global-netconf-ssh-scheduled-executor</name>', + '</keepalive-executor>', + '</module>' ].join('').format(mp.name, mp.ipaddress, mp.port, mp.username, mp.password); */ + var xml = [ + '<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">', + ' <node-id>{0}</node-id>', + ' <host xmlns="urn:opendaylight:netconf-node-topology">{1}</host>', + ' <port xmlns="urn:opendaylight:netconf-node-topology">{2}</port>', + ' <username xmlns="urn:opendaylight:netconf-node-topology">{3}</username>', + ' <password xmlns="urn:opendaylight:netconf-node-topology">{4}</password>', + ' <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>', + + ' <!-- non-mandatory fields with default values, you can safely remove these if you do not wish to override any of these values-->', + ' <reconnect-on-changed-schema xmlns="urn:opendaylight:netconf-node-topology">false</reconnect-on-changed-schema>', + ' <connection-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">20000</connection-timeout-millis>', + ' <max-connection-attempts xmlns="urn:opendaylight:netconf-node-topology">100</max-connection-attempts>', + ' <between-attempts-timeout-millis xmlns="urn:opendaylight:netconf-node-topology">2000</between-attempts-timeout-millis>', + ' <sleep-factor xmlns="urn:opendaylight:netconf-node-topology">1.5</sleep-factor>', + + ' <!-- keepalive-delay set to 0 turns off keepalives-->', + ' <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">120</keepalive-delay>', + '</node>'].join('').format(mp.name, mp.ipaddress, mp.port, mp.username, mp.password); + + var request = { + method: 'PUT', + url: url, + headers: { + 'Content-Type': 'application/xml', + 'Accept': 'application/xml' + }, + data: xml + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + deferred.resolve(success.data); + }, function (error) { + $mwtnLog.error({ component: '$mwtnCommons.mount', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise to unmount netconf devices the old way from OpenDaylight Lithium. + * This is needed in case Netconf devices from 3rd ONF Wireless PoC were mounted. + * @param {string} nodeId - The mountpoint identifier which should be unmounted the old way. + */ + var unmountDeprecated = function (nodeId) { + var url = [service.base, + 'config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/', + nodeId].join(''); + var request = { + method: 'DELETE', + url: url + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + $mwtnLog.info({ component: COMPONENT, message: 'Mounting Point deleted: ' + nodeId }); + deferred.resolve(success.data); + }, function (error) { + $mwtnLog.info({ component: '$mwtnCommons.unmount', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + } + + /** + * A promise to unmount netconf devices from OpenDaylight Beryllium and higher. + * @param {string} nodeId - The mountpoint identifier which unmounted/disconnected from OpenDaylight. + */ + service.unmount = function (nodeId) { + var url = [service.base, service.url.unmount(nodeId)].join(''); + var request = { + method: 'DELETE', + url: url + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + $mwtnLog.info({ component: COMPONENT, message: 'Mounting Point deleted: ' + nodeId }); + deferred.resolve(success.data); + }, function (error) { + // try the old way + unmountDeprecated(nodeId).then( + function (success) { + $mwtnLog.info({ component: COMPONENT, message: 'Mounting Point deleted: ' + nodeId }); + deferred.resolve(success.data); + }, + function (error) { + $mwtnLog.info({ component: '$mwtnCommons.unmount', message: JSON.stringify(error.data) }); + deferred.reject(error); + } + ); + }); + return deferred.promise; + }; + + service.getPacParts = function (spec) { + var errorMsg = { info: 'No data received' }; + var deferred = $q.defer(); + switch (spec.pacId) { + case 'ne': + service.getActualNetworkElement(spec.nodeId, spec.revision).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting ' + spec.nodeId + ' failed!' }); + deferred.reject(error); + }); + break; + case 'clock': + service.getPtpClockData(spec.nodeId, spec.revision).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting clock for ' + spec.nodeId + ' failed!' }); + deferred.reject(); + }); + break; + case 'forwardingDomain': + console.warn('fd', JSON.stringify(spec)); + service.getForwardingDomain(spec.nodeId, 'eth-switch').then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting forwarding domain for ' + spec.nodeId + ' failed!' }); + deferred.reject(error); + }); + break; + case 'ltp': + var ltpKey = 'ltp'; + switch (spec.revision) { + case '2017-02-17': + case '2017-03-20': + case '2017-03-24': + case '2017-10-20': + ltpKey = 'ltp'; + break; + default: + ltpKey = '_ltpRefList'; + } + var odlRequest = { + method: 'GET', + url: [service.url.actualNetworkElement(spec.nodeId, spec.revision), ltpKey, spec.layerProtocolId].join('/') + }; + // console.info(odlRequest.url); + service.genericRequest(odlRequest).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting LTPs of ' + spec.nodeId + ' failed!' }); + deferred.reject(errorMsg); + }); + break; + case 'MWPS': + case 'MWS': + case 'ETH-CTP': + case 'ETC': + case 'airinterface': + case 'structure': + case 'container': + // 3rd PoC + case 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac': + case 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_Pac': + case 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac': + // 4th PoC + case 'microwave-model:mw-air-interface-pac': + case 'microwave-model:mw-air-interface-diversity-pac': + case 'microwave-model:mw-pure-ethernet-structure-pac': + case 'microwave-model:mw-hybrid-mw-structure-pac': + case 'microwave-model:mw-tdm-container-pac': + case 'microwave-model:mw-ethernet-container-pac': + case 'onf-ethernet-conditional-packages:ethernet-pac': + // PoC 4.1 + case 'onf-otn-odu-conditional-packages:otn-odu-connection-pac': + case 'onf-otn-odu-conditional-packages:otn-odu-termination-pac': + if (spec.partId) { + service.getConditionalPackagePart(spec).then(function (success) { + success.layerProtocol = spec.layerProtocolId; + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting conditional package of ' + JSON.stringify(spec) + ' failed!' }); + deferred.reject(errorMsg); + }); + } else { + deferred.resolve(); + } + break; + case 'neCurrentProblems': + service.getNetworkElementCurrentProblemList(spec.nodeId, spec.revision).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Requesting ' + spec.nodeId + ' failed!' }); + deferred.reject(error); + }); + break; + case 'mountpoint': + case 'forwardingConstructs': + // not needed (currently) + deferred.resolve(); + break; + default: + $mwtnLog.error({ component: COMPONENT, message: 'Requesting ' + spec.pacId + ' is not supported!' }); + deferred.reject(errorMsg); + } + return deferred.promise; + }; + service.setPacParts = function (spec, data) { + var errorMsg = { info: 'No data received' }; + var deferred = $q.defer(); + switch (spec.pacId) { + // case 'ne': + // service.getActualNetworkElement(spec.nodeId, spec.revision).then(function(success){ + // deferred.resolve(success); + // }, function(error){ + // $mwtnLog.error({component: COMPONENT, message: 'Requesting ' + spec.nodeId + ' failed!'}); + // deferred.reject(errorMsg); + // }); + // break; + // case 'ltp': + // var odlRequest = { + // method: 'GET', + // url: [service.url.actualNetworkElement(spec.nodeId, spec.revision), '_ltpRefList', spec.layerProtocolId].join('/') + // }; + // service.genericRequest(odlRequest).then(function(success){ + // deferred.resolve(success); + // }, function(error){ + // $mwtnLog.error({component: COMPONENT, message: 'Requesting LTPs of ' + spec.nodeId + ' failed!'}); + // deferred.reject(errorMsg); + // }); + // break; + case 'airinterface': + case 'structure': + case 'container': + // 4th PoC + case 'microwave-model:mw-air-interface-pac': + case 'microwave-model:mw-air-interface-diversity-pac': + case 'microwave-model:mw-pure-ethernet-structure-pac': + case 'microwave-model:mw-hybrid-mw-structure-pac': + case 'microwave-model:mw-tdm-container-pac': + case 'microwave-model:mw-ethernet-container-pac': + case 'onf-ethernet-conditional-packages:ethernet-pac': + // PoC 4.1 + case 'onf-otn-odu-conditional-packages:otn-odu-connection-pac': + case 'onf-otn-odu-conditional-packages:otn-odu-termination-pac': + service.setConditionalPackagePart(spec, data).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Modification of ' + JSON.stringify(spec) + ' failed!' }); + deferred.reject(errorMsg); + }); + break; + default: + $mwtnLog.error({ component: COMPONENT, message: 'Modification of ' + spec.pacId + ' not supported!' }); + deferred.reject(errorMsg); + } + return deferred.promise; + }; + service.setPacPartLists = function (spec, listData) { + var errorMsg = { info: 'No data received' }; + var deferred = $q.defer(); + switch (spec.pacId) { + // case 'ne': + // service.getActualNetworkElement(spec.nodeId, spec.revision).then(function(success){ + // deferred.resolve(success); + // }, function(error){ + // $mwtnLog.error({component: COMPONENT, message: 'Requesting ' + spec.nodeId + ' failed!'}); + // deferred.reject(errorMsg); + // }); + // break; + // case 'ltp': + // var odlRequest = { + // method: 'GET', + // url: [service.url.actualNetworkElement(spec.nodeId, spec.revision), '_ltpRefList', spec.layerProtocolId].join('/') + // }; + // service.genericRequest(odlRequest).then(function(success){ + // deferred.resolve(success); + // }, function(error){ + // $mwtnLog.error({component: COMPONENT, message: 'Requesting LTPs of ' + spec.nodeId + ' failed!'}); + // deferred.reject(errorMsg); + // }); + // break; + case 'airinterface': + case 'structure': + case 'container': + // 4th PoC + case 'microwave-model:mw-air-interface-pac': + case 'microwave-model:mw-air-interface-diversity-pac': + case 'microwave-model:mw-pure-ethernet-structure-pac': + case 'microwave-model:mw-hybrid-mw-structure-pac': + case 'microwave-model:mw-tdm-container-pac': + case 'microwave-model:mw-ethernet-container-pac': + case 'onf-ethernet-conditional-packages:ethernet-pac': + // PoC 4.1 + case 'onf-otn-odu-conditional-packages:otn-odu-connection-pac': + case 'onf-otn-odu-conditional-packages:otn-odu-termination-pac': + service.setConditionalPackagePartList(spec, listData).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Modification of ' + JSON.stringify(spec) + ' failed!' }); + deferred.reject(errorMsg); + }); + break; + default: + $mwtnLog.error({ component: COMPONENT, message: 'Modification of ' + spec.pacId + ' not supported!' }); + deferred.reject(errorMsg); + } + return deferred.promise; + }; + var nodeIntId = 100; + service.getNodeIntIdFromNodeId = function (nodeId) { + nodeIntId = nodeIntId + 1; + if (nodeId.contains('-')) { + return nodeId.split('-')[1]; + } + return nodeIntId; + }; + + service.getRequiredNetworkElements = function (complete) { + var sort = [{ _id: { order: 'asc' } }];; + var query = { + match: { + required: true + } + }; + var deferred = $q.defer(); + $mwtnDatabase.getFilteredSortedData('mwtn', 'required-networkelement', 0, 10000, sort, query).then( + function (success) { + if (complete) { + deferred.resolve(success.data.hits.hits); + } + var result = success.data.hits.hits.map(function (ne) { + var yangifiedObj = service.yangifyObject(ne._source); + var pacKey = 'microwave-model:mw-air-interface-pac'; + if (yangifiedObj['microwave-model-object-classes-air-interface:mw-air-interface-pac']) { + pacKey = 'microwave-model-object-classes-air-interface:mw-air-interface-pac'; + } + var configKey = 'air-interface-configuration'; + var radioSignalIds = []; + if (yangifiedObj[pacKey]) { + radioSignalIds = yangifiedObj[pacKey].filter( + function (mwps) { + return mwps[configKey] && mwps[configKey]['radio-signal-id']; + } + ).map( + function (mwps) { + return mwps[configKey]['radio-signal-id']; + } + ).sort(); + } + return { + id: service.getNodeIntIdFromNodeId(yangifiedObj['node-id']), + name: yangifiedObj['node-id'], + ipaddress: yangifiedObj.connect.host, + port: yangifiedObj.connect.port, + username: yangifiedObj.connect.username, + password: yangifiedObj.connect.password, + radioSignalIds: JSON.stringify(radioSignalIds), + connectionStatus: 'disconnected' + }; + }); + deferred.resolve(result); + }, + function (error) { + $mwtnLog.error({ component: COMPONENT, message: 'Problems in retrieving required network elements.' }); + deferred.reject(error); + } + ); + return deferred.promise; + }; + + service.getConnectionStatus = function (neId) { + var url = service.base + service.url.connectionStatus(neId); + var request = { + method: 'GET', + url: url + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + // console.log(JSON.stringify(success)); + deferred.resolve(success.data.node[0]['netconf-node-topology:connection-status']); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + service.executeClosedLoopAutomation = function () { + var url = service.base + 'operations/closedLoopAutomation:start'; + var request = { + method: 'POST', + url: url + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + service.saveClosedLoopAutomation = function (enabled, option) { + var url = service.base + 'operations/closedLoopAutomation:save-timer'; + var request = { + method: 'POST', + url: url, + data: { + "input": { + "enabled": enabled, + "option": option + } + } + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + service.readClosedLoopAutomation = function () { + var url = service.base + 'operations/closedLoopAutomation:read-timer'; + var request = { + method: 'POST', + url: url, + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise inquiring the a single mountpoint from topology-netconf. + * @param {string} nodeId - The mountpoint identifier. + * @return {{'node-id':string, 'netconf-node-topology:tcp-only': boolean, 'netconf-node-topology:host', string, 'netconf-node-topology:keepalive-delay':number, 'netconf-node-topology:port':number, 'netconf-node-topology:username':string, 'netconf-node-topology:password': string}} - The mountpoint from topology-netconf. + */ + service.getMountPoint = function (nodeId) { + var odlRequest = { + method: 'GET', + url: service.url.mount(nodeId) + }; + var deferred = $q.defer(); + service.genericRequest(odlRequest).then( + function (success) { + deferred.resolve(success.data.node[0]); + }, + function (error) { + deferred.reject(error); + } + ); + return deferred.promise; + }; + + service.getMountPoints = function () { + var url = service.base + service.url.actualNetworkElements(); + var request = { + method: 'GET', + url: url + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + var requiredTopology = 'topology-netconf'; + var topo = success.data.topology.filter(function (topo) { + return topo['topology-id'] === requiredTopology; + }); + // console.log('topo', JSON.stringify(topo)); + if (topo.length === 0) { + var message = ['ODL', requiredTopology, 'not found!'].join(' '); + $mwtnLog.error({ component: COMPONENT, message: message }); + deferred.reject(message); + } else if (topo[0].node) { + var mwMountPoints = topo[0].node.filter(function (mountpoint) { + return mountpoint['node-id'] !== 'controller-config'; + }).map(function (mountpoint) { + // console.info('mountpoint', JSON.stringify(mountpoint)); + var capId = 'netconf-node-topology:available-capabilities'; + if (mountpoint[capId] && mountpoint[capId]['available-capability']) { + var caps = mountpoint[capId]['available-capability'].filter(function (cap) { + // console.info(JSON.stringify(cap)); + return cap.capability.contains('?revision='); + }).map(function (cap) { + return { + module: cap.capability.split(')')[1], + revision: cap.capability.split('?revision=')[1].substring(0, 10) + }; + }).sort(function (a, b) { + if (a.module < b.module) return -1; + if (a.module > b.module) return 1; + return 0; + }); + // console.log('mountpoint', JSON.stringify(caps)); + mountpoint.onfCapabilities = caps; + mountpoint.onfCoreModelRevision = caps.filter(function (cap) { + return cap.module === 'core-model' || cap.module === 'CoreModel-CoreNetworkModule-ObjectClasses'; + }).map(function (cap) { + return cap.revision; + }); + if (mountpoint.onfCoreModelRevision.length === 1) { + mountpoint.onfCoreModelRevision = mountpoint.onfCoreModelRevision[0]; + } else { + $mwtnLog.error({ component: COMPONENT, message: mountpoint.onfCoreModelRevision.length + ' CoreModels supported by ' + mountpoint['node-id'] }); + } + + // console.log('caps', JSON.stringify(caps)); + mountpoint.onfAirInterfaceRevision = caps.filter(function (cap) { + return cap.module === 'microwave-model' || cap.module === 'MicrowaveModel-ObjectClasses-AirInterface'; + }).map(function (cap) { + return cap.revision; + }); + // console.log('onfAirInterfaceRevision', mountpoint.onfAirInterfaceRevision); + if (mountpoint.onfAirInterfaceRevision.length === 1) { + mountpoint.onfAirInterfaceRevision = mountpoint.onfAirInterfaceRevision[0]; + } else { + $mwtnLog.error({ component: COMPONENT, message: 'More than 1 or no MicrowaveModel supported by ' + mountpoint['node-id'] }); + } + } + var clusterConneactionStatus = 'netconf-node-topology:clustered-connection-status'; + if (mountpoint[clusterConneactionStatus] && mountpoint[clusterConneactionStatus]['netconf-master-node']) { + var value = mountpoint[clusterConneactionStatus]['netconf-master-node']; + value = value.substring(value.indexOf('@')); + mountpoint.client = value.substring(1, value.indexOf(':')); + } else { + mountpoint.client = window.location.hostname; + } + return mountpoint; + }); + // console.log('mwMountPoints', JSON.stringify(mwMountPoints)); + deferred.resolve(mwMountPoints); + } + }, function (error) { + $mwtnLog.error({ component: COMPONENT, message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + service.separator = ' '; + // grid settings + service.highlightFilteredHeader = function (row, rowRenderIndex, + col, colRenderIndex) { + if (col.filters[0].term) { + return 'header-filtered'; + } else { + return ''; + } + }; + service.gridOptions = { + data: [], + enableColumnResizing: true, + enableSorting: true, + enableFiltering: true, + enableGridMenu: true, + exporterMenuPdf: false, + showGridFooter: true, + // showColumnFooter: true, + fastWatch: true, + enableRowSelection: true, + enableRowHeaderSelection: true, + multiSelect: false + }; + service.gridOptions.gridMenuCustomItems = [{ + title: 'Rotate Grid', + action: function ($event) { + this.grid.element.toggleClass('rotated'); + }, + order: 210 + }]; + service.url = { + actualNetworkElements: function () { + return 'operational/network-topology:network-topology/topology/topology-netconf'; + }, + connectionStatus: function (neId) { + return 'operational/network-topology:network-topology/topology/topology-netconf/node/' + neId; + }, + mount: function (neId) { + return 'config/network-topology:network-topology/topology/topology-netconf/node/' + neId; + // return 'config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules'; // depricated + }, + unmount: function (neId) { + // return 'config/network-topology:network-topology/topology/topology-netconf/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/' + neId; // depricated + return 'config/network-topology:network-topology/topology/topology-netconf/node/' + neId; + }, + forwardingDomain: function (neId, fdUuid) { + return 'operational/network-topology:network-topology/topology/topology-netconf/node/' + neId + '/yang-ext:mount/core-model:network-element/fd/' +fdUuid; + }, + forwardingConstruct: function (neId, fcUuid) { + return 'operational/network-topology:network-topology/topology/topology-netconf/node/' + neId + '/yang-ext:mount/core-model:forwarding-construct/' +fcUuid; + }, + clock: function (neId, revision) { + return 'operational/network-topology:network-topology/topology/topology-netconf/node/' + neId + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1'; + }, + actualNetworkElement: function (neId, revision) { + switch (revision) { + case "2016-03-23": + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/CoreModel-CoreNetworkModule-ObjectClasses:NetworkElement/', + neId].join(''); + case "2017-02-17": + case "2017-03-20": + case "2017-03-24": + case "2017-10-20": + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/core-model:network-element'].join(''); + default: // 2016-08-11 + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/CoreModel-CoreNetworkModule-ObjectClasses:NetworkElement'].join(''); + } + }, + networkElementCurrentProblemList: function (neId, revision) { + console.log(neId, revision); + switch (revision) { + case "2016-08-11": + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/MicrowaveModel-NetworkElement-CurrentProblemList:NetworkElementCurrentProblems'].join(''); + case "2017-02-17": + case "2017-03-20": // TODO sko equipmentAlarms check new yang file if agreed + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/onf-core-model-conditional-packages:network-element-pac/network-element-current-problems'].join(''); + default: + return [ + 'operational/network-topology:network-topology/topology/topology-netconf/node/', + neId, + '/yang-ext:mount/onf-core-model-conditional-packages:network-element-pac/network-element-current-problems'].join(''); + } + } + }; + /* + * Changes different time formats to a common time fromat + * TODO currently not implemented! + */ + service.normalizeTimeFormat = function (time, format) { + return time; + }; + /* + * Changing a string according to yang naming conventions. + * The function should be alinged with the ONF Eagle project. + */ + service.yangify = function (str) { + var result = str + .replace(/RefList+$/, '') // endling "List" was removed + .replace(/List+$/, '') // endling "List" was removed + .replace(/([a-z])([A-Z])/g, '$1-$2') // insert dashes + .replace(/([0-9])([a-zA-Z])/g, '$1-$2') // insert dashes + .replace(/([A-Z])([A-Z])([a-z])/g, '$1-$2$3') // insert dashes + .toLowerCase() // lowercase everything + .replace(/^_/, '') // remove leading underscore + .replace(/:_/g, ':') // and leading underscores in path segments + .replace(/_/g, '-'); // convert underscore to dashes + + // catch "wrong" UML labels + var exceptions = { + 'air-interface':'air-interface-list', + 'air-interface-ltp':'air-interface-ltp-list', + 'air-interface-capability': 'air-interface-capability-list', + 'air-interface-current-problem': 'air-interface-current-problem-list', + 'container-capability': 'container-capability-list', + 'current-performance-data':'current-performance-data-list', + 'current-problem':'current-problem-list', + 'historical-performance-data':'historical-performance-data-list', + 'problem-kind-severity':'problem-kind-severity-list', + 'pure-ethernet-structure-capability':'pure-ethernet-structure-capability-list', + 'segment-status':'segment-status-list', + 'segments-id':'segments-id-list', + 'structure-capability': 'structure-capability-list', + 'structure-current-problem': 'structure-current-problem-list', + 'supported-tdm-container-types':'supported-tdm-container-types-list', + 'supported-tdm-structure-types':'supported-tdm-structure-types-list', + 'supported-channel-plan':'supported-channel-plan-list', + 'supported-loop-back-kind':'transmission-mode-list', + 'transmission-mode':'transmission-mode-list' + }; + if (exceptions[result]) { + console.warn(result, '.>', exceptions[result]); + result=exceptions[result]; + } + + // catch modulation value difference + if (result.startsWith('time') && result.endsWith('symbols') + || result.startsWith('time') && result.contains('-symbols-') && result.endsWith('-s') + || result.startsWith('time') && result.contains('-symbols-') && result.endsWith('-l')) { + result = result.replace('symbols', 'states'); + } + return result; + }; + + /* + * Checking, whether a jsonObject should be yangifyed + */ + service.isCamelCase = function (jsonObject) { + if (jsonObject === undefined || jsonObject === null) { + return true; + } + var result; + var type = service.getType(jsonObject); + switch (type) { + case 'object': + result = false; + Object.keys(jsonObject).map(function (key) { + result = result || key !== [service.yangify(key)]; + }); + break; + case 'array': + case 'boolean': + case 'function': + case 'string': + case 'number': + case 'null': + case 'undefined': + result = true; + break; + default: + console.error('Type1:', type, ' is not supported!'); + result = true; + } + return result; + }; + /* + * Yangifies a names/keys of a jsonOject + */ + service.yangifyObject = function (jsonObject) { + if (jsonObject === undefined || jsonObject === null) { + return jsonObject; + } + var result; + var type = service.getType(jsonObject); + switch (type) { + case 'object': + case 'name-value': + result = {}; + Object.keys(jsonObject).map(function (key) { + result[service.yangify(key)] = service.yangifyObject(jsonObject[key]); + }); + break; + case 'array': + result = jsonObject.map(function (item, index) { + return service.yangifyObject(item); + }); + break; + case 'boolean': + case 'function': + case 'string': + case 'number': + case 'null': + case 'undefined': + result = jsonObject; + break; + default: + console.error('Type:', type, ' is not supported!'); + result = jsonObject; + } + return result; + }; + /* + * Send a restconf request to OpenDayligth. + * All ODL restconf requests should pass this function. + */ + service.genericRequest = function (odlRequest) { + var url = [service.base, odlRequest.url].join(''); + var request = { + method: odlRequest.method, + url: url, + data: odlRequest.data + }; + var deferred = $q.defer(); + $http(request).then(function (success) { + // yangifing the response is required until all NEs has switch to CoreModel 1.2 (ONF-TR-532) + // deferred.resolve(service.yangifyObject(success)); + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: COMPONENT + '.genericRequest', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + service.getMountedNetConfServers = function (callback) { + var url = service.base + service.url.actualNetworkElements(); + var request = { + method: 'GET', + url: url + }; + $http(request).then(function (success) { + return callback(success.data); + }, function (error) { + console.error(JSON.stringify(error)); + return callback(); + }); + }; + + service.getActualNetworkElement = function (neId, revision) { + var url = [service.base, + service.url.actualNetworkElement(neId, revision)].join(''); + var request = { + method: 'GET', + url: url + }; + var taskId = [neId, 'ONF:CoreModel:NetworkElement data received'].join(' '); + + var deferred = $q.defer(); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = revision; + // deferred.resolve(service.yangifyObject(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getActualNetworkElement', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getForwardingDomain = function(neId, fdUuid) { + var url = [service.base, + service.url.forwardingDomain(neId, fdUuid)].join(''); + var request = { + method: 'GET', + url: url + }; + var taskId = [neId, 'ONF:ForwardingDomain received'].join(' '); + + var deferred = $q.defer(); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + // deferred.resolve(service.yangifyObject(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getForwardingDomain', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getForwardingConstruct = function(neId, fcUuid) { + var url = [service.base, + service.url.forwardingConstruct(neId, fcUuid)].join(''); + var request = { + method: 'GET', + url: url + }; + var taskId = [neId, fcUuid, 'ONF:ForwardingConstruct received'].join(' '); + + var deferred = $q.defer(); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + // deferred.resolve(service.yangifyObject(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getForwardingConstruct', message: JSON.stringify(error.data) }); + deferred.reject(); + }); + return deferred.promise; + }; + + service.getPtpClockData = function(neId, revision) { + var url = [service.base, + service.url.clock(neId, revision)].join(''); + var request = { + method: 'GET', + url: url + }; + var taskId = [neId, 'ONF:PTP:DataSet received'].join(' '); + + var deferred = $q.defer(); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = revision; + // deferred.resolve(service.yangifyObject(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getPtpClockData', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getNetworkElementCurrentProblemList = function (neId, revision) { + var url = [service.base, + service.url.networkElementCurrentProblemList(neId, revision)].join(''); + var request = { + method: 'GET', + url: url + }; + var taskId = [neId, 'ONF:CoreModel:NetworkElement data received'].join(' '); + + var deferred = $q.defer(); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = revision; + // deferred.resolve(service.yangifyObject(success.data)); TODO: check if correct + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getActualNetworkElement', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + var getIdsByRevision = function (revision, pacId, partId) { + + switch (revision) { + case '2016-03-23': + switch (pacId) { + case 'MWPS': + case 'AirInterface': + case 'airinterface': + case 'airInterface': + pacId = 'MicrowaveModel-ObjectClasses-MwConnection:MW_AirInterface_Pac'; + partId = 'airInterface' + partId; + if (partId === 'airInterfaceCapability' || partId === 'airInterfaceCurrentProblems') { + partId = undefined; + } + break; + case 'MWS': + case 'Structure': + case 'structure': + pacId = 'MicrowaveModel-ObjectClasses-MwConnection:MW_Structure_Pac'; + partId = 'structure' + partId; + break; + case 'ETH-CTP': + case 'ETH': + case 'Container': + case 'container': + pacId = 'MicrowaveModel-ObjectClasses-MwConnection:MW_Container_Pac'; + partId = 'container' + partId; + break; + case 'TDM': + pacId = 'MicrowaveModel-ObjectClasses-MwConnection:MW_Container_Pac'; + partId = 'container' + partId; + break; + } + break; + case '2017-02-17': + case '2017-03-20': + case '2017-03-24': + switch (pacId) { + case 'MWPS': + case 'AirInterface': + case 'airinterface': + case 'airInterface': + case 'air-interface': + pacId = 'microwave-model:mw-air-interface-pac'; + partId = 'air-interface-' + service.yangify(partId); + break; + case 'MWS': + case 'Structure': + case 'structure': + var isHybrid = false; // TODO How do I know this? + if (isHybrid) { + pacId = 'microwave-model:mw-hybrid-mw-structure-pac'; + partId = 'hybrid-mw-structure-' + service.yangify(partId); + } else { + pacId = 'microwave-model:mw-pure-ethernet-structure-pac'; + partId = 'pure-ethernet-structure-' + service.yangify(partId); + } + break; + case 'ETH-CTP': + case 'ETC': + case 'Container': + case 'container': + pacId = 'microwave-model:mw-ethernet-container-pac'; + partId = 'ethernet-container-' + service.yangify(partId); + break; + case 'TDM': + pacId = 'microwave-model:mw-tdm-container-pac'; + partId = 'tdm-container-' + service.yangify(partId); + break; + } + break; + default: + switch (pacId) { + case 'MWPS': + case 'AirInterface': + case 'airinterface': + case 'airInterface': + pacId = 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac'; + partId = 'airInterface' + partId; + break; + case 'MWS': + case 'Structure': + case 'structure': + pacId = 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac'; + partId = 'pureEthernetStructure' + partId; + break; + case 'ETH-CTP': + case 'ETH': + case 'Container': + case 'container': + pacId = 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_Pac'; + partId = 'ethernetContainer' + partId; + break; + case 'TDM': + pacId = 'microwave-model:mw-tdm-container-pac'; + partId = 'tdm-container-' + service.yangify(partId); + break; + } + } + return { + pacId: pacId, + partId: partId + }; + }; + + service.getConditionalPackagePart = function (spec) { + // console.log(JSON.stringify(spec)); + var deferred = $q.defer(); + if (!spec.partId) { + deferred.reject('ignore'); + return deferred.promise; + } + + var ids = getIdsByRevision(spec.revision, spec.pacId, spec.partId); + var operation = 'operational'; + if (spec.config === true) { + operation = 'config'; + } + + var url = [service.base, operation, + '/network-topology:network-topology/topology/topology-netconf/node/', + spec.nodeId, + '/yang-ext:mount/', ids.pacId, '/', + spec.layerProtocolId, '/', + ids.partId].join(''); + var request = { + method: 'GET', + url: url + }; + // console.log(JSON.stringify(request)); + + var taskId = [spec.nodeId, spec.layerProtocolId, spec.pacId, 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = spec.revision; + deferred.resolve(success.data); + // console.log(JSON.stringify(service.yangifyObject(success.data))); + // [sko] not now - later after all apps are updated to the new model: deferred.resolve(service.yangifyObject(success.data)); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getConditionalPackagePart', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getPtpPort = function (spec) { + var deferred = $q.defer(); + if (!spec.networkElement || !spec.value) { + deferred.reject('ignore'); + return deferred.promise; + } + + var operation = 'config'; + var url = [service.base, operation, + '/network-topology:network-topology/topology/topology-netconf/node/', + spec.networkElement, + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1/port-ds-list/', + spec.value['port-number']].join(''); + var request = { + method: 'GET', + url: url + }; + console.warn(JSON.stringify(request)); + + var taskId = [spec.networkElement, spec.value['port-number'], 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + console.warn(JSON.stringify(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getPtpPort', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.setPtpPort = function (spec, data) { + var deferred = $q.defer(); + if (!spec.networkElement || !spec.value) { + deferred.reject('ignore'); + return deferred.promise; + } + + var operation = 'config'; + var url = [service.base, operation, + '/network-topology:network-topology/topology/topology-netconf/node/', + spec.networkElement, + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1/port-ds-list/', + spec.value['port-number']].join(''); + + var body = {'port-ds-list': data}; + + var request = { + method: 'PUT', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: body + }; + + var taskId = [spec.networkElement, spec.value['port-number'], 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + deferred.resolve(success.data); + // deferred.resolve(service.yangifyObject(success.data)); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.error({ component: '$mwtnCommons.setPtpPort', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + + service.getPtpDefaultDs = function (spec) { + var deferred = $q.defer(); + if (!spec.networkElement || !spec.value) { + deferred.reject('ignore'); + return deferred.promise; + } + + var operation = 'config'; + var url = [service.base, operation, + '/network-topology:network-topology/topology/topology-netconf/node/', + spec.networkElement, + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1/default-ds/'].join(''); + var request = { + method: 'GET', + url: url + }; + console.warn(JSON.stringify(request)); + + var taskId = [spec.networkElement, 'default-ds', 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + console.warn(JSON.stringify(success.data)); + deferred.resolve(success.data); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.info({ component: '$mwtnCommons.getPtpPort', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.setPtpDefaultDs = function (spec, data) { + var deferred = $q.defer(); + if (!spec.networkElement || !spec.value) { + deferred.reject('ignore'); + return deferred.promise; + } + + var operation = 'config'; + var url = [service.base, operation, + '/network-topology:network-topology/topology/topology-netconf/node/', + spec.networkElement, + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1/default-ds/'].join(''); + + var body = {'default-ds': data}; + + var request = { + method: 'PUT', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: body + }; + + var taskId = [spec.networkElement, 'default-ds', 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + deferred.resolve(success.data); + // deferred.resolve(service.yangifyObject(success.data)); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.error({ component: '$mwtnCommons.setPtpPort', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + + service.setConditionalPackagePart = function (spec, data) { + var deferred = $q.defer(); + if (!spec.partId) { + deferred.reject('ignore'); + return deferred.promise; + } + + var ids = getIdsByRevision(spec.revision, spec.pacId, spec.partId); + var body = {}; + body[ids.partId] = data; + + var url = [service.base, + 'config/network-topology:network-topology/topology/topology-netconf/node/', + spec.nodeId, + '/yang-ext:mount/', ids.pacId, '/', + spec.layerProtocolId, '/', + ids.partId].join(''); + var request = { + method: 'PUT', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: body + }; + + var taskId = [spec.nodeId, spec.layerProtocolId, spec.pacId, 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = spec.revision; + deferred.resolve(success.data); + // deferred.resolve(service.yangifyObject(success.data)); + }, function (error) { + console.timeEnd(taskId); + $mwtnLog.error({ component: '$mwtnCommons.setConditionalPackagePart', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + // pureEthernetStructureConfiguration/problemKindSeverityList/value1 + // { + // "problemKindSeverityList": [ + // { + // "problemKindName": "severity1", + // "problemKindSeverity": "warning" + // } + // ] + // } + + var processData = function (item, i, callback) { + var spec = item.spec; + var ids = getIdsByRevision(spec.revision, spec.pacId, + spec.partId); + item.spec = undefined; + var body = {}; + body[spec.attribute] = [item]; + $mwtnDatabase.getSchema().then(function (schema) { + + var key; + Object.keys(item).map(function (k) { + // works currently only for single key lists + if (schema[k] && schema[k]['is-key']) { + key = k; + } + }); + + var url = [ + service.base.slice(0, -1), + 'config/network-topology:network-topology/topology/topology-netconf/node', + spec.nodeId, 'yang-ext:mount', ids.pacId, + spec.layerProtocolId, ids.partId, + spec.attribute, item[key]].join('/'); + var request = { + method: 'PUT', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: body + }; + // console.log(JSON.stringify(request)); + var taskId = [spec.nodeId, spec.layerProtocolId, + spec.pacId, item.problemKindName, + 'data received'].join(' '); + console.time(taskId); + $http(request).then(function (success) { + console.timeEnd(taskId); + success.data.revision = spec.revision; + return callback(); + }, + function (error) { + console.timeEnd(taskId); + $mwtnLog + .error({ + component: '$mwtnCommons.setConditionalPackagePart', + message: JSON + .stringify(error.data) + }); + return callback(); + }); + }); + }; + + service.setConditionalPackagePartList = function (spec, data) { + var deferred = $q.defer(); + if (!spec.partId) { + deferred.reject('ignore'); + return deferred.promise; + } + + data.map(function (item) { + item.spec = spec; + }); + + doSynchronousLoop(data, processData, function () { + deferred.resolve(); + }); + return deferred.promise; + }; + + var saveRequiredNetworkElement = function (requiredNode) { + var url = [$mwtnDatabase.base, $mwtnDatabase.index, 'required-networkelement', + requiredNode.nodeId].join('/'); + var bodyString = JSON.stringify(requiredNode); + var headers = { + 'Content-Type': 'application/json', + 'Content-Length': bodyString.length + }; + var request = { + method: 'PUT', + url: url, + data: requiredNode + }; + + var deferred = $q.defer(); + console.time('database:' + url); + $http(request).then(function (success) { + console.timeEnd('database:' + url); + // console.log(JSON.stringify(success)); + deferred.resolve(success); + }, function (error) { + console.timeEnd('database:' + url); + $mwtnLog.error({ component: '$mwtnCommons.saveRequiredNetworkElement', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A function which inquires data from a netconf server and stores it in a database. + * @param {{'node-id': string, ipAddress: string, port: number, username: string, password: string, site:string, onfCoreModelRevision: string, onfAirInterfaceRevision: string}} netconfServer - A netConf server object with all connectivity parameters. + */ + service.addRequiredNetworkElement = function (netconfServer) { + /** {Object} requiredNode - Data set to be stored in database */ + var requiredNode = { + nodeId: netconfServer['node-id'], + siteRef: netconfServer.site, + onfCoreModelRevision: netconfServer.onfCoreModelRevision, + onfAirInterfaceRevision: netconfServer.onfAirInterfaceRevision, + required: true, + connect: { + mountId: netconfServer['node-id'], + host: netconfServer['netconf-node-topology:host'], + port: netconfServer['netconf-node-topology:port'], + username: netconfServer.username, + password: netconfServer.password + }, + 'core-model:network-element': {}, + }; + + var deferred = $q.defer(); + saveRequiredNetworkElement(requiredNode).then(function (success) { + deferred.resolve(success); + }, function (error) { + $mwtnLog.error({ component: '$mwtnCommons.saveRequiredNetworkElement', message: JSON.stringify(error.data) }); + deferred.reject(error); + }); + + // [sko] much simplified du to ONAP concepts, no device configuration needs to be stored in database. + + // // get NetworkElement object from node + // var spec = { + // nodeId: requiredNode.nodeId, + // revision: requiredNode.onfCoreModelRevision, + // pacId: 'ne' + // }; + + // var updatePart = function (spec, data) { + // data.layerProtocol = spec.layerProtocolId; + // requiredNode[spec.pacId].push(data); + // }; + + // var numberOfLtps = -1; + // var processLTPs = function (item, i, callback) { + // var ltp = new LogicalTerminationPoint(item); + // ltp.getLayerProtocols().map( + // /** + // * A function processing a layer-protocol object + // * @param {LayerProtocol} lp A layer-protocol object + // */ + // function (lp) { + // var conditionalPackage = lp.getConditionalPackage(true); + // if (conditionalPackage !== '') { + // if (requiredNode[conditionalPackage] === undefined) { + // // create missing pac array + // requiredNode[conditionalPackage] = []; + // } + // var spec = { + // nodeId: requiredNode.nodeId, + // revision: requiredNode.onfCoreModelRevision, + // pacId: conditionalPackage, + // layer: lp.getLayer(), + // layerProtocolId: lp.getId() + // }; + // spec.partId = service.getPartGlobalId(spec, 'configuration'); + // // console.info(JSON.stringify(spec)); + // service.getPacParts(spec).then(function (success) { + // // console.log(JSON.stringify(success)); + // spec.message = ['Process LTP', i+1, 'of', numberOfLtps].join(' '); + // $notifying.notify(spec); + // updatePart(spec, service.yangifyObject(success)); + // return callback(); + // }, function (error) { + // spec.message = ['Process LTP', i+1, 'of', numberOfLtps].join(' '); + // $notifying.notify(spec); + // $mwtnLog.error({ component: '$mwtnCommons.processLTPs bad data', message: JSON.stringify(error) }); + // return callback(); + // }); + // } else { + // $mwtnLog.info({ component: COMPONENT, message: 'No condtional package found: ' + ltp.getId() }); + // return callback(); + // } + // }); + + // // console.log(JSON.stringify(ltp.getData())); + // }; + + // service.getPacParts(spec).then(function (success) { + // success = service.yangifyObject(success); + // requiredNode['core-model:network-element'] = success['network-element']; + // var id = success['network-element']['node-id']; + // numberOfLtps = success['network-element'].ltp.length; + // doSynchronousLoop(success['network-element'].ltp, processLTPs, function () { + // saveRequiredNetworkElement(requiredNode).then(function (success) { + // $notifying.notify( { nodeId: id, message: 'finish'} ); + // deferred.resolve(success); + // }, function (error) { + // $mwtnLog.error({ component: '$mwtnCommons.saveRequiredNetworkElement', message: JSON.stringify(error.data) }); + // deferred.reject(error); + // }); + // }); + + // }, function (error) { + // $mwtnLog.error({ component: '$mwtnCommons.getPacParts', message: JSON.stringify(error.data) }); + // deferred.reject(error); + // }); + return deferred.promise; + }; + + service.registerForOdlEvents = function (path, callback) { + var request = { + method: 'POST', + url: [service.base, + 'operations/sal-remote:create-data-change-event-subscription'] + .join(''), + data: { + "input": { + "path": path, + "sal-remote-augment:datastore": "CONFIGURATION", + "sal-remote-augment:scope": "SUBTREE" + } + } + }; + $http(request).then( + function successCallback(response) { + // this callback will be called asynchronously + // when the response is available + // console.log(JSON.stringify(response)); + createStream(response.data.output['stream-name'], + function (socketLocation) { + callback(socketLocation); + }); + }, function errorCallback(response) { + // called asynchronously if an error occurs + // or server returns response with an error status. + console.error(JSON.stringify(response)); + }); + }; + + return service; + }); + + // Precision Time Protocol PTP + mwtnCommonsApp.register.factory('$mwtnPtp', function ($http, $q, $mwtnCommons, PtpClock) { + var key1 = 'netconf-node-topology:available-capabilities'; + var key2 = 'available-capability'; + var filterActivePtpClocks = function(mountpoints) { + return mountpoints.filter(function(mountpoint) { + if (!mountpoint) return false; + if (!mountpoint[key1]) return false; + if (!mountpoint[key1][key2]) return false; + if (mountpoint['netconf-node-topology:connection-status'] !== 'connected') return false; + var ptpCapability = mountpoint[key1][key2].filter(function(capability){ + return capability.contains('ietf-ptp-dataset'); + }); + return ptpCapability.length > 0; + }).map(function(mountpoint){ + return mountpoint['node-id']; + }); + }; + var ptpClocks = {}; + var processData = function (nodeId, i, callback) { + $mwtnCommons.getPtpClockData(nodeId).then( + function (success) { + ptpClocks[nodeId] = new PtpClock(success); + callback(); + }, + function (error) { + console.error(error); + callback(); + } + ); + }; + + var service = {}; + service.getPtpClocks = function() { + var deferred = $q.defer(); + + $mwtnCommons.getMountPoints().then(function (mountpoints) { + var ptpClockNodeIds = filterActivePtpClocks(mountpoints); + doSynchronousLoop(ptpClockNodeIds, processData, function () { + deferred.resolve(ptpClocks); + }); + }, function (error) { + console.log(error); + deferred.reject(); + }); + + return deferred.promise; + }; + + service.getParent = function(nodeId) { + var deferred = $q.defer(); + var request = { + method: 'GET', + url: 'operational/network-topology:network-topology/topology/topology-netconf/node/' + nodeId + '/yang-ext:mount/ietf-ptp-dataset:instance-list/1/parent-ds/parent-port-identity' + }; + + $mwtnCommons.genericRequest(request).then(function(success){ + console.warn(JSON.stringify(success)); + deferred.resolve(success.data['parent-port-identity']); + }, function(error) { + console.error(JSon.stringify(error)); + deferred.reject(); + }); + return deferred.promise; + }; + + return service; + }); + + // Service log + mwtnCommonsApp.register.factory('$mwtnLog', function ($http, $q, $mwtnDatabase) { + var writeLogToDB = function (data, callback) { + var url = [$mwtnDatabase.base, $mwtnDatabase.index, 'log'].join('/'); + var request = { + method: 'POST', + url: url, + data: { + timestamp: data.timestamp ? data.timestamp : new Date().toISOString(), + type: data.type ? data.type : 'info', + component: data.component ? data.component : 'unkonwn', + message: data.message + } + }; + $http(request).then(function successCallback(response) { + return callback(true); + }, function errorCallback(response) { + console.error(JSON.stringify(response)); + return callback(false); + }); + }; + + var createIndex = function (index, callback) { + var url = [$mwtnDatabase.base, index].join('/'); + var request = { + method: 'POST', + url: url, + data: { + timestamp: new Date().toISOString(), + type: 'info', + component: '$mwtnLog', + message: 'init log' + } + }; + $http(request).then(function (success) { + return callback(true); + }, function (error) { + console.error(JSON.stringify(error)); + return callback(false); + }); + }; + var checkIndex = function (index, callback) { + var url = [$mwtnDatabase.base, index].join('/'); + var request = { + method: 'HEAD', + url: url + }; + $http(request).then(function successCallback(response) { + return callback(true); + }, function errorCallback(response) { + console.error(JSON.stringify(response)); + createIndex(index, function (created) { + return callback(created); + }); + }); + }; + var checkDatabase = function (callback) { + var url = $mwtnDatabase.base; + var request = { + method: 'GET', + url: url + }; + $http(request).then(function successCallback(response) { + checkIndex($mwtnDatabase.index, function (exists) { + return callback(exists); + }); + }, function errorCallback(response) { + console.error(JSON.stringify(response)); + return callback(false); + }); + }; + var getData = function (type, log) { + var data = {}; + data.timestamp = new Date().toISOString(); + switch (typeof log) { + case 'string': + data.type = type; + data.component = 'unknown'; + data.message = log; + break; + case 'object': + data.type = type; + data.component = log.component; + data.message = log.message; + break; + default: + data.type = 'error'; + data.component = '$mwtnLog'; + data.message = 'pnf log service is called with wrong parameters.'; + } + // console.log(JSON.stringify(data)); + return data; + }; + var service = { + base: $mwtnDatabase.base + }; + service.debug = function (log) { + var data = getData('debug', log); + checkDatabase(function (isRunning) { + if (isRunning) { + writeLogToDB(data, function () { + // console.log('log stored'); + }); + } else { + console.error(data.timestamp, service.base, + 'Database (ElasticSerach) not reachable!?'); + } + }); + console.log(data.timestamp, JSON.stringify(log)); + }; + service.error = function (log) { + var data = getData('error', log); + checkDatabase(function (isRunning) { + if (isRunning) { + writeLogToDB(data, function () { + // console.log('log stored'); + }); + } else { + console.error(data.timestamp, service.base, + 'Database (ElasticSerach) not reachable!?'); + } + }); + console.error(data.timestamp, JSON.stringify(log)); + }; + service.info = function (log) { + var data = getData('info', log); + checkDatabase(function (isRunning) { + if (isRunning) { + writeLogToDB(data, function () { + // console.log('log stored'); + }); + } else { + console.error(data.timestamp, service.base, 'Database (ElasticSerach) not reachable!?'); + } + }); + console.info(data.timestamp, JSON.stringify(log)); + }; + service.warning = function (log) { + var data = getData('warning', log); + checkDatabase(function (isRunning) { + if (isRunning) { + writeLogToDB(data, function () { + // console.log('log stored'); + }); + } else { + console.error(data.timestamp, service.base, 'Database (ElasticSerach) not reachable!?'); + } + }); + console.warn(data.timestamp, JSON.stringify(log)); + }; + return service; + }); + + // Service log + mwtnCommonsApp.register.factory('$mwtnEthernet', function ($http, $q) { + var service = {}; + + service.base = window.location.origin + '/restconf'; + service.url = { + create: service.base + '/operations/route:create', + delete: service.base + '/operations/route:delete' + }; + + service.createForwardingConstruct = function(spec) { + var deferred = $q.defer(); + + var request = { + method: 'POST', + url: service.url.create, + data: { + input: { + vlanid: spec.vlan, + fc: [{ + nodeName: spec.nodeId, + aEnd: spec.ltp1, + zEnd: spec.ltp2 + } + ] + } + } + }; + console.log(JSON.stringify(spec)); + console.log(JSON.stringify(request)); + + var consoleId = 'create-forwarding-consturuct: '; + console.time(consoleId); + $http(request).then(function (success) { + console.timeEnd(consoleId); + console.log(JSON.stringify(success)); + deferred.resolve(success.data.output.status); + }, function (error) { + console.timeEnd(consoleId); + // console.error(JSON.stringify(error.statusText)); + deferred.reject(error.statusText); + }); + return deferred.promise; + }; + + service.deleteForwardingConstruct = function(spec) { + + var deferred = $q.defer(); + var request = { + method: 'POST', + url: service.url.delete, + data: {input:{vlanid:spec.ltp.slice(-2)}} + }; + console.log(JSON.stringify(spec)); + console.log(JSON.stringify(request)); + + var consoleId = 'delete-forwarding-consturuct: '; + console.time(consoleId); + $http(request).then(function (success) { + console.timeEnd(consoleId); + console.log(JSON.stringify(success)); + deferred.resolve(success.data.output.status); + }, function (error) { + console.timeEnd(consoleId); + // console.error(JSON.stringify(error.statusText)); + deferred.reject(error.statusText); + }); + return deferred.promise; + }; + + return service; + }); + + // Service Database (ElasticSerach) + mwtnCommonsApp.register.factory('$mwtnDatabase', function ($http, $q) { + var service = { + base: window.location.origin + '/database', + index: 'mwtn', + command: '_search', + mwtn: 'todo' + }; + + // TODO getBase is not needed anymore + service.getBase = function (functionId) { + var deferred = $q.defer(); + + deferred.resolve({ + base: service.base, + index: functionId + }); + + return deferred.promise; + }; + + service.genericRequest = function (databaseRequest) { + var url = [databaseRequest.base, databaseRequest.index, databaseRequest.docType, + databaseRequest.command].join('/'); + var request = { + method: databaseRequest.method, + url: url, + data: { + from: databaseRequest.from, + size: databaseRequest.size, + sort: databaseRequest.sort, + filter: databaseRequest.filter, + query: databaseRequest.query + } + }; + // overwrite request data if given + if (databaseRequest.data) { + request.data = databaseRequest.data; + } + var deferred = $q.defer(); + var consoleId = 'database: ' + url; + console.time(consoleId); + $http(request).then(function (success) { + console.timeEnd(consoleId); + // console.log(JSON.stringify(success)); + deferred.resolve(success); + }, function (error) { + console.timeEnd(consoleId); + console.warn(JSON.stringify(error)); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.aggregationRequest = function (databaseRequest) { + var url = [databaseRequest.base, databaseRequest.index, databaseRequest.docType, + databaseRequest.command].join('/'); + var request = { + method: databaseRequest.method, + url: url, + data: databaseRequest.aggregation + }; + var deferred = $q.defer(); + var consoleId = 'database: ' + url; + console.time(consoleId); + $http(request).then(function (success) { + console.timeEnd(consoleId); + deferred.resolve(success); + }, function (error) { + console.timeEnd(consoleId); + console.warn(JSON.stringify(error)); + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getAllData = function (functionId, docType, from, size, sort) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + command: '_search', + docType: docType, + from: from, + size: size, + sort: sort, + query: { + match_all: {} + } + }; + service.genericRequest(databaseRequest).then(function (success) { + // console.log('getAllData', success); + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getFilteredData = function (functionId, docType, from, size, query) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + command: '_search', + docType: docType, + from: from, + size: size, + sort: [], + query: query + }; + service.genericRequest(databaseRequest).then(function (success) { + // console.log('getAllData', success); + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getFilteredSortedData = function (functionId, docType, from, size, sort, query) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + command: '_search', + docType: docType, + from: from, + size: size, + sort: sort, + query: query + }; + service.genericRequest(databaseRequest).then(function (success) { + // console.log('getAllData', success); + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getAggregatedData = function (functionId, docType, aggregation) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + command: '_search', + docType: docType, + aggregation: aggregation + }; + service.aggregationRequest(databaseRequest).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getAggregations = function (functionId, docType, aggregations) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + command: '_search', + docType: docType, + aggregation: aggregations + }; + service.aggregationRequest(databaseRequest).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.getData = function (docType, from, size, sort, filter, query) { + var deferred = $q.defer(); + service.getBase('mwtn').then(function (success) { + var databaseRequest = { + method: 'POST', + base: success.base, + index: success.index, + docType: docType, + from: from, + size: size, + sort: sort, + filter: filter, + query: query + }; + service.genericRequest(databaseRequest).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + service.deleteDocType = function (spec) { + var deferred = $q.defer(); + service.getBase(spec.functionId).then(function (success) { + var databaseRequest = { + method: 'DELETE', + base: success.base, + index: success.index, + docType: spec.docType, + command: '_query', + query: spec.query + }; + + service.genericRequest(databaseRequest).then(function (success) { + deferred.resolve(status); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise, which inquires a single document from database. + * @param {string} functionId - An identifier of an SDN function (e.g 'mwtn'). + * @param {string} docType - The document type of the document to be deleted. + * @param {string} id - An identifier of the document to be deleted. + */ + service.getSingleDocument = function (functionId, docType, id) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'GET', + base: success.base, + index: success.index, + docType: docType, + command: id + }; + + service.genericRequest(databaseRequest).then(function (success) { + deferred.resolve(success.data._source); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise, creating or updateing a single document of the database. + * @param {string} functionId - An identifier of an SDN function (e.g 'mwtn'). + * @param {string} docType - The document type of the document to be deleted. + * @param {string} id - An identifier of the document to be deleted. + * @param {Object} data - A json object to be stored in the database + */ + service.createSingleDocument = function (functionId, docType, id, data) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'PUT', + base: success.base, + index: success.index, + docType: docType, + command: id, + data: data + }; + + service.genericRequest(databaseRequest).then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise, which deletes one document within the database. + * @param {string} functionId - An identifier of an SDN function (e.g 'mwtn'). + * @param {string} docType - The document type of the document to be deleted. + * @param {string} id - An identifier of the document to be deleted. + */ + service.deleteSingleDocument = function (functionId, docType, id) { + var deferred = $q.defer(); + service.getBase(functionId).then(function (success) { + var databaseRequest = { + method: 'DELETE', + base: success.base, + index: success.index, + docType: docType, + command: id, + }; + + service.genericRequest(databaseRequest).then(function (success) { + deferred.resolve({ status: success.status, logId: success.data._id }); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + var moduleInformation; + var inquireModuleInformation = function () { + var deferred = $q.defer(); + service.getBase('mwtn').then(function (success) { + var databaseRequest = { + method: 'GET', + base: success.base, + index: success.index, + from: 0, + size: 999 + }; + service.getAllData('mwtn', 'module', 0, 999, undefined).then(function (success) { + // console.log(JSON.stringify(data.data.hits.hits)); + moduleInformation = {}; + success.data.hits.hits.map(function (hit) { + moduleInformation[hit._id] = hit._source; + }); + // console.log('got moduleInformation', Object.keys(moduleInformation).length); + return deferred.resolve(moduleInformation); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise which returns object yang class and attribute descriptions + */ + service.getModules = function () { + var deferred = $q.defer(); + if (moduleInformation) { + deferred.resolve(moduleInformation); + } else { + inquireModuleInformation().then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + } + return deferred.promise; + }; + + var schemaInformation; + var inquireSchemaInformation = function () { + var deferred = $q.defer(); + service.getBase('mwtn').then(function (success) { + var databaseRequest = { + method: 'GET', + base: success.base, + index: success.index, + from: 0, + size: 999 + }; + service.getAllData('mwtn', 'schema-information', 0, 9999, undefined).then(function (success) { + // console.log(JSON.stringify(data.data.hits.hits)); + schemaInformation = {}; + success.data.hits.hits.map(function (hit) { + schemaInformation[hit._id] = hit._source; + }); + // console.log('got schemaInformation', Object.keys(schemaInformation).length); + return deferred.resolve(schemaInformation); + }, function (error) { + deferred.reject(error); + }); + }, function (error) { + deferred.reject(error); + }); + return deferred.promise; + }; + + /** + * A promise which returns object yang class and attribute descriptions + */ + service.getSchema = function () { + var deferred = $q.defer(); + if (schemaInformation) { + deferred.resolve(schemaInformation); + } else { + inquireSchemaInformation().then(function (success) { + deferred.resolve(success); + }, function (error) { + deferred.reject(error); + }); + } + return deferred.promise; + }; + + return service; + }); + // Class NetConfServer + mwtnCommonsApp.register.factory('NetConfServer', function () { + // Classes + // Class NetConfServer + var NetConfServer = function (data) { + this.data = data; + this.getData = function () { + return this.data; + }; + this.getRadioSignalId = function () { + return this.data.airInterfaceConfiguration.radioSignalId; + }; + this.isLinkUp = function () { + return this.data.airInterfaceStatus.linkIsUp; + }; + this.isPowerOn = function () { + return this.data.airInterfaceConfiguration.powerIsOn; + }; + this.isActive = function () { + return this.isPowerOn() && this.isLinkUp(); + }; + }; + return NetConfServer; + }); + + mwtnCommonsApp.register.factory('ActualNetworkElement', function () { + // Classes + // Class ActualNetworkElement + var ActualNetworkElement = function (data) { + this.data = data; + this.data.layerProtocols = {}; + this.setOnfNetworkElement = function (onfNe) { + this.data.onfNetworkElement = onfNe; + }; + this.getLpByRadioSignalId = function (radioSignalId) { + //console.log('getLP', JSON.stringify(this.data.ltp)); + var layerProtocol; + for (var layerProtocolKey in this.data.layerProtocols) { + if (this.data.layerProtocols[layerProtocolKey].getRadioSignalId && + radioSignalId === parseInt(this.data.layerProtocols[layerProtocolKey].getRadioSignalId())) { + layerProtocol = this.data.layerProtocols[layerProtocolKey]; + } + } + return layerProtocol; + }; + this.getLpByRadioSignalIds = function (radioSignalIds) { + //console.log('getLP', JSON.stringify(this.data.ltp)); + var layerProtocol; + if (radioSignalIds !== undefined) { + for (var layerProtocolKey in this.data.layerProtocols) { + if (this.data.layerProtocols[layerProtocolKey].getRadioSignalIds && + radioSignalIds.toString() === this.data.layerProtocols[layerProtocolKey].getRadioSignalIds(this).toString()) { + layerProtocol = this.data.layerProtocols[layerProtocolKey]; + } + } + } + return layerProtocol; + }; + this.setLP = function (onfPac) { + this.data.layerProtocols[onfPac.data.layerProtocol] = onfPac; + }; + this.getLpPac = function (lpRef) { + return this.data.layerProtocols[lpRef]; + }; + this.getName = function () { + return this.data.name; + }; + this.getConnectionStatus = function () { + return this.data.connectionStatus; + }; + this.isConnected = function () { + return this.data.name !== 'controller-config' && this.data.connectionStatus == 'connected'; + }; + this.setConnectionStatus = function (status) { + this.data.connectionStatus = status; + }; + }; + return ActualNetworkElement; + }); + + mwtnCommonsApp.register.factory('LogicalTerminationPoint', function ($mwtnGlobal, $mwtnLog) { + // Sub-Class LayerProtocol + /** + * An object representing an LP. + * @typedef {Object} LayerProtocol + */ + var LayerProtocol = function (data) { + // take a guess, if termiation-state is not exposed + if (data['termination-state'] === undefined) { + + data['termination-state'] = 'terminated-bidirectional'; + if (data['layer-protocol-name'] === "ETH") { + data['termination-state'] = 'lp-can-never-terminate'; + } + $mwtnLog.warning({ component: 'LTP.getTerminationState', message: 'Check whether NE provided mandatory termination state. ' + data.uuid }); + } else if (data['termination-state'] === false || data['termination-state'] === 'false' ) { + data['termination-state'] = 'terminated-bidirectional'; + } + + // console.log('in', JSON.stringify(data)); + var defaultMapping = { + 'ety-ttp': {}, + // [FFA 1709] 'etc-ttp': { 'capability': 'urn:onf:params:xml:ns:yang:microwave-model?module=microwave-model', 'revision': '2017-03-24', 'conditional-package': 'mw-ethernet-container-pac' }, + 'etc-ttp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-EthernetContainerl?module=MicrowaveModel-ObjectClasses-EthernetContainer', 'revision': '2016-09-02', 'conditional-package': 'MW_EthernetContainer_Pac' }, + 'tdm-ctp': { 'capability': 'urn:onf:params:xml:ns:yang:microwave-model?module=microwave-model', 'revision': '2017-03-24', 'conditional-package': 'mw-tdm-container-pac' }, + + // due to E/// + 'mws-ctp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-PureEthernetStructure?module=MicrowaveModel-ObjectClasses-PureEthernetStructure', 'revision': '2016-09-02', 'conditional-package': 'MW_PureEthernetStructure_Pac' }, + 'mwps-ctp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-AirInterface?module=MicrowaveModel-ObjectClasses-AirInterface', 'revision': '2016-09-01', 'conditional-package': 'MW_AirInterface_Pac' }, + // 'mws-ctp': { 'capability': 'urn:onf:params:xml:ns:yang:microwave-model?module=microwave-model', 'revision': '2017-03-24', 'conditional-package': 'mw-air-interface-diversity-pac' }, + + 'eth-ctp': { 'capability': 'urn:onf:params:xml:ns:yang:onf-ethernet-conditional-packages?module=onf-ethernet-conditional-packages', 'revision': '2017-04-02', 'conditional-package': 'ethernet-pac' }, + // 3rd PoC + 'mwps-ttp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-AirInterface?module=MicrowaveModel-ObjectClasses-AirInterface', 'revision': '2016-09-01', 'conditional-package': 'MW_AirInterface_Pac' }, + 'mws-ttp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-PureEthernetStructure?module=MicrowaveModel-ObjectClasses-PureEthernetStructure', 'revision': '2016-09-02', 'conditional-package': 'MW_PureEthernetStructure_Pac' }, + 'eth-ctp-ctp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-EthernetContainerl?module=MicrowaveModel-ObjectClasses-EthernetContainer', 'revision': '2016-09-02', 'conditional-package': 'MW_EthernetContainer_Pac' }, + 'etc-ctp': { 'capability': 'uri:onf:MicrowaveModel-ObjectClasses-EthernetContainerl?module=MicrowaveModel-ObjectClasses-EthernetContainer', 'revision': '2016-09-02', 'conditional-package': 'MW_EthernetContainer_Pac' }, + + }; + // create empty extension, if not exists + if (!data.extension) { + data.extension = []; + } + this.data = data; + + // methods + this.getData = function () { + return this.data; + }; + this.getId = function () { + return this.getData().uuid; + }; + this.getLabel = function () { + return ['LP(', this.getItuLabel(true).toUpperCase(), '): ', this.getId()].join(''); + }; + this.getLayer = function () { + var layer = this.getData()['layer-protocol-name']; + if (layer === 'ETH-CTP') { + layer = 'ETC'; + } + return layer; + }; + this.getTerminationState = function (abstract) { + // 3th PoC termination state is of type boolean + if (this.getData()['termination-state'] === true) { + return 'ttp'; + } else if (this.getData()['termination-state'] === false) { + return 'ctp'; + } + // 4th PoC termination state is of type enum + if (abstract !== true) { + return this.getData()['termination-state']; + } + var mapping = { + 'lp-can-never-terminate': 'ctp', + 'lt-not-terminated': 'ctp', + 'terminated-server-to-client-flow': 'ttp', + 'terminated-client-to-server-flow': 'ttp', + 'terminated-bidirectional': 'ttp', + 'lt-permenantly-terminated': 'ttp', + 'termination-state-unknown': 'ttp' + }; + return mapping[this.getData()['termination-state']]; + }; + this.getItuLabel = function () { + return [this.getLayer(), this.getTerminationState(true)].join('-').toLowerCase(); + }; + this.getExtension = function (key) { + var result = this.getData().extension.filter(function (ex) { + return ex['value-name'] === key; + }).map(function (ex) { + return ex.value; + }); + if (result && result.length > 0) { + return result[0]; + } + // check hardcoded alternatives + var ituLabel = this.getItuLabel(); + if (!defaultMapping[ituLabel]) { + return ''; + } + return defaultMapping[ituLabel][key]; + }; + /** + * A getter for the yang-capability of the LayerProtocol + * @param {boolean|undefined} moduleOnly - Defines, whether the result should contain only yang-module-name. + * @return {string} The conditional package name of the LayerProtocol + */ + this.getCapability = function (moduleOnly) { + var cap = this.getExtension('capability'); + if (!cap) return ''; + + // workaround bug in spec + if (cap.contains('onf-ethernet-conditional-package') && !cap.contains('onf-ethernet-conditional-packages')) { + console.warn('Inform vendor about spec error and updates'); + cap = cap.replaceAll('onf-ethernet-conditional-package', 'onf-ethernet-conditional-packages'); + } + if (cap !== '' && moduleOnly === true) { + return cap.split('?module=')[1]; + } + return cap; + }; + this.getRevision = function () { + return this.getExtension('revision'); + }; + /** + * A getter for the conditional package name of the LayerProtocol + * @param {boolean|undefined} addModule - Defines, whether the result should include the yang-module-name. + * @return {string} The conditional package name of the LayerProtocol + */ + this.getConditionalPackage = function (addModule) { + var cp = this.getExtension('conditional-package'); + if (!cp) { + return ''; + } + if (addModule === true) { + return [this.getCapability(true), cp].join(':'); + } + return cp; + }; + }; + + // Sub-Class LogicalTerminationPoint + /** + * An object representing an LTP. + * @typedef {Object} LogicalTerminationPoint + */ + var LogicalTerminationPoint = function (data) { + this.data = data; + this.layerProtocols = this.data.lp.map(function (layerProtocol) { + return new LayerProtocol(layerProtocol); + }); + // console.log(this.layerProtocols); + this.getData = function () { + return this.data; + }; + this.getId = function () { + return this.getData().uuid; + }; + this.getName = function () { + return this.getData().name[0].value; + }; + this.getDirectionality = function () { + return this.getData()['ltp-direction']; + }; + this.getServerLtps = function () { + return this.getData()['server-ltp']; + }; + this.getClientLtps = function () { + return this.getData()['client-ltp']; + }; + this.getLayer = function () { + return this.getLayerProtocols()[0].getLayer(); + }; + this.getLabel = function () { + return ['LTP(', this.getLayerProtocols()[0].getItuLabel(true).toUpperCase(), '): ', this.getId()].join(''); + }; + this.getLayerProtocols = function () { + return this.layerProtocols; + }; + this.getConditionalPackages = function () { + console.error(JSON.stringifythis.getLayerProtocols()()); + return this.getLayerProtocols().map(function (lp) { + return lp.getConditionalPackage(); + }); + }; + } + return LogicalTerminationPoint; + }); + + mwtnCommonsApp.register.factory('PtpClock', function (PtpPort) { + var PtpClock = function (data) { + var COMPONENT = "PtpClock"; + this.data = {}; + if (data && data['instance-list'] && data['instance-list'][0]) { + this.data = data['instance-list'][0]; + } + if (!this.data['port-ds-list'] || this.data['port-ds-list'].length === 0) { + this.ptpPorts = []; + var message = ['The PTP clock', data['instance-number'], 'dose not support a single PTP port.'].join(' '); + console.info({ component: COMPONENT, message: message }); + } else { + this.ptpPorts = this.data['port-ds-list'].map(function(ptpPort) { + return new PtpPort(ptpPort); + }); + } + + this.getData = function () { + return this.data; + // return JSON.parse(JSON.stringify(this.data).replaceAll('onf-ptp-dataset:', '')); + }; + this.getIdentity = function(hex) { + var defaultDs = this.getData()['default-ds']; + var result = 'ERROR: no clock identity found'; + if (defaultDs && defaultDs['clock-identity']) { + result = defaultDs['clock-identity']; + if (hex) { + result = result.base64ToHex(); + } + } + return result; + }; + this.getParent = function(hex) { + var parentDs = this.getData()['parent-ds']; + var key = 'parent-port-identity'; + var result = ''; + if (parentDs && parentDs[key] && parentDs[key]['clock-identity'] && parentDs[key]['port-number']) { + result = parentDs[key]['clock-identity']; + if (hex) { + result = result.base64ToHex(); + } + result = [result, parentDs[key]['port-number']].join('#'); + } + return result; + }; + this.getGrandMaster = function(hex) { + var parentDs = this.getData()['parent-ds']; + // console.warn(JSON.stringify(parentDs)); + var key = 'parent-port-identity'; + var result = ''; + if (parentDs && parentDs['grandmaster-identity']) { + result = parentDs['grandmaster-identity']; + if (hex) { + result = result.base64ToHex(); + } + } + return result; + }; + this.getPtpPorts = function () { + return this.ptpPorts; + }; + }; + return PtpClock; + }); + + mwtnCommonsApp.register.factory('PtpPort', function () { + var PtpPort = function (data) { + this.data = data; + this.getData = function () { + return this.data; + }; + this.getId = function() { + return this.getData()['port-number']; + }; + this.getNumber = function() { + return this.getData()['port-number']; + }; + this.getState = function() { + return this.getData()['port-state']; + }; + this.isSlave = function() { + return this.getData()['port-state'] === 'SLAVE'; + }; + this.isMaster = function() { + return this.getData()['port-state'] === 'MASTER'; + }; + this.getLogicalTerminationPointReference = function() { + return this.getData()['onf-ptp-dataset:logical-termination-point']; + }; + }; + return PtpPort; + }); + + mwtnCommonsApp.register.factory('OnfNetworkElement', function ($mwtnGlobal, LogicalTerminationPoint) { + // Classes + // Class OnfNetworkElement + var OnfNetworkElement = function (data) { + var COMPONENT = "OnfNetworkElement"; + + this.data = data; + if (!this.data) { + var message = ['No data received.'].join(' '); + console.warn({ component: COMPONENT, message: message }); + return; + } + + // console.log(JSON.stringify(data)); + if (!this.data.ltp || this.data.ltp.length === 0) { + this.logicalTerminationPoints = []; + var message = ['The network-element', data.uuid, 'does not support a single LTP. No LTP -> no SDN integration via ONF core-model.'].join(' '); + // TODO $mwtnLog -> Unknown provider: $mwtnlogProvider <- $mwtnlog <- OnfNetworkElement [sko] Dont get it ;( + console.warn({ component: COMPONENT, message: message }); + } else { + this.logicalTerminationPoints = this.data.ltp.map(function (logicalTerminationPoint) { + return new LogicalTerminationPoint(logicalTerminationPoint); + }); + } + + this.getData = function () { + return this.data; + }; + this.getId = function () { + return this.getData().uuid; + }; + this.getForwardingDomain = function () { + return this.getData().fd; + }; + this.getName = function () { + return this.getData().name[0].value || this.getData().uuid; + }; + this.getLogicalTerminationPoints = function () { + return this.logicalTerminationPoints; + }; + this.getLtp = function (id) { + var result = this.getLogicalTerminationPoints().filter(function (ltp) { + return ltp.getId() === id; + }); + if (result.length === 1) { + return result[0]; + } + return undefined; + }; + this.getLpById = function (id) { + var result = {}; + this.getLogicalTerminationPoints().map(function (ltp) { + ltp.getLayerProtocols().map(function (lp) { + if (lp.getData().uuid === id) { + result = lp; + } + }); + }); + return result; + }; + this.getNumberOfLtps = function () { + return this.logicalTerminationPoints.length; + }; + this.getServerLtps = function (layerProtocolRef) { + var result = []; + if (this.data._ltpRefList) { + var ltpList = this.data._ltpRefList.map(function (ltp) { + if (ltp.lp[0].uuid === layerProtocolRef) { + result = ltp._serverLtpRefList; + } + }); + } + return result; + }; + this.getClientLtpIds = function (layerProtocolRef) { + var result = []; + if (this.data._ltpRefList) { + var ltpList = this.data._ltpRefList.map(function (ltp) { + if (ltp.lp[0].uuid === layerProtocolRef) { + result = ltp._clientLtpRefList; + } + }); + } + return result; + }; + this.getLpByLtpRef = function (ltpRef) { + var result; + if (this.data._ltpRefList) { + var ltpList = this.data._ltpRefList.map(function (ltp) { + if (ltp.uuid === ltpRef) { + result = ltp.lp[0]; + } + }); + } + return result; + }; + this.getLtpsByLayer = function (layerProtocolName) { + return this.getLogicalTerminationPoints().filter(function (ltp) { + return ltp.getLayer() === layerProtocolName; + }); + }; + this.getLTPMwpsList = function () { + return this.getLtpsByLayer('MWPS'); + }; + this.getLTPMwsList = function () { + return this.getLtpsByLayer('MWS'); + }; + this.getLTPEthCtpList = function () { + return this.getLtpsByLayer('ETH'); + }; + this.getLTPTdmCtpList = function () { + return this.getLtpsByLayer('TDM'); + }; + }; + return OnfNetworkElement; + }); + + mwtnCommonsApp.register.factory('MicrowavePhysicalSection', function () { + // Classes + // Class MicrowavePhysicalSection + var MicrowavePhysicalSection = function (data) { + this.data = data; + this.getData = function () { + return this.data; + }; + this.getLayerProtocolId = function () { + return this.getData().layerProtocol; + }; + this.getRadioSignalId = function () { + return this.getData()['air-interface-configuration'] ? this.data['air-interface-configuration']['radio-signal-id'] : -1; + }; + this.isLinkUp = function () { + return this.getData()['air-interface-status']['link-is-up']; + }; + this.isPowerOn = function () { + return this.getData()['air-interface-configuration']['power-is-on']; + }; + this.isActive = function () { + return this.isPowerOn() && this.isLinkUp(); + }; + }; + return MicrowavePhysicalSection; + }); + + mwtnCommonsApp.register.factory('MicrowaveSection', function () { + // Classes + // Class MicrowaveSection + var MicrowaveSection = function (data) { + this.data = data; + this.getData = function () { + return this.data; + }; + this.getId = function () { + return this.data.layerProtocol; + }; + this.getRadioSignalIds = function (actualNe) { + this.data.parent = actualNe; + var result = []; + var onfNe = actualNe.data.onfNetworkElement; + var lpId = this.getId(); + onfNe.getServerLtps(lpId).map(function (mwpsLtpRef) { + var lpRef = onfNe.getLpByLtpRef(mwpsLtpRef).uuid; + var mwps = actualNe.getLpPac(lpRef); + result.push(mwps.getRadioSignalId()); + }); + return result; + }; + this.getTimeSlotCapacity = function () { + return this.data.structureCapability.timeSlotCapacity; + }; + this.getTotalNumberOfTimeSlots = function () { + return this.data.structureCapability.totalNumberOfTimeSlots; + }; + this.getNumberOfEffectiveTimeSlots = function () { + var count = 0; + this.data.structureStatus.timeSlotStatusList.map(function (ts) { + if (ts.operationalStatus === 'ENABLED') { + count = count + 1; + } + }); + return count; + }; + this.getConfiguredCapacity = function () { + return this.getTotalNumberOfTimeSlots() * this.getTimeSlotCapacity(); + }; + this.getEffectiveCapacity = function () { + return this.getNumberOfEffectiveTimeSlots() * this.getTimeSlotCapacity(); + }; + this.isActive = function () { + if (this.data.parent === undefined) { + return false; + } + var actualNe = this.data.parent; + var result = true; + var onfNe = actualNe.data.onfNetworkElement; + var lpId = this.getId(); + onfNe.getServerLtps(lpId).map(function (mwpsLtpRef) { + var lpRef = onfNe.getLpByLtpRef(mwpsLtpRef).uuid; + var mwps = actualNe.getLpPac(lpRef); + result = result && mwps.isActive(); + }); + return result; + }; + }; + return MicrowaveSection; + }); + });
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.tpl.html new file mode 100644 index 00000000..9594bca7 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.tpl.html @@ -0,0 +1,7 @@ +<!-- This is the landing page of you application, Update the content as per your requirements --> + +<h4>Your {{data}} application is loaded</h4> +<hr /> +<div class="owl"> + <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span> +</div> diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnFooter.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnFooter.tpl.html new file mode 100644 index 00000000..597bcb98 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnFooter.tpl.html @@ -0,0 +1,4 @@ +<hr /> +<div class="owl"> + <span class="white">{{prefix}} - Build: @buildtime@</span> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnGrid.tpl.html new file mode 100644 index 00000000..2751ffcb --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnGrid.tpl.html @@ -0,0 +1,23 @@ +<div class="owl co1ntainer" > + + <div class="row"> + <div class="col-md-12"> + + <div ng-if="info !== false"> + <span class="owl-dark">{{info}}</span> + </div> + + <div ui-grid="gridOptions" + ui-grid-exporter + ui-grid-selection + ui-grid-pinning + ui-grid-resize-columns + ui-grid-move-columns + ui-grid-auto-resize + class="mwtn-grid" + ng-style="getTableHeight()"></div> + + </div> + </div> + +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnJsonViewer.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnJsonViewer.tpl.html new file mode 100644 index 00000000..5f3cfbf5 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnJsonViewer.tpl.html @@ -0,0 +1,110 @@ +<div class="owl"> + <div class="row text-right" > + <div class="form-group" ng-if="noButtons !== true"> + <button class="btn btn-default" type="button" clipboard supported="myClipboard.supported" text="myClipboard.getJson()" + on-copied="myClipboard.copyToClipboard()" on-error="myClipboard.error(err)"> + <i class="fa fa-clipboard" aria-hidden="true"></i> + </button> + <button class="btn btn-default" type="button" ng-if="replace" ng-click="openConfigView()"> + <i class="fa fa-pencil-square-o pointer" aria-hidden="true" ></i> + </button> + <div> + </div> +</div> +<div class="owl"> + + <div ng-if="info !== false"> + <span class="owl-dark">{{info}}</span> + </div> + + <div class="row" ng-repeat="(key, value) in viewData track by $index" ng-show="value.value !== undefined"> + + <!-- type- default --> + <div class="col col-md-4 text-right" title="{{value.description}}" ng-if="value.type !== 'array' && value.visible === true"> + <span class="owl-dark">{{value.labelId | translate}}</span> + </div> + <div class="col col-md-4 text-left" ng-if="value.type !== 'boolean' && value.type !== 'number' && value.type !== 'object' && value.type !== 'array' && value.visible === true"> + <b>{{value.value}}</b> + </div> + + <!-- type-boolean --> + + <div class="col col-md-2" ng-if="value.type === 'boolean' && value.visible === true"> + <i class="fa" ng-class="{'fa-square-o': value.value === false, 'fa-check-square-o green': value.value === true}" aria-hidden="true"></i> + </div> + + <!-- type- number --> + <div class="col col-md-2 number" ng-if="value.type === 'number' && value.visible === true"> + <b>{{value.value}}</b> + </div> + <div class="col col-md-2 text-left" ng-if="value.unit && value.visible === true"> + <span class="owl-dark">{{value.unit}}</span> + </div> + + <!-- type- array of objects --> + <div class="col col-md-12" ng-if="value.type === 'array' && value.value.length !== 0 && getType(value.value[0]) === 'object'"> + <span class="owl-dark text-right" style="margin-top: 5px;">{{value.labelId | translate}}</span><br/> + <mwtn-grid network-element="networkElement" data="value.value" path="path"></mwtn-grid> + </div> + <!-- type- array of non objects --> + <div class="col col-md-4 text-right" title="{{value.description}}" ng-if="value.type === 'array' && value.value.length !== 0 && getType(value.value[0]) !== 'object'"> + <span class="owl-dark">{{value.labelId | translate}}</span> + </div> + <div class="col col-md-8 text-left" ng-if="value.type === 'array' && value.value.length !== 0 && getType(value.value[0]) !== 'object'"> + <b>{{value.value}}</b> + </div> + + <!-- type- object --> + <div class="col col-md-7" ng-if="value.type === 'object'"> + +<!-- <pre>{{value | json}}</pre> + ### + <hr> +<mwtn-json-viewer data="value.value"></mwtn-json-viewer> + <hr> + ### --> + + <div class="owl"> + + <!-- TODO exception case: current pm --> + <div class="row" ng-repeat="(oKey, oValue) in value.value track by $index" ng-if="oValue.value === undefined"> + <div class="col col-md-3 text-right"> + <span class="owl-dark">{{oKey | translate}}</span> + </div> + <div class="col col-md-4 text-right" ng-if="oValue.type !== 'object'"> + <b>{{oValue | json}}</b> + </div> + </div> + + <!-- expected case: --> + <div class="row" ng-repeat="(oKey, oValue) in value.value track by $index" ng-if="oValue.value !== undefined"> + <!-- oValue.type !== 'object'' && oValue.type !== 'array' --> + <div class="col col-md-3 text-right" ng-if="oValue.type !== 'object' && oValue.type !== 'array'"> + <span class="owl-dark">{{oValue.labelId || oKey.replace('onf-ptp-dataset:' ,'') | translate}}</span> + </div> + <div class="col col-md-4 text-right" ng-if="oValue.type !== 'object' && oValue.type !== 'array'"> + <b>{{oValue.value || oValue}}</b> + </div> + + + <!-- oValue.type === 'array'' --> + <div class="col col-md-3 text-right" ng-if="oValue.type === 'array'"> + <span class="owl-dark">{{oValue.labelId || oKey.replace('onf-ptp-dataset:' ,'') | translate}}</span> + </div> + <div class="col col-md-4" ng-if="oValue.type === 'array'"> + <json-formatter json="oValue.value" open="1"></json-formatter> + </div> + + <!-- oValue.type === 'object' --> + <div class="col col-md-3 text-right" ng-if="oValue.type === 'object'"> + <span class="owl-dark">{{oValue.labelId || oKey.replace('onf-ptp-dataset:' ,'') | translate}}</span> + </div> + <div class="col col-md-4" ng-if="oValue.type === 'object'"> + <json-formatter json="oValue.value" open="1"></json-formatter> + </div> + </div> + </div> + </div> + </div> + +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnSelectNetworkElement.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnSelectNetworkElement.tpl.html new file mode 100644 index 00000000..58515605 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnSelectNetworkElement.tpl.html @@ -0,0 +1,33 @@ +<div class="owl container" ng-hide="networkElements.lenght !== 0" style="width: 100%"> + <p> + <span>{{ 'MWTN_NO_DEVICES_CONNECTED' | translate }}</span> + <span>Please check</span> + <a href="#/mwtnConnect" class="white"> + <span>MWTN Connect</span> + </a> + <span>.</span> + </p> +</div> +<div class="owl container" ng-show="networkElements.lenght !== 0" style="width: 100%"> + <div class="row"> + <div class="col-md-3 form-group" ng-show="networkElements.length > 30"> + <input list="networkElements" class="form-control" ng-model="networkElement"> + <datalist id="networkElements"> + <option ng-repeat="ne in networkElements" value="{{ne.id}}">{{ne.id}}</option> + </datalist> + </div> + <div class="col-md-3 form-group" ng-hide="networkElements.length > 30"> + <select class="form-control" ng-model="networkElement"> + <option ng-repeat="ne in networkElements" value="{{ne.id}}">{{ne.id}}</option> + </select> + </div> + <div class="col-md-2"> + <span class="white">{{'MWTN_SELECT_NETWORK_ELEMENT' | translate}}</span> + </div> + <div class="col-md-7 text-right"> + <div class="form-group"> + <button type="button" class="btn btn-default" ng-click="collapseAll()">{{'MWTN_COLLAPSE_ALL' | translate}}</button> + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/openConfigView.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/openConfigView.html new file mode 100644 index 00000000..64c06e96 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/openConfigView.html @@ -0,0 +1,69 @@ + +<div class="modal-header"> + <h3 class="modal-title" id="modal-title">{{'MWTN_CONFIGURATION' | translate}}</h3> +</div> +<div class="modal-body" id="modal-body"> + <div class="container" style="width:100%"> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_NETWORKELEMENT' | translate}} + </div> + <div class="col-md-9"> + <b>{{spec.nodeId}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_CONDITIONAL_PACKAGE' | translate}} + </div> + <div class="col-md-9"> + <b>{{spec.pacId}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_LP' | translate}} + </div> + <div class="col-md-9"> + <b>{{spec.layerProtocolId}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_SUBOBJECT' | translate}} + </div> + <div class="col-md-9"> + <b>{{spec.partId}}</b> + </div> + <hr /> + </div> + <div class="row"> + + <div ng-repeat="(key, item) in viewData" ng-if="item.visible === true"> + + <!-- text, number, combo --> + <div class="col-md-3 text-right radio">{{item.labelId | translate}}</div> + <div ng-class="{'col-md-2':item.unit, 'col-md-3':!item.unit}" class="form-group" ng-if="item.controlType !== 'checkbox' && getType(item.controlType) !== 'array'"> + <input class="form-control" type="{{item.controlType}}" ng-model="item.value"></input> + </div> + <div class="col-md-3 checkbox" ng-if="item.controlType === 'checkbox'"><input type="checkbox" ng-model="item.value" /></div> + <div ng-class="{'col-md-2':item.unit, 'col-md-3':!item.unit}" class="form-group" ng-if="getType(item.controlType) === 'array'"> + <select class="form-control" ng-model="item.value"> + <option ng-repeat="option in item.controlType track by $index" value="{{option}}">{{option}}</option> + </select> + </div> + <div class="col-md-1 radio" ng-if="item.unit"> + <span class="owl-dark">{{item.unit}}</span> + </div> + + </div> + </div> +</div> +<div class="modal-footer"> + <div class="{{applied.class}}", ng-show="applied">{{applied.text}}</div> + <button class="btn btn-primary" type="button" ng-click="ok()"> + <span style="color: white;">{{'MWTN_APPLY' | translate}}</span> + <i class="pull-right fa fa-spinner fa-pulse" ng-show="processing"></i> + </button> + <button class="btn btn-warning" type="button" ng-click="cancel()">{{'MWTN_CLOSE' | translate}}</button> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/showGridCellDetail.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/showGridCellDetail.html new file mode 100644 index 00000000..ab449bbc --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/showGridCellDetail.html @@ -0,0 +1,54 @@ + +<div class="modal-header"> + <h3 class="modal-title" id="modal-title">{{'MWTN_CONFIGURATION' | translate}}</h3> +</div> +<div class="modal-body" id="modal-body"> + <div class="container" style="width:100%"> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_NETWORKELEMENT' | translate}} + </div> + <div class="col-md-9"> + <b>{{networkElement}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_CONDITIONAL_PACKAGE' | translate}} + </div> + <div class="col-md-9"> + <b>{{path.split('&nbsp;')[0]}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_LP' | translate}} + </div> + <div class="col-md-9"> + <b>{{path.split('&nbsp;')[1]}}</b> + </div> + </div> + <div class="row"> + <div class="col-md-3 text-right" > + {{'MWTN_SUBOBJECT' | translate}} + </div> + <div class="col-md-9"> + <b>{{path.split('&nbsp;')[2]}}</b> + </div> + <hr /> + </div> + <div class="row"> + <mwtn-json-viewer network-element="networkElement" data="value" ng-if="type === 'object'"></mwtn-json-viewer> + <mwtn-grid network-element="networkElement" data="value" ng-if="type === 'array'"></mwtn-grid> + </div> + </div> +</div> +<div class="modal-footer"> + <div class="{{applied.class}}", ng-show="applied">{{applied.text}}</div> +<!-- + <button class="btn btn-primary" type="button" ng-click="ok()"> + <span>{{'MWTN_APPLY' | translate}}</span> + <i class="pull-right fa fa-spinner fa-pulse" ng-show="processing"></i> + </button> --> + <button class="btn btn-warning" type="button" ng-click="cancel()">{{'MWTN_CLOSE' | translate}}</button> +</div>
\ No newline at end of file diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/xml2json.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/xml2json.js new file mode 100644 index 00000000..5ff7e578 --- /dev/null +++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/xml2json.js @@ -0,0 +1,567 @@ +/*
+ Copyright 2011-2013 Abdulla Abdurakhmanov
+ Original sources are available at https://code.google.com/p/x2js/
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+function X2JS(config) {
+ 'use strict';
+
+ var VERSION = "1.1.5";
+
+ config = config || {};
+ initConfigDefaults();
+ initRequiredPolyfills();
+
+ function initConfigDefaults() {
+ if(config.escapeMode === undefined) {
+ config.escapeMode = true;
+ }
+ config.attributePrefix = config.attributePrefix || "_";
+ config.arrayAccessForm = config.arrayAccessForm || "none";
+ config.emptyNodeForm = config.emptyNodeForm || "text";
+ if(config.enableToStringFunc === undefined) {
+ config.enableToStringFunc = true;
+ }
+ config.arrayAccessFormPaths = config.arrayAccessFormPaths || [];
+ if(config.skipEmptyTextNodesForObj === undefined) {
+ config.skipEmptyTextNodesForObj = true;
+ }
+ if(config.stripWhitespaces === undefined) {
+ config.stripWhitespaces = true;
+ }
+ config.datetimeAccessFormPaths = config.datetimeAccessFormPaths || [];
+ }
+
+ var DOMNodeTypes = {
+ ELEMENT_NODE : 1,
+ TEXT_NODE : 3,
+ CDATA_SECTION_NODE : 4,
+ COMMENT_NODE : 8,
+ DOCUMENT_NODE : 9
+ };
+
+ function initRequiredPolyfills() {
+ function pad(number) {
+ var r = String(number);
+ if ( r.length === 1 ) {
+ r = '0' + r;
+ }
+ return r;
+ }
+ // Hello IE8-
+ if(typeof String.prototype.trim !== 'function') {
+ String.prototype.trim = function() {
+ return this.replace(/^\s+|^\n+|(\s|\n)+$/g, '');
+ }
+ }
+ if(typeof Date.prototype.toISOString !== 'function') {
+ // Implementation from http://stackoverflow.com/questions/2573521/how-do-i-output-an-iso-8601-formatted-string-in-javascript
+ Date.prototype.toISOString = function() {
+ return this.getUTCFullYear()
+ + '-' + pad( this.getUTCMonth() + 1 )
+ + '-' + pad( this.getUTCDate() )
+ + 'T' + pad( this.getUTCHours() )
+ + ':' + pad( this.getUTCMinutes() )
+ + ':' + pad( this.getUTCSeconds() )
+ + '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 )
+ + 'Z';
+ };
+ }
+ }
+
+ function getNodeLocalName( node ) {
+ var nodeLocalName = node.localName;
+ if(nodeLocalName == null) // Yeah, this is IE!!
+ nodeLocalName = node.baseName;
+ if(nodeLocalName == null || nodeLocalName=="") // =="" is IE too
+ nodeLocalName = node.nodeName;
+ return nodeLocalName;
+ }
+
+ function getNodePrefix(node) {
+ return node.prefix;
+ }
+
+ function escapeXmlChars(str) {
+ if(typeof(str) == "string")
+ return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
+ else
+ return str;
+ }
+
+ function unescapeXmlChars(str) {
+ return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(///g, '\/');
+ }
+
+ function toArrayAccessForm(obj, childName, path) {
+ switch(config.arrayAccessForm) {
+ case "property":
+ if(!(obj[childName] instanceof Array))
+ obj[childName+"_asArray"] = [obj[childName]];
+ else
+ obj[childName+"_asArray"] = obj[childName];
+ break;
+ /*case "none":
+ break;*/
+ }
+
+ if(!(obj[childName] instanceof Array) && config.arrayAccessFormPaths.length > 0) {
+ var idx = 0;
+ for(; idx < config.arrayAccessFormPaths.length; idx++) {
+ var arrayPath = config.arrayAccessFormPaths[idx];
+ if( typeof arrayPath === "string" ) {
+ if(arrayPath == path)
+ break;
+ }
+ else
+ if( arrayPath instanceof RegExp) {
+ if(arrayPath.test(path))
+ break;
+ }
+ else
+ if( typeof arrayPath === "function") {
+ if(arrayPath(obj, childName, path))
+ break;
+ }
+ }
+ if(idx!=config.arrayAccessFormPaths.length) {
+ obj[childName] = [obj[childName]];
+ }
+ }
+ }
+
+ function fromXmlDateTime(prop) {
+ // Implementation based up on http://stackoverflow.com/questions/8178598/xml-datetime-to-javascript-date-object
+ // Improved to support full spec and optional parts
+ var bits = prop.split(/[-T:+Z]/g);
+
+ var d = new Date(bits[0], bits[1]-1, bits[2]);
+ var secondBits = bits[5].split("\.");
+ d.setHours(bits[3], bits[4], secondBits[0]);
+ if(secondBits.length>1)
+ d.setMilliseconds(secondBits[1]);
+
+ // Get supplied time zone offset in minutes
+ if(bits[6] && bits[7]) {
+ var offsetMinutes = bits[6] * 60 + Number(bits[7]);
+ var sign = /\d\d-\d\d:\d\d$/.test(prop)? '-' : '+';
+
+ // Apply the sign
+ offsetMinutes = 0 + (sign == '-'? -1 * offsetMinutes : offsetMinutes);
+
+ // Apply offset and local timezone
+ d.setMinutes(d.getMinutes() - offsetMinutes - d.getTimezoneOffset())
+ }
+ else
+ if(prop.indexOf("Z", prop.length - 1) !== -1) {
+ d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()));
+ }
+
+ // d is now a local time equivalent to the supplied time
+ return d;
+ }
+
+ function checkFromXmlDateTimePaths(value, childName, fullPath) {
+ if(config.datetimeAccessFormPaths.length > 0) {
+ var path = fullPath.split("\.#")[0];
+ var idx = 0;
+ for(; idx < config.datetimeAccessFormPaths.length; idx++) {
+ var dtPath = config.datetimeAccessFormPaths[idx];
+ if( typeof dtPath === "string" ) {
+ if(dtPath == path)
+ break;
+ }
+ else
+ if( dtPath instanceof RegExp) {
+ if(dtPath.test(path))
+ break;
+ }
+ else
+ if( typeof dtPath === "function") {
+ if(dtPath(obj, childName, path))
+ break;
+ }
+ }
+ if(idx!=config.datetimeAccessFormPaths.length) {
+ return fromXmlDateTime(value);
+ }
+ else
+ return value;
+ }
+ else
+ return value;
+ }
+
+ function parseDOMChildren( node, path ) {
+ if(node.nodeType == DOMNodeTypes.DOCUMENT_NODE) {
+ var result = new Object;
+ var nodeChildren = node.childNodes;
+ // Alternative for firstElementChild which is not supported in some environments
+ for(var cidx=0; cidx <nodeChildren.length; cidx++) {
+ var child = nodeChildren.item(cidx);
+ if(child.nodeType == DOMNodeTypes.ELEMENT_NODE) {
+ var childName = getNodeLocalName(child);
+ result[childName] = parseDOMChildren(child, childName);
+ }
+ }
+ return result;
+ }
+ else
+ if(node.nodeType == DOMNodeTypes.ELEMENT_NODE) {
+ var result = new Object;
+ result.__cnt=0;
+
+ var nodeChildren = node.childNodes;
+
+ // Children nodes
+ for(var cidx=0; cidx <nodeChildren.length; cidx++) {
+ var child = nodeChildren.item(cidx); // nodeChildren[cidx];
+ var childName = getNodeLocalName(child);
+
+ if(child.nodeType!= DOMNodeTypes.COMMENT_NODE) {
+ result.__cnt++;
+ if(result[childName] == null) {
+ result[childName] = parseDOMChildren(child, path+"."+childName);
+ toArrayAccessForm(result, childName, path+"."+childName);
+ }
+ else {
+ if(result[childName] != null) {
+ if( !(result[childName] instanceof Array)) {
+ result[childName] = [result[childName]];
+ toArrayAccessForm(result, childName, path+"."+childName);
+ }
+ }
+ (result[childName])[result[childName].length] = parseDOMChildren(child, path+"."+childName);
+ }
+ }
+ }
+
+ // Attributes
+ for(var aidx=0; aidx <node.attributes.length; aidx++) {
+ var attr = node.attributes.item(aidx); // [aidx];
+ result.__cnt++;
+ result[config.attributePrefix+attr.name]=attr.value;
+ }
+
+ // Node namespace prefix
+ var nodePrefix = getNodePrefix(node);
+ if(nodePrefix!=null && nodePrefix!="") {
+ result.__cnt++;
+ result.__prefix=nodePrefix;
+ }
+
+ if(result["#text"]!=null) {
+ result.__text = result["#text"];
+ if(result.__text instanceof Array) {
+ result.__text = result.__text.join("\n");
+ }
+ if(config.escapeMode)
+ result.__text = unescapeXmlChars(result.__text);
+ if(config.stripWhitespaces)
+ result.__text = result.__text.trim();
+ delete result["#text"];
+ if(config.arrayAccessForm=="property")
+ delete result["#text_asArray"];
+ result.__text = checkFromXmlDateTimePaths(result.__text, childName, path+"."+childName);
+ }
+ if(result["#cdata-section"]!=null) {
+ result.__cdata = result["#cdata-section"];
+ delete result["#cdata-section"];
+ if(config.arrayAccessForm=="property")
+ delete result["#cdata-section_asArray"];
+ }
+
+ if( result.__cnt == 1 && result.__text!=null ) {
+ result = result.__text;
+ }
+ else
+ if( result.__cnt == 0 && config.emptyNodeForm=="text" ) {
+ result = '';
+ }
+ else
+ if ( result.__cnt > 1 && result.__text!=null && config.skipEmptyTextNodesForObj) {
+ if( (config.stripWhitespaces && result.__text=="") || (result.__text.trim()=="")) {
+ delete result.__text;
+ }
+ }
+ delete result.__cnt;
+
+ if( config.enableToStringFunc && (result.__text!=null || result.__cdata!=null )) {
+ result.toString = function() {
+ return (this.__text!=null? this.__text:'')+( this.__cdata!=null ? this.__cdata:'');
+ };
+ }
+
+ return result;
+ }
+ else
+ if(node.nodeType == DOMNodeTypes.TEXT_NODE || node.nodeType == DOMNodeTypes.CDATA_SECTION_NODE) {
+ return node.nodeValue;
+ }
+ }
+
+ function startTag(jsonObj, element, attrList, closed) {
+ var resultStr = "<"+ ( (jsonObj!=null && jsonObj.__prefix!=null)? (jsonObj.__prefix+":"):"") + element;
+ if(attrList!=null) {
+ for(var aidx = 0; aidx < attrList.length; aidx++) {
+ var attrName = attrList[aidx];
+ var attrVal = jsonObj[attrName];
+ if(config.escapeMode)
+ attrVal=escapeXmlChars(attrVal);
+ resultStr+=" "+attrName.substr(config.attributePrefix.length)+"='"+attrVal+"'";
+ }
+ }
+ if(!closed)
+ resultStr+=">";
+ else
+ resultStr+="/>";
+ return resultStr;
+ }
+
+ function endTag(jsonObj,elementName) {
+ return "</"+ (jsonObj.__prefix!=null? (jsonObj.__prefix+":"):"")+elementName+">";
+ }
+
+ function endsWith(str, suffix) {
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
+ }
+
+ function jsonXmlSpecialElem ( jsonObj, jsonObjField ) {
+ if((config.arrayAccessForm=="property" && endsWith(jsonObjField.toString(),("_asArray")))
+ || jsonObjField.toString().indexOf(config.attributePrefix)==0
+ || jsonObjField.toString().indexOf("__")==0
+ || (jsonObj[jsonObjField] instanceof Function) )
+ return true;
+ else
+ return false;
+ }
+
+ function jsonXmlElemCount ( jsonObj ) {
+ var elementsCnt = 0;
+ if(jsonObj instanceof Object ) {
+ for( var it in jsonObj ) {
+ if(jsonXmlSpecialElem ( jsonObj, it) )
+ continue;
+ elementsCnt++;
+ }
+ }
+ return elementsCnt;
+ }
+
+ function parseJSONAttributes ( jsonObj ) {
+ var attrList = [];
+ if(jsonObj instanceof Object ) {
+ for( var ait in jsonObj ) {
+ if(ait.toString().indexOf("__")== -1 && ait.toString().indexOf(config.attributePrefix)==0) {
+ attrList.push(ait);
+ }
+ }
+ }
+ return attrList;
+ }
+
+ function parseJSONTextAttrs ( jsonTxtObj ) {
+ var result ="";
+
+ if(jsonTxtObj.__cdata!=null) {
+ result+="<![CDATA["+jsonTxtObj.__cdata+"]]>";
+ }
+
+ if(jsonTxtObj.__text!=null) {
+ if(config.escapeMode)
+ result+=escapeXmlChars(jsonTxtObj.__text);
+ else
+ result+=jsonTxtObj.__text;
+ }
+ return result;
+ }
+
+ function parseJSONTextObject ( jsonTxtObj ) {
+ var result ="";
+
+ if( jsonTxtObj instanceof Object ) {
+ result+=parseJSONTextAttrs ( jsonTxtObj );
+ }
+ else
+ if(jsonTxtObj!=null) {
+ if(config.escapeMode)
+ result+=escapeXmlChars(jsonTxtObj);
+ else
+ result+=jsonTxtObj;
+ }
+
+ return result;
+ }
+
+ function parseJSONArray ( jsonArrRoot, jsonArrObj, attrList ) {
+ var result = "";
+ if(jsonArrRoot.length == 0) {
+ result+=startTag(jsonArrRoot, jsonArrObj, attrList, true);
+ }
+ else {
+ for(var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) {
+ result+=startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false);
+ result+=parseJSONObject(jsonArrRoot[arIdx]);
+ result+=endTag(jsonArrRoot[arIdx],jsonArrObj);
+ }
+ }
+ return result;
+ }
+
+ function parseJSONObject ( jsonObj ) {
+ var result = "";
+
+ var elementsCnt = jsonXmlElemCount ( jsonObj );
+
+ if(elementsCnt > 0) {
+ for( var it in jsonObj ) {
+
+ if(jsonXmlSpecialElem ( jsonObj, it) )
+ continue;
+
+ var subObj = jsonObj[it];
+
+ var attrList = parseJSONAttributes( subObj )
+
+ if(subObj == null || subObj == undefined) {
+ result+=startTag(subObj, it, attrList, true);
+ }
+ else
+ if(subObj instanceof Object) {
+
+ if(subObj instanceof Array) {
+ result+=parseJSONArray( subObj, it, attrList );
+ }
+ else if(subObj instanceof Date) {
+ result+=startTag(subObj, it, attrList, false);
+ result+=subObj.toISOString();
+ result+=endTag(subObj,it);
+ }
+ else {
+ var subObjElementsCnt = jsonXmlElemCount ( subObj );
+ if(subObjElementsCnt > 0 || subObj.__text!=null || subObj.__cdata!=null) {
+ result+=startTag(subObj, it, attrList, false);
+ result+=parseJSONObject(subObj);
+ result+=endTag(subObj,it);
+ }
+ else {
+ result+=startTag(subObj, it, attrList, true);
+ }
+ }
+ }
+ else {
+ result+=startTag(subObj, it, attrList, false);
+ result+=parseJSONTextObject(subObj);
+ result+=endTag(subObj,it);
+ }
+ }
+ }
+ result+=parseJSONTextObject(jsonObj);
+
+ return result;
+ }
+
+ this.parseXmlString = function(xmlDocStr) {
+ var isIEParser = window.ActiveXObject || "ActiveXObject" in window;
+ if (xmlDocStr === undefined) {
+ return null;
+ }
+ var xmlDoc;
+ if (window.DOMParser) {
+ var parser=new window.DOMParser();
+ var parsererrorNS = null;
+ // IE9+ now is here
+ if(!isIEParser) {
+ try {
+ parsererrorNS = parser.parseFromString("INVALID", "text/xml").childNodes[0].namespaceURI;
+ }
+ catch(err) {
+ parsererrorNS = null;
+ }
+ }
+ try {
+ xmlDoc = parser.parseFromString( xmlDocStr, "text/xml" );
+ if( parsererrorNS!= null && xmlDoc.getElementsByTagNameNS(parsererrorNS, "parsererror").length > 0) {
+ //throw new Error('Error parsing XML: '+xmlDocStr);
+ xmlDoc = null;
+ }
+ }
+ catch(err) {
+ xmlDoc = null;
+ }
+ }
+ else {
+ // IE :(
+ if(xmlDocStr.indexOf("<?")==0) {
+ xmlDocStr = xmlDocStr.substr( xmlDocStr.indexOf("?>") + 2 );
+ }
+ xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
+ xmlDoc.async="false";
+ xmlDoc.loadXML(xmlDocStr);
+ }
+ return xmlDoc;
+ };
+
+ this.asArray = function(prop) {
+ if(prop instanceof Array)
+ return prop;
+ else
+ return [prop];
+ };
+
+ this.toXmlDateTime = function(dt) {
+ if(dt instanceof Date)
+ return dt.toISOString();
+ else
+ if(typeof(dt) === 'number' )
+ return new Date(dt).toISOString();
+ else
+ return null;
+ };
+
+ this.asDateTime = function(prop) {
+ if(typeof(prop) == "string") {
+ return fromXmlDateTime(prop);
+ }
+ else
+ return prop;
+ };
+
+ this.xml2json = function (xmlDoc) {
+ return parseDOMChildren ( xmlDoc );
+ };
+
+ this.xml_str2json = function (xmlDocStr) {
+ var xmlDoc = this.parseXmlString(xmlDocStr);
+ if(xmlDoc!=null)
+ return this.xml2json(xmlDoc);
+ else
+ return null;
+ };
+
+ this.json2xml_str = function (jsonObj) {
+ return parseJSONObject ( jsonObj );
+ };
+
+ this.json2xml = function (jsonObj) {
+ var xmlDocStr = this.json2xml_str (jsonObj);
+ return this.parseXmlString(xmlDocStr);
+ };
+
+ this.getVersion = function () {
+ return VERSION;
+ };
+
+}
|