diff options
author | 2018-07-10 18:07:44 +0200 | |
---|---|---|
committer | 2018-07-11 16:30:28 -0400 | |
commit | 27fb2d06608fbb070ae2c15a5580a4f5b2423d15 (patch) | |
tree | ccd717991b4e556b67f1fd2cacb345b4d174b41f /sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main | |
parent | 60315525ab5e7c12a9f47c409092e8dba6ad656d (diff) |
Add seed code for sdnr app based on ONF Centennial
At this point in time all the Carbon code from ONF Centennial is added to ONAP.
Later it needs to be refactored and modified for ODL Oxygen.
Change-Id: Iff85dd940c05c3827f1c4e6f9542ecd060c58a46
Issue-ID: SDNC-374
Signed-off-by: demx8as6 <martin.skorupski@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wireless-transport/code-Carbon-SR1/ux/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;
+ };
+
+}
|