summaryrefslogtreecommitdiffstats
path: root/sdnr/wireless-transport/code-Carbon-SR1/ux
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wireless-transport/code-Carbon-SR1/ux')
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/pom.xml118
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/pom.xml14
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService-custom.css58
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.controller.js25
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.services.js20
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.tpl.html9
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/images/ethService.pngbin0 -> 2270 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/pom.xml23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/features/pom.xml65
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/features/src/main/features/features.xml231
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/pom.xml14
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.js284
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.ts130
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.custom.css105
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.js33
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.ts35
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.service.ts92
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tpl.html17
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.html0
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.ts55
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.utilities.ts63
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/images/help.pngbin0 -> 2121 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.d.ts284
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.js1320
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/help/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnBrowser.pngbin0 -> 2838 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnConfig.pngbin0 -> 2838 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser-custom.css24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.controller.js1090
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.module.js53
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.services.js37
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/frame.tpl.html191
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpClockViewer.tpl.html66
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpPorts.tpl.html23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpDefaultDsConfigView.tpl.html45
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpPortConfigView.tpl.html53
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/pom.xml22
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/pom.xml118
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/pom.xml15
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/images/mwtnClosedLoop.pngbin0 -> 3524 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop-custom.css26
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.controller.js160
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.module.js51
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.services.js74
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.tpl.html64
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/pom.xml117
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/pom.xml69
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/README.md34
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower.json39
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bowerInstall.sh18
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/bower_components_patches/angular-chart.js.patch400
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/locale/locale-en_US.json924
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons-custom.css108
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.controller.js25
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.module.js622
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.services.js3826
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/mwtnCommons.tpl.html7
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnFooter.tpl.html4
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnGrid.tpl.html23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnJsonViewer.tpl.html110
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/mwtnSelectNetworkElement.tpl.html33
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/openConfigView.html69
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/templates/showGridCellDetail.html54
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/src/main/resources/mwtnCommons/xml2json.js567
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/pom.xml26
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/pom.xml118
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/pom.xml15
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/images/mwtnCompare.pngbin0 -> 3342 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare-custom.css36
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.controller.js526
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.directives.js21
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.module.js50
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.services.js26
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.tpl.html333
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/templates/compare.tpl.html12
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/pom.xml118
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml20
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/mwtnConnect.pngbin0 -> 2271 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/sdncConnect.pngbin0 -> 11379 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect-custom.css85
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.controller.js1143
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.services.js75
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.tpl.html150
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/addToRequired.tpl.html79
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmDelete.tpl.html23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmHide.tpl.html21
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/mountPointDetails.tpl.html125
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/pom.xml15
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/images/mwtnEvents.pngbin0 -> 2224 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents-custom.css12
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.controller.js153
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.module.js53
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.services.js22
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.tpl.html45
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/xml2json.js567
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/pom.xml27
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml15
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.pngbin0 -> 2048 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css100
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js597
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js163
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js100
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html119
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html21
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html17
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/pom.xml15
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.html37
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.ts28
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.html5
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.ts41
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/images/mwtnInventory.pngbin0 -> 2627 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/models/equipment.ts6
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory-custom.css31
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.js372
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.ts116
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.js33
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.ts36
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.service.ts144
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.services.js100
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.tpl.html16
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/_0
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/accordeonHeader.tpl.html13
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/images/mwtnLog.pngbin0 -> 2261 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog-custom.css58
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.controller.js151
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.services.js40
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.tpl.html26
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/templates/clearLogConfirmation.tpl.html12
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/pom.xml14
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/class.mediator.js569
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/images/mwtnMediator.pngbin0 -> 2923 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator-custom.css69
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.controller.js613
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.module.js54
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.services.js113
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/frame.tpl.html49
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorCreateNew.tpl.html99
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorDetails.tpl.html96
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorServerConfigCtrl.tpl.html41
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/images/mwtnPerformance.pngbin0 -> 2974 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent-custom.css13
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.controller.js741
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module.js55
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.services.js30
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.tpl.html119
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/images/mwtnPerformance.pngbin0 -> 2974 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory-custom.css13
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.controller.js1196
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.module.js55
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.services.js54
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.tpl.html127
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/images/mwtnPerformance.pngbin0 -> 2974 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink-custom.css17
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.controller.js3346
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.module.js55
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.services.js68
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.tpl.html487
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/pom.xml119
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/pom.xml15
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/bluelight.gifbin0 -> 61554 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/mwtnSpectrum.pngbin0 -> 3229 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum-custom.css45
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.controller.js135
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.module.js54
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.services.js90
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.tpl.html64
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/images/mwtnTdm.pngbin0 -> 2861 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm-custom.css11
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.controller.js159
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.module.js53
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.services.js31
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/templates/frame.tpl.html52
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/pom.xml89
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/images/mwtnTest.pngbin0 -> 2868 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest-custom.css24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.controller.js477
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.module.js53
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.services.js32
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/templates/frame.tpl.html172
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/pom.xml117
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.builinfo.md39
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.fs.md78
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/images/mwtnTopology.pngbin0 -> 3447 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology-custom.css102
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.controller.js4877
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.module.js57
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.rest209
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.services.js1020
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/accordeonHeader.tpl.html13
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/clocksGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethConnectionsGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethernetView.tpl.html18
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/frame.tpl.html34
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ieee1588View.tpl.html18
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linkDetails.tpl.html110
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/links.tpl.html2
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linksGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/maps.tpl.html59
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/networkElementsGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/nodes.tpl.html2
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/physicalView.tpl.html18
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/portsGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ptpLinksGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteDetails.tpl.html77
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteGrid.tpl.html9
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteLinkGrid.tpl.html8
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/sitePathGrid.tpl.html1
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteView.tpl.html31
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/topology.tpl.html2
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/pom.xml27
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/pom.xml116
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/pom.xml14
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/logo_chat.gifbin0 -> 2046 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat-custom.css3
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.controller.js69
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.module.js50
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.pngbin0 -> 1862 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.services.js103
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.tpl.html102
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/pom.xml27
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/images/onapAai.pngbin0 -> 12931 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai-custom.css58
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.controller.js49
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.services.js162
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.tpl.html12
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onap-5g-architecture.pngbin0 -> 106656 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onapDcae.pngbin0 -> 14200 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae-custom.css58
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.controller.js23
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.services.js20
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.tpl.html13
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onap-end-to-end-slicing.pngbin0 -> 115927 bytes
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onapSo.pngbin0 -> 12003 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo-custom.css78
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.controller.js84
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.services.js162
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.tpl.html103
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/pom.xml115
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/pom.xml14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/images/otnBrowser.pngbin0 -> 2938 bytes
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser-custom.css58
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.controller.js25
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.module.js56
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.services.js20
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.tpl.html9
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/pom.xml24
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/pom.xml139
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/pom.xml28
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/pom.xml80
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml19
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/pom.xml18
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/build.config.js42
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/gulpfile.js142
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/package.json29
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.js149
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.ts63
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.custom.css11
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.js33
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.ts36
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.service.ts99
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.tpl.html50
-rw-r--r--sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/templates/userDetails.html14
-rwxr-xr-xsdnr/wireless-transport/code-Carbon-SR1/ux/ux-dev.sh103
335 files changed, 40685 insertions, 0 deletions
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/pom.xml
new file mode 100644
index 00000000..d0850dea
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>ethService-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <parent>
+ <artifactId>ethService</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>ethService-module</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>ethService-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..b92ee913
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="ethService"/>
+ <property name="url" value="/src/app/ethService"/>
+ <property name="directory" value="/ethService"/>
+ <property name="requireJs" value="app/ethService/ethService.module"/>
+ <property name="angularJs" value="app.ethService"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/ethService/ethService-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/pom.xml
new file mode 100644
index 00000000..6a99723c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>ethService-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+ <parent>
+ <artifactId>ethService</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService-custom.css
new file mode 100644
index 00000000..fed4402a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService-custom.css
@@ -0,0 +1,58 @@
+/**
+ * Add your application related css here
+ */
+.ethServiceGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.ethServiceGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.ethServiceGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.ethServiceGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.ethServiceGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.ethServiceGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.controller.js
new file mode 100644
index 00000000..080aa33b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.controller.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/ethService/ethService.module',
+ 'app/ethService/ethService.services'],
+ function (ethServiceApp) {
+
+ ethServiceApp.register.controller('ethServiceCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$ethService', '$mwtnLog',
+ function (uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $ethService, $mwtnLog) {
+
+ var COMPONENT = 'ethServiceCtrl';
+ $mwtnLog.info({ component: COMPONENT, message: 'ethServiceCtrl started!' });
+
+ $rootScope.section_logo = 'src/app/ethService/images/ethService.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $ethService.highlightFilteredHeader;
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.module.js
new file mode 100644
index 00000000..14729451
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var ethServiceApp = angular.module('app.ethService', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ ethServiceApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ ethServiceApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/ethService/ethService.controller');
+ NavHelperProvider.addToMenu('ethService', {
+ "link" : "#/ethService/",
+ "active" : "main.ethService",
+ "title" : "ETH Service",
+ "icon" : "fa fa-arrows-h", // Add navigation icon css class here
+ "page" : {
+ "title" : "ETH Service",
+ "description" : "Ethernet Service Provisioning"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.ethService', {
+ url: 'ethService/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/ethService/ethService.tpl.html',
+ controller: 'ethServiceCtrl'
+ }
+ }
+ });
+
+ });
+
+ return ethServiceApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.services.js
new file mode 100644
index 00000000..fa8ef2f6
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.services.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/ethService/ethService.module', 'app/mwtnCommons/mwtnCommons.services'], function (ethServiceApp) {
+
+ ethServiceApp.register.factory('$ethService', function ($q, $http, Base64, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.tpl.html
new file mode 100644
index 00000000..b5f022f8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/ethService.tpl.html
@@ -0,0 +1,9 @@
+<ht-header help-link='sdnr/ethService/0.4.0/README.md'></ht-header>
+
+<h1 style="color: red; transform: rotate(-30deg);">Under Construction</h1>
+<br/><br/><br/><br/><br/>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/images/ethService.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/images/ethService.png
new file mode 100755
index 00000000..9cca24f1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/ethService-module/src/main/resources/ethService/images/ethService.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/pom.xml
new file mode 100644
index 00000000..ba49da79
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ethService/pom.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>ethService</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>pom</packaging>
+
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+
+ <modules>
+ <module>ethService-module</module>
+ <module>ethService-bundle</module>
+ </modules>
+
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/features/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/features/pom.xml
new file mode 100644
index 00000000..13eba24e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/features/pom.xml
@@ -0,0 +1,65 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnFeatures</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>ONF :: Wireless :: ${project.artifactId}</name>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-parent</artifactId>
+ <version>1.8.1-Carbon</version>
+ </parent>
+
+ <properties>
+ <prefix>ONF :: Wireless :: </prefix>
+
+ <apache.felix.compendium>1.4.0</apache.felix.compendium>
+ <decanter.version>1.1.0</decanter.version>
+ <elasticsearch.version>2.2.0</elasticsearch.version>
+ <osgi.core.version>5.0.0</osgi.core.version>
+
+ <dlux.version>0.5.1-Carbon</dlux.version>
+ <mdsal.version>1.5.1-Carbon</mdsal.version>
+ <mdsal.model.version>0.10.1-Carbon</mdsal.model.version>
+ <restconf.version>1.5.1-Carbon</restconf.version>
+ <yangtools.version>1.1.1-Carbon</yangtools.version>
+ <openflow.plugin.version>0.4.1-Carbon</openflow.plugin.version>
+ <netconf.version>1.2.1-Carbon</netconf.version>
+ <l2switch.version>0.5.1-Carbon</l2switch.version>
+ <dlux.loader.version>0.5.1-Carbon</dlux.loader.version>
+ <securityproject.version>0.5.1</securityproject.version>
+ <configfile.directory>etc/opendaylight/karaf</configfile.directory>
+ </properties>
+
+ <!-- <dependencyManagement> <dependencies> <dependency> <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId> <version>${mdsal.version}</version>
+ <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> -->
+ <dependencies>
+
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>features-dlux</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ <version>0.5.3-Carbon</version>
+ </dependency>
+ <!-- <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>features-yangtools</artifactId>
+ <classifier>features</classifier> <type>xml</type> <scope>runtime</scope>
+ <version>${yangtools.version}</version> </dependency> <dependency> <groupId>org.opendaylight.controller</groupId>
+ <artifactId>features-mdsal</artifactId> <classifier>features</classifier>
+ <type>xml</type> <scope>runtime</scope> </dependency> <dependency> <groupId>org.opendaylight.controller</groupId>
+ <artifactId>features-restconf</artifactId> <classifier>features</classifier>
+ <type>xml</type> <scope>runtime</scope> </dependency> -->
+
+ <!-- WTN app dependencies - -> <dependency> <groupId>${project.groupId}</groupId>
+ <artifactId>mwtnCommons</artifactId> <version>${project.version}</version>
+ </dependency> -->
+ <!-- <dependency> <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTopology</artifactId> <version>0.5.1-SNAPSHOT</version> </dependency> -->
+ </dependencies>
+
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/features/src/main/features/features.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/features/src/main/features/features.xml
new file mode 100644
index 00000000..5fe79651
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/features/src/main/features/features.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="odl-mwtn-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+<!--
+ => Only to be placed into feature-parents
+ <repository>mvn:org.apache.karaf.decanter/apache-karaf-decanter/${decanter.version}/xml/features</repository>
+ -->
+
+<!--
+ Section 2: UX basis feature, used by all features in section 3
+ -->
+
+ <feature name="sdnr-wt-ux-all" version="${project.version}" description="ONAP :: SDN-R :: WT :: UX :: All">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/onapAai-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnFault-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnBrowser-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnInventory-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnMediator-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/help-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="onap-sdnr-ux-all" version="${project.version}" description="ONAP :: OpenDaylight :: SDN-R :: UX :: All">
+ <feature version="${project.version}">odl-mwtn-ux-connect</feature>
+
+ <feature version="${project.version}">onap-sdnr-aai-ux</feature>
+ <feature version="${project.version}">onap-sdnr-dcae-ux</feature>
+ <feature version="${project.version}">onap-sdnr-so-ux</feature>
+
+ <!--
+ <feature version="${project.version}">odl-eth-ux-service</feature>
+ <feature version="${project.version}">odl-otn-ux-config</feature> -->
+
+ <feature version="${project.version}">odl-mwtn-ux-fault</feature>
+ <feature version="${project.version}">odl-mwtn-ux-config</feature>
+ <feature version="${project.version}">odl-mwtn-ux-performance</feature>
+ <feature version="${project.version}">odl-mwtn-ux-inventory</feature>
+ <feature version="${project.version}">odl-mwtn-ux-topology</feature>
+ <!-- sko not ready yet
+ <feature version="${project.version}">odl-mwtn-ux-compare</feature>
+ <feature version="${project.version}">odl-mwtn-ux-spectrum</feature>
+ <feature version="${project.version}">odl-mwtn-ux-closed-loop</feature> -->
+ <feature version="${project.version}">odl-mwtn-ux-mediator</feature>
+ <feature version="${project.version}">odl-help-core</feature>
+
+ <!-- not needed
+ <feature version="${project.version}">odl-mwtn-ux-events</feature>
+ <feature version="${project.version}">odl-mwtn-ux-test</feature>
+ <feature version="${project.version}">odl-mwtn-ux-log</feature>
+ <feature version="${project.version}">odl-mwtn-ux-chat</feature> -->
+ </feature>
+
+<!-- PoC Specific feature for "poc180628" delivery -->
+ <feature name="ht-mwtn-ux-poc180628" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Release1806">
+ <feature version="${project.version}">odl-mwtn-ux-connect</feature>
+ <feature version="${project.version}">onap-sdnr-so-ux</feature>
+ <feature version="${project.version}">onap-sdnr-dcae-ux</feature>
+ <feature version="${project.version}">onap-sdnr-aai-ux</feature>
+ <feature version="${project.version}">odl-mwtn-ux-fault</feature>
+ <feature version="${project.version}">odl-mwtn-ux-config</feature>
+ <feature version="${project.version}">odl-mwtn-ux-performance</feature>
+ <bundle>mvn:org.onap.sdnc.dluxapps/security-bundle/${securityproject.version}</bundle>
+ <feature version="${project.version}">odl-mwtn-ux-inventory</feature>
+ <feature version="${project.version}">odl-mwtn-ux-topology</feature>
+ <feature version="${project.version}">odl-mwtn-ux-mediator</feature>
+ <feature version="${project.version}">odl-mwtn-ux-log</feature>
+ <feature version="${project.version}">odl-ux-help</feature>
+ </feature>
+
+<!-- All UC features for test purpose -->
+ <feature name="odl-mwtn-ux-all" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: All">
+ <feature version="${project.version}">odl-mwtn-ux-connect</feature>
+
+ <feature version="${project.version}">onap-sdnr-aai-ux</feature>
+ <feature version="${project.version}">onap-sdnr-dcae-ux</feature>
+ <feature version="${project.version}">onap-sdnr-so-ux</feature>
+
+ <feature version="${project.version}">odl-mwtn-ux-fault</feature>
+ <feature version="${project.version}">odl-mwtn-ux-performance</feature>
+ <feature version="${project.version}">odl-mwtn-ux-config</feature>
+ <feature version="${project.version}">odl-mwtn-ux-topology</feature>
+ <feature version="${project.version}">odl-mwtn-ux-inventory</feature>
+ <!-- sko not ready yet
+ <feature version="${project.version}">odl-mwtn-ux-compare</feature>
+ <feature version="${project.version}">odl-mwtn-ux-spectrum</feature>
+ <feature version="${project.version}">odl-mwtn-ux-closed-loop</feature> -->
+ <feature version="${project.version}">odl-mwtn-ux-mediator</feature>
+ <feature version="${project.version}">odl-mwtn-ux-events</feature>
+ <feature version="${project.version}">odl-mwtn-ux-test</feature>
+ <feature version="${project.version}">odl-mwtn-ux-log</feature>
+ <feature version="${project.version}">odl-mwtn-ux-chat</feature>
+ <feature version="${project.version}">odl-ux-help</feature>
+ </feature>
+
+<!--
+ Section 2: UX basis feature, used by all features in section 3
+ -->
+
+ <feature name="odl-ux-commons" version="${project.version}" description="OpenDaylight :: UX :: Commons">
+ <bundle>mvn:com.highstreet.technologies.apigateway/apigateway-impl/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnCommons-bundle/${project.version}</bundle>
+ </feature>
+
+<!--
+ Section 3: Entry per GUI element/project
+ -->
+
+ <feature name="odl-mwtn-ux-connect" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Connect">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="onap-sdnr-aai-ux" version="${project.version}" description="ONAP :: AAI :: SDN-R :: UX">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/onapAai-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="onap-sdnr-dcae-ux" version="${project.version}" description="ONAP :: DCAE :: SDN-R :: UX">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/onapDcae-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="onap-sdnr-so-ux" version="${project.version}" description="ONAP :: SO :: SDN-R :: UX">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/onapSo-bundle/${project.version}</bundle>
+ </feature>
+
+ <!-- sko not needed
+ <feature name="odl-eth-ux-service" version="${project.version}" description="OpenDaylight :: ETH :: UX :: Service">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/ethService-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-otn-ux-config" version="${project.version}" description="OpenDaylight :: OTN :: UX :: Configuration">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/otnBrowser-bundle/${project.version}</bundle>
+ </feature>
+ -->
+
+ <feature name="odl-mwtn-ux-fault" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Fault">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnFault-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-config" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Configuration">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnBrowser-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-performance" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Performance">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceCurrent-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceHistory-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceLink-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-inventory" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Inventory">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnInventory-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-topology" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Topology">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnTopology-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-tdm" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: TDM">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnTdm-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-ux-help" version="${project.version}" description="OpenDaylight :: UX :: Help">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/help-bundle/${project.version}</bundle>
+ </feature>
+
+<!--
+ <feature name="odl-mwtn-ux-compare" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Comparision">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnCompare-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-spectrum" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Spectrum Management">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:cn.com.zte.odl.dlux/mwtnSpectrum-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-closed-loop" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Closed Loop Automation">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnClosedLoop-bundle/${project.version}</bundle>
+ </feature>
+-->
+ <feature name="odl-mwtn-ux-events" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Events">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnEvents-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-test" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Test">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/${project.version}</bundle>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnTest-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-mediator" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Mediator">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnMediator-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-log" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Log">
+ <feature version="${project.version}">odl-ux-commons</feature>
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/mwtnLog-bundle/${project.version}</bundle>
+ </feature>
+
+ <feature name="odl-mwtn-ux-chat" version="${project.version}" description="OpenDaylight :: MWTN :: UX :: Chat">
+ <bundle>mvn:com.highstreet.technologies.odl.dlux/odlChat-bundle/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/pom.xml
new file mode 100644
index 00000000..06081c2c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>help</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>help-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>help-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>help-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..490a2301
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="help"/>
+ <property name="url" value="/src/app/help"/>
+ <property name="directory" value="/help"/>
+ <property name="requireJs" value="app/help/help.module"/>
+ <property name="angularJs" value="app.help"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/help/help.custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/pom.xml
new file mode 100644
index 00000000..dd744b3a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>help</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>help-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.js
new file mode 100644
index 00000000..c82464a8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.js
@@ -0,0 +1,284 @@
+var __assign = (this && this.__assign) || Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+};
+define("help.tree", ["require", "exports", "angularAMD"], function (require, exports, angular) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var help = angular.module('app.help');
+ // class HelpTreeController implements ng.IController {
+ // constructor(private $scope: ng.IScope & { rootNode: Node, data: Node[]}) {
+ // $scope.$watch("rootNode", (n, o) => {
+ // $scope.data = Object.keys($scope.rootNode).map(key => $scope.rootNode[key]);
+ // });
+ // }
+ // }
+ // help.controller("treeCtrl", ["$scope", HelpTreeController]);
+ var helpTree = function ($compile) {
+ return {
+ restrict: "E",
+ transclude: true,
+ scope: { rootNode: '=' },
+ //controller: 'treeCtrl',
+ template: '<ul>' +
+ '<li ng-transclude></li>' +
+ '<li ng-repeat="child in rootNode.nodes">' +
+ '<tree root-node="child"><div ng-transclude></div></tree>' +
+ '</li>' +
+ '</ul>',
+ compile: function (tElement, tAttr, transclude) {
+ var contents = tElement.contents().remove();
+ var compiledContents;
+ return function (scope, iElement, iAttr) {
+ if (!compiledContents) {
+ compiledContents = $compile(contents, transclude);
+ }
+ compiledContents(scope, function (clone, scope) {
+ iElement.append(clone);
+ });
+ };
+ }
+ };
+ };
+ help.directive("tree", ["$compile", helpTree]);
+});
+define("help.service", ["require", "exports", "angularAMD"], function (require, exports, angular) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var help = angular.module('app.help');
+ var Helpservice = /** @class */ (function () {
+ function Helpservice($q, $http, env) {
+ this.$q = $q;
+ this.$http = $http;
+ this.env = env;
+ this.tocNodeCollection = null;
+ this.documents = {};
+ }
+ Helpservice.prototype.getTableOfContents = function () {
+ var _this = this;
+ if (this.tocNodeCollection) {
+ return this.$q.resolve(this.tocNodeCollection);
+ }
+ return this.$http({
+ method: "GET",
+ url: window.location.origin + "/help/?meta"
+ }).then(function (result) {
+ if (result.status === 200) {
+ _this.tocNodeCollection = result.data;
+ return result.data;
+ }
+ });
+ };
+ Helpservice.prototype.getDocument = function (path) {
+ var _this = this;
+ if (this.documents[path] != null) {
+ return this.$q.resolve(this.documents[path]);
+ }
+ return this.$http({
+ method: "GET",
+ url: window.location.origin + "/help/" + path
+ }).then(function (result) {
+ if (result.status === 200) {
+ return _this.documents[path] = {
+ basePath: result.config && result.config.url && result.config.url,
+ document: result.data
+ };
+ }
+ });
+ };
+ return Helpservice;
+ }());
+ help.service('helpService', ['$q', '$http', Helpservice]);
+});
+define("help.utilities", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.resolvePath = function () {
+ var paths = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ paths[_i] = arguments[_i];
+ }
+ console.log(paths);
+ function resolve(pathA, pathB) {
+ // ‘a’ => ['a']
+ // 'a/b' => ['a', 'b']
+ // '/a/b' => ['', 'a', 'b']
+ // '/a/b/' => ['', 'a', 'b', '']
+ pathB = pathB.split('/');
+ if (pathB[0] === '') {
+ return pathB.join('/');
+ }
+ pathA = pathA.split('/');
+ var aLastIndex = pathA.length - 1;
+ if (pathA[aLastIndex] !== '') {
+ pathA[aLastIndex] = '';
+ }
+ var part;
+ var i = 0;
+ while (typeof (part = pathB[i]) === 'string') {
+ switch (part) {
+ case '..':
+ pathA.pop();
+ pathA.pop();
+ pathA.push('');
+ break;
+ case '.':
+ pathA.pop();
+ pathA.push('');
+ break;
+ default:
+ pathA.pop();
+ pathA.push(part);
+ pathA.push('');
+ break;
+ }
+ i++;
+ }
+ if (pathB[pathB.length - 1] !== '')
+ pathA.pop();
+ return pathA.join('/');
+ }
+ var i = 0;
+ var path;
+ var r = location.pathname;
+ var urlRegex = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i;
+ var multiSlashReg = /\/\/+/g;
+ while (typeof (path = paths[i]) === 'string') {
+ // debugger;
+ var matches = path && path.match(urlRegex);
+ if (matches || !i) {
+ r = path;
+ }
+ else {
+ path = path.replace(multiSlashReg, '/');
+ r = resolve(r, path);
+ }
+ i++;
+ }
+ return r;
+ };
+});
+define( ["require", "exports", "./lib/marked", "help.utilities", "help.tree", "help.service"], function (require, exports, marked, help_utilities_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var currentPath = '/help';
+ var currentDoc = '';
+ var renderer = new marked.Renderer();
+ renderer.link = function (href, title, text) {
+ // check if href is rel or abs
+ var absUrlMatch = href.trim().match(/^https?:\/\//i);
+ return "<a "+(absUrlMatch ? "target=\"_blank\"":"")+" href=\"" + (absUrlMatch ? href : help_utilities_1.resolvePath('#/help/', currentDoc, href)) + "\" title=\"" + title + "\" >" + text + "</a>";
+ };
+ renderer.image = function (href, title, text) {
+ return "<img src=\"" + help_utilities_1.resolvePath(currentPath, href) + "\" alt=\"" + title + "\" />";
+ };
+ marked.setOptions({
+ renderer: renderer,
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ smartLists: true,
+ smartypants: false,
+ xhtml: false
+ });
+ var help = angular.module('app.help');
+ var HelpDirective = function () {
+ return {
+ restrict: 'AE',
+ template: "<div class=\"global-help\" ><a href=\"{{ '#/help/'+ link }}\"><i class=\"fa fa-question-circle\"></i> Help</a></div>",
+ scope: {
+ link: '@'
+ },
+ replace: true
+ };
+ };
+ help.directive('help', [HelpDirective]);
+ var MarkdownItDirective = function ($sanitize) {
+ var attribute = 'markdownIt';
+ var render = function (value) {
+ var md2html = (marked instanceof Function) ? marked : marked.default;
+ return value
+ ? $sanitize(md2html(value.trim()))
+ : '';
+ };
+ return {
+ restrict: 'AE',
+ scope: {
+ markdownIt: '='
+ },
+ replace: true,
+ link: function (scope, element, attrs) {
+ if (attrs[attribute]) {
+ scope.$watch(attribute, function (value) {
+ element.html(render(value));
+ });
+ }
+ else {
+ element.html(render(element.text()));
+ }
+ }
+ };
+ };
+ help.directive('markdownIt', ['$sanitize', MarkdownItDirective]);
+ var mapNode = function (tocNode) {
+ return tocNode && Object.keys(tocNode).map(function (key) {
+ return __assign({}, tocNode[key], { href: "#/help/" + tocNode[key]['versions']['current']['path'], nodes: mapNode(tocNode[key].nodes) });
+ });
+ };
+ var HelpController = /** @class */ (function () {
+ function HelpController($scope, $rootScope, $state, $timeout, helpService) {
+ var _this = this;
+ this.$scope = $scope;
+ this.$state = $state;
+ this.$timeout = $timeout;
+ this.helpService = helpService;
+ this._content = "## Loading";
+ this._path = '';
+ this._toc = {};
+
+ $rootScope.section_logo = 'src/app/help/images/help.png';
+
+ helpService.getTableOfContents().then(function (toc) {
+ _this._toc = { nodes: mapNode(toc) };
+ if (!$state.params.path) {
+ $state.go('main.help', { path: toc['sdnr']['versions']['current']['path'] });
+ }
+ else {
+ _this.navigateTo($state.params.path);
+ }
+ });
+ }
+ Object.defineProperty(HelpController.prototype, "content", {
+ get: function () { return this._content; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(HelpController.prototype, "path", {
+ get: function () { return this._path; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(HelpController.prototype, "toc", {
+ get: function () { return this._toc; },
+ enumerable: true,
+ configurable: true
+ });
+ HelpController.prototype.navigateTo = function (path) {
+ var _this = this;
+ this.helpService.getDocument(path).then(function (result) {
+ currentDoc = path;
+ currentPath = result.basePath;
+ _this._content = result.document;
+ });
+ };
+ return HelpController;
+ }());
+ help.controller('helpCtrl', ['$scope', '$rootScope', '$state', '$timeout', 'helpService', HelpController]);
+});
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscC5jb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2FwcC9oZWxwL2hlbHAudHJlZS50cyIsInNyYy9hcHAvaGVscC9oZWxwLnNlcnZpY2UudHMiLCJzcmMvYXBwL2hlbHAvaGVscC51dGlsaXRpZXMudHMiLCJzcmMvYXBwL2hlbHAvaGVscC5jb250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0lBY0EsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV4Qyx1REFBdUQ7SUFDdkQsK0VBQStFO0lBQy9FLDRDQUE0QztJQUM1QyxxRkFBcUY7SUFDckYsVUFBVTtJQUNWLE1BQU07SUFDTixJQUFJO0lBRUosK0RBQStEO0lBRS9ELElBQU0sUUFBUSxHQUFHLFVBQVUsUUFBUTtRQUNqQyxNQUFNLENBQUM7WUFDTCxRQUFRLEVBQUUsR0FBRztZQUNiLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7WUFDeEIseUJBQXlCO1lBQ3pCLFFBQVEsRUFDTixNQUFNO2dCQUNOLHlCQUF5QjtnQkFDekIsMENBQTBDO2dCQUMxQywwREFBMEQ7Z0JBQzFELE9BQU87Z0JBQ1AsT0FBTztZQUNULE9BQU8sRUFBRSxVQUFVLFFBQVEsRUFBRSxLQUFLLEVBQUUsVUFBVTtnQkFDNUMsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM1QyxJQUFJLGdCQUFnQixDQUFDO2dCQUNyQixNQUFNLENBQUMsVUFBVSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUs7b0JBQ3JDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO3dCQUN0QixnQkFBZ0IsR0FBRyxRQUFRLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO29CQUNwRCxDQUFDO29CQUNELGdCQUFnQixDQUFDLEtBQUssRUFBRSxVQUFVLEtBQUssRUFBRSxLQUFLO3dCQUM1QyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN6QixDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUM7WUFDSixDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7Ozs7O0lDcEQvQyxJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBMkN4QztRQUtDLHFCQUFvQixFQUFxQixFQUFVLEtBQTJCLEVBQVUsR0FBUztZQUE3RSxPQUFFLEdBQUYsRUFBRSxDQUFtQjtZQUFVLFVBQUssR0FBTCxLQUFLLENBQXNCO1lBQVUsUUFBRyxHQUFILEdBQUcsQ0FBTTtZQUM5RixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1lBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLENBQUM7UUFFTSx3Q0FBa0IsR0FBekI7WUFBQSxpQkFjQztZQWJDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNuRCxDQUFDO1lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ2QsTUFBTSxFQUFFLEtBQUs7Z0JBQ2hCLEdBQUcsRUFBSyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsZ0JBQWE7YUFDaEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLE1BQWdEO2dCQUN2RCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQzlCLEtBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO29CQUNyQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDakIsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVNLGlDQUFXLEdBQWxCLFVBQW1CLElBQVk7WUFBL0IsaUJBaUJDO1lBaEJDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDakMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBRUYsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ2YsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsR0FBRyxFQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxjQUFTLElBQU07YUFDckQsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLE1BQXFDO2dCQUM1QyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQzFCLE1BQU0sQ0FBQyxLQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHO3dCQUM1QixRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUc7d0JBQ2pFLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSTtxQkFDdEIsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFTCxDQUFDO1FBQ0gsa0JBQUM7SUFBRCxDQUFDLEFBNUNELElBNENDO0lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRyxXQUFXLENBQUMsQ0FBQyxDQUFDOzs7OztJQzNGdkQsUUFBQSxXQUFXLEdBQUc7UUFBVSxlQUFrQjthQUFsQixVQUFrQixFQUFsQixxQkFBa0IsRUFBbEIsSUFBa0I7WUFBbEIsMEJBQWtCOztRQUNuRCxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25CLGlCQUFpQixLQUFLLEVBQUUsS0FBSztZQUMzQixvQkFBb0I7WUFDcEIseUJBQXlCO1lBQ3pCLDZCQUE2QjtZQUM3QixpQ0FBaUM7WUFDakMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDekIsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3pCLENBQUM7WUFDRCxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN6QixJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUNsQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDN0IsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN6QixDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUM7WUFDVCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPLE9BQU8sQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ2IsS0FBSyxJQUFJO3dCQUNQLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDWixLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ1osS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDZixLQUFLLENBQUM7b0JBQ1IsS0FBSyxHQUFHO3dCQUNOLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDWixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUNmLEtBQUssQ0FBQztvQkFDUjt3QkFDRSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ1osS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFDakIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDZixLQUFLLENBQUM7Z0JBQ1YsQ0FBQztnQkFDRCxDQUFDLEVBQUUsQ0FBQztZQUNOLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2hELE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDVixJQUFJLElBQUksQ0FBQztRQUNULElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFFMUIsSUFBTSxRQUFRLEdBQUcsc0NBQXNDLENBQUM7UUFDeEQsSUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDO1FBRS9CLE9BQU8sT0FBTyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM3QyxRQUFRLENBQUM7WUFDVCxJQUFNLE9BQU8sR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QyxFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ1gsQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDeEMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdkIsQ0FBQztZQUNELENBQUMsRUFBRSxDQUFDO1FBQ04sQ0FBQztRQUVELE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7Ozs7O0lDbkRGLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQztJQUMxQixJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFFcEIsSUFBTSxRQUFRLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7SUFFdkMsUUFBUSxDQUFDLElBQUksR0FBRyxVQUFDLElBQVksRUFBRSxLQUFhLEVBQUUsSUFBWTtRQUN4RCw4QkFBOEI7UUFDOUIsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsZ0JBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLDRCQUFXLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsb0JBQVksS0FBSyxZQUFNLElBQUksU0FBTSxDQUFBO0lBQ25ILENBQUMsQ0FBQztJQUVGLFFBQVEsQ0FBQyxLQUFLLEdBQUcsVUFBQyxJQUFZLEVBQUUsS0FBYSxFQUFFLElBQVk7UUFDekQsTUFBTSxDQUFDLGdCQUFhLDRCQUFXLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxpQkFBVSxLQUFLLFVBQU0sQ0FBQTtJQUN6RSxDQUFDLENBQUM7SUFFRixNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ2hCLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLEdBQUcsRUFBRSxJQUFJO1FBQ1QsTUFBTSxFQUFFLElBQUk7UUFDWixNQUFNLEVBQUUsS0FBSztRQUNiLFFBQVEsRUFBRSxLQUFLO1FBQ2YsUUFBUSxFQUFFLEtBQUs7UUFDZixVQUFVLEVBQUUsSUFBSTtRQUNoQixXQUFXLEVBQUUsS0FBSztRQUNsQixLQUFLLEVBQUUsS0FBSztLQUNiLENBQUMsQ0FBQztJQUVILElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFeEMsSUFBTSxhQUFhLEdBQUc7UUFFcEIsTUFBTSxDQUFDO1lBQ0wsUUFBUSxFQUFFLElBQUk7WUFDZCxRQUFRLEVBQUUsNEhBQXNIO1lBQ2hJLEtBQUssRUFBRTtnQkFDTCxJQUFJLEVBQUUsR0FBRzthQUNWO1lBQ0QsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDO0lBQ0osQ0FBQyxDQUFBO0lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBRXhDLElBQU0sbUJBQW1CLEdBQUcsVUFBQyxTQUE0QztRQUN2RSxJQUFNLFNBQVMsR0FBRyxZQUFZLENBQUM7UUFFL0IsSUFBTSxNQUFNLEdBQUcsVUFBVSxLQUFLO1lBQzVCLElBQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxZQUFZLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7WUFDdkUsTUFBTSxDQUFDLEtBQUs7Z0JBQ1YsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ2xDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDVCxDQUFDLENBQUM7UUFFRixNQUFNLENBQUM7WUFDTCxRQUFRLEVBQUUsSUFBSTtZQUNkLEtBQUssRUFBRTtnQkFDTCxVQUFVLEVBQUUsR0FBRzthQUNoQjtZQUNELE9BQU8sRUFBRSxJQUFJO1lBQ2IsSUFBSSxFQUFFLFVBQVUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLO2dCQUNuQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNyQixLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxVQUFVLEtBQUs7d0JBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQzlCLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ04sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDdkMsQ0FBQztZQUNILENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQyxDQUFBO0lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxXQUFXLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO0lBTWpFLElBQU0sT0FBTyxHQUFHLFVBQUMsT0FBMEI7UUFDekMsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFBLEdBQUc7WUFDNUMsTUFBTSxjQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFDZixJQUFJLEVBQUUsWUFBVSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFHLEVBQzdELEtBQUssRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUNsQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0lBRUY7UUFLRSx3QkFBb0IsTUFBa0IsRUFBVSxNQUFNLEVBQVUsUUFBaUMsRUFBVSxXQUF5QjtZQUFwSSxpQkFVQztZQVZtQixXQUFNLEdBQU4sTUFBTSxDQUFZO1lBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBQTtZQUFVLGFBQVEsR0FBUixRQUFRLENBQXlCO1lBQVUsZ0JBQVcsR0FBWCxXQUFXLENBQWM7WUFKNUgsYUFBUSxHQUFHLFlBQVksQ0FBQztZQUN4QixVQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ1gsU0FBSSxHQUFVLEVBQUcsQ0FBQztZQUl4QixXQUFXLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHO2dCQUN2QyxLQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFFO2dCQUNyQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDeEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQTtnQkFDdEYsQ0FBQztnQkFBQyxJQUFJLENBQUMsQ0FBQztvQkFDTixLQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3RDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxzQkFBVyxtQ0FBTztpQkFBbEIsY0FBdUIsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDOzs7V0FBQTtRQUM5QyxzQkFBVyxnQ0FBSTtpQkFBZixjQUFvQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7OztXQUFBO1FBQ3hDLHNCQUFXLCtCQUFHO2lCQUFkLGNBQW1CLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzs7O1dBQUE7UUFFOUIsbUNBQVUsR0FBbEIsVUFBbUIsSUFBWTtZQUEvQixpQkFNQztZQUxDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLE1BQU07Z0JBQzdDLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ2xCLFdBQVcsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUM5QixLQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDbEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUgscUJBQUM7SUFBRCxDQUFDLEFBN0JELElBNkJDO0lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsY0FBYyxDQUFFLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFuZ3VsYXIgZnJvbSAnYW5ndWxhckFNRCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gIGxhYmVsPzogc3RyaW5nLFxuICBub2Rlcz86IE5vZGVbXSxcbiAgdmVyc2lvbnM/OiB7XG4gICAgW3ZlcnNpb246IHN0cmluZ106IHsgXG4gICAgICBsYWJlbDogc3RyaW5nLFxuICAgICAgZGF0ZTogc3RyaW5nLFxuICAgICAgcGF0aDogc3RyaW5nXG4gICAgfVxuICB9IFxufVxuXG5jb25zdCBoZWxwID0gYW5ndWxhci5tb2R1bGUoJ2FwcC5oZWxwJyk7XG5cbi8vIGNsYXNzIEhlbHBUcmVlQ29udHJvbGxlciBpbXBsZW1lbnRzIG5nLklDb250cm9sbGVyIHtcbi8vICAgY29uc3RydWN0b3IocHJpdmF0ZSAkc2NvcGU6IG5nLklTY29wZSAmIHsgcm9vdE5vZGU6IE5vZGUsIGRhdGE6IE5vZGVbXX0pIHtcbi8vICAgICAkc2NvcGUuJHdhdGNoKFwicm9vdE5vZGVcIiwgKG4sIG8pID0+IHtcbi8vICAgICAgICRzY29wZS5kYXRhID0gT2JqZWN0LmtleXMoJHNjb3BlLnJvb3ROb2RlKS5tYXAoa2V5ID0+ICRzY29wZS5yb290Tm9kZVtrZXldKTtcbi8vICAgICB9KTtcbi8vICAgfVxuLy8gfVxuXG4vLyBoZWxwLmNvbnRyb2xsZXIoXCJ0cmVlQ3RybFwiLCBbXCIkc2NvcGVcIiwgSGVscFRyZWVDb250cm9sbGVyXSk7XG5cbmNvbnN0IGhlbHBUcmVlID0gZnVuY3Rpb24gKCRjb21waWxlKSB7XG4gIHJldHVybiB7XG4gICAgcmVzdHJpY3Q6IFwiRVwiLFxuICAgIHRyYW5zY2x1ZGU6IHRydWUsXG4gICAgc2NvcGU6IHsgcm9vdE5vZGU6ICc9JyB9LFxuICAgIC8vY29udHJvbGxlcjogJ3RyZWVDdHJsJyxcbiAgICB0ZW1wbGF0ZTpcbiAgICAgICc8dWw+JyArXG4gICAgICAnPGxpIG5nLXRyYW5zY2x1ZGU+PC9saT4nICtcbiAgICAgICc8bGkgbmctcmVwZWF0PVwiY2hpbGQgaW4gcm9vdE5vZGUubm9kZXNcIj4nICtcbiAgICAgICc8dHJlZSByb290LW5vZGU9XCJjaGlsZFwiPjxkaXYgbmctdHJhbnNjbHVkZT48L2Rpdj48L3RyZWU+JyArXG4gICAgICAnPC9saT4nICtcbiAgICAgICc8L3VsPicsXG4gICAgY29tcGlsZTogZnVuY3Rpb24gKHRFbGVtZW50LCB0QXR0ciwgdHJhbnNjbHVkZSkge1xuICAgICAgdmFyIGNvbnRlbnRzID0gdEVsZW1lbnQuY29udGVudHMoKS5yZW1vdmUoKTtcbiAgICAgIHZhciBjb21waWxlZENvbnRlbnRzO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzY29wZSwgaUVsZW1lbnQsIGlBdHRyKSB7XG4gICAgICAgIGlmICghY29tcGlsZWRDb250ZW50cykge1xuICAgICAgICAgIGNvbXBpbGVkQ29udGVudHMgPSAkY29tcGlsZShjb250ZW50cywgdHJhbnNjbHVkZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29tcGlsZWRDb250ZW50cyhzY29wZSwgZnVuY3Rpb24gKGNsb25lLCBzY29wZSkge1xuICAgICAgICAgIGlFbGVtZW50LmFwcGVuZChjbG9uZSk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9XG4gIH07XG59O1xuXG5oZWxwLmRpcmVjdGl2ZShcInRyZWVcIiwgW1wiJGNvbXBpbGVcIiwgaGVscFRyZWVdKTsiLCJpbXBvcnQgKiBhcyBhbmd1bGFyIGZyb20gJ2FuZ3VsYXJBTUQnO1xuXG5jb25zdCBoZWxwID0gYW5ndWxhci5tb2R1bGUoJ2FwcC5oZWxwJyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvbkluZm8ge1xuICBsYWJlbDogc3RyaW5nLFxuICBwYXRoOiBzdHJpbmcsXG4gIGRhdGU6IHN0cmluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRvY05vZGUge1xuICBsYWJlbDogc3RyaW5nOyBcbiAgdmVyc2lvbnM6IHtcbiAgICBbdmVyc2lvbktleTogc3RyaW5nXTogVmVyc2lvbkluZm9cbiAgfTtcbiAgbm9kZXM/OiBUb2NOb2RlQ29sbGVjdGlvbjtcbn1cblxuZXhwb3J0IHR5cGUgVG9jTm9kZUNvbGxlY3Rpb24gPSB7IFt0b2NOb2RlS2V5OiBzdHJpbmddOiBUb2NOb2RlIH07XG5cblxuaW50ZXJmYWNlIElFbnYge1xuICBnZXRCYXNlVVJMOiAoc2FsVHlwZTogJ0FEX1NBTCcgfCAnTURfU0FMJykgPT4gc3RyaW5nO1xufVxuXG4vKiogUmVwcmVzZW50cyBhIHNlcnZpY2UgdXNlZCBmb3IgdGhlIGhlbHAgYXBwbGljYXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIElIZWxwU2VydmljZSB7XG5cbiAgLyoqXG4gICAqIFF1ZXJpZXMgdGhlIHRhYmxlIG9mIGNvbnRlbnRzIGZvciBhIHNwZWNpZmljIHZlcnNpb24uXG4gICAqIEBwYXJhbSB2ZXJzaW9uIFRoZSB2ZXJzaW9uIHRoZSB0YWJsZSBvZiBjb250ZW50cyBzaGFsbCBiZSByZXF1ZXN0ZWQgZm9yLlxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgY29udGFpbmluZyB0aGUgcmVxdWVzdGVkIHRhYmxlIG9mIGNvbnRlbnRzLlxuICAgKiBcbiAgICovXG4gIGdldFRhYmxlT2ZDb250ZW50cyh2ZXJzaW9uPzogc3RyaW5nKTogYW5ndWxhci5JUHJvbWlzZTxUb2NOb2RlQ29sbGVjdGlvbj47XG5cbiAgLyoqXG4gICAqIEdldCBhIHNwZWNpdGljIGRvY3VtZW50IGJ5IGl0cyBwYXRoLlxuICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgZG9jdW1lbnQgdG8gZ2V0LlxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgY29udGFpbmluZyB0aGUgcmVxdWVzdGVkIGRvY3VtZW50LlxuICAgKiBcbiAgICovXG4gIGdldERvY3VtZW50KHBhdGg6IHN0cmluZyk6IGFuZ3VsYXIuSVByb21pc2U8eyBiYXNlUGF0aDogc3RyaW5nLCBkb2N1bWVudDogc3RyaW5nIH0+O1xufVxuXG5jbGFzcyBIZWxwc2VydmljZSBpbXBsZW1lbnRzIElIZWxwU2VydmljZSB7XG5cbiAgcHJpdmF0ZSB0b2NOb2RlQ29sbGVjdGlvbjogVG9jTm9kZUNvbGxlY3Rpb247XG4gIHByaXZhdGUgZG9jdW1lbnRzOiB7IFtwYXRoOiBzdHJpbmddOiB7IGJhc2VQYXRoOiBzdHJpbmcsIGRvY3VtZW50OiBzdHJpbmcgfSB9O1xuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgJHE6IGFuZ3VsYXIuSVFTZXJ2aWNlLCBwcml2YXRlICRodHRwOiBhbmd1bGFyLklIdHRwU2VydmljZSwgcHJpdmF0ZSBlbnY6IElFbnYpIHtcbiAgICB0aGlzLnRvY05vZGVDb2xsZWN0aW9uID0gbnVsbDtcbiAgICB0aGlzLmRvY3VtZW50cyA9IHt9O1xuICB9XG4gXG4gIHB1YmxpYyBnZXRUYWJsZU9mQ29udGVudHMoKTogYW5ndWxhci5JUHJvbWlzZTxUb2NOb2RlQ29sbGVjdGlvbj4ge1xuICAgIGlmICh0aGlzLnRvY05vZGVDb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy4kcS5yZXNvbHZlKHRoaXMudG9jTm9kZUNvbGxlY3Rpb24pO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLiRodHRwKHtcbiAgICAgIG1ldGhvZDogXCJHRVRcIixcblx0XHRcdHVybDogYCR7dGhpcy5lbnYuZ2V0QmFzZVVSTCgnTURfU0FMJyl9L2hlbHAvP21ldGFgXG4gICAgfSkudGhlbigocmVzdWx0OiBhbmd1bGFyLklIdHRwUmVzcG9uc2U8VG9jTm9kZUNvbGxlY3Rpb24+KSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gMjAwKSB7XG5cdFx0XHRcdHRoaXMudG9jTm9kZUNvbGxlY3Rpb24gPSByZXN1bHQuZGF0YTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdC5kYXRhO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldERvY3VtZW50KHBhdGg6IHN0cmluZyk6IGFuZ3VsYXIuSVByb21pc2U8e2Jhc2VQYXRoOiBzdHJpbmcsIGRvY3VtZW50OiBzdHJpbmd9PiB7XG4gICAgaWYgKHRoaXMuZG9jdW1lbnRzW3BhdGhdICE9IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLiRxLnJlc29sdmUodGhpcy5kb2N1bWVudHNbcGF0aF0pO1xuICAgIH1cblxuICAgcmV0dXJuIHRoaXMuJGh0dHAoe1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgdXJsOiBgJHt0aGlzLmVudi5nZXRCYXNlVVJMKCdNRF9TQUwnKX0vaGVscC8ke3BhdGh9YFxuICAgIH0pLnRoZW4oKHJlc3VsdDogYW5ndWxhci5JSHR0cFJlc3BvbnNlPHN0cmluZz4pID0+IHtcbiAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnRzW3BhdGhdID0ge1xuICAgICAgICAgIGJhc2VQYXRoOiByZXN1bHQuY29uZmlnICYmIHJlc3VsdC5jb25maWcudXJsICYmIHJlc3VsdC5jb25maWcudXJsLFxuICAgICAgICAgIGRvY3VtZW50OiByZXN1bHQuZGF0YVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuXG4gIH0gXG59XG5cbmhlbHAuc2VydmljZSgnaGVscFNlcnZpY2UnLCBbJyRxJywgJyRodHRwJywgJ0VOVicsICBIZWxwc2VydmljZV0pOyIsImV4cG9ydCB2YXIgcmVzb2x2ZVBhdGggPSBmdW5jdGlvbiAoLi4ucGF0aHM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc29sZS5sb2cocGF0aHMpO1xuICBmdW5jdGlvbiByZXNvbHZlKHBhdGhBLCBwYXRoQikge1xuICAgIC8vICDigJhh4oCZICAgICA9PiBbJ2EnXVxuICAgIC8vICAnYS9iJyAgID0+IFsnYScsICdiJ11cbiAgICAvLyAgJy9hL2InICA9PiBbJycsICdhJywgJ2InXVxuICAgIC8vICAnL2EvYi8nID0+IFsnJywgJ2EnLCAnYicsICcnXVxuICAgIHBhdGhCID0gcGF0aEIuc3BsaXQoJy8nKTtcbiAgICBpZiAocGF0aEJbMF0gPT09ICcnKSB7XG4gICAgICByZXR1cm4gcGF0aEIuam9pbignLycpO1xuICAgIH1cbiAgICBwYXRoQSA9IHBhdGhBLnNwbGl0KCcvJyk7XG4gICAgdmFyIGFMYXN0SW5kZXggPSBwYXRoQS5sZW5ndGggLSAxO1xuICAgIGlmIChwYXRoQVthTGFzdEluZGV4XSAhPT0gJycpIHtcbiAgICAgIHBhdGhBW2FMYXN0SW5kZXhdID0gJyc7XG4gICAgfVxuXG4gICAgdmFyIHBhcnQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlICh0eXBlb2YgKHBhcnQgPSBwYXRoQltpXSkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBzd2l0Y2ggKHBhcnQpIHtcbiAgICAgICAgY2FzZSAnLi4nOlxuICAgICAgICAgIHBhdGhBLnBvcCgpO1xuICAgICAgICAgIHBhdGhBLnBvcCgpO1xuICAgICAgICAgIHBhdGhBLnB1c2goJycpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICcuJzpcbiAgICAgICAgICBwYXRoQS5wb3AoKTtcbiAgICAgICAgICBwYXRoQS5wdXNoKCcnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBwYXRoQS5wb3AoKTtcbiAgICAgICAgICBwYXRoQS5wdXNoKHBhcnQpO1xuICAgICAgICAgIHBhdGhBLnB1c2goJycpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaSsrO1xuICAgIH1cbiAgICBpZiAocGF0aEJbcGF0aEIubGVuZ3RoIC0gMV0gIT09ICcnKSBwYXRoQS5wb3AoKTsgXG4gICAgcmV0dXJuIHBhdGhBLmpvaW4oJy8nKTtcbiAgfVxuXG4gIHZhciBpID0gMDtcbiAgdmFyIHBhdGg7XG4gIHZhciByID0gbG9jYXRpb24ucGF0aG5hbWU7XG5cbiAgY29uc3QgdXJsUmVnZXggPSAvXmh0dHBzP1xcOlxcL1xcLyhbXlxcLz8jXSspKD86W1xcLz8jXXwkKS9pO1xuICBjb25zdCBtdWx0aVNsYXNoUmVnID0gL1xcL1xcLysvZztcblxuICB3aGlsZSAodHlwZW9mIChwYXRoID0gcGF0aHNbaV0pID09PSAnc3RyaW5nJykge1xuICAgIGRlYnVnZ2VyO1xuICAgIGNvbnN0IG1hdGNoZXMgPSBwYXRoICYmIHBhdGgubWF0Y2godXJsUmVnZXgpO1xuICAgIGlmIChtYXRjaGVzIHx8ICFpKSB7XG4gICAgICByID0gcGF0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgcGF0aCA9IHBhdGgucmVwbGFjZShtdWx0aVNsYXNoUmVnLCAnLycpO1xuICAgICAgciA9IHJlc29sdmUociwgcGF0aCk7XG4gICAgfVxuICAgIGkrKztcbiAgfVxuXG4gIHJldHVybiByO1xufTsiLCJkZWNsYXJlIHZhciBhbmd1bGFyOiBhbmd1bGFyLklBbmd1bGFyU3RhdGljO1xuXG5pbXBvcnQgKiBhcyBtYXJrZWQgZnJvbSBcIi4vbGliL21hcmtlZFwiOyAgXG5cbmltcG9ydCBcIi4vaGVscC50cmVlXCI7XG5pbXBvcnQgXCIuL2hlbHAuc2VydmljZVwiO1xuXG5pbXBvcnQgeyBJSGVscFNlcnZpY2UgLCBUb2NOb2RlQ29sbGVjdGlvbiB9IGZyb20gXCIuL2hlbHAuc2VydmljZVwiO1xuaW1wb3J0IHsgcmVzb2x2ZVBhdGggfSBmcm9tICcuL2hlbHAudXRpbGl0aWVzJztcbmltcG9ydCB7IE5vZGUgfSBmcm9tICBcIi4vaGVscC50cmVlXCI7XG5cbmxldCBjdXJyZW50UGF0aCA9ICcvaGVscCc7XG5sZXQgY3VycmVudERvYyA9ICcnO1xuXG5jb25zdCByZW5kZXJlciA9IG5ldyBtYXJrZWQuUmVuZGVyZXIoKTtcblxucmVuZGVyZXIubGluayA9IChocmVmOiBzdHJpbmcsIHRpdGxlOiBzdHJpbmcsIHRleHQ6IHN0cmluZykgPT4ge1xuICAvLyBjaGVjayBpZiBocmVmIGlzIHJlbCBvciBhYnNcbiAgY29uc3QgYWJzVXJsTWF0Y2ggPSBocmVmLnRyaW0oKS5tYXRjaCgvXmh0dHBzPzpcXC9cXC8vaSk7XG4gIHJldHVybiBgPGEgaHJlZj1cIiR7YWJzVXJsTWF0Y2ggPyBocmVmIDogcmVzb2x2ZVBhdGgoJyMvaGVscC8nLCBjdXJyZW50RG9jLCBocmVmKX1cIiB0aXRsZT1cIiR7dGl0bGV9XCIgPiR7dGV4dH08L2E+YFxufTtcblxucmVuZGVyZXIuaW1hZ2UgPSAoaHJlZjogc3RyaW5nLCB0aXRsZTogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpID0+IHtcbiAgcmV0dXJuIGA8aW1nIHNyYz1cIiR7cmVzb2x2ZVBhdGgoY3VycmVudFBhdGgsIGhyZWYpfVwiIGFsdD1cIiR7dGl0bGV9XCIgLz5gXG59O1xuXG5tYXJrZWQuc2V0T3B0aW9ucyh7XG4gIHJlbmRlcmVyOiByZW5kZXJlcixcbiAgZ2ZtOiB0cnVlLFxuICB0YWJsZXM6IHRydWUsXG4gIGJyZWFrczogZmFsc2UsXG4gIHBlZGFudGljOiBmYWxzZSxcbiAgc2FuaXRpemU6IGZhbHNlLFxuICBzbWFydExpc3RzOiB0cnVlLFxuICBzbWFydHlwYW50czogZmFsc2UsXG4gIHhodG1sOiBmYWxzZVxufSk7XG5cbmNvbnN0IGhlbHAgPSBhbmd1bGFyLm1vZHVsZSgnYXBwLmhlbHAnKTtcblxuY29uc3QgSGVscERpcmVjdGl2ZSA9ICgpID0+IHtcblxuICByZXR1cm4ge1xuICAgIHJlc3RyaWN0OiAnQUUnLFxuICAgIHRlbXBsYXRlOiBgPGRpdiBjbGFzcz1cImdsb2JhbC1oZWxwXCIgPjxhIGhyZWY9XCJ7eyAnIy9oZWxwLycrJHNjb3BlLmxpbmsgfX1cIj48aSBjbGFzcz1cImZhIGZhLXF1ZXN0aW9uLWNpcmNsZVwiPjwvaT4gSGVscDwvYT48L2Rpdj5gLFxuICAgIHNjb3BlOiB7XG4gICAgICBsaW5rOiAnQCdcbiAgICB9LFxuICAgIHJlcGxhY2U6IHRydWVcbiAgfTtcbn1cblxuaGVscC5kaXJlY3RpdmUoJ2hlbHAnLCBbSGVscERpcmVjdGl2ZV0pO1xuXG5jb25zdCBNYXJrZG93bkl0RGlyZWN0aXZlID0gKCRzYW5pdGl6ZTogYW5ndWxhci5zYW5pdGl6ZS5JU2FuaXRpemVTZXJ2aWNlKSA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZSA9ICdtYXJrZG93bkl0JztcbiAgXG4gIGNvbnN0IHJlbmRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGNvbnN0IG1kMmh0bWwgPSAobWFya2VkIGluc3RhbmNlb2YgRnVuY3Rpb24pID8gbWFya2VkIDogbWFya2VkLmRlZmF1bHQ7XG4gICAgcmV0dXJuIHZhbHVlXG4gICAgICA/ICRzYW5pdGl6ZShtZDJodG1sKHZhbHVlLnRyaW0oKSkpXG4gICAgICA6ICcnO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgcmVzdHJpY3Q6ICdBRScsXG4gICAgc2NvcGU6IHtcbiAgICAgIG1hcmtkb3duSXQ6ICc9J1xuICAgIH0sXG4gICAgcmVwbGFjZTogdHJ1ZSxcbiAgICBsaW5rOiBmdW5jdGlvbiAoc2NvcGUsIGVsZW1lbnQsIGF0dHJzKSB7XG4gICAgICBpZiAoYXR0cnNbYXR0cmlidXRlXSkge1xuICAgICAgICBzY29wZS4kd2F0Y2goYXR0cmlidXRlLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBlbGVtZW50Lmh0bWwocmVuZGVyKHZhbHVlKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5odG1sKHJlbmRlcihlbGVtZW50LnRleHQoKSkpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuaGVscC5kaXJlY3RpdmUoJ21hcmtkb3duSXQnLCBbJyRzYW5pdGl6ZScsIE1hcmtkb3duSXREaXJlY3RpdmVdKTtcblxuaW50ZXJmYWNlIElIZWxwU2NvcGUgZXh0ZW5kcyBhbmd1bGFyLklTY29wZSB7XG4gIHRvYzogVG9jTm9kZUNvbGxlY3Rpb25cbn1cblxuY29uc3QgbWFwTm9kZSA9ICh0b2NOb2RlOiBUb2NOb2RlQ29sbGVjdGlvbik6IE5vZGVbXSA9PiB7XG4gIHJldHVybiB0b2NOb2RlICYmIE9iamVjdC5rZXlzKHRvY05vZGUpLm1hcChrZXkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50b2NOb2RlW2tleV0sXG4gICAgICBocmVmOiBgIy9oZWxwLyR7dG9jTm9kZVtrZXldWyd2ZXJzaW9ucyddWydjdXJyZW50J11bJ3BhdGgnXX1gLFxuICAgICAgbm9kZXM6IG1hcE5vZGUodG9jTm9kZVtrZXldLm5vZGVzKVxuICAgIH07XG4gIH0pO1xufTtcblxuY2xhc3MgSGVscENvbnRyb2xsZXIge1xuICBwcml2YXRlIF9jb250ZW50ID0gXCIjIyBMb2FkaW5nXCI7XG4gIHByaXZhdGUgX3BhdGggPSAnJztcbiAgcHJpdmF0ZSBfdG9jIDogTm9kZSA9IHsgfTsgXG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSAkc2NvcGU6IElIZWxwU2NvcGUsIHByaXZhdGUgJHN0YXRlLCBwcml2YXRlICR0aW1lb3V0OiBhbmd1bGFyLklUaW1lb3V0U2VydmljZSwgcHJpdmF0ZSBoZWxwU2VydmljZTogSUhlbHBTZXJ2aWNlKSB7XG4gIFxuICAgIGhlbHBTZXJ2aWNlLmdldFRhYmxlT2ZDb250ZW50cygpLnRoZW4odG9jID0+IHtcbiAgICAgIHRoaXMuX3RvYyA9IHsgbm9kZXM6IG1hcE5vZGUodG9jKSB9IDtcbiAgICAgIGlmICghJHN0YXRlLnBhcmFtcy5wYXRoKSB7XG4gICAgICAgICRzdGF0ZS5nbygnbWFpbi5oZWxwJywgeyBwYXRoOiB0b2NbJ29wZW5kYXlsaWdodCddWyd2ZXJzaW9ucyddWydjdXJyZW50J11bJ3BhdGgnXSB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5uYXZpZ2F0ZVRvKCRzdGF0ZS5wYXJhbXMucGF0aCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGNvbnRlbnQoKSB7IHJldHVybiB0aGlzLl9jb250ZW50OyB9XG4gIHB1YmxpYyBnZXQgcGF0aCgpIHsgcmV0dXJuIHRoaXMuX3BhdGg7IH1cbiAgcHVibGljIGdldCB0b2MoKSB7IHJldHVybiB0aGlzLl90b2M7IH1cblxuICBwcml2YXRlIG5hdmlnYXRlVG8ocGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5oZWxwU2VydmljZS5nZXREb2N1bWVudChwYXRoKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgIGN1cnJlbnREb2MgPSBwYXRoO1xuICAgICAgY3VycmVudFBhdGggPSByZXN1bHQuYmFzZVBhdGg7XG4gICAgICB0aGlzLl9jb250ZW50ID0gcmVzdWx0LmRvY3VtZW50O1xuICAgIH0pO1xuICB9XG5cbn1cblxuaGVscC5jb250cm9sbGVyKCdoZWxwQ3RybCcsIFsnJHNjb3BlJywgJyRzdGF0ZScsICckdGltZW91dCcsICdoZWxwU2VydmljZScsIEhlbHBDb250cm9sbGVyIF0pOyJdfQ== \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.ts
new file mode 100644
index 00000000..5a12bbfe
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.controller.ts
@@ -0,0 +1,130 @@
+declare var angular: angular.IAngularStatic;
+
+import * as marked from "./lib/marked";
+
+import "./help.tree";
+import "./help.service";
+
+import { IHelpService , TocNodeCollection } from "./help.service";
+import { resolvePath } from './help.utilities';
+import { Node } from "./help.tree";
+
+let currentPath = '/help';
+let currentDoc = '';
+
+const renderer = new marked.Renderer();
+
+renderer.link = (href: string, title: string, text: string) => {
+ // check if href is rel or abs
+ const absUrlMatch = href.trim().match(/^https?:\/\//i);
+ return `<a href="${absUrlMatch ? href : resolvePath('#/help/', currentDoc, href)}" title="${title}" >${text}</a>`
+};
+
+renderer.image = (href: string, title: string, text: string) => {
+ return `<img src="${resolvePath(currentPath, href)}" alt="${title}" />`
+};
+
+marked.setOptions({
+ renderer: renderer,
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ smartLists: true,
+ smartypants: false,
+ xhtml: false
+});
+
+const help = angular.module('app.help');
+
+const HelpDirective = () => {
+
+ return {
+ restrict: 'AE',
+ template: `<div class="global-help" ><a href="{{ '#/help/'+ link }}"><i class="fa fa-question-circle"></i> Help</a></div>`,
+ scope: {
+ link: '@'
+ },
+ replace: true
+ };
+}
+
+help.directive('help', [HelpDirective]);
+
+const MarkdownItDirective = ($sanitize: angular.sanitize.ISanitizeService) => {
+ const attribute = 'markdownIt';
+
+ const render = function (value) {
+ const md2html = (marked instanceof Function) ? marked : marked.default;
+ return value
+ ? $sanitize(md2html(value.trim()))
+ : '';
+ };
+
+ return {
+ restrict: 'AE',
+ scope: {
+ markdownIt: '='
+ },
+ replace: true,
+ link: function (scope, element, attrs) {
+ if (attrs[attribute]) {
+ scope.$watch(attribute, function (value) {
+ element.html(render(value));
+ });
+ } else {
+ element.html(render(element.text()));
+ }
+ }
+ };
+}
+
+help.directive('markdownIt', ['$sanitize', MarkdownItDirective]);
+
+interface IHelpScope extends angular.IScope {
+ toc: TocNodeCollection
+}
+
+const mapNode = (tocNode: TocNodeCollection): Node[] => {
+ return tocNode && Object.keys(tocNode).map(key => {
+ return {
+ ...tocNode[key],
+ href: `#/help/${tocNode[key]['versions']['current']['path']}`,
+ nodes: mapNode(tocNode[key].nodes)
+ };
+ });
+};
+
+class HelpController {
+ private _content = "## Loading";
+ private _path = '';
+ private _toc : Node = { };
+
+ constructor(private $scope: IHelpScope, private $state, private $timeout: angular.ITimeoutService, private helpService: IHelpService) {
+
+ helpService.getTableOfContents().then(toc => {
+ this._toc = { nodes: mapNode(toc) } ;
+ if (!$state.params.path) {
+ $state.go('main.help', { path: toc['sdnr']['versions']['current']['path'] })
+ } else {
+ this.navigateTo($state.params.path);
+ }
+ });
+ }
+
+ public get content() { return this._content; }
+ public get path() { return this._path; }
+ public get toc() { return this._toc; }
+
+ private navigateTo(path: string): void {
+ this.helpService.getDocument(path).then((result) => {
+ currentDoc = path;
+ currentPath = result.basePath;
+ this._content = result.document;
+ });
+ }
+
+}
+
+help.controller('helpCtrl', ['$scope', '$state', '$timeout', 'helpService', HelpController ]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.custom.css
new file mode 100644
index 00000000..d54b5c25
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.custom.css
@@ -0,0 +1,105 @@
+.app-help {
+ color:azure;
+}
+
+.global-help {
+ float: left;
+ margin: 5px;
+ margin-left: 8px;
+}
+
+.app-help th {
+ padding: 3px;
+ border-bottom: #eeeeee solid 1px;
+}
+
+.app-help td {
+ padding: 2px;
+}
+
+.app-help tbody {
+ padding: 2px;
+ border-bottom: #eeeeee solid 1px;
+ margin-bottom: 20px;
+}
+
+.app-help .toc {
+ padding-left: 0;
+ padding-top: 25px;
+ max-width: 170px;
+}
+
+.app-help a[href^="http://"]:after {
+ content: "\f08e";
+ display: inline-block;
+ font-family: FontAwesome;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ padding-left: 3px;
+}
+
+.app-help a[href^="https://"]:after {
+ content: "\f08e";
+ display: inline-block;
+ font-family: FontAwesome;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ padding-left: 3px;
+}
+
+.app-help a, .global-help a {
+ color:azure;
+ text-decoration: none;
+}
+
+.app-help a:visited, .global-help a:visited {
+ color:azure;
+ text-decoration: none;
+}
+
+.app-help a:hover, .global-help a:hover {
+ color:bisque;
+}
+
+.app-help .toc ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ border: none;
+ overflow: hidden;
+}
+
+.app-help .toc li {
+ line-height: 1.5em;
+ position: relative;
+ padding: 0 0 0 20px;
+}
+
+.app-help .toc > tree > ul > li {
+ padding: 0
+}
+
+.app-help .toc li a {
+ color:azure;
+ text-decoration: none;
+}
+
+.app-help .toc li a:visited {
+ color:azure;
+ text-decoration: none;
+}
+
+.app-help .toc li a:hover {
+ color:bisque;
+ text-decoration: none;
+}
+
+.app-help > .help {
+ color:azure;
+}
+
+.app-help > .help img {
+ width: 100%
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.js
new file mode 100644
index 00000000..71d43be9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.js
@@ -0,0 +1,33 @@
+define( ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.help = angular.module('app.help', ['app.core']);
+ exports.help.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+ //$translatePartialLoaderProvider.addPart('app/help/locale/locale');
+ NavHelperProvider.addControllerUrl('app/help/help.controller');
+ NavHelperProvider.addToMenu('help', {
+ "link": "#/help/",
+ "active": "main.help",
+ "title": "Help",
+ "icon": "fa fa-question-circle",
+ "page": {
+ "title": "Help",
+ "description": "help"
+ }
+ });
+ $stateProvider.state('main.help', {
+ url: 'help/*path',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/help/help.tpl.html',
+ controller: 'helpCtrl as vm'
+ }
+ }
+ });
+ });
+});
+/* non ES6 export */
+// export = help;
+// export default help;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscC5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcmMvYXBwL2hlbHAvaGVscC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0lBRWEsUUFBQSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBRTdELFlBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxrQkFBa0IsRUFBRSwrQkFBK0I7UUFFMUssb0VBQW9FO1FBRXBFLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDL0QsaUJBQWlCLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtZQUNsQyxNQUFNLEVBQUUsU0FBUztZQUNqQixRQUFRLEVBQUUsV0FBVztZQUNyQixPQUFPLEVBQUUsTUFBTTtZQUNmLE1BQU0sRUFBRSx1QkFBdUI7WUFDL0IsTUFBTSxFQUFFO2dCQUNOLE9BQU8sRUFBRSxXQUFXO2dCQUNwQixhQUFhLEVBQUUsTUFBTTthQUN0QjtTQUNGLENBQUMsQ0FBQztRQUVILGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFO1lBQ2hDLEdBQUcsRUFBRSxZQUFZO1lBQ2pCLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFO2dCQUNMLFNBQVMsRUFBRTtvQkFDVCxXQUFXLEVBQUUsNEJBQTRCO29CQUN6QyxVQUFVLEVBQUUsZ0JBQWdCO2lCQUM3QjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7O0FBRUgsb0JBQW9CO0FBQ3BCLG9CQUFvQjtBQUNwQix1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIHZhciBhbmd1bGFyOiBhbmd1bGFyLklBbmd1bGFyU3RhdGljO1xuXG5leHBvcnQgY29uc3QgaGVscCA9IGFuZ3VsYXIubW9kdWxlKCdhcHAuaGVscCcsIFsnYXBwLmNvcmUnXSk7XG5cbmhlbHAuY29uZmlnKGZ1bmN0aW9uICgkc3RhdGVQcm92aWRlciwgJGNvbXBpbGVQcm92aWRlciwgJGNvbnRyb2xsZXJQcm92aWRlciwgJHByb3ZpZGUsIE5hdkhlbHBlclByb3ZpZGVyLCAkaHR0cFByb3ZpZGVyLCAkdHJhbnNsYXRlUHJvdmlkZXIsICR0cmFuc2xhdGVQYXJ0aWFsTG9hZGVyUHJvdmlkZXIpIHtcblxuICAvLyR0cmFuc2xhdGVQYXJ0aWFsTG9hZGVyUHJvdmlkZXIuYWRkUGFydCgnYXBwL2hlbHAvbG9jYWxlL2xvY2FsZScpO1xuXG4gIE5hdkhlbHBlclByb3ZpZGVyLmFkZENvbnRyb2xsZXJVcmwoJ2FwcC9oZWxwL2hlbHAuY29udHJvbGxlcicpO1xuICBOYXZIZWxwZXJQcm92aWRlci5hZGRUb01lbnUoJ2hlbHAnLCB7XG4gICAgXCJsaW5rXCI6IFwiIy9oZWxwL1wiLFxuICAgIFwiYWN0aXZlXCI6IFwibWFpbi5oZWxwXCIsXG4gICAgXCJ0aXRsZVwiOiBcIkhlbHBcIixcbiAgICBcImljb25cIjogXCJmYSBmYS1xdWVzdGlvbi1jaXJjbGVcIiwgIC8vIEFkZCBuYXZpZ2F0aW9uIGljb24gY3NzIGNsYXNzIGhlcmVcbiAgICBcInBhZ2VcIjoge1xuICAgICAgXCJ0aXRsZVwiOiBcIk1XVE4gRGVtb1wiLFxuICAgICAgXCJkZXNjcmlwdGlvblwiOiBcImhlbHBcIlxuICAgIH1cbiAgfSk7XG5cbiAgJHN0YXRlUHJvdmlkZXIuc3RhdGUoJ21haW4uaGVscCcsIHtcbiAgICB1cmw6ICdoZWxwLypwYXRoJyxcbiAgICBhY2Nlc3M6IDIsXG4gICAgdmlld3M6IHtcbiAgICAgICdjb250ZW50Jzoge1xuICAgICAgICB0ZW1wbGF0ZVVybDogJ3NyYy9hcHAvaGVscC9oZWxwLnRwbC5odG1sJyxcbiAgICAgICAgY29udHJvbGxlcjogJ2hlbHBDdHJsIGFzIHZtJ1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59KTtcblxuLyogbm9uIEVTNiBleHBvcnQgKi9cbi8vIGV4cG9ydCA9IGhlbHA7ICAgXG4vLyBleHBvcnQgZGVmYXVsdCBoZWxwOyJdfQ==
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.ts
new file mode 100644
index 00000000..d3acc645
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.module.ts
@@ -0,0 +1,35 @@
+declare var angular: angular.IAngularStatic;
+
+export const help = angular.module('app.help', ['app.core']);
+
+help.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+
+ //$translatePartialLoaderProvider.addPart('app/help/locale/locale');
+
+ NavHelperProvider.addControllerUrl('app/help/help.controller');
+ NavHelperProvider.addToMenu('help', {
+ "link": "#/help/",
+ "active": "main.help",
+ "title": "Help",
+ "icon": "fa fa-question-circle", // Add navigation icon css class here
+ "page": {
+ "title": "MWTN Demo",
+ "description": "help"
+ }
+ });
+
+ $stateProvider.state('main.help', {
+ url: 'help/*path',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/help/help.tpl.html',
+ controller: 'helpCtrl as vm'
+ }
+ }
+ });
+});
+
+/* non ES6 export */
+// export = help;
+// export default help; \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.service.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.service.ts
new file mode 100644
index 00000000..f09ec7b7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.service.ts
@@ -0,0 +1,92 @@
+import * as angular from 'angularAMD';
+
+const help = angular.module('app.help');
+
+export interface VersionInfo {
+ label: string,
+ path: string,
+ date: string
+}
+
+export interface TocNode {
+ label: string;
+ versions: {
+ [versionKey: string]: VersionInfo
+ };
+ nodes?: TocNodeCollection;
+}
+
+export type TocNodeCollection = { [tocNodeKey: string]: TocNode };
+
+
+interface IEnv {
+ getBaseURL: (salType: 'AD_SAL' | 'MD_SAL') => string;
+}
+
+/** Represents a service used for the help application. */
+export interface IHelpService {
+
+ /**
+ * Queries the table of contents for a specific version.
+ * @param version The version the table of contents shall be requested for.
+ * @returns A Promise containing the requested table of contents.
+ *
+ */
+ getTableOfContents(version?: string): angular.IPromise<TocNodeCollection>;
+
+ /**
+ * Get a specitic document by its path.
+ * @param path The path of the document to get.
+ * @returns A Promise containing the requested document.
+ *
+ */
+ getDocument(path: string): angular.IPromise<{ basePath: string, document: string }>;
+}
+
+class Helpservice implements IHelpService {
+
+ private tocNodeCollection: TocNodeCollection;
+ private documents: { [path: string]: { basePath: string, document: string } };
+
+ constructor(private $q: angular.IQService, private $http: angular.IHttpService, private env: IEnv) {
+ this.tocNodeCollection = null;
+ this.documents = {};
+ }
+
+ public getTableOfContents(): angular.IPromise<TocNodeCollection> {
+ if (this.tocNodeCollection) {
+ return this.$q.resolve(this.tocNodeCollection);
+ }
+
+ return this.$http({
+ method: "GET",
+ url: `${this.env.getBaseURL('MD_SAL')}/help/?meta`
+ }).then((result: angular.IHttpResponse<TocNodeCollection>) => {
+ if (result.status === 200) {
+ this.tocNodeCollection = result.data;
+ return result.data;
+ }
+ });
+ }
+
+ public getDocument(path: string): angular.IPromise<{basePath: string, document: string}> {
+ if (this.documents[path] != null) {
+ return this.$q.resolve(this.documents[path]);
+ }
+
+ return this.$http({
+ method: "GET",
+ url: `${this.env.getBaseURL('MD_SAL')}/help/${path}`
+ }).then((result: angular.IHttpResponse<string>) => {
+ if (result.status === 200) {
+ return this.documents[path] = {
+ basePath: result.config && result.config.url && result.config.url,
+ document: result.data
+ };
+ }
+ });
+
+ }
+}
+
+help.service('helpService', ['$q', '$http', 'ENV', Helpservice]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tpl.html
new file mode 100644
index 00000000..6c2970c8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tpl.html
@@ -0,0 +1,17 @@
+<ht-header help-link='sdnr/0.4.0/README.md'></ht-header>
+
+<div class="app-help">
+
+ <div class="toc col-sm-12 col-md-2">
+ <tree root-node= "vm.toc" >
+ <a href="{{rootNode.href}}" >{{ rootNode.label }}</a>
+ </tree>
+ </div>
+
+ <div markdown-it="vm.content" class="help col-sm-12 col-md-10" ></div>
+
+</div>
+<hr class="col-sm-12"/>
+<div class="owl col-sm-12">
+ <span class="white">ONAP SDN-R | ONF Wireless - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.html
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.html
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.ts
new file mode 100644
index 00000000..3d142804
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.tree.ts
@@ -0,0 +1,55 @@
+import * as angular from 'angularAMD';
+
+export interface Node {
+ label?: string,
+ nodes?: Node[],
+ versions?: {
+ [version: string]: {
+ label: string,
+ date: string,
+ path: string
+ }
+ }
+}
+
+const help = angular.module('app.help');
+
+// class HelpTreeController implements ng.IController {
+// constructor(private $scope: ng.IScope & { rootNode: Node, data: Node[]}) {
+// $scope.$watch("rootNode", (n, o) => {
+// $scope.data = Object.keys($scope.rootNode).map(key => $scope.rootNode[key]);
+// });
+// }
+// }
+
+// help.controller("treeCtrl", ["$scope", HelpTreeController]);
+
+const helpTree = function ($compile) {
+ return {
+ restrict: "E",
+ transclude: true,
+ scope: { rootNode: '=' },
+ //controller: 'treeCtrl',
+ template:
+ '<ul>' +
+ '<li ng-transclude></li>' +
+ '<li ng-repeat="child in rootNode.nodes">' +
+ '<tree root-node="child"><div ng-transclude></div></tree>' +
+ '</li>' +
+ '</ul>',
+ compile: function (tElement, tAttr, transclude) {
+ var contents = tElement.contents().remove();
+ var compiledContents;
+ return function (scope, iElement, iAttr) {
+ if (!compiledContents) {
+ compiledContents = $compile(contents, transclude);
+ }
+ compiledContents(scope, function (clone, scope) {
+ iElement.append(clone);
+ });
+ };
+ }
+ };
+};
+
+help.directive("tree", ["$compile", helpTree]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.utilities.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.utilities.ts
new file mode 100644
index 00000000..ec34b624
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/help.utilities.ts
@@ -0,0 +1,63 @@
+export var resolvePath = function (...paths: string[]): string {
+ console.log(paths);
+ function resolve(pathA, pathB) {
+ // ‘a’ => ['a']
+ // 'a/b' => ['a', 'b']
+ // '/a/b' => ['', 'a', 'b']
+ // '/a/b/' => ['', 'a', 'b', '']
+ pathB = pathB.split('/');
+ if (pathB[0] === '') {
+ return pathB.join('/');
+ }
+ pathA = pathA.split('/');
+ var aLastIndex = pathA.length - 1;
+ if (pathA[aLastIndex] !== '') {
+ pathA[aLastIndex] = '';
+ }
+
+ var part;
+ var i = 0;
+ while (typeof (part = pathB[i]) === 'string') {
+ switch (part) {
+ case '..':
+ pathA.pop();
+ pathA.pop();
+ pathA.push('');
+ break;
+ case '.':
+ pathA.pop();
+ pathA.push('');
+ break;
+ default:
+ pathA.pop();
+ pathA.push(part);
+ pathA.push('');
+ break;
+ }
+ i++;
+ }
+ if (pathB[pathB.length - 1] !== '') pathA.pop();
+ return pathA.join('/');
+ }
+
+ var i = 0;
+ var path;
+ var r = location.pathname;
+
+ const urlRegex = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i;
+ const multiSlashReg = /\/\/+/g;
+
+ while (typeof (path = paths[i]) === 'string') {
+ // debugger;
+ const matches = path && path.match(urlRegex);
+ if (matches || !i) {
+ r = path;
+ } else {
+ path = path.replace(multiSlashReg, '/');
+ r = resolve(r, path);
+ }
+ i++;
+ }
+
+ return r;
+}; \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/images/help.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/images/help.png
new file mode 100755
index 00000000..5ca1f1cc
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/images/help.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.d.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.d.ts
new file mode 100644
index 00000000..74a11ae8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.d.ts
@@ -0,0 +1,284 @@
+// Type definitions for Marked 0.3
+// Project: https://github.com/chjj/marked
+// Definitions by: William Orr <https://github.com/worr>
+// BendingBender <https://github.com/BendingBender>
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+declare var marked : marked.markedStatic;
+
+export as namespace marked;
+
+export = marked;
+
+declare namespace marked {
+ /**
+ * Compiles markdown to HTML.
+ *
+ * @param src String of markdown source to be compiled
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
+ * @return String of compiled HTML
+ */
+ function markedStatic(src: string, callback: (error: any | undefined, parseResult: string) => void): string;
+
+ /**
+ * Compiles markdown to HTML.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
+ * @return String of compiled HTML
+ */
+ function markedStatic(src: string, options?: marked.MarkedOptions, callback?: (error: any | undefined, parseResult: string) => void): string;
+
+ /**
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ */
+ function lexer(src: string, options?: MarkedOptions): TokensList;
+
+ /**
+ * Compiles markdown to HTML.
+ *
+ * @param src String of markdown source to be compiled
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
+ * @return String of compiled HTML
+ */
+ function parse(src: string, callback: (error: any | undefined, parseResult: string) => void): string;
+
+ /**
+ * Compiles markdown to HTML.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
+ * @return String of compiled HTML
+ */
+ function parse(src: string, options?: MarkedOptions, callback?: (error: any | undefined, parseResult: string) => void): string;
+
+ /**
+ * @param src Tokenized source as array of tokens
+ * @param options Hash of options
+ */
+ function parser(src: TokensList, options?: MarkedOptions): string;
+
+ /**
+ * Sets the default options.
+ *
+ * @param options Hash of options
+ */
+ function setOptions(options: MarkedOptions): typeof marked;
+
+ class Renderer {
+ constructor(options?: MarkedOptions);
+ code(code: string, language: string, isEscaped: boolean): string;
+ blockquote(quote: string): string;
+ html(html: string): string;
+ heading(text: string, level: number, raw: string): string;
+ hr(): string;
+ list(body: string, ordered: boolean): string;
+ listitem(text: string): string;
+ paragraph(text: string): string;
+ table(header: string, body: string): string;
+ tablerow(content: string): string;
+ tablecell(content: string, flags: {
+ header: boolean;
+ align: 'center' | 'left' | 'right' | null;
+ }): string;
+ strong(text: string): string;
+ em(text: string): string;
+ codespan(code: string): string;
+ br(): string;
+ del(text: string): string;
+ link(href: string, title: string, text: string): string;
+ image(href: string, title: string, text: string): string;
+ text(text: string): string;
+ }
+
+ class Lexer {
+ rules: Rules;
+ tokens: TokensList;
+ constructor(options?: MarkedOptions);
+ lex(src: string): TokensList;
+ }
+
+ interface Rules {
+ [ruleName: string]: RegExp | Rules;
+ }
+
+ type TokensList = Token[] & {
+ links: {
+ [key: string]: { href: string; title: string; }
+ }
+ };
+
+ type Token =
+ Tokens.Space
+ | Tokens.Code
+ | Tokens.Heading
+ | Tokens.Table
+ | Tokens.Hr
+ | Tokens.BlockquoteStart
+ | Tokens.BlockquoteEnd
+ | Tokens.ListStart
+ | Tokens.LooseItemStart
+ | Tokens.ListItemStart
+ | Tokens.ListItemEnd
+ | Tokens.ListEnd
+ | Tokens.Paragraph
+ | Tokens.HTML
+ | Tokens.Text;
+
+ namespace Tokens {
+ interface Space {
+ type: 'space';
+ }
+
+ interface Code {
+ type: 'code';
+ lang?: string;
+ text: string;
+ }
+
+ interface Heading {
+ type: 'heading';
+ depth: number;
+ text: string;
+ }
+
+ interface Table {
+ type: 'table';
+ header: string[];
+ align: Array<'center' | 'left' | 'right' | null>;
+ cells: string[][];
+ }
+
+ interface Hr {
+ type: 'hr';
+ }
+
+ interface BlockquoteStart {
+ type: 'blockquote_start';
+ }
+
+ interface BlockquoteEnd {
+ type: 'blockquote_end';
+ }
+
+ interface ListStart {
+ type: 'list_start';
+ ordered: boolean;
+ }
+
+ interface LooseItemStart {
+ type: 'loose_item_start';
+ }
+
+ interface ListItemStart {
+ type: 'list_item_start';
+ }
+
+ interface ListItemEnd {
+ type: 'list_item_end';
+ }
+
+ interface ListEnd {
+ type: 'list_end';
+ }
+
+ interface Paragraph {
+ type: 'paragraph';
+ pre?: boolean;
+ text: string;
+ }
+
+ interface HTML {
+ type: 'html';
+ pre: boolean;
+ text: string;
+ }
+
+ interface Text {
+ type: 'text';
+ text: string;
+ }
+ }
+
+ interface MarkedOptions {
+ /**
+ * Type: object Default: new Renderer()
+ *
+ * An object containing functions to render tokens to HTML.
+ */
+ renderer?: Renderer;
+
+ /**
+ * Enable GitHub flavored markdown.
+ */
+ gfm?: boolean;
+
+ /**
+ * Enable GFM tables. This option requires the gfm option to be true.
+ */
+ tables?: boolean;
+
+ /**
+ * Enable GFM line breaks. This option requires the gfm option to be true.
+ */
+ breaks?: boolean;
+
+ /**
+ * Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
+ */
+ pedantic?: boolean;
+
+ /**
+ * Sanitize the output. Ignore any HTML that has been input.
+ */
+ sanitize?: boolean;
+
+ /**
+ * Optionally sanitize found HTML with a sanitizer function.
+ */
+ sanitizer?(html: string): string;
+
+ /**
+ * Mangle autolinks (<email@domain.com>).
+ */
+ mangle?: boolean;
+
+ /**
+ * Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.
+ */
+ smartLists?: boolean;
+
+ /**
+ * Shows an HTML error message when rendering fails.
+ */
+ silent?: boolean;
+
+ /**
+ * A function to highlight code blocks. The function takes three arguments: code, lang, and callback.
+ */
+ highlight?(code: string, lang: string, callback?: (error: any | undefined, code: string) => void): string;
+
+ /**
+ * Set the prefix for code block classes.
+ */
+ langPrefix?: string;
+
+ /**
+ * Use "smart" typograhic punctuation for things like quotes and dashes.
+ */
+ smartypants?: boolean;
+
+ /**
+ * Set the prefix for header tag ids.
+ */
+ headerPrefix?: string;
+
+ /**
+ * Generate closing slash for self-closing tags (<br/> instead of <br>)
+ */
+ xhtml?: boolean;
+ }
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.js
new file mode 100644
index 00000000..04386a6c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/help-module/src/main/resources/help/lib/marked.js
@@ -0,0 +1,1320 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+; (function () {
+ 'use strict';
+
+ /**
+ * Block-Level Grammar
+ */
+
+ var block = {
+ newline: /^\n+/,
+ code: /^( {4}[^\n]+\n*)+/,
+ fences: noop,
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+ nptable: noop,
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
+ blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
+ list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+ html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+ table: noop,
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+ text: /^[^\n]+/
+ };
+
+ block.bullet = /(?:[*+-]|\d+\.)/;
+ block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+ block.item = replace(block.item, 'gm')
+ (/bull/g, block.bullet)
+ ();
+
+ block.list = replace(block.list)
+ (/bull/g, block.bullet)
+ ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
+ ('def', '\\n+(?=' + block.def.source + ')')
+ ();
+
+ block.blockquote = replace(block.blockquote)
+ ('def', block.def)
+ ();
+
+ block._tag = '(?!(?:'
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
+
+ block.html = replace(block.html)
+ ('comment', /<!--[\s\S]*?-->/)
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
+ (/tag/g, block._tag)
+ ();
+
+ block.paragraph = replace(block.paragraph)
+ ('hr', block.hr)
+ ('heading', block.heading)
+ ('lheading', block.lheading)
+ ('blockquote', block.blockquote)
+ ('tag', '<' + block._tag)
+ ('def', block.def)
+ ();
+
+ /**
+ * Normal Block Grammar
+ */
+
+ block.normal = merge({}, block);
+
+ /**
+ * GFM Block Grammar
+ */
+
+ block.gfm = merge({}, block.normal, {
+ fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
+ paragraph: /^/,
+ heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
+ });
+
+ block.gfm.paragraph = replace(block.paragraph)
+ ('(?!', '(?!'
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
+ + block.list.source.replace('\\1', '\\3') + '|')
+ ();
+
+ /**
+ * GFM + Tables Block Grammar
+ */
+
+ block.tables = merge({}, block.gfm, {
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
+ });
+
+ /**
+ * Block Lexer
+ */
+
+ function Lexer(options) {
+ this.tokens = [];
+ this.tokens.links = {};
+ this.options = options || marked.defaults;
+ this.rules = block.normal;
+
+ if (this.options.gfm) {
+ if (this.options.tables) {
+ this.rules = block.tables;
+ } else {
+ this.rules = block.gfm;
+ }
+ }
+ }
+
+ /**
+ * Expose Block Rules
+ */
+
+ Lexer.rules = block;
+
+ /**
+ * Static Lex Method
+ */
+
+ Lexer.lex = function (src, options) {
+ var lexer = new Lexer(options);
+ return lexer.lex(src);
+ };
+
+ /**
+ * Preprocessing
+ */
+
+ Lexer.prototype.lex = function (src) {
+ src = src
+ .replace(/\r\n|\r/g, '\n')
+ .replace(/\t/g, ' ')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\u2424/g, '\n');
+
+ return this.token(src, true);
+ };
+
+ /**
+ * Lexing
+ */
+
+ Lexer.prototype.token = function (src, top, bq) {
+ var src = src.replace(/^ +$/gm, '')
+ , next
+ , loose
+ , cap
+ , bull
+ , b
+ , item
+ , space
+ , i
+ , l;
+
+ while (src) {
+ // newline
+ if (cap = this.rules.newline.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[0].length > 1) {
+ this.tokens.push({
+ type: 'space'
+ });
+ }
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ cap = cap[0].replace(/^ {4}/gm, '');
+ this.tokens.push({
+ type: 'code',
+ text: !this.options.pedantic
+ ? cap.replace(/\n+$/, '')
+ : cap
+ });
+ continue;
+ }
+
+ // fences (gfm)
+ if (cap = this.rules.fences.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'code',
+ lang: cap[2],
+ text: cap[3] || ''
+ });
+ continue;
+ }
+
+ // heading
+ if (cap = this.rules.heading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[1].length,
+ text: cap[2]
+ });
+ continue;
+ }
+
+ // table no leading pipe (gfm)
+ if (top && (cap = this.rules.nptable.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i].split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // lheading
+ if (cap = this.rules.lheading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[2] === '=' ? 1 : 2,
+ text: cap[1]
+ });
+ continue;
+ }
+
+ // hr
+ if (cap = this.rules.hr.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'hr'
+ });
+ continue;
+ }
+
+ // blockquote
+ if (cap = this.rules.blockquote.exec(src)) {
+ src = src.substring(cap[0].length);
+
+ this.tokens.push({
+ type: 'blockquote_start'
+ });
+
+ cap = cap[0].replace(/^ *> ?/gm, '');
+
+ // Pass `top` to keep the current
+ // "toplevel" state. This is exactly
+ // how markdown.pl works.
+ this.token(cap, top, true);
+
+ this.tokens.push({
+ type: 'blockquote_end'
+ });
+
+ continue;
+ }
+
+ // list
+ if (cap = this.rules.list.exec(src)) {
+ src = src.substring(cap[0].length);
+ bull = cap[2];
+
+ this.tokens.push({
+ type: 'list_start',
+ ordered: bull.length > 1
+ });
+
+ // Get each top-level item.
+ cap = cap[0].match(this.rules.item);
+
+ next = false;
+ l = cap.length;
+ i = 0;
+
+ for (; i < l; i++) {
+ item = cap[i];
+
+ // Remove the list item's bullet
+ // so it is seen as the next token.
+ space = item.length;
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
+
+ // Outdent whatever the
+ // list item contains. Hacky.
+ if (~item.indexOf('\n ')) {
+ space -= item.length;
+ item = !this.options.pedantic
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
+ : item.replace(/^ {1,4}/gm, '');
+ }
+
+ // Determine whether the next list item belongs here.
+ // Backpedal if it does not belong in this list.
+ if (this.options.smartLists && i !== l - 1) {
+ b = block.bullet.exec(cap[i + 1]) [0];
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+ src = cap.slice(i + 1).join('\n') + src;
+ i = l - 1;
+ }
+ }
+
+ // Determine whether item is loose or not.
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+ // for discount behavior.
+ loose = next || /\n\n(?!\s*$)/.test(item);
+ if (i !== l - 1) {
+ next = item.charAt(item.length - 1) === '\n';
+ if (!loose) loose = next;
+ }
+
+ this.tokens.push({
+ type: loose
+ ? 'loose_item_start'
+ : 'list_item_start'
+ });
+
+ // Recurse.
+ this.token(item, false, bq);
+
+ this.tokens.push({
+ type: 'list_item_end'
+ });
+ }
+
+ this.tokens.push({
+ type: 'list_end'
+ });
+
+ continue;
+ }
+
+ // html
+ if (cap = this.rules.html.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: this.options.sanitize
+ ? 'paragraph'
+ : 'html',
+ pre: !this.options.sanitizer
+ && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
+ text: cap[0]
+ });
+ continue;
+ }
+
+ // def
+ if ((!bq && top) && (cap = this.rules.def.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.links[cap[1].toLowerCase()] = {
+ href: cap[2],
+ title: cap[3]
+ };
+ continue;
+ }
+
+ // table (gfm)
+ if (top && (cap = this.rules.table.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i]
+ .replace(/^ *\| *| *\| *$/g, '')
+ .split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // top-level paragraph
+ if (top && (cap = this.rules.paragraph.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'paragraph',
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
+ ? cap[1].slice(0, -1)
+ : cap[1]
+ });
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ // Top-level should never reach here.
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'text',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return this.tokens;
+ };
+
+ /**
+ * Inline-Level Grammar
+ */
+
+ var inline = {
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+ autolink: /^<([^ <>]+(@|:\/)[^ <>]+)>/,
+ url: noop,
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,
+ link: /^!?\[(inside)\]\(href\)/,
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+ em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+ code: /^(`+)([\s\S]*?[^`])\1(?!`)/,
+ br: /^ {2,}\n(?!\s*$)/,
+ del: noop,
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
+ };
+
+ inline._inside = /(?:\[[^\]]*\]|\\[\[\]]|[^\[\]]|\](?=[^\[]*\]))*/;
+ inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+ inline.link = replace(inline.link)
+ ('inside', inline._inside)
+ ('href', inline._href)
+ ();
+
+ inline.reflink = replace(inline.reflink)
+ ('inside', inline._inside)
+ ();
+
+ /**
+ * Normal Inline Grammar
+ */
+
+ inline.normal = merge({}, inline);
+
+ /**
+ * Pedantic Inline Grammar
+ */
+
+ inline.pedantic = merge({}, inline.normal, {
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
+ });
+
+ /**
+ * GFM Inline Grammar
+ */
+
+ inline.gfm = merge({}, inline.normal, {
+ escape: replace(inline.escape)('])', '~|])')(),
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
+ text: replace(inline.text)
+ (']|', '~]|')
+ ('|', '|https?://|')
+ ()
+ });
+
+ /**
+ * GFM + Line Breaks Inline Grammar
+ */
+
+ inline.breaks = merge({}, inline.gfm, {
+ br: replace(inline.br)('{2,}', '*')(),
+ text: replace(inline.gfm.text)('{2,}', '*')()
+ });
+
+ /**
+ * Inline Lexer & Compiler
+ */
+
+ function InlineLexer(links, options) {
+ this.options = options || marked.defaults;
+ this.links = links;
+ this.rules = inline.normal;
+ this.renderer = this.options.renderer || new Renderer;
+ this.renderer.options = this.options;
+
+ if (!this.links) {
+ throw new
+ Error('Tokens array requires a `links` property.');
+ }
+
+ if (this.options.gfm) {
+ if (this.options.breaks) {
+ this.rules = inline.breaks;
+ } else {
+ this.rules = inline.gfm;
+ }
+ } else if (this.options.pedantic) {
+ this.rules = inline.pedantic;
+ }
+ }
+
+ /**
+ * Expose Inline Rules
+ */
+
+ InlineLexer.rules = inline;
+
+ /**
+ * Static Lexing/Compiling Method
+ */
+
+ InlineLexer.output = function (src, links, options) {
+ var inline = new InlineLexer(links, options);
+ return inline.output(src);
+ };
+
+ /**
+ * Lexing/Compiling
+ */
+
+ InlineLexer.prototype.output = function (src) {
+ var out = ''
+ , link
+ , text
+ , href
+ , cap;
+
+ while (src) {
+ // escape
+ if (cap = this.rules.escape.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += cap[1];
+ continue;
+ }
+
+ // autolink
+ if (cap = this.rules.autolink.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[2] === '@') {
+ text = escape(
+ cap[1].charAt(6) === ':'
+ ? this.mangle(cap[1].substring(7))
+ : this.mangle(cap[1])
+ );
+ href = this.mangle('mailto:') + text;
+ } else {
+ text = escape(cap[1]);
+ href = text;
+ }
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // url (gfm)
+ if (!this.inLink && (cap = this.rules.url.exec(src))) {
+ src = src.substring(cap[0].length);
+ text = escape(cap[1]);
+ href = text;
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // tag
+ if (cap = this.rules.tag.exec(src)) {
+ if (!this.inLink && /^<a /i.test(cap[0])) {
+ this.inLink = true;
+ } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
+ this.inLink = false;
+ }
+ src = src.substring(cap[0].length);
+ out += this.options.sanitize
+ ? this.options.sanitizer
+ ? this.options.sanitizer(cap[0])
+ : escape(cap[0])
+ : cap[0]
+ continue;
+ }
+
+ // link
+ if (cap = this.rules.link.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.inLink = true;
+ out += this.outputLink(cap, {
+ href: cap[2],
+ title: cap[3]
+ });
+ this.inLink = false;
+ continue;
+ }
+
+ // reflink, nolink
+ if ((cap = this.rules.reflink.exec(src))
+ || (cap = this.rules.nolink.exec(src))) {
+ src = src.substring(cap[0].length);
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+ link = this.links[link.toLowerCase()];
+ if (!link || !link.href) {
+ out += cap[0].charAt(0);
+ src = cap[0].substring(1) + src;
+ continue;
+ }
+ this.inLink = true;
+ out += this.outputLink(cap, link);
+ this.inLink = false;
+ continue;
+ }
+
+ // strong
+ if (cap = this.rules.strong.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // em
+ if (cap = this.rules.em.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.codespan(escape(cap[2].trim(), true));
+ continue;
+ }
+
+ // br
+ if (cap = this.rules.br.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.br();
+ continue;
+ }
+
+ // del (gfm)
+ if (cap = this.rules.del.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.del(this.output(cap[1]));
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.text(escape(this.smartypants(cap[0])));
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return out;
+ };
+
+ /**
+ * Compile Link
+ */
+
+ InlineLexer.prototype.outputLink = function (cap, link) {
+ var href = escape(link.href)
+ , title = link.title ? escape(link.title) : null;
+
+ return cap[0].charAt(0) !== '!'
+ ? this.renderer.link(href, title, this.output(cap[1]))
+ : this.renderer.image(href, title, escape(cap[1]));
+ };
+
+ /**
+ * Smartypants Transformations
+ */
+
+ InlineLexer.prototype.smartypants = function (text) {
+ if (!this.options.smartypants) return text;
+ return text
+ // em-dashes
+ .replace(/---/g, '\u2014')
+ // en-dashes
+ .replace(/--/g, '\u2013')
+ // opening singles
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+ // closing singles & apostrophes
+ .replace(/'/g, '\u2019')
+ // opening doubles
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+ // closing doubles
+ .replace(/"/g, '\u201d')
+ // ellipses
+ .replace(/\.{3}/g, '\u2026');
+ };
+
+ /**
+ * Mangle Links
+ */
+
+ InlineLexer.prototype.mangle = function (text) {
+ if (!this.options.mangle) return text;
+ var out = ''
+ , l = text.length
+ , i = 0
+ , ch;
+
+ for (; i < l; i++) {
+ ch = text.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = 'x' + ch.toString(16);
+ }
+ out += '&#' + ch + ';';
+ }
+
+ return out;
+ };
+
+ /**
+ * Renderer
+ */
+
+ function Renderer(options) {
+ this.options = options || {};
+ }
+
+ Renderer.prototype.code = function (code, lang, escaped) {
+ if (this.options.highlight) {
+ var out = this.options.highlight(code, lang);
+ if (out != null && out !== code) {
+ escaped = true;
+ code = out;
+ }
+ }
+
+ if (!lang) {
+ return '<pre><code>'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>';
+ }
+
+ return '<pre><code class="'
+ + this.options.langPrefix
+ + escape(lang, true)
+ + '">'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>\n';
+ };
+
+ Renderer.prototype.blockquote = function (quote) {
+ return '<blockquote>\n' + quote + '</blockquote>\n';
+ };
+
+ Renderer.prototype.html = function (html) {
+ return html;
+ };
+
+ Renderer.prototype.heading = function (text, level, raw) {
+ return '<h'
+ + level
+ + ' id="'
+ + this.options.headerPrefix
+ + raw.toLowerCase().replace(/[^\w]+/g, '-')
+ + '">'
+ + text
+ + '</h'
+ + level
+ + '>\n';
+ };
+
+ Renderer.prototype.hr = function () {
+ return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+ };
+
+ Renderer.prototype.list = function (body, ordered) {
+ var type = ordered ? 'ol' : 'ul';
+ return '<' + type + '>\n' + body + '</' + type + '>\n';
+ };
+
+ Renderer.prototype.listitem = function (text) {
+ return '<li>' + text + '</li>\n';
+ };
+
+ Renderer.prototype.paragraph = function (text) {
+ return '<p>' + text + '</p>\n';
+ };
+
+ Renderer.prototype.table = function (header, body) {
+ return '<table>\n'
+ + '<thead>\n'
+ + header
+ + '</thead>\n'
+ + '<tbody>\n'
+ + body
+ + '</tbody>\n'
+ + '</table>\n';
+ };
+
+ Renderer.prototype.tablerow = function (content) {
+ return '<tr>\n' + content + '</tr>\n';
+ };
+
+ Renderer.prototype.tablecell = function (content, flags) {
+ var type = flags.header ? 'th' : 'td';
+ var tag = flags.align
+ ? '<' + type + ' style="text-align:' + flags.align + '">'
+ : '<' + type + '>';
+ return tag + content + '</' + type + '>\n';
+ };
+
+ // span level renderer
+ Renderer.prototype.strong = function (text) {
+ return '<strong>' + text + '</strong>';
+ };
+
+ Renderer.prototype.em = function (text) {
+ return '<em>' + text + '</em>';
+ };
+
+ Renderer.prototype.codespan = function (text) {
+ return '<code>' + text + '</code>';
+ };
+
+ Renderer.prototype.br = function () {
+ return this.options.xhtml ? '<br/>' : '<br>';
+ };
+
+ Renderer.prototype.del = function (text) {
+ return '<del>' + text + '</del>';
+ };
+
+ Renderer.prototype.link = function (href, title, text) {
+ if (this.options.sanitize) {
+ try {
+ var prot = decodeURIComponent(unescape(href))
+ .replace(/[^\w:]/g, '')
+ .toLowerCase();
+ } catch (e) {
+ return text;
+ }
+ if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
+ return text;
+ }
+ }
+ if (this.options.baseUrl && !originIndependentUrl.test(href)) {
+ href = resolveUrl(this.options.baseUrl, href);
+ }
+ var out = '<a href="' + href + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += '>' + text + '</a>';
+ return out;
+ };
+
+ Renderer.prototype.image = function (href, title, text) {
+ if (this.options.baseUrl && !originIndependentUrl.test(href)) {
+ href = resolveUrl(this.options.baseUrl, href);
+ }
+ var out = '<img src="' + href + '" alt="' + text + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += this.options.xhtml ? '/>' : '>';
+ return out;
+ };
+
+ Renderer.prototype.text = function (text) {
+ return text;
+ };
+
+ /**
+ * Parsing & Compiling
+ */
+
+ function Parser(options) {
+ this.tokens = [];
+ this.token = null;
+ this.options = options || marked.defaults;
+ this.options.renderer = this.options.renderer || new Renderer;
+ this.renderer = this.options.renderer;
+ this.renderer.options = this.options;
+ }
+
+ /**
+ * Static Parse Method
+ */
+
+ Parser.parse = function (src, options, renderer) {
+ var parser = new Parser(options, renderer);
+ return parser.parse(src);
+ };
+
+ /**
+ * Parse Loop
+ */
+
+ Parser.prototype.parse = function (src) {
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
+ this.tokens = src.reverse();
+
+ var out = '';
+ while (this.next()) {
+ out += this.tok();
+ }
+
+ return out;
+ };
+
+ /**
+ * Next Token
+ */
+
+ Parser.prototype.next = function () {
+ return this.token = this.tokens.pop();
+ };
+
+ /**
+ * Preview Next Token
+ */
+
+ Parser.prototype.peek = function () {
+ return this.tokens[this.tokens.length - 1] || 0;
+ };
+
+ /**
+ * Parse Text Tokens
+ */
+
+ Parser.prototype.parseText = function () {
+ var body = this.token.text;
+
+ while (this.peek().type === 'text') {
+ body += '\n' + this.next().text;
+ }
+
+ return this.inline.output(body);
+ };
+
+ /**
+ * Parse Current Token
+ */
+
+ Parser.prototype.tok = function () {
+ switch (this.token.type) {
+ case 'space': {
+ return '';
+ }
+ case 'hr': {
+ return this.renderer.hr();
+ }
+ case 'heading': {
+ return this.renderer.heading(
+ this.inline.output(this.token.text),
+ this.token.depth,
+ this.token.text);
+ }
+ case 'code': {
+ return this.renderer.code(this.token.text,
+ this.token.lang,
+ this.token.escaped);
+ }
+ case 'table': {
+ var header = ''
+ , body = ''
+ , i
+ , row
+ , cell
+ , flags
+ , j;
+
+ // header
+ cell = '';
+ for (i = 0; i < this.token.header.length; i++) {
+ flags = { header: true, align: this.token.align[i] };
+ cell += this.renderer.tablecell(
+ this.inline.output(this.token.header[i]),
+ { header: true, align: this.token.align[i] }
+ );
+ }
+ header += this.renderer.tablerow(cell);
+
+ for (i = 0; i < this.token.cells.length; i++) {
+ row = this.token.cells[i];
+
+ cell = '';
+ for (j = 0; j < row.length; j++) {
+ cell += this.renderer.tablecell(
+ this.inline.output(row[j]),
+ { header: false, align: this.token.align[j] }
+ );
+ }
+
+ body += this.renderer.tablerow(cell);
+ }
+ return this.renderer.table(header, body);
+ }
+ case 'blockquote_start': {
+ var body = '';
+
+ while (this.next().type !== 'blockquote_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.blockquote(body);
+ }
+ case 'list_start': {
+ var body = ''
+ , ordered = this.token.ordered;
+
+ while (this.next().type !== 'list_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.list(body, ordered);
+ }
+ case 'list_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.token.type === 'text'
+ ? this.parseText()
+ : this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'loose_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'html': {
+ var html = !this.token.pre && !this.options.pedantic
+ ? this.inline.output(this.token.text)
+ : this.token.text;
+ return this.renderer.html(html);
+ }
+ case 'paragraph': {
+ return this.renderer.paragraph(this.inline.output(this.token.text));
+ }
+ case 'text': {
+ return this.renderer.paragraph(this.parseText());
+ }
+ }
+ };
+
+ /**
+ * Helpers
+ */
+
+ function escape(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;')
+ .replace(/'/g, '&#39;');
+ }
+
+ function unescape(html) {
+ // explicitly match decimal, hex, and named HTML entities
+ return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function (_, n) {
+ n = n.toLowerCase();
+ if (n === 'colon') return ':';
+ if (n.charAt(0) === '#') {
+ return n.charAt(1) === 'x'
+ ? String.fromCharCode(parseInt(n.substring(2), 16))
+ : String.fromCharCode(+n.substring(1));
+ }
+ return '';
+ });
+ }
+
+ function replace(regex, opt) {
+ regex = regex.source;
+ opt = opt || '';
+ return function self(name, val) {
+ if (!name) return new RegExp(regex, opt);
+ val = val.source || val;
+ val = val.replace(/(^|[^\[])\^/g, '$1');
+ regex = regex.replace(name, val);
+ return self;
+ };
+ }
+
+ function resolveUrl(base, href) {
+ if (!baseUrls[' ' + base]) {
+ // we can ignore everything in base after the last slash of its path component,
+ // but we might need to add _that_
+ // https://tools.ietf.org/html/rfc3986#section-3
+ if (/^[^:]+:\/*[^/]*$/.test(base)) {
+ baseUrls[' ' + base] = base + '/';
+ } else {
+ baseUrls[' ' + base] = base.replace(/[^/]*$/, '');
+ }
+ }
+ base = baseUrls[' ' + base];
+
+ if (href.slice(0, 2) === '//') {
+ return base.replace(/:[\s\S]*/, ':') + href;
+ } else if (href.charAt(0) === '/') {
+ return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
+ } else {
+ return base + href;
+ }
+ }
+ var baseUrls = {};
+ var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
+
+ function noop() { }
+ noop.exec = noop;
+
+ function merge(obj) {
+ var i = 1
+ , target
+ , key;
+
+ for (; i < arguments.length; i++) {
+ target = arguments[i];
+ for (key in target) {
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
+ obj[key] = target[key];
+ }
+ }
+ }
+
+ return obj;
+ }
+
+
+ /**
+ * Marked
+ */
+
+ function marked(src, opt, callback) {
+ if (callback || typeof opt === 'function') {
+ if (!callback) {
+ callback = opt;
+ opt = null;
+ }
+
+ opt = merge({}, marked.defaults, opt || {});
+
+ var highlight = opt.highlight
+ , tokens
+ , pending
+ , i = 0;
+
+ try {
+ tokens = Lexer.lex(src, opt)
+ } catch (e) {
+ return callback(e);
+ }
+
+ pending = tokens.length;
+
+ var done = function (err) {
+ if (err) {
+ opt.highlight = highlight;
+ return callback(err);
+ }
+
+ var out;
+
+ try {
+ out = Parser.parse(tokens, opt);
+ } catch (e) {
+ err = e;
+ }
+
+ opt.highlight = highlight;
+
+ return err
+ ? callback(err)
+ : callback(null, out);
+ };
+
+ if (!highlight || highlight.length < 3) {
+ return done();
+ }
+
+ delete opt.highlight;
+
+ if (!pending) return done();
+
+ for (; i < tokens.length; i++) {
+ (function (token) {
+ if (token.type !== 'code') {
+ return --pending || done();
+ }
+ return highlight(token.text, token.lang, function (err, code) {
+ if (err) return done(err);
+ if (code == null || code === token.text) {
+ return --pending || done();
+ }
+ token.text = code;
+ token.escaped = true;
+ --pending || done();
+ });
+ })(tokens[i]);
+ }
+
+ return;
+ }
+ try {
+ if (opt) opt = merge({}, marked.defaults, opt);
+ return Parser.parse(Lexer.lex(src, opt), opt);
+ } catch (e) {
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
+ if ((opt || marked.defaults).silent) {
+ return '<p>An error occurred:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Options
+ */
+
+ marked.options =
+ marked.setOptions = function (opt) {
+ merge(marked.defaults, opt);
+ return marked;
+ };
+
+ marked.defaults = {
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ sanitizer: null,
+ mangle: true,
+ smartLists: false,
+ silent: false,
+ highlight: null,
+ langPrefix: 'lang-',
+ smartypants: false,
+ headerPrefix: '',
+ renderer: new Renderer,
+ xhtml: false,
+ baseUrl: null
+ };
+
+ /**
+ * Expose
+ */
+
+ marked.Parser = Parser;
+ marked.parser = Parser.parse;
+
+ marked.Renderer = Renderer;
+
+ marked.Lexer = Lexer;
+ marked.lexer = Lexer.lex;
+
+ marked.InlineLexer = InlineLexer;
+ marked.inlineLexer = InlineLexer.output;
+
+ marked.parse = marked;
+
+ if (typeof module !== 'undefined' && typeof exports === 'object') {
+ module.exports = marked;
+ } else if (typeof define === 'function' && define.amd) {
+ define(function () { return marked; });
+ } else {
+ this.marked = marked;
+ }
+
+}).call(function () {
+ return this || (typeof window !== 'undefined' ? window : global);
+}()); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/help/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/pom.xml
new file mode 100644
index 00000000..91fc77bb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/help/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>help</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>help-module</module>
+ <module>help-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/pom.xml
new file mode 100644
index 00000000..7499a987
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnBrowser</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnBrowser-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnBrowser-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnBrowser-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..383b124b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnBrowser"/>
+ <property name="url" value="/src/app/mwtnBrowser"/>
+ <property name="directory" value="/mwtnBrowser"/>
+ <property name="requireJs" value="app/mwtnBrowser/mwtnBrowser.module"/>
+ <property name="angularJs" value="app.mwtnBrowser"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnBrowser/mwtnBrowser-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/pom.xml
new file mode 100644
index 00000000..7c33ed89
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>mwtnBrowser-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+ <parent>
+ <artifactId>mwtnBrowser</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnBrowser.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnBrowser.png
new file mode 100755
index 00000000..ae596db7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnBrowser.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnConfig.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnConfig.png
new file mode 100755
index 00000000..ae596db7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/images/mwtnConfig.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser-custom.css
new file mode 100644
index 00000000..15c398c1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser-custom.css
@@ -0,0 +1,24 @@
+/**
+ * Add your application related css here
+ */
+
+.json-formatter-row .constructor-name {
+ cursor: pointer;
+ color: #333333;
+}
+
+.json-formatter-row .toggler:after {
+ color: darkgreen;
+ font-weight: bold;
+ display: inline-block;
+ transition: transform .1s ease-in;
+ content: ">"
+}
+
+.owl span.key-text {
+ color: #333333;
+}
+
+.owl span.colon {
+ color: #333333;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.controller.js
new file mode 100644
index 00000000..76d3148d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.controller.js
@@ -0,0 +1,1090 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnBrowser/mwtnBrowser.module',
+ 'app/mwtnBrowser/mwtnBrowser.services'],
+ function(mwtnBrowserApp) {
+
+ 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;
+ };
+
+ mwtnBrowserApp.register.controller('ptpDefaultDsViewController', ['$scope', '$uibModalInstance', '$mwtnGlobal', '$mwtnCommons', '$mwtnDatabase', '$mwtnLog', 'defaultDs',
+ function ($scope, $uibModalInstance, $mwtnGlobal, $mwtnCommons, $mwtnDatabase, $mwtnLog, defaultDs) {
+
+ var vm = this;
+ var COMPONENT = 'ptpDefaultDsViewController';
+ $scope.data = defaultDs;
+
+ $scope.getType = $mwtnGlobal.getType;
+
+
+ $mwtnCommons.getPtpDefaultDs(defaultDs).then(function (success) {
+
+ $scope.configuredData = success;
+ $scope.viewData = $mwtnGlobal.getViewData($scope.configuredData['default-ds']);
+
+ $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;
+ $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['is-read-only'] = schema[key]['is-read-only'];
+ if (schema[key].min) {
+ item.min = schema[key].min;
+ }
+ if (schema[key].max) {
+ item.max = schema[key].max;
+ if (item.unit) {
+ item.unit = schema[key].min + '..' + schema[key].max + ' ' + item.unit;
+ } else {
+ item.unit = schema[key].min + '..' + schema[key].max;
+ }
+ }
+
+
+ item['order-number'] = $mwtnCommons.getOrderNumber(schema[key]['order-number'], item);
+ item.description = schema[key].description;
+ 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 PTP default ds ' + JSON.stringify($scope.data) + ' failed!' });
+ });
+
+ $scope.$watch('viewData', function(newValue, oldValue) {
+ if (oldValue && newValue !== oldValue) {
+ Object.keys(newValue).filter(function(key){
+ return newValue[key]['is-read-only'] !== true && newValue[key].controlType === 'number' ;
+ }).map(function(key){
+ if (newValue[key].value < newValue[key].min) newValue[key].value = newValue[key].min;
+ if (newValue[key].value > newValue[key].max) newValue[key].value = newValue[key].max;
+ if (!newValue[key].value) newValue[key].value = newValue[key].min;
+ });
+ }
+ }, true);
+
+ $scope.newData = {};
+ $scope.ok = function () {
+ $scope.processing = true;
+ $scope.newData = {};
+ Object.keys($scope.viewData).map(function(key){
+ $scope.newData[key] = $scope.viewData[key].value;
+ });
+
+ $mwtnCommons.setPtpDefaultDs($scope.data, $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);
+ };
+
+ // events
+
+
+ }]);
+
+ mwtnBrowserApp.register.controller('ptpPortConfigViewController', ['$scope', '$uibModalInstance', '$mwtnGlobal', '$mwtnCommons', '$mwtnDatabase', '$mwtnLog', 'valueData',
+ function ($scope, $uibModalInstance, $mwtnGlobal, $mwtnCommons, $mwtnDatabase, $mwtnLog, data) {
+
+ var vm = this;
+ var COMPONENT = 'ptpPortConfigViewController';
+
+ $scope.data = data;
+
+ $scope.getType = $mwtnGlobal.getType;
+ console.warn(JSON.stringify(data));
+ $mwtnCommons.getPtpPort(data).then(function (success) {
+
+ $scope.configuredData = success;
+
+ $scope.viewData = $mwtnGlobal.getViewData($scope.configuredData['port-ds-list'][0]);
+ $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;
+ $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;
+ console.warn(key, schema[key]['is-read-only']);
+ item['is-read-only'] = schema[key]['is-read-only'];
+ if (schema[key].min) {
+ item.min = schema[key].min;
+ }
+ if (schema[key].max) {
+ item.max = schema[key].max;
+ if (item.unit) {
+ item.unit = schema[key].min + '..' + schema[key].max + ' ' + item.unit;
+ } else {
+ item.unit = schema[key].min + '..' + schema[key].max;
+ }
+ }
+
+
+ item['order-number'] = $mwtnCommons.getOrderNumber(schema[key]['order-number'], item);
+ item.description = schema[key].description;
+ 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 PTP port ' + JSON.stringify($scope.data) + ' failed!' });
+ });
+
+ $scope.$watch('viewData', function(newValue, oldValue) {
+ if (oldValue && newValue !== oldValue) {
+ Object.keys(newValue).filter(function(key){
+ return newValue[key]['is-read-only'] !== true && newValue[key].controlType === 'number' ;
+ }).map(function(key){
+ if (newValue[key].value < newValue[key].min) newValue[key].value = newValue[key].min;
+ if (newValue[key].value > newValue[key].max) newValue[key].value = newValue[key].max;
+ if (!newValue[key].value) newValue[key].value = newValue[key].min;
+ });
+ }
+ }, true);
+
+ $scope.newData = {};
+ $scope.ok = function () {
+ $scope.processing = true;
+ $scope.newData = {};
+ Object.keys($scope.viewData).map(function(key){
+ $scope.newData[key] = $scope.viewData[key].value;
+ });
+
+ $mwtnCommons.setPtpPort($scope.data, $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);
+ };
+
+ // events
+
+
+ }]);
+
+ mwtnBrowserApp.register.controller('mwtnPtpPortsController', ['$scope', '$filter', '$uibModal', '$mwtnGlobal', '$mwtnCommons', '$mwtnLog',
+ function ($scope, $filter, $uibModal, $mwtnGlobal, $mwtnCommons, $mwtnLog) {
+ var vm = this;
+ var COMPONENT = 'mwtnPtpPortsController';
+
+ $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.ptpPorts = [];
+
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnCommons.gridOptions));
+ $scope.gridOptions.data = 'ptpPorts';
+ $scope.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+
+ // $scope.getTableHeight = function() {
+ // var rowHeight = 30;
+ // var headerHeight = 40;
+ // var maxCount = 12;
+ // var rowCount = $scope.gridOptions.data.length + 2;
+ // if (rowCount > maxCount) {
+ // return {
+ // height: (maxCount * rowHeight + headerHeight) + 'px'
+ // };
+ // }
+ // return {}; // use auto-resize feature
+ // };
+
+ var getCellTemplate = function(field) {
+ var object = ['transmission-mode-list', 'performance-data'];
+ if (object.contains(field)) {
+ return ['<div class="ui-grid-cell-contents">',
+ '<i class="fa fa-info-circle pointer" aria-hidden="true"',
+ ' ng-click="grid.appScope.show(grid.getCellValue(row, col))"></i> ',
+ '{{grid.getCellValue(row, col)}}</div>'].join('');
+ } else if (field === 'action') {
+ return [
+ '<a class="vCenter" ng-class="{attention: grid.appScope.hover, hidden: onfAirInterfaceRevision}" >',
+ ' <i class="fa fa-pencil-square-o pointer" aria-hidden="true" ng-click="grid.appScope.show(row.entity)"></i>',
+ '</a>' ].join('<span>&nbsp;</span>');
+ } else {
+ return '<div class="ui-grid-cell-contents">{{grid.getCellValue(row, col)}}</div>';
+ }
+ };
+
+ $scope.show = function(value){
+ var type = $mwtnGlobal.getType(value);
+ // if (type === 'object')
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnBrowser/templates/ptpPortConfigView.tpl.html',
+ controller: 'ptpPortConfigViewController',
+ size: 'huge',
+ resolve: {
+ valueData: function () {
+ return {networkElement: $scope.networkElement, value:value};
+ }
+ }
+ });
+ modalInstance.result.then(function(object) {
+ console.warn(JSON.stringify(object));
+ $scope.ptpPorts.map(function(row, index){
+ if (row['port-number'] === object['port-number']) {
+ console.log($scope.ptpPorts[index]['onf-ptp-dataset:master-only']);
+ $scope.ptpPorts[index] = object;
+ console.log($scope.ptpPorts[index]['onf-ptp-dataset:master-only']);
+ };
+ });
+ }, function () {
+ // ignore;
+ });
+ };
+
+ 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
+ };
+ });
+ $scope.gridOptions.columnDefs.push({
+ field: 'action',
+ displayName: 'Action',
+ enableSorting: false,
+ enableFiltering: false,
+ headerCellClass: $scope.highlightFilteredHeader,
+ cellTemplate: getCellTemplate('action'),
+ width: 100,
+ visible: true,
+ pinnedRight : true
+
+ });
+ if ($scope.gridOptions.data.length < 10) {
+ $scope.gridOptions.minRowsToShow = data.length; // 10 is default
+ }
+ $scope.ptpPorts = data.map(function(item){
+ item.action = '';
+ return item;
+ });
+ // .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 });
+ }
+ };
+ }]);
+
+ mwtnBrowserApp.register.directive('mwtnPtpPorts', function () {
+ return {
+ restrict: 'E',
+ scope: {
+ data: '=',
+ path: '=',
+ networkElement: '='
+ },
+ controller: 'mwtnPtpPortsController',
+ controllerAs: 'vm',
+ templateUrl: 'src/app/mwtnBrowser/templates/mwtnPtpPorts.tpl.html'
+ };
+ });
+
+ mwtnBrowserApp.register.controller('mwtnPtpClockViewerController', ['$scope', '$timeout', '$uibModal', '$mwtnGlobal', '$mwtnCommons', '$mwtnDatabase', '$mwtnLog', '$mwtnBrowser',
+ function ($scope, $timeout, $uibModal, $mwtnGlobal, $mwtnCommons, $mwtnDatabase, $mwtnLog, $mwtnBrowser) {
+ var vm = this;
+ var COMPONENT = 'mwtnPtpClockViewerController';
+ 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);
+ }
+
+ 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){
+ if ($mwtnGlobal.getType( clone[key].value ) === 'object') {
+ Object.keys(clone[key].value).filter(function(subKey){
+ return subKey.endsWith('-identity');
+ }).map(function(subKey){
+ var clockId = clone[key].value[subKey];
+ if ($mwtnGlobal.getType(clockId) === 'object') {
+ if (clockId['clock-identity']) {
+ var ascii = clockId['clock-identity'].base64ToHex();
+ clone[key].value[subKey]['clock-identity'] = [clone[key].value[subKey]['clock-identity'], '(ascii:', ascii, ')'].join(' ');
+ }
+ } else {
+ var ascii = clone[key].value[subKey].base64ToHex();
+ clone[key].value[subKey] = [clone[key].value[subKey], '(ascii:', ascii, ')'].join(' ');
+ }
+ });
+ ordered[key] = clone[key];
+ } else {
+ 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;
+ });
+ }
+
+ $scope.show = function(value){
+ var type = $mwtnGlobal.getType(value);
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnBrowser/templates/ptpDefaultDsConfigView.tpl.html',
+ controller: 'ptpDefaultDsViewController',
+ size: 'huge',
+ resolve: {
+ defaultDs: function () {
+ return {networkElement: $scope.networkElement, value:value};
+ }
+ }
+ });
+ modalInstance.result.then(function(object) {
+ $mwtnBrowser.refreshPTP();
+ }, function () {
+ // ignore;
+ });
+ };
+ }]);
+
+ mwtnBrowserApp.register.directive('mwtnPtpClockViewer', function () {
+ return {
+ restrict: 'E',
+ scope: {
+ data: '=',
+ path: '=',
+ ne: '=', // flag if ne class
+ networkElement: '='
+ },
+ controller: 'mwtnPtpClockViewerController',
+ controllerAs: 'vm',
+ templateUrl: 'src/app/mwtnBrowser/templates/mwtnPtpClockViewer.tpl.html'
+ };
+ });
+
+
+ mwtnBrowserApp.register.controller('mwtnBrowserCtrl', ['$scope', '$rootScope', '$mwtnLog', '$mwtnCommons', '$mwtnEthernet', '$mwtnBrowser', '$translate', 'OnfNetworkElement', 'PtpClock', 'LogicalTerminationPoint',
+ function($scope, $rootScope, $mwtnLog, $mwtnCommons, $mwtnEthernet, $mwtnBrowser, $translate, OnfNetworkElement, PtpClock, LogicalTerminationPoint) {
+
+ var COMPONENT = 'mwtnBrowserCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnBrowserCtrl started!'});
+ $rootScope.section_logo = 'src/app/mwtnBrowser/images/mwtnBrowser.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var pacTemplate = {
+ 'layer-protocol': 'unknown'
+ };
+
+ $scope.fcDeletion = {
+ nodeId: $scope.networkElementId,
+ ltp:'',
+ info: 'handle with care, no further warning, qualified user expected ;)'
+ };
+ $scope.deleteForwardingConstruct = function() {
+ $scope.fcDeletion.nodeId = $scope.networkElementId;
+ $scope.fcDeletion.info = 'Processing ...';
+ $scope.fcDeletion.error = undefined;
+ if ($scope.fcDeletion.ltp === undefined || $scope.fcDeletion.ltp === '') {
+ $scope.fcDeletion.error = 'Please select a valid LTP#1.!';
+ return;
+ }
+ $mwtnEthernet.deleteForwardingConstruct($scope.fcDeletion).then(function(success){
+ console.log(success);
+ $scope.fcDeletion.info = success;
+ }, function(error){
+ console.log(error);
+ $scope.fcDeletion.error = error;
+ });
+ }
+
+ $scope.fcCreation = {
+ nodeId: $scope.networkElementId,
+ ltp1:'',
+ ltp2:'',
+ vlan:42,
+ info:'handle with care, no further warning, qualified user expected ;)'
+ };
+ $scope.createForwardingConstruct = function() {
+ console.warn(JSON.stringify($scope.networkElementId));
+ console.warn(JSON.stringify($scope.networkElement));
+ $scope.fcCreation.nodeId = $scope.networkElementId;
+ $scope.fcCreation.info = 'Processing ...';
+ $scope.fcCreation.error = undefined;
+ if ($scope.fcCreation.ltp1 === undefined || $scope.fcCreation.ltp1 === '') {
+ $scope.fcCreation.error = 'Please select a valid LTP#1!';
+ return;
+ }
+ if ($scope.fcCreation.ltp2 === undefined || $scope.fcCreation.ltp2 === '') {
+ $scope.fcCreation.error = 'Please select a valid LTP#2!';
+ return;
+ }
+ if ($scope.fcCreation.vlan === undefined) {
+ $scope.fcCreation.error = 'Please select a valid vlan-id!';
+ return;
+ }
+ if ($scope.fcCreation.ltp1 === $scope.fcCreation.ltp2) {
+ $scope.fcCreation.error = 'Please select different LTPs. Loopback is not supported yet!';
+ return;
+ }
+ $mwtnEthernet.createForwardingConstruct($scope.fcCreation).then(function(success){
+ console.log(success);
+ $scope.fcCreation.info = success;
+ }, function(error){
+ console.log(error);
+ $scope.fcCreation.error = error;
+ });
+ }
+
+ // get important infromation from yang modules
+ console.error('help');
+ $mwtnBrowser.getModules().then(function(success){
+
+ var pacOrder = [
+ 'onf-otn-odu-conditional-packages:otn-odu-termination-pac',
+ 'onf-otn-odu-conditional-packages:otn-odu-connection-pac',
+ 'onf-ethernet-conditional-packages:ethernet-pac',
+ 'microwave-model:mw-air-interface-diversity-pac',
+ 'microwave-model:mw-air-interface-hsb-end-point-pac',
+ 'microwave-model:mw-air-interface-hsb-fc-switch-pac',
+ 'onf-core-model-conditional-packages:holder-pac',
+ 'onf-core-model-conditional-packages:connector-pac',
+ 'onf-core-model-conditional-packages:equipment-pac',
+ 'microwave-model:mw-ethernet-container-pac',
+ 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_Pac',
+ 'microwave-model:mw-ethernet-container-pac',
+ 'microwave-model:mw-tdm-container-pac',
+ 'microwave-model:mw-pure-ethernet-structure-pac',
+ 'microwave-model:mw-hybrid-mw-structure-pac',
+ 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac',
+ 'microwave-model:mw-air-interface-pac',
+ 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac'
+ ];
+
+ $scope.modules = success;
+ $scope.orderedPacs = [];
+ $scope.parts = [];
+ Object.keys(success).map(function(module){
+ Object.keys(success[module]).filter(function(key){
+ return key.endsWith('-pac') || key.endsWith('_Pac');
+ }).map(function(pacName){
+ $scope.orderedPacs.push([module, pacName].join(':'));
+ // sort
+ $scope.orderedPacs.sort(function(a, b) {
+ if (!pacOrder.indexOf(a)) console.warn(a);
+ if (!pacOrder.indexOf(b)) console.warn(b);
+ if(pacOrder.indexOf(a) > pacOrder.indexOf(b)) return 1;
+ if(pacOrder.indexOf(a) < pacOrder.indexOf(b)) return -1;
+ return 0;
+ })
+
+ if (pacName === 'mw-air-interface-pac') {
+ $scope.parts = Object.keys(success[module][pacName]).filter(function(conditionalPackage){
+ return success[module][pacName][conditionalPackage]['local-name'];
+ }).map(function(conditionalPackage){
+ return success[module][pacName][conditionalPackage]['local-name'];
+ });
+ }
+ });
+ });
+ }, function(error){
+ $scope.modules = undefined;
+ $scope.orderedPacs = undefined;
+ $scope.parts = undefined;
+ });
+
+ /**
+ * @function updateNe
+ * A function, which updates onfNetworkElement by new data.
+ * @param {*} data New data recieved from OpenDaylight via RestConf
+ */
+ var updateNe = function(data) {
+ if (!data) return;
+ // update onfNetworkElement
+ switch ($scope.mountpoint.onfCoreModelRevision) {
+ case '2016-03-23':
+ $scope.onfNetworkElement = JSON.parse(JSON.stringify(data['network-element'][0]));
+ $scope.onfLtps = data['network-element'][0].ltp;
+ $scope.onfNetworkElement.ltp = undefined;
+ break;
+ case '2016-08-09':
+ case '2016-08-11':
+ case '2017-02-17':
+ case '2017-03-20':
+ case '2017-10-20':
+ // console.log(JSON.stringify(data));
+ $scope.onfNetworkElement = new OnfNetworkElement(data['network-element']);
+ var fd = $scope.onfNetworkElement.getForwardingDomain();
+ $scope.forwardingDomain = undefined;
+ $scope.forwardingConstructs = undefined;
+ if (fd && fd.length > 0) {
+ $scope.forwardingDomain = fd[0]; // $mwtnBrowser.getViewData(fd[0]);
+ $scope.forwardingConstructs = [];
+ if (fd[0].fc) {
+ fd[0].fc.map(function(id){
+ $mwtnBrowser.getForwardingConstruct($scope.networkElement, id).then(function(fc){
+
+ // TODO make robust
+ if (fc['forwarding-construct'] && fc['forwarding-construct'][0]) {
+ var item = fc['forwarding-construct'][0];
+ if (item['fc-port'] &&
+ item['fc-port'][0] && item['fc-port'][0].ltp && item['fc-port'][0].ltp[0] &&
+ item['fc-port'][1] && item['fc-port'][1].ltp && item['fc-port'][1].ltp[0]) {
+ $scope.forwardingConstructs.push( {
+ uuid: item.uuid,
+ 'fc-port#1': $scope.onfNetworkElement.getLtp( item['fc-port'][0].ltp[0] ).getLabel(),
+ 'fc-port#2': $scope.onfNetworkElement.getLtp( item['fc-port'][1].ltp[0] ).getLabel()
+ });
+ }
+ }
+ });
+ });
+ }
+ }
+ $scope.onfLtps = $scope.onfNetworkElement.getLogicalTerminationPoints();
+ // $scope.onfNetworkElement.ltp = undefined;
+ break;
+ default:
+ $mwtnLog.info({component: COMPONENT, message: ['The ONF CoreModel revision', $scope.mountpoint.onfCoreModelRevision, ' is not supported (yet)!'].join(' ')});
+ $scope.onfNetworkElement = {};
+ $scope.onfLtps = {};
+ }
+
+ var order = $mwtnBrowser.layerProtocolNameOrder;
+ // update onfLTPs
+ $scope.onfLtps.sort(function(a, b){
+ if(order[a.getLayer()] < order[b.getLayer()]) return -1;
+ if(order[a.getLayer()] > order[b.getLayer()]) return 1;
+ if(a.getId() < b.getId()) return -1;
+ if(a.getId() > b.getId()) return 1;
+ return 0;
+ });
+
+ // calculate conditional packages
+ $scope.pacs = {};
+ $scope.onfLtps.map(function(ltp) {
+ ltp.getLayerProtocols().map(
+ /**
+ * A function processing a layer-protocol object
+ * @param {LayerProtocol} lp A layer-protocol object
+ */
+ function(lp) {
+ var template = JSON.parse(JSON.stringify(pacTemplate));
+ template['layer-protocol'] = lp.getId();
+ var conditionalPackage = lp.getConditionalPackage(true);
+ // console.log(conditionalPackage);
+ if (conditionalPackage !== '') {
+ if ($scope.pacs[conditionalPackage] === undefined) {
+ // create missing pac array
+ $scope.pacs[conditionalPackage] = [];
+ }
+ $scope.pacs[conditionalPackage].push(template);
+ console.error(conditionalPackage, JSON.stringify(template));
+ } else {
+ $mwtnLog.info({component: COMPONENT, message: 'No conditional package for ' + ltp.getLabel() });
+ }
+ });
+ });
+
+ // sort the conditional packages
+ if ($scope.orderedPacs) {
+ $scope.orderedPacs.filter(function(item){
+ return $scope.pacs[item] !== undefined;
+ }).map(function(item){
+ $scope.pacs[item].sort(function(a, b){
+ if(a['layer-protocol'] < b['layer-protocol']) return -1;
+ if(a['layer-protocol'] > b['layer-protocol']) return 1;
+ return 0;
+ });
+ });
+ }
+ data.revision = undefined;
+ };
+
+ var updateNetworkElementCurrentProblems = function(data) {
+ if (data && data['network-element-current-problems'] && data['network-element-current-problems']['current-problem-list'] ) {
+ data.revision = undefined;
+ $scope.neCurrentProblems = data['network-element-current-problems']['current-problem-list'];
+ } else {
+ $scope.neCurrentProblems = [];
+ }
+ };
+
+ var updateLtp = function(data) {
+ $scope.onfLtps.map(function(ltp){
+ if (ltp.getData().uuid === data.data.ltp[0].uuid) {
+ ltp = new LogicalTerminationPoint(data.data.ltp[0]);
+ }
+ });
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateAirInterface = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.airinterfaces.map(function(airinterface){
+ // console.log(JSON.stringify(airinterface));
+ if (airinterface['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].startsWith('air-interface')) {
+ airinterface[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ airinterface[part] = data['mw-air-interface-pac'][0]['air-interface-capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ airinterface[part] = data['mw-air-interface-pac'][0]['air-interface-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateStructure = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.structures.map(function(structure){
+ // console.log(JSON.stringify(structure));
+ if (structure['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].contains('tructure')) {
+ structure[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ structure[part] = data['mw-structure-pac'][0]['structure.capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ structure[part] = data['mw-structure-pac'][0]['structure-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateContainer = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.containers.map(function(container){
+ // console.log(JSON.stringify(container));
+ if (container['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].contains('ontainer') ) {
+ container[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ container[part] = data['mw-container-pac'][0]['container-capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ container[part] = data['mw-container-pac'][0]['container-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * Creates a template of a conditional packages with its subclasses
+ * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass
+ */
+ var initPac = function(spec) {
+ $scope.pacs[spec.pacId].filter(function(conditionalPackage){
+ return conditionalPackage['layer-protocol'] === spec.layerProtocolId;
+ }).map(function(pac){
+ $scope.parts.map(function(localName){
+ pac[localName] = {id:$mwtnBrowser.getPartGlobalId(spec, localName),localName: localName, data:'No data available'}
+ });
+ });
+ };
+
+ /**
+ * Updates an existing template of a conditional packages with its subclasses
+ * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass
+ */
+ var updateSubClassData = function(spec, data) {
+ $scope.pacs[spec.pacId].filter(function(conditionalPackage){
+ return conditionalPackage['layer-protocol'] === spec.layerProtocolId;
+ }).map(function(conditionalPackage){
+ conditionalPackage[$mwtnBrowser.getPartLocalId(spec)].data = data[$mwtnBrowser.yangify(spec.partId)];
+ });
+ };
+
+ var updatePart = function(spec, data) {
+ switch (spec.pacId) {
+ case 'ne':
+ updateNe(data);
+ break;
+ case 'forwardingDomain':
+ // TODO $scope.forwardingDomain = new ForwardingDomain(data);
+ break;
+ case 'neCurrentProblems':
+ updateNetworkElementCurrentProblems(data);
+ break;
+ case 'clock':
+ if (data) {
+ $scope.clock = new PtpClock(data);
+ } else {
+ $scope.clock = undefined;
+ }
+ break;
+ case 'ltp':
+ updateLtp(data);
+ break;
+ case 'airinterface':
+ console.warn(JSON.stringify(spec, JSON.stringify(data)));
+ updateAirInterface(spec.layerProtocolId, spec.partId, data);
+ break;
+ case 'structure':
+ console.warn(JSON.stringify(data));
+ updateStructure(spec.layerProtocolId, spec.partId, data);
+ break;
+ case 'container':
+ console.warn(JSON.stringify(data));
+ updateContainer(spec.layerProtocolId, spec.partId, data);
+ break;
+ // 3rd Poc
+ case 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac':
+ case 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac':
+ case 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_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':
+ if (!spec.partId) {
+ initPac(spec);
+ } else {
+ updateSubClassData(spec, data);
+ }
+ break;
+ }
+ };
+
+ // events
+ $scope.status = {ne:false};
+ $scope.spinner = {ne:false};
+ $scope.separator = $mwtnBrowser.separator; //'&nbsp;'
+
+ $scope.collapseAll = function() {
+ // close all groups
+ Object.keys($scope.status).map(function(group){
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function(group){
+ $scope.spinner[group] = false;
+ });
+ };
+
+ $scope.$watch('status', function(status, oldValue) {
+ Object.keys(status).filter(function(key){
+ return $scope.networkElementId && status[key] && status[key] !== oldValue[key];
+ }).map(function(key){
+ $scope.spinner[key] = true;
+ var info = key.split($scope.separator);
+ var spec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: info[0],
+ layerProtocolId: info[1],
+ partId: info[2]
+ };
+ $mwtnBrowser.getPacParts(spec).then(function(success){
+ success = $mwtnBrowser.yangifyObject(success)
+ updatePart(spec, success);
+ $scope.spinner[key] = false;
+ }, function(error){
+ updatePart(spec, error);
+ $scope.spinner[key] = false;
+ });
+ });
+ }, true);
+
+ $scope.$watch('networkElement', function(neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+
+ $scope.collapseAll();
+
+ // clear old data
+ $scope.airinterfaces = [];
+ $scope.structures = [];
+ $scope.containers = [];
+ $scope.onfLtps = [];
+ $scope.clock = undefined;
+
+ $scope.networkElementId = neId;
+ $scope.revision = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ $scope.mountpoint = mountpoint;
+ return mountpoint.onfCoreModelRevision;
+ })[0];
+
+ var spec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: 'ne'
+ };
+ $mwtnBrowser.getPacParts(spec).then(function(success){
+ updatePart(spec, $mwtnBrowser.yangifyObject(success));
+ }, function(error){
+ updatePart(spec, error);
+ });
+
+ // network element alarms
+ var neAlarms = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ return mountpoint.onfCapabilities.filter(function(cap){
+ return cap.module === 'MicrowaveModel-NetworkElement-CurrentProblemList' || cap.module === 'onf-core-model-conditional-packages';
+ });
+ });
+
+ if (neAlarms.length === 1 && neAlarms[0].length === 1 ) {
+ $translate('MWTN_LOADING').then(function (translation) {
+ $scope.neCurrentProblems = translation;
+ });
+ } else {
+ $scope.neCurrentProblems = undefined;
+ }
+
+ // ptp-clock
+ var ptpClock = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ return mountpoint.onfCapabilities.filter(function(cap){
+ return cap.module === 'onf-ptp-dataset';
+ });
+ });
+ if (ptpClock.length === 1 && ptpClock[0].length === 1 ) {
+ $translate('MWTN_LOADING').then(function (translation) {
+ $scope.clock = {'translation': translation};
+ });
+ } else {
+ $scope.clock = undefined;
+ }
+
+ }
+ });
+
+ }]);
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.module.js
new file mode 100644
index 00000000..d529ca2f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.module.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module',
+ 'app/mwtnCommons/bower_components/angular-clipboard/angular-clipboard'], function(ng) {
+ var mwtnBrowserApp = angular.module('app.mwtnBrowser', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'angular-clipboard']);
+
+ mwtnBrowserApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnBrowserApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnBrowser/mwtnBrowser.controller');
+ NavHelperProvider.addToMenu('mwtnBrowser', {
+ "link" : "#/pnfBrowser/",
+ "active" : "main.mwtnBrowser",
+ "title" : "pnf Config",
+ "icon" : "fa fa-cogs", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf Config",
+ "description" : "mwtnBrowser"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnBrowser', {
+ url: 'pnfBrowser/:nodeId',
+ access: access.admin,
+ views : {
+ content : {
+ templateUrl: 'src/app/mwtnBrowser/templates/frame.tpl.html',
+ controller: 'mwtnBrowserCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnBrowserApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.services.js
new file mode 100644
index 00000000..7cd9dc07
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/mwtnBrowser.services.js
@@ -0,0 +1,37 @@
+/*
+ * @copyright 2017 highstreet technologies 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/mwtnBrowser/mwtnBrowser.module'],function(mwtnBrowserApp) {
+
+ mwtnBrowserApp.register.factory('$mwtnBrowser', function($mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnBrowser';
+ $mwtnLog.info({component: COMPONENT, message: '$mwtnBrowser started!'});
+
+ var service = {};
+
+ service.separator = $mwtnCommons.separator;
+
+ service.parts = $mwtnCommons.parts;
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.getModules = $mwtnDatabase.getModules;
+ service.getPartGlobalId = $mwtnCommons.getPartGlobalId;
+ service.getPartLocalId = $mwtnCommons.getPartLocalId;
+ service.getViewData = $mwtnCommons.getViewData;
+ service.getForwardingConstruct = $mwtnCommons.getForwardingConstruct;
+ service.layerProtocolNameOrder = $mwtnCommons.layerProtocolNameOrder;
+ service.yangify = $mwtnCommons.yangify;
+ service.yangifyObject = $mwtnCommons.yangifyObject;
+
+ service.refreshPTP = function() {
+ console.error('refresh ptp');
+ }
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/frame.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/frame.tpl.html
new file mode 100644
index 00000000..6d43dbd8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/frame.tpl.html
@@ -0,0 +1,191 @@
+<ht-header help-link='sdnr/pnfConfig/0.4.0/README.md'></ht-header>
+<mwtn-select-network-element></mwtn-select-network-element>
+
+<div class="owl container" ng-if="networkElements.length !== 0 && networkElement" style="width: 100%;">
+ <div class="row">
+ <uib-accordion close-others="oneAtATime">
+ <div class="col-md-12">
+ <div uib-accordion-group class="panel-primary" is-open="status.ne">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status.ne, 'fa-chevron-right': !status.ne}"></i>
+ <span>{{'MWTN_NETWORKELEMENT' | translate}} '{{onfNetworkElement.getName()}}' </span>
+ <span> (#{{'MWTN_LTPS' | translate}}: {{onfNetworkElement.getLogicalTerminationPoints().length}})</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner.ne"></i>
+ </uib-accordion-heading>
+ <mwtn-json-viewer network-element="networkElement" data="onfNetworkElement.getData()" ne="true" ng-if="status.ne"></mwtn-json-viewer>
+ <br/>
+
+ <uib-accordion close-others="oneAtATime">
+ <div uib-accordion-group class="panel-default" is-open="status.neCurrentProblems" ng-if="neCurrentProblems">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status.neCurrentProblems, 'fa-chevron-right': !status.neCurrentProblems}"></i>
+ <span>{{'MWTN_CURRENT_PROBLEM_LIST' | translate}}</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner.neCurrentProblems"></i>
+ </uib-accordion-heading>
+
+ <mwtn-grid network-element="networkElement" data="neCurrentProblems" ng-if="neCurrentProblems && !spinner.neCurrentProblems"></mwtn-grid>
+ </div>
+
+ <div uib-accordion-group class="panel-default" is-open="status.forwardingDomain" ng-show="forwardingDomain">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status.forwardingDomain, 'fa-chevron-right': !status.forwardingDomain}"></i>
+ <span>{{'MWTN_FORWARDING_DOMAIN' | translate}}</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner.forwardingDomain"></i>
+ </uib-accordion-heading>
+
+ <mwtn-json-viewer network-element="networkElement" data="forwardingDomain" ng-if="status.forwardingDomain"></mwtn-json-viewer>
+ </div>
+
+ <div uib-accordion-group class="panel-default" is-open="status.forwardingConstructs" ng-show="forwardingConstructs">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status.forwardingConstructs, 'fa-chevron-right': !status.forwardingConstructs}"></i>
+ <span>{{'MWTN_FORWARDING_CONSTRUCTS' | translate}}</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner.forwardingConstructs"></i>
+ </uib-accordion-heading>
+
+ <mwtn-grid network-element="networkElement" data="forwardingConstructs" ng-if="forwardingConstructs && !spinner.forwardingConstructs"></mwtn-grid>
+
+ <!-- create fc -->
+ <div class="row">
+ <div class="col col-md-3">
+ <label class="owl-dark" for="vlan">{{'MWTN_LTP1' | translate}}</label><br/>
+ <select class="form-control" ng-model="fcCreation.ltp1">
+ <option ng-repeat="ltp in forwardingDomain.ltp" value="{{ltp}}">{{ltp}}</option>
+ </select>
+ </div>
+ <div class="col col-md-3">
+ <label class="owl-dark" for="vlan">{{'MWTN_LTP2' | translate}}</label><br/>
+ <select class="form-control" ng-model="fcCreation.ltp2">
+ <option ng-repeat="ltp in forwardingDomain.ltp" value="{{ltp}}">{{ltp}}</option>
+ </select>
+ </div>
+ <div class="col col-md-1 form-group">
+ <label class="owl-dark" for="vlan">{{'MWTN_SERVICE_ID' | translate}}</label><br/>
+ <input class="form-control" type="number" value="42" id="example-number-input" ng-model="fcCreation.vlan">
+ </div>
+ <div class="col col-md-2">
+ <label style="color:white;" for="create">create</label><br/>
+ <button type="button" class="btn btn-warning" ng-click="createForwardingConstruct()">
+ <i class="fa fa-plus" aria-hidden="true"></i>
+ <span style="color:white;">{{'MWTN_CREATE' | translate}}</span>
+ </button>
+ </div>
+ <div class="col col-md-3">
+ <span class="owl-dark" ng-if="!fcCreation.error">{{fcCreation.info}}</span>
+ <span class="error" ng-if="fcCreation.error">{{fcCreation.error}}</span>
+ </div>
+ </div>
+
+ <!-- delete fc -->
+ <div class="row">
+ <div class="col col-md-6 form-group">
+ <label class="owl-dark" for="vlan">{{'MWTN_FC_UUID' | translate}}</label><br/>
+ <select class="form-control" ng-model="fcDeletion.ltp">
+ <option ng-repeat="fc in forwardingConstructs" value="{{fc.uuid}}">{{fc.uuid}}</option>
+ </select>
+ </div>
+ <div class="col col-md-2 col-md-offset-1" >
+ <label style="color:white;" for="delete">delete</label><br/>
+ <button type="button" class="btn btn-danger" ng-click="deleteForwardingConstruct()">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span style="color:white;">{{'MWTN_DELETE' | translate}}</span>
+ </button>
+ </div>
+ <div class="col col-md-3">
+ <span class="owl-dark" ng-if="!fcDeletion.error">{{fcDeletion.info}}</span>
+ <span class="error" ng-if="fcDeletion.error">{{fcDeletion.error}}</span>
+ </div>
+ </div>
+
+ </div>
+
+ <div ng-repeat="ltp in onfLtps" ng-show="status.ne" uib-accordion-group class="panel-default" is-open="status['ltp' + separator + ltp.getData().uuid]">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status['ltp' + separator + ltp.getData().uuid], 'fa-chevron-right': !status['ltp' + separator + ltp.getData().uuid]}"></i>
+ <span>{{'MWTN_LTP' | translate}}(</span>
+ <b>{{ltp.getLayerProtocols()[0].getItuLabel().toUpperCase()}}</b>
+ <span>): {{ltp.getName()}} (ID: {{ltp.getId()}})</span>
+ </uib-accordion-heading>
+
+ <mwtn-json-viewer network-element="networkElement" data="ltp.getData()" ng-if="status['ltp' + separator + ltp.getData().uuid]"></mwtn-json-viewer>
+ </div>
+ </uib-accordion>
+ </div>
+
+ <div uib-accordion-group class="panel-default" is-open="status.clock" ng-if="clock">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status.clock, 'fa-chevron-right': !status.clock}"></i>
+ <span>{{'MWTN_CLOCK' | translate}}</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner.clock"></i>
+ </uib-accordion-heading>
+
+ <!-- <mwtn-json-viewer network-element="networkElement" data="clock.getData()" ng-if="clock.getData() && !spinner.clock"></mwtn-json-viewer> -->
+ <mwtn-ptp-clock-viewer network-element="networkElement" data="clock.getData()" ng-if="clock.getData() && !spinner.clock"></mwtn-ptp-clock-viewer>
+ </div>
+
+
+ </div>
+
+
+ </uib-accordion>
+ </div>
+
+ <div class="row" ng-repeat="orderedPac in orderedPacs" ng-if="pacs[orderedPac]">
+ <uib-accordion close-others="oneAtATime">
+ <div ng-class="{ 'col-md-12': pacs[orderedPac].length === 1, 'col-md-6': pacs[orderedPac].length !== 1 }" style="margin-top: 5px;"
+ ng-repeat="pac in pacs[orderedPac]">
+ <div uib-accordion-group class="panel-primary" is-open="status[ [orderedPac, pac['layer-protocol']].join(separator) ]">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status[ [orderedPac, pac['layer-protocol']].join(separator) ], 'fa-chevron-right': !status[ [orderedPac, pac['layer-protocol']].join(separator) ]}"></i>
+ <span>{{ ['mwtn', orderedPac].join('-').replaceAll('-', '_').toUpperCase() | translate }} '{{pac['layer-protocol']}}'</span>
+ </uib-accordion-heading>
+
+ <div ng-repeat="part in parts" uib-accordion-group class="panel-default" is-open="status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]">
+ <uib-accordion-heading>
+ <i class="fa" ng-class="{'fa-chevron-down': status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ], 'fa-chevron-right': !status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]}"></i>
+ <span>{{ ['mwtn', part].join('-').replaceAll('-', '_').toUpperCase() | translate}}</span>
+ <i class="fa fa-spinner fa-pulse" ng-show="spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></i>
+ </uib-accordion-heading>
+
+
+ <!-- current-problem-list -->
+ <mwtn-grid network-element="networkElement" data="pac[part].data['current-problem-list']" ng-if="pac[part].data['current-problem-list'] && !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></mwtn-grid>
+ <div ng-if="pac[part].data['current-problem-list'].length === 0">Alarm free ;)</div>
+
+ <!-- PM Current -->
+ <mwtn-json-viewer network-element="networkElement" data="pac[part].data['current-performance-data-list'][0]"
+ path="[orderedPac, pac['layer-protocol'], pac[part].id].join(separator)"
+ ng-if="part === 'current-performance' && pac[part].data && !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></mwtn-json-viewer>
+ <hr ng-if="part === 'current-performance' && pac[part].data && !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]">
+ <mwtn-json-viewer network-element="networkElement" data="pac[part].data['current-performance-data-list'][1]"
+ path="[orderedPac, pac['layer-protocol'], pac[part].id].join(separator)"
+ ng-if="part === 'current-performance' && pac[part].data && !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></mwtn-json-viewer>
+
+ <!-- PM history -->
+ <mwtn-grid network-element="networkElement" data="pac[part].data['historical-performance-data-list']"
+ path="[orderedPac, pac['layer-protocol'], pac[part].id].join(separator)"
+ ng-if="pac[part].data['historical-performance-data-list'] && !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></mwtn-grid>
+
+ <!-- else -->
+ <mwtn-json-viewer network-element="networkElement" data="pac[part].data"
+ path="[orderedPac, pac['layer-protocol'], pac[part].id].join(separator)"
+ ng-if="status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator)] &&
+ pac[part].data &&
+ part !== 'current-problems' &&
+ part !== 'current-performance' &&
+ part !== 'historical-performances' &&
+ !spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></mwtn-json-viewer>
+
+ </div>
+ </div>
+ </div>
+ <hr class="white">
+ </uib-accordion>
+ </div>
+
+</div>
+
+<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/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpClockViewer.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpClockViewer.tpl.html
new file mode 100644
index 00000000..1a6849df
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpClockViewer.tpl.html
@@ -0,0 +1,66 @@
+<div class="owl">
+ <div class="row text-right">
+ <div class="form-group">
+ <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">
+ <i class="fa fa-pencil-square-o pointer" aria-hidden="true" ng-click="openConfigView()" ></i>
+ </button>
+ <div>
+ </div>
+</div>
+<div class="owl">
+
+<!--
+ <div class="row" ng-repeat="(key, value) in viewData track by $index" ng-show="value.value !== undefined">
+ <span class="owl-dark">{{key | json}}</span><br/>
+ <span class="owl-dark">{{value | json}}</span><br/>
+ <span class="owl-dark">{{viewData[key].labelId | translate}}</span>
+ <span class="owl-dark">{{viewData['instance-number'].labelId | translate}}</span>
+ </div> -->
+
+ <!-- instance-number - ->
+ <div class="row">
+ <div class="col col-md-3 text-right" title="{{viewData['instance-number'].description}}">
+ <span class="owl-dark">{{viewData['instance-number'].labelId | translate}}</span>
+ </div>
+ <div class="col col-md-4">
+ <b>{{viewData['instance-number'].value}}</b>
+ </div>
+ </div> -->
+
+ <!-- current-ds -->
+ <div class="row">
+ <div class="column col-md-6 text-left" title="{{viewData['default-ds'].description}}">
+ <b>{{viewData['default-ds'].labelId | translate}}</b>
+ <i class="fa fa-pencil-square-o pointer" aria-hidden="true" ng-click="show(viewData['default-ds'].value)"></i>
+ <br/>
+ <mwtn-json-viewer network-element="networkElement" data="viewData['default-ds'].value" no-buttons="true" ng-if="viewData['default-ds'].value"></mwtn-json-viewer>
+ <hr/>
+ </div>
+
+ <div class="column col-md-6 text-left" title="{{viewData['parent-ds'].description}}">
+ <b>{{viewData['parent-ds'].labelId | translate}}</b>
+ <br/>
+ <mwtn-json-viewer network-element="networkElement" data="viewData['parent-ds'].value" no-buttons="true" ng-if="viewData['parent-ds'].value"></mwtn-json-viewer>
+ <hr/>
+ </div>
+
+ <div class="column col-md-6 text-left" ng-repeat="key in ['current-ds', 'time-properties-ds']" title="{{viewData[key].description}}">
+ <b>{{viewData[key].labelId | translate}}</b>
+ <br/>
+ <mwtn-json-viewer network-element="networkElement" data="viewData[key].value" no-buttons="true" ng-if="viewData[key].value"></mwtn-json-viewer>
+ <hr/>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col col-md-12 text-left" >
+ <b>{{'MWTN_PORT_DS_LIST' | translate}}</b>
+ <br/>
+ <mwtn-ptp-ports network-element="networkElement" data="viewData['port-ds-list'].value" path="path"></mwtn-ptp-ports>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpPorts.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpPorts.tpl.html
new file mode 100644
index 00000000..2751ffcb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/mwtnPtpPorts.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/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpDefaultDsConfigView.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpDefaultDsConfigView.tpl.html
new file mode 100644
index 00000000..cb0e40c2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpDefaultDsConfigView.tpl.html
@@ -0,0 +1,45 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'MWTN_PTP_DEFAULT_DS_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>{{data.networkElement}}</b>
+ </div>
+ </div>
+ <hr/>
+ <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" ng-disabled="item['is-read-only'] === true" min="{{item.min}}" max="{{item.max}}"></input>
+ </div>
+
+ <div class="col-md-3 checkbox" ng-if="item.controlType === 'checkbox' "><input type="checkbox" ng-model="item.value" ng-disabled="item['is-read-only'] === true" /></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" ng-disabled="item['is-read-only'] === true">
+ <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/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpPortConfigView.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpPortConfigView.tpl.html
new file mode 100644
index 00000000..5d7d9df5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/mwtnBrowser-module/src/main/resources/mwtnBrowser/templates/ptpPortConfigView.tpl.html
@@ -0,0 +1,53 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'MWTN_PTP_PORT_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>{{data.networkElement}}</b>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3 text-right" >
+ {{'MWTN_PORT_IDENTITY' | translate}}
+ </div>
+ <div class="col-md-9">
+ <b>{{data.value['port-identity']['clock-identity']}}#{{data.value['port-identity']['port-number']}}</b>
+ </div>
+ </div>
+ <hr/>
+ <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" ng-disabled="item['is-read-only'] === true" min="{{item.min}}" max="{{item.max}}"></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" ng-disabled="item['is-read-only'] === true">
+ <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/mwtnBrowser/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/pom.xml
new file mode 100644
index 00000000..7584afdc
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnBrowser/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnBrowser</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>pom</packaging>
+
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modules>
+ <module>mwtnBrowser-module</module>
+ <module>mwtnBrowser-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/pom.xml
new file mode 100644
index 00000000..b7993d31
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnClosedLoop</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnClosedLoop-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnClosedLoop-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnClosedLoop-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..8187f7fe
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnClosedLoop"/>
+ <property name="url" value="/src/app/mwtnClosedLoop"/>
+ <property name="directory" value="/mwtnClosedLoop"/>
+ <property name="requireJs" value="app/mwtnClosedLoop/mwtnClosedLoop.module"/>
+ <property name="angularJs" value="app.mwtnClosedLoop"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnClosedLoop/mwtnClosedLoop-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/pom.xml
new file mode 100644
index 00000000..aadd37ce
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnClosedLoop</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>mwtnClosedLoop-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/images/mwtnClosedLoop.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/images/mwtnClosedLoop.png
new file mode 100755
index 00000000..b4ed3d5c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/images/mwtnClosedLoop.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop-custom.css
new file mode 100644
index 00000000..6e9a480c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop-custom.css
@@ -0,0 +1,26 @@
+/**
+ * Add your application related css here
+ */
+
+.mwtnClosedLoopGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnClosedLoopGrid span {
+ color: #393939;
+}
+
+.mwtnClosedLoopGrid span.mismatch {
+ font-weight: bold;
+ color: #428bca;
+}
+
+.mwtnClosedLoopGrid .green {
+ color: darkgreen;
+}
+.mwtnClosedLoopGrid .green span {
+ color: darkgreen;
+}
+
+ \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.controller.js
new file mode 100644
index 00000000..99ad48b7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.controller.js
@@ -0,0 +1,160 @@
+/*
+ * 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/mwtnClosedLoop/mwtnClosedLoop.module','app/mwtnClosedLoop/mwtnClosedLoop.services','app/mwtnCommons/mwtnCommons.services'], function(mwtnClosedLoopApp) {
+
+ mwtnClosedLoopApp.register.controller('mwtnClosedLoopCtrl', ['$scope', '$rootScope', 'uiGridConstants', '$mwtnClosedLoop', '$mwtnCommons', '$mwtnLog', 'OnfNetworkElement', 'MicrowavePhysicalSection',
+ function($scope, $rootScope, uiGridConstants, $mwtnClosedLoop, $mwtnCommons, $mwtnLog, OnfNetworkElement, MicrowavePhysicalSection) {
+
+ var COMPONENT = 'mwtnClosedLoopCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'Started!'});
+
+ $rootScope.section_logo = 'src/app/mwtnClosedLoop/images/mwtnClosedLoop.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.timerOptionList = [
+ {id : '5seconds', name : "5 seconds"},
+ {id : '30seconds', name : "30 seconds"},
+ {id : '1minute', name : "One minute"},
+ {id : '2minutes', name : "Two minutes"},
+ {id : '30minutes', name : "30 minutes"},
+ {id : '1hour', name : "One hour"}];
+
+ var clearMessages = function() {
+ $scope.info = undefined;
+ $scope.error = undefined;
+ };
+
+ $scope.executeNow = function() {
+ clearMessages();
+ $mwtnCommons.executeClosedLoopAutomation().then(function(message){
+ $mwtnLog.info({component: 'mwtnClosedLoopCtrl', message: 'Closed loop automation was started'});
+ $scope.info = 'Closed loop automation was executed: ' + new Date().toISOString().toHumanReadableTimeFormat();
+ $scope.refresh();
+ }, function(error){
+ $mwtnLog.error({component: 'mwtnClosedLoopCtrl', message: 'Cannot execute Closed Loop Automation'});
+ $scope.error = 'Cannot execute Closed Loop Automation';
+ $scope.refresh();
+ });
+ };
+
+ $scope.save = function() {
+ clearMessages();
+ $mwtnCommons.saveClosedLoopAutomation($scope.timerEnabled, $scope.timerOption).then(function(message){
+ $mwtnLog.info({component: 'mwtnClosedLoopCtrl', message: 'Timer was changed'});
+ $scope.info = 'Timer was changed';
+ $scope.refresh();
+ }, function(error){
+ $mwtnLog.error({component: 'mwtnClosedLoopCtrl', message: 'Cannot save timer'});
+ $scope.error = 'Cannot save timer';
+ $scope.refresh();
+ });
+ };
+
+ $scope.read = function() {
+ clearMessages();
+ $mwtnCommons.readClosedLoopAutomation().then(function(message){
+ $scope.timerEnabled = message.data.output.enabled;
+ $scope.timerOption = message.data.output.option;
+ $scope.refresh();
+ }, function(error){
+ $mwtnLog.error({component: 'mwtnClosedLoopCtrl', message: 'Cannot read configuration data from the server'});
+ $scope.error = 'Cannot read configuration data from the server';
+ $scope.refresh();
+ });
+ };
+
+ $scope.read();
+
+ var updateAirInterface = function(spec, data) {
+ if (data) {
+ var radioSignalID = data.airInterfaceConfiguration.radioSignalID;
+ $scope.gridOptions.data.map(function(row){
+ if (row.name === spec.nodeId && row.radioSignalID === radioSignalID) {
+ row.actualAirInterfaceName = data.airInterfaceConfiguration.airInterfaceName;
+ }
+ });
+ } else {
+ $scope.gridOptions.data.map(function(row){
+ if (row.nodeId === spec.nodeId) {
+ row.actualAirInterfaceName = '?';
+ }
+ });
+ }
+ };
+
+ $scope.processing = false;
+ $scope.refresh = function() {
+ $scope.processing = true;
+ $mwtnClosedLoop.refresh().then(function(success){
+ $scope.processing = false;
+ $scope.gridOptions.data = success.airInterfaces;
+ success.actualNodes.map(function(actualNode){
+ if (actualNode.connectionStatus !== 'connected') {
+ return;
+ }
+ var revision = '2016-09-01';
+ $mwtnClosedLoop.getActualNetworkElement(actualNode.id, revision).then(function(onfNe){
+ var aOnfNe = new OnfNetworkElement(onfNe.NetworkElement);
+ aOnfNe.getLTPMwpsList().map(function(ltp){
+ var spec = {
+ nodeId: actualNode.id,
+ revision: revision,
+ pacId: 'airinterface',
+ layerProtocolId: ltp._lpList[0].uuid,
+ partId: 'Configuration'
+ };
+ $mwtnClosedLoop.getPacParts(spec).then(function(success){
+ updateAirInterface(spec, success);
+ }, function(error){
+ updateAirInterface(spec, error);
+ });
+ });
+ }, function(error){
+ // do nothing
+ });
+ });
+ }, function(error){
+ $scope.processing = false;
+ $scope.gridOptions.data = [];
+ });
+ };
+
+ $scope.highlightFilteredHeader = $mwtnClosedLoop.highlightFilteredHeader;
+
+ var requiredNesConnectionStatusCellTemplate = [
+ '<div class="ui-grid-cell-contents" ng-class="{ \'green\': grid.getCellValue(row, col) === \'connected\'}"}>',
+ ' <i ng-show="grid.getCellValue(row, col) === \'connected\'" class="fa fa-link" aria-hidden="true"></i>',
+ ' <span>{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ // ng-class="{\'mismatch\': {{row.entity.plannedAirInterfaceName}} !== grid.getCellValue(row, col) }"
+ var actualAirinterfaceNameTemplate = [
+ '<div class="ui-grid-cell-contents">',
+ ' <span>{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnClosedLoop.gridOptions));
+ $scope.gridOptions.columnDefs = [
+ { field: 'id', type: 'number', displayName: 'Id', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true , sort: {
+ direction: uiGridConstants.ASC,
+ ignoreSort: false,
+ priority: 0
+ }},
+ { field: 'name', type: 'string', displayName: 'Name', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'connectionStatus', type: 'string', displayName: 'Connection status', headerCellClass: $scope.highlightFilteredHeader, width : 150, cellTemplate: requiredNesConnectionStatusCellTemplate },
+ { field: 'radioSignalID', type: 'string', displayName: 'Radio signal id', headerCellClass: $scope.highlightFilteredHeader, width : 130 },
+ { field: 'plannedAirInterfaceName', type: 'string', displayName: 'Planned airinterface name', headerCellClass: $scope.highlightFilteredHeader, width : 200 },
+ { field: 'actualAirInterfaceName', type: 'string', displayName: 'Actual airinterface name', headerCellClass: $scope.highlightFilteredHeader, width : 250, cellTemplate: actualAirinterfaceNameTemplate},
+ ];
+
+ $scope.refresh();
+
+ }]);
+
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.module.js
new file mode 100644
index 00000000..cec6f69b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.module.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD', 'app/routingConfig', 'app/core/core.services', 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnClosedLoopApp = angular.module('app.mwtnClosedLoop', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state','config']);
+
+ mwtnClosedLoopApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnClosedLoopApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/mwtnClosedLoop/mwtnClosedLoop.controller');
+ NavHelperProvider.addToMenu('mwtnClosedLoop', {
+ "link" : "#/mwtnClosedLoop",
+ "active" : "main.mwtnClosedLoop",
+ "title" : "MWTN Closed Loop Automation",
+ "icon" : "fa fa-circle-o", // Add navigation icon css class here
+ "page" : {
+ "title" : "MWTN Closed Loop Automation",
+ "description" : "mwtnClosedLoop"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnClosedLoop', {
+ url: 'mwtnClosedLoop',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnClosedLoop/mwtnClosedLoop.tpl.html',
+ controller: 'mwtnClosedLoopCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnClosedLoopApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.services.js
new file mode 100644
index 00000000..96c8c3e7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.services.js
@@ -0,0 +1,74 @@
+/*
+ * 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/mwtnClosedLoop/mwtnClosedLoop.module'],function(mwtnClosedLoopApp) {
+
+
+ mwtnClosedLoopApp.register.factory('$mwtnClosedLoop', function($q, $mwtnCommons, $mwtnLog) {
+ var service = {};
+
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+ service.getActualNetworkElement = $mwtnCommons.getActualNetworkElement;
+ service.getPacParts = $mwtnCommons.getPacParts;
+
+
+ service.refresh = function() {
+ var deferred = $q.defer();
+ $mwtnCommons.getRequiredNetworkElements(true).then(function(pNes){
+ var neIds = pNes.map(function(pNe){
+ pNe._source.connectionStatus = 'disconnected';
+ return pNe._id;
+ });
+ $mwtnCommons.getMountPoints(). then(function(mountpoints){
+ var actualNodes = mountpoints.map(function(mountpoint){
+ var pIndex = neIds.indexOf(mountpoint['node-id']);
+ if (pIndex > -1) {
+ pNes[pIndex]._source.connectionStatus = mountpoint['netconf-node-topology:connection-status'];
+ }
+ return {
+ id: mountpoint['node-id'],
+ connectionStatus: mountpoint['netconf-node-topology:connection-status']
+ };
+ });
+ var airInterfaces = [];
+ pNes.map(function(hit){
+ hit._source.MW_AirInterface_Pac.map(function(airinterface){
+ return airinterface.airInterfaceConfiguration;
+ }).map(function(airinterface){
+ airInterfaces.push({
+ id: $mwtnCommons.getNodeIntIdFromNodeId(hit._source.nodeId),
+ name: hit._source.nodeId,
+ connectionStatus: hit._source.connectionStatus,
+ radioSignalID: airinterface.airInterfaceConfiguration.radioSignalID,
+ plannedAirInterfaceName: airinterface.airInterfaceConfiguration.airInterfaceName,
+ actualAirInterfaceName: '?'
+ });
+ });
+ });
+
+ airInterfaces.sort(function(a, b){
+ if(a.radioSignalID < b.radioSignalID) return -1;
+ if(a.radioSignalID > b.radioSignalID) return 1;
+ return 0;
+ });
+ deferred.resolve({airInterfaces: airInterfaces, actualNodes: actualNodes});
+ }, function(error){
+ deferred.reject([]);
+ });
+
+ }, function(error){
+ deferred.reject([]);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.tpl.html
new file mode 100644
index 00000000..62a2aca0
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/mwtnClosedLoop-module/src/main/resources/mwtnClosedLoop/mwtnClosedLoop.tpl.html
@@ -0,0 +1,64 @@
+<ht-header help-link='sdnr/mwtn/mwtnClosedLoop/0.4.0/README.md'></ht-header>
+<div class="owl container">
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span class="white">{{'Timer ON/OFF' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <input type="checkbox" ng-model="timerEnabled">
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span class="white">{{'Timer Option' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <select class="form-control" ng-model="timerOption" ng-disabled="!timerEnabled">
+ <option ng-repeat="timerOption in timerOptionList" value="{{timerOption.id}}">{{timerOption.name}}</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="col-md-6 text-right">
+ <div class="form-group">
+ <button type="button" class="btn btn-primary" ng-click="save()">{{'Save' | translate}}</button>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <hr />
+ <div class="col-md-2">
+ <div class="form-group">
+ <button type="button" class="btn btn-primary" ng-click="executeNow()">{{'Execute now' | translate}}</button>
+ </div>
+ </div>
+ <div class="col-md-8">
+ <div class="form-group">
+ <span class="white" ng-show="info">{{ info }}</span>
+ <span ng-show="error" class="mwtnError">{{ error }}</span>
+ </div>
+ </div>
+ <div clase="col-md-2 text-right">
+ <button class="btn btn-primary pull-right" ng-click="refresh()">
+ <i class="fa fa-refresh" ng-class="{'fa-spin':processing == true}" aria-hidden="true"></i>
+ <span>{{'MWTN_REFRESH' | translate}}</span>
+ </button>
+ </div>
+ </div>
+ <div class="row">
+ <div clase="col-md-12">
+ <div id="mwtnClosedLoopGrid" ui-grid="gridOptions" ui-grid-exporter
+ ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnClosedLoopGrid"></div>
+ </div>
+ </div>
+
+</div>
+<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/mwtnClosedLoop/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/pom.xml
new file mode 100644
index 00000000..fc75d742
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnClosedLoop/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnClosedLoop</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnClosedLoop-module</module>
+ <module>mwtnClosedLoop-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/pom.xml
new file mode 100644
index 00000000..e9f85e05
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnCommons</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnCommons-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnCommons-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnCommons-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..5a693e16
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,23 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnCommons"/>
+ <property name="url" value="/src/app/mwtnCommons"/>
+ <property name="directory" value="/mwtnCommons"/>
+ <property name="requireJs" value="app/mwtnCommons/mwtnCommons.module"/>
+ <property name="angularJs" value="app.mwtnCommons"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnCommons/mwtnCommons-custom.css</value>
+ <value>src/app/mwtnCommons/bower_components/font-awesome/css/font-awesome.css</value>
+ <value>src/app/mwtnCommons/bower_components/angular-ui-grid/ui-grid.min.css</value>
+ <value>src/app/mwtnCommons/bower_components/json-formatter/dist/json-formatter.min.css</value>
+<!-- <value>src/app/mwtnCommons/bower_components/angular-bootstrap/ui-bootstrap-csp.css</value> -->
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/pom.xml
new file mode 100644
index 00000000..b031831f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/mwtnCommons-module/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnCommons</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnCommons-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence
+ on the Maven build itself. -->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <versionRange>[1.0.0,)</versionRange>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <execute/>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.6.0</version>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <executable>./bowerInstall.sh</executable>
+ <arguments>
+ <argument>install</argument>
+ </arguments>
+ <workingDirectory>${basedir}/src/main/resources/mwtnCommons/</workingDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g, '&#x2F;');
+ else
+ return str;
+ }
+
+ function unescapeXmlChars(str) {
+ return str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&#x2F;/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 = '&nbsp;';
+ // 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('&amp;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('&amp;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('&amp;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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g, '&#x2F;');
+ else
+ return str;
+ }
+
+ function unescapeXmlChars(str) {
+ return str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&#x2F;/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;
+ };
+
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/pom.xml
new file mode 100644
index 00000000..93caaec9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCommons/pom.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtn</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnCommons</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>pom</packaging>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnCommons-module</module>
+ <module>mwtnCommons-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/pom.xml
new file mode 100644
index 00000000..66e1ee9e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnCompare</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnCompare-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnCompare-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnCompare-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..dae4aa40
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnCompare"/>
+ <property name="url" value="/src/app/mwtnCompare"/>
+ <property name="directory" value="/mwtnCompare"/>
+ <property name="requireJs" value="app/mwtnCompare/mwtnCompare.module"/>
+ <property name="angularJs" value="app.mwtnCompare"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnCompare/mwtnCompare-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/pom.xml
new file mode 100644
index 00000000..c0de516d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnCompare</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnCompare-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+
+ </project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/images/mwtnCompare.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/images/mwtnCompare.png
new file mode 100755
index 00000000..f4f9c096
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/images/mwtnCompare.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare-custom.css
new file mode 100644
index 00000000..1cab6029
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare-custom.css
@@ -0,0 +1,36 @@
+/**
+ * Add your application related css here
+ * Build: @buildtime@
+ */
+
+#mwtnCompare .footable > thead > tr > th {
+ background-color: #428bca;
+ color: #ffffff;
+ background-image: none;
+ border: none;
+ box-shadow: none;
+}
+
+.connected {
+ color: lightgreen;
+}
+
+.connected span {
+ color: lightgreen;
+}
+
+.match {
+ color: lightgreen;
+}
+
+.match span {
+ color: lightgreen;
+}
+
+.nowrap {
+ white-space: nowrap;
+}
+
+.red {
+ color: red;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.controller.js
new file mode 100644
index 00000000..e83885a6
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.controller.js
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnCompare/mwtnCompare.module',
+ 'app/mwtnCompare/mwtnCompare.services',
+ 'app/mwtnCommons/mwtnCommons.services',
+ 'app/mwtnCompare/mwtnCompare.directives',
+ 'app/mwtnCommons/bower_components/angular-ui-grid/ui-grid.min'], function(mwtnCompareApp) {
+
+ mwtnCompareApp.register.controller('mwtnCompareCtrl', ['$scope', '$rootScope', '$mwtnCompare', '$mwtnLog', 'orderByFilter', 'OnfNetworkElement', 'MicrowavePhysicalSection', 'MicrowaveSection',
+ function($scope, $rootScope, $mwtnCompare, $mwtnLog, orderBy, OnfNetworkElement, MicrowavePhysicalSection, MicrowaveSection) {
+
+ $rootScope.section_logo = 'src/app/mwtnCompare/images/mwtnCompare.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var rOnfNe;
+ var aOnfNe;
+
+ $scope.status = {ne:false};
+ $scope.spinner = {ne:false};
+ $scope.separator = $mwtnCompare.separator; //'&nbsp;'
+ $scope.connectionStatus = 'disconnected';
+ $scope.oneATime = true;
+ $scope.match = {
+ numberOfLTPs: false,
+ numberOfLTPsStatus: 'unknown',
+ radioSignalIds: false,
+ radioSignalIdsStatus: 'unknown',
+ mapping: {},
+ addActualRadioSignalId: function(rsId) {
+ if (!this.actualRadioSignalIds) {
+ this.actualRadioSignalIds = [];
+ }
+ if (this.actualRadioSignalIds.contains(rsId)) {
+ return;
+ }
+ this.actualRadioSignalIds.push(rsId);
+ this.actualRadioSignalIds.sort();
+ this.checkRadioSignalIdsStatus();
+ },
+ clearActualNumberOfLtps: function() {
+ this.actualNumberOfLtps = undefined;
+ this.numberOfLTPs = false;
+ this.numberOfLTPsStatus = this.requiredNumberOfLtps;
+ },
+ clearActualRadioSignalIds: function() {
+ this.actualRadioSignalIds = undefined;
+ this.radioSignalIds = false;
+ this.radioSignalIdsStatus = this.requiredRadioSignalIds;
+ },
+ setRequiredNumberOfLtps: function(rNoLtps) {
+ this.requiredNumberOfLtps = rNoLtps;
+ this.checkNumberOfLTPs();
+ },
+ setRequiredRadioSignalIds: function(rRsIds) {
+ this.requiredRadioSignalIds = rRsIds.sort();
+ this.checkRadioSignalIdsStatus();
+ },
+ setActualNumberOfLtps: function(aNoLtps) {
+ this.actualNumberOfLtps = aNoLtps;
+ this.checkNumberOfLTPs();
+ },
+ setActualRadioSignalIds: function(aRsIds) {
+ this.actualRadioSignalIds = aRsIds.sort();
+ this.checkRadioSignalIdsStatus();
+ },
+ checkNumberOfLTPs: function() {
+ if (!this.requiredNumberOfLtps) {
+ this.numberOfLTPs = false;
+ this.numberOfLTPsStatus = 'unknown';
+ } else {
+ if (!this.actualNumberOfLtps) {
+ this.numberOfLTPs = false;
+ this.numberOfLTPsStatus = this.requiredNumberOfLtps;
+ } else {
+ if (this.requiredNumberOfLtps === this.actualNumberOfLtps) {
+ this.numberOfLTPs = true;
+ this.numberOfLTPsStatus = this.requiredNumberOfLtps;
+ } else {
+ this.numberOfLTPs = false;
+ this.numberOfLTPsStatus = ['required:', this.requiredNumberOfLtps, 'does not match actual:',this.actualNumberOfLtps].join(' ');
+ }
+ }
+ }
+ },
+ checkRadioSignalIdsStatus: function() {
+ if (!this.requiredRadioSignalIds) {
+ this.radioSignalIds = false;
+ this.radioSignalIdsStatus = 'unknown';
+ } else {
+ if (!this.actualRadioSignalIds) {
+ this.radioSignalIds = false;
+ this.radioSignalIdsStatus = this.requiredRadioSignalIds;
+ } else {
+ if (JSON.stringify(this.requiredRadioSignalIds) === JSON.stringify(this.actualRadioSignalIds)) {
+ this.radioSignalIds = true;
+ this.radioSignalIdsStatus = this.requiredRadioSignalIds;
+ } else {
+ this.radioSignalIds = false;
+ this.radioSignalIdsStatus = ['required:', this.requiredRadioSignalIds, 'does not match actual:',this.actualRadioSignalIds].join(' ');
+ }
+ }
+ }
+ }
+
+ };
+
+ $scope.schema = {initShowObjectCtrl:false};
+ $mwtnCompare.getSchema().then(function(data){
+ $scope.schema = data;
+ });
+
+ var initNodeList = function(nodes){
+ $scope.neSelection = [];
+ if (nodes.length > 0) {
+ nodes.map(function(ne) {
+ if (ne._source.onfAirInterfaceRevision) {
+ $scope.neSelection.push({id:ne._id, revision:ne._source.onfAirInterfaceRevision});
+
+ }
+ });
+ $scope.neSelection.sort(function(a, b){
+ if(a.id < b.id) return -1;
+ if(a.id > b.id) return 1;
+ return 0;
+ });
+ }
+ };
+ $scope.requiredNetworkElements = [];
+ $mwtnCompare.getRequiredNetworkElements(true).then(function(nodes){
+ $scope.requiredNetworkElements = nodes;
+ initNodeList(nodes);
+ }, function(error){
+ $scope.neSelection = [];
+ $scope.requiredNetworkElements = [];
+ });
+
+ $scope.collapseAll = function() {
+ // close all groups
+ Object.keys($scope.status).map(function(group){
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function(group){
+ $scope.spinner[group] = false;
+ });
+ };
+
+
+ // events
+ $scope.$watch('selection', function(neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+ $scope.collapseAll();
+ $scope.connectionStatus = 'disconnected';
+ $scope.match.clearActualNumberOfLtps();
+ $scope.match.clearActualRadioSignalIds();
+ $mwtnCompare.getConnectionStatus(neId).then(function(connectionStatus){
+ $scope.connectionStatus = connectionStatus;
+ // get actual data
+ if ($scope.connectionStatus === 'connected') {
+ var key = 'ne';
+ var spec = {
+ nodeId: $scope.selection,
+ revision: $scope.requiredNetworkElement.onfAirInterfaceRevision,
+ pacId: key,
+ };
+ $mwtnCompare.getPacParts(spec).then(function(success){
+ updatePart(spec, success);
+ $scope.spinner[key] = false;
+ }, function(error){
+ updatePart(spec, error);
+ $scope.spinner[key] = false;
+ });
+ }
+
+ },function(error){
+ $scope.connectionStatus = 'disconnected';
+ });
+
+ $scope.requiredNetworkElements.map(function(rne){
+ console.warn(JSON.stringify(rne._id, neId, rne._id === neId));
+ if (rne._id === neId) {
+ $scope.requiredNetworkElement = rne._source;
+ rOnfNe = new OnfNetworkElement(rne._source['core-model:network-element']);
+ $scope.match.setRequiredNumberOfLtps(rOnfNe.getNumberOfLtps());
+ // required NE
+ var rMwpsList = rOnfNe.getLTPMwpsList().map(function(mwpsLtp){
+ var key = 'microwave-model:mw-air-interface-pac';
+ if ($scope.requiredNetworkElement.onfAirInterfaceRevision.contains('2016')) {
+ key = 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac';
+ }
+ var rMwpsList = $scope.requiredNetworkElement[key].map(function(mwps){
+ if (mwps.layerProtocol === mwpsLtp.getLayerProtocols()[0].getId()) {
+ return new MicrowavePhysicalSection(mwps);
+ }
+ });
+
+ if (rMwpsList) {
+ return rMwpsList.clean(undefined)[0];
+ } else {
+ return {};
+ }
+ });
+
+ var rRadioSignalIds = rMwpsList.map(function(rMwps){
+ return rMwps.getRadioSignalId();
+ });
+ $scope.match.setRequiredRadioSignalIds(rRadioSignalIds);
+ }
+ });
+ }
+ });
+
+ var getArrayValueToHtml = function(array) {
+ if (array === undefined) {
+ return '';
+ }
+ if (array.length > 0 && ($mwtnCompare.getType(array[0]) === 'object' || $mwtnCompare.getType(array[0]) === 'array') ) {
+ var converted = array.map(function(item){
+ if ($mwtnCompare.getType(item) === 'object' && Object.keys(item).length === 2 ) {
+ return [item[Object.keys(item)[0]], item[Object.keys(item)[1]]].join(':');
+ } else {
+ return JSON.stringify(item);
+ }
+ });
+ return converted.join('<br/>');
+ } else {
+ return array.join('<br/>');
+ }
+ };
+
+ var getCompares = function(obj, actualData) {
+ var compares = [];
+
+ for (var labelId in obj) {
+ var missingActualValueLabelId = 'not connected';
+ var match = false;
+
+ switch (labelId) {
+ case 'compares':
+ break;
+ case 'open':
+ break;
+// case 'nameList':
+// var requiredName = obj[labelId][0].value;
+// var actualName = '';
+// if (actualData) {
+// actualName = actualData[labelId][0].value;
+// }
+// match = ((requiredName === '' || actualName === '') || (requiredName === actualName));
+// // console.log('NAME', requiredName, actualName, match);
+// compares.push({
+// labelId : 'NE name',
+// requiredValue : requiredName,
+// actualValue : actualName,
+// match : match,
+// missingActualValueLabelId : missingActualValueLabelId,
+//// unit : $scope.schema[labelId].unit,
+//// description : $scope.schema[labelId].description,
+// showDescriptions : false
+// });
+// break;
+ case '_ltpRefList':
+ var requiredLtpLength = obj[labelId].length;
+ var actualLtpLength = '';
+ if (actualData) {
+ actualLtpLength = actualData[labelId].length;
+ }
+ match = ((requiredLtpLength === '' || actualLtpLength === '') || (requiredLtpLength === actualLtpLength));
+ compares.push({
+ labelId : 'numberOfLTPs',
+ requiredValue : requiredLtpLength,
+ actualValue : actualLtpLength,
+ match : match,
+ missingActualValueLabelId : missingActualValueLabelId,
+ unit : $scope.schema[labelId].unit,
+ order: $scope.schema[labelId]['order-number'],
+ description : $scope.schema[labelId].description,
+ showDescriptions : false
+ });
+ break;
+ default:
+ if (labelId === 'installedCapacity') {
+ missingActualValueLabelId = '<pure planning value>';
+ }
+ if (labelId === 'timeSlotIDList') {
+ var requiredTimeSlotIDListLength = obj[labelId].length;
+ var actualTimeSlotIDListLength = '';
+ if (actualData) {
+ actualTimeSlotIDListLength = actualData[labelId].length;
+ }
+ compares.push({
+ labelId : 'currentNumberOfTimeSlots',
+ requiredValue : requiredTimeSlotIDListLength,
+ actualValue : actualTimeSlotIDListLength,
+ match : true,
+ missingActualValueLabelId : missingActualValueLabelId,
+ unit : $scope.schema[labelId].unit,
+ order: $scope.schema[labelId]['order-number'],
+ description : $scope.schema[labelId].description,
+ showDescriptions : false
+ });
+ }
+
+ switch($mwtnCompare.getType(obj[labelId])) {
+ case 'object':
+ if (actualData) {
+ var withActual = getCompares(obj[labelId], actualData[labelId]);
+ compares = compares.concat(withActual);
+ } else {
+ var withoutActual = getCompares(obj[labelId]);
+ compares = compares.concat(withoutActual);
+ }
+ break;
+ case 'array':
+ var requiredDataValue = getArrayValueToHtml(obj[labelId]);
+ var actualDataValue = '';
+ if (actualData) {
+ actualDataValue = getArrayValueToHtml(actualData[labelId]);
+ }
+ match = ((requiredDataValue === '' || actualDataValue === '') || (requiredDataValue === actualDataValue));
+ compares.push({
+ labelId : labelId,
+ requiredValue : requiredDataValue,
+ actualValue : actualDataValue,
+ match : match,
+ missingActualValueLabelId : missingActualValueLabelId,
+ unit : $scope.schema[labelId].unit,
+ order: $scope.schema[labelId]['order-number'],
+ description : $scope.schema[labelId].description,
+ showDescriptions : false
+ });
+ break;
+ default:
+ var requiredValue = obj[labelId];
+ var actualValue = actualData ? actualData[labelId] : '';
+// // console.log('match');
+// // console.log('match1', requiredValue, (requiredValue === ''));
+// // console.log('match2', actualValue, (actualValue === ''));
+// // console.log('match3', requiredValue, actualValue, (requiredValue === actualValue));
+// // console.log('match4', (requiredValue === '' || actualValue === '') || (requiredValue === actualValue));
+ match = (requiredValue === '' || actualValue === '') || (requiredValue === actualValue);
+ compares.push({
+ labelId : labelId,
+ requiredValue : requiredValue,
+ actualValue : actualValue,
+ match : match,
+ missingActualValueLabelId : missingActualValueLabelId,
+ unit : $scope.schema[labelId].unit,
+ order: $scope.schema[labelId]['order-number'],
+ description : $scope.schema[labelId].description,
+ showDescriptions : false
+ });
+ }
+ }
+ }
+ return orderBy(compares, 'order', false);
+ };
+
+ var updateNe = function(data) {
+
+ var rne = $scope.requiredNetworkElement;
+ if (!data) {
+ rne['core-model:network-element'].compares = getCompares(rne['core-model:network-element']);
+ return;
+ }
+ rne['core-model:network-element'].compares = getCompares(rne['core-model:network-element'], data['core-model:network-element']);
+ console.error(JSON.stringify(data));
+ aOnfNe = new OnfNetworkElement(data['core-model:network-element']);
+ $scope.match.setActualNumberOfLtps(aOnfNe.getNumberOfLtps());
+ var aMwpsList = aOnfNe.getLTPMwpsList().map(function(mwpsLtp){
+
+ var spec = {
+ nodeId: $scope.selection,
+ revision: $scope.requiredNetworkElement.onfAirInterfaceRevision,
+ pacId: 'microwave-model:mw-air-interface-pac',
+ layerProtocolId: mwpsLtp.getLayerProtocols()[0].getId(),
+ partId: 'configuration'
+ };
+
+ $mwtnCompare.getPacParts(spec).then(function(success){
+ updatePart(spec, success);
+ }, function(error){
+ updatePart(spec, error);
+ });
+ return mwpsLtp._lpList[0].uuid;
+ });
+ // console.log(aMwpsList)
+ var mwClient = rne['microwave-model:mw-ethernet-container-pac'][0];
+ $scope.match.mapping[mwClient.layerProtocol] = aOnfNe.getLTPEthCtpList()[0].getLayerProtocols()[0].getId();
+ };
+
+ var addShowDescriptionEvent = function(obj) {
+ $scope.$watch(function() {
+ return obj.showDescriptions;
+ }, function(newValue, oldValue) {
+ if (newValue !== oldValue) {
+ obj.compares.map(function(compare){
+ compare.showDescriptions = newValue;
+ });
+ }
+ });
+ };
+
+ var updateAirInterface = function(spec, data) {
+ if (!data) {
+ $scope.requiredNetworkElement['microwave-model:mw-air-interface-pac'].map(function(mwps){
+ mwps.compares = getCompares(mwps.airInterfaceConfiguration);
+ addShowDescriptionEvent(mwps);
+ });
+ } else {
+ var actual = new MicrowavePhysicalSection(data);
+ $scope.match.addActualRadioSignalId(actual.getRadioSignalId());
+ // console.log(actual.getRadioSignalId());
+ $scope.requiredNetworkElement['microwave-model:mw-air-interface-pac'].map(function(mwps){
+ var required = new MicrowavePhysicalSection(mwps);
+ if (actual.getRadioSignalId() === required.getRadioSignalId()) {
+ $scope.match.mapping[required.getLayerProtocolId()] = actual.getLayerProtocolId();
+ var actualData = data.airInterfaceConfiguration;
+ mwps.compares = getCompares(mwps.airInterfaceConfiguration, actualData);
+ addShowDescriptionEvent(mwps);
+
+ // MWS mapping
+ var rMws = rOnfNe.getClientLtpIds(required.getLayerProtocolId());
+ var aMws = aOnfNe.getClientLtpIds(actual.getLayerProtocolId());
+ // In PoC just a 1:1 relation between MWPS and MWS
+ $scope.match.mapping[rOnfNe.getLpByLtpRef(rMws[0]).uuid] = aOnfNe.getLpByLtpRef(aMws[0]).uuid;
+ }
+ });
+ }
+ };
+
+ var updateStructure = function(spec, data) {
+ if (!data) {
+ $scope.requiredNetworkElement.MW_PureEthernetStructure_Pac.map(function(mws){
+ mws.compares = getCompares(mws.pureEthernetStructureConfiguration);
+ addShowDescriptionEvent(mws);
+ });
+ } else {
+ $scope.requiredNetworkElement.MW_PureEthernetStructure_Pac.map(function(mws){
+ if ($scope.match.mapping[mws.layerProtocol] === data.layerProtocol) {
+ var actualData = data.pureEthernetStructureConfiguration;
+ mws.compares = getCompares(mws.pureEthernetStructureConfiguration, actualData);
+ addShowDescriptionEvent(mws);
+ }
+ });
+ }
+ };
+
+ var updateContainer = function(spec, data) {
+ // there is only one container in PoCs
+ var mwClient = $scope.requiredNetworkElement.MW_EthernetContainer_Pac[0];
+ if (!data) {
+ mwClient.compares = getCompares(mwClient.ethernetContainerConfiguration);
+ addShowDescriptionEvent(mwClient);
+ } else {
+ var actualData = data.ethernetContainerConfiguration;
+ mwClient.compares = getCompares(mwClient.ethernetContainerConfiguration, actualData);
+ addShowDescriptionEvent(mwClient);
+ }
+ };
+
+ var updatePart = function(spec, data) {
+ switch (spec.pacId) {
+ case 'ne':
+ updateNe(data);
+ break;
+ case 'airinterface':
+ // console.log(JSON.stringify(spec, JSON.stringify(data)));
+ updateAirInterface(spec, data);
+ break;
+ case 'structure':
+ // console.log(JSON.stringify(data));
+ updateStructure(spec, data);
+ break;
+ case 'container':
+ // console.log(JSON.stringify(data));
+ updateContainer(spec, data);
+ break;
+ }
+ };
+
+ $scope.$watch('status', function(status, oldValue) {
+ Object.keys(status).map(function(key){
+ if ($scope.selection && status[key] && status[key] !== oldValue[key]) {
+ var info = key.split($scope.separator);
+ var spec = {
+ nodeId: $scope.selection,
+ revision: $scope.requiredNetworkElement.onfAirInterfaceRevision,
+ pacId: info[0],
+ requiredLayerProtocolId: info[1],
+ layerProtocolId: $scope.match.mapping[info[1]],
+ partId: 'Configuration'
+ };
+
+ if ($scope.connectionStatus !== 'connected') {
+ updatePart(spec, undefined);
+ return;
+ }
+ if (info.length > 1 && !$scope.match.mapping[info[1]]) {
+ updatePart(spec, undefined);
+ return;
+ }
+
+ $scope.spinner[key] = true;
+ $mwtnCompare.getPacParts(spec).then(function(success){
+ updatePart(spec, success);
+ $scope.spinner[key] = false;
+ }, function(error){
+ updatePart(spec, error);
+ $scope.spinner[key] = false;
+ });
+
+ }
+ });
+ }, true);
+
+
+
+ }]);
+
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.directives.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.directives.js
new file mode 100644
index 00000000..f5fadd77
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.directives.js
@@ -0,0 +1,21 @@
+/*
+ * 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/mwtnCompare/mwtnCompare.module' ], function(mwtnCompareApp) {
+
+ mwtnCompareApp.register.directive('compare', function() {
+ return {
+ restrict : 'A',
+ scope: {
+ item: '=compare'
+ },
+ templateUrl : 'src/app/mwtnCompare/templates/compare.tpl.html'
+ };
+ });
+
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.module.js
new file mode 100644
index 00000000..e3761f36
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.module.js
@@ -0,0 +1,50 @@
+/*
+ * 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'], function(ng) {
+ var mwtnCompareApp = angular.module('app.mwtnCompare', ['app.core', 'ui.router.state','config', 'pascalprecht.translate']);
+
+ mwtnCompareApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnCompareApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/mwtnCompare/mwtnCompare.controller');
+ NavHelperProvider.addToMenu('mwtnCompare', {
+ "link" : "#/pnfCompare/",
+ "active" : "main.mwtnCompare",
+ "title" : "pnf Compare",
+ "icon" : "fa fa-tags", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf Compare",
+ "description" : "mwtnCompare"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnCompare', {
+ url: 'pnfCompare/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnCompare/mwtnCompare.tpl.html',
+ controller: 'mwtnCompareCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnCompareApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.services.js
new file mode 100644
index 00000000..9a133e3b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.services.js
@@ -0,0 +1,26 @@
+/*
+ * 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/mwtnCompare/mwtnCompare.module'],function(mwtnCompareApp) {
+
+ mwtnCompareApp.register.factory('$mwtnCompare', function($mwtnCommons, $mwtnDatabase) {
+
+ var service = {};
+
+ service.getConnectionStatus = $mwtnCommons.getConnectionStatus;
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.getRequiredNetworkElements = $mwtnCommons.getRequiredNetworkElements;
+ service.getSchema = $mwtnDatabase.getSchema;
+ service.getType = $mwtnCommons.getType;
+ service.separator = $mwtnCommons.separator;
+
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.tpl.html
new file mode 100644
index 00000000..b3601ec2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/mwtnCompare.tpl.html
@@ -0,0 +1,333 @@
+<ht-header help-link='sdnr/mwtnCompare/0.4.0/README.md'></ht-header>
+<div id="mwtnCompare">
+ <div class="owl container" style="width: 100%">
+ <div class="row" ng-show="neSelection.length === 0">
+ <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="row" ng-show="neSelection.length > 0">
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'Select planned NetworkElement' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+
+ <input list="networkElements" class="form-control" ng-model="selection">
+ <datalist id="networkElements">
+ <option ng-repeat="ne in neSelection" value="{{ne.id}}">{{ne.id}}</option>
+ </datalist>
+
+ </div>
+ </div>
+ <div class="col-md-2 text-right">
+ <span class="white" ng-class="{'connected':connectionStatus === 'connected'}">{{'MWTN_CONNECTIONSTATUS' | translate}}: </span><br/>
+ <span class="white" ng-class="{'match':match.numberOfLTPs}">{{'MWTN_NUMBEROFLTPS' | translate}}: </span><br/>
+ <span class="white" ng-class="{'match':match.radioSignalIds}">{{'MWTN_RADIOSIGNALIDS' | translate}}: </span>
+ </div>
+ <div class="col-md-2">
+ <a href="#/mwtnConnect">
+ <i ng-show="connectionStatus === 'connected'" class="fa fa-link" aria-hidden="true" ng-class="{'connected':connectionStatus === 'connected'}"></i>
+ <span class="white" ng-class="{'connected':connectionStatus === 'connected'}">{{connectionStatus}}</span>
+ </a><br/>
+ <i ng-class="{'match':match.numberOfLTPs}" ng-show="match.numberOfLTPs" class="fa fa-check-square-o" aria-hidden="true"></i>
+ <span class="white" ng-class="{'match':match.numberOfLTPs}">{{match.numberOfLTPsStatus}}</span><br/>
+ <i ng-class="{'match':match.radioSignalIds}" ng-show="match.radioSignalIds" class="fa fa-check-square-o" aria-hidden="true"></i>
+ <span class="white" ng-class="{'match':match.radioSignalIds}">{{match.radioSignalIdsStatus}}</span>
+ </div>
+ <div class="col-md-2 text-right">
+ <div class="form-group">
+ <button type="button" class="btn btn-default" ng-click="collapseAll()">{{'Collapse all' | translate}}</button>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ <div class="owl container" style="width: 100%">
+ <hr/>
+ <div class="row">
+ <div class="col-md-12">
+ <uib-accordion close-others="oneATime">
+
+ <div uib-accordion-group class="panel-primary" is-open="status.ne">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.ne, 'fa-chevron-right': !status.ne}"></i>
+ <span>{{'MWTN_NETWORKELEMENT' | translate}} '{{requiredNetworkElement['core-model:network-element'].nameList[0].value}}'</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.ne"></i>
+ </uib-accordion-heading>
+<pre>{{requiredNetworkElement | json}}</pre>
+
+ <table class="table">
+ <tr>
+ <td>
+ <table class="footable table table-hover">
+ <thead>
+ <tr>
+ <th class="nowrap">{{ 'Label' | translate }}</th>
+ <th class="nowrap">{{ 'Required value' | translate }}</th>
+ <th class="nowrap">{{ 'Actual value' | translate }}</th>
+ <th>{{ 'Unit' | translate }}</th>
+ <th ng-show="mwps.showDescriptions">{{ 'Description' | translate }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="compare in requiredNetworkElement['core-model:network-element'].compares" compare="compare"></tr>
+ </tbody>
+ </table>
+ </td>
+ <td>
+ <h4 style="color: #444444;">
+ <b>NetworkElement</b>
+ </h4>
+ <p>{{ schema['NetworkElement'].description }}</p>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <div ng-repeat="mwps in requiredNetworkElement.MW_AirInterface_Pac" uib-accordion-group class="panel-primary" is-open="status['airinterface' + separator + mwps.layerProtocol]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status[['airinterface', mwps.layerProtocol].join(separator)], 'fa-chevron-right': !status['airinterface' + separator + airinterface.layerProtocol]}"></i>
+ <span>AirInterface MWPS '{{mwps.layerProtocol}}'</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner[['airinterface', mwps.layerProtocol].join(separator)]"></i>
+ </uib-accordion-heading>
+
+ <div class="text-right">
+ <a style="cursor: pointer;" ng-click="mwps.showDescriptions = !mwps.showDescriptions">
+ <span ng-show="mwps.showDescriptions" style="color: #444444">Hide </span>
+ <span ng-show="!mwps.showDescriptions" style="color: #444444">Show </span>
+ <span style="color: #444444"> descriptions</span>
+ </a>
+ </div>
+
+ <table class="table" ng-show="mwps.showDescriptions">
+ <tr>
+
+ <td style="width: 50%">
+ <div ng-repeat="item in ['LogicalTerminationPoint', 'LayerProtocol', 'MW_AirInterface_Pac']">
+ <h4 style="color: #444444;">
+ <b>{{item}}</b>
+ </h4>
+ {{schema[item].description}}
+ </div>
+ </td>
+ <td style="width: 50%">
+ <h4 style="color: #444444;">
+ <b>AirInterfaceConfiguration</b>
+ </h4>
+ {{schema['AirInterfaceConfiguration'].description}}
+ </td>
+
+ </tr>
+ </table>
+
+
+ <table class="footable table table-hover">
+ <thead>
+ <tr>
+ <th>{{ 'Label' | translate }}</th>
+ <th>{{ 'Required value' | translate }}</th>
+ <th>{{ 'Actual value' | translate }}</th>
+ <th>{{ 'Unit' | translate }}</th>
+ <th ng-show="mwps.showDescriptions">{{ 'Description' | translate }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="compare in mwps.compares" compare="compare"></tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="99" ng-class="text-center">
+ <button class="btn btn-default" title="Operation to planning" ng-click="message('operation2Planning', mwps)">
+ <i class="icon-forward"></i>
+ </button>
+ <button class="btn btn-default" title="Planning to operation" ng-click="message('planning2Operation', mwps)">
+ <i class="icon-backward"></i>
+ </button>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+
+ </div>
+
+ <div ng-repeat="mws in requiredNetworkElement.MW_PureEthernetStructure_Pac" uib-accordion-group class="panel-primary" heading=""
+ is-open="status['structure' + separator + mws.layerProtocol]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status[['structure', mws.layerProtocol].join(separator)], 'fa-chevron-right': !status['structure' + separator + structure.layerProtocol]}"></i>
+ <span>Structure MWS '{{mws.layerProtocol}}'</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner[['structure', mws.layerProtocol].join(separator)]"></i>
+ </uib-accordion-heading>
+
+ <div class="text-right">
+ <a style="cursor: pointer;" ng-click="mws.showDescriptions = !mws.showDescriptions">
+ <span ng-show="mws.showDescriptions" style="color: #444444">Hide </span>
+ <span ng-show="!mws.showDescriptions" style="color: #444444">Show </span>
+ <span style="color: #444444"> descriptions</span>
+ </a>
+ </div>
+
+ <table class="table" ng-show="mws.showDescriptions">
+ <tr>
+
+ <td style="width: 50%">
+ <div ng-repeat="item in ['LogicalTerminationPoint', 'LayerProtocol', 'MW_PureEthernetStructure_Pac']">
+ <h4 style="color: #444444;">
+ <b>{{item}}</b>
+ </h4>
+ {{schema[item].description}}
+ </div>
+ </td>
+ <td style="width: 50%">
+ <h4 style="color: #444444;">
+ <b>PureEthernetStructureConfiguration</b>
+ </h4>
+ {{schema['PureEthernetStructureConfiguration'].description}}
+ </td>
+
+ </tr>
+ </table>
+ <table class="footable table table-hover">
+ <thead>
+ <tr>
+ <th>{{ 'Label' | translate }}</th>
+ <th>{{ 'Required value' | translate }}</th>
+ <th>{{ 'Actual value' | translate }}</th>
+ <th>{{ 'Unit' | translate }}</th>
+ <th ng-show="mws.showDescriptions">{{ 'Description' | translate }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="compare in mws.compares" compare="compare"></tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="99" ng-class="text-center">
+ <button class="btn btn-default" title="Operation to planning" ng-click="message('operation2Planning', mws)">
+ <i class="icon-forward"></i>
+ </button>
+ <button class="btn btn-default" title="Planning to operation" ng-click="message('planning2Operation', mws)">
+ <i class="icon-backward"></i>
+ </button>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+ </div>
+
+ <div ng-repeat="mwClient in requiredNetworkElement.MW_EthernetContainer_Pac" uib-accordion-group class="panel-primary" is-open="status['container' + separator + mwClient.layerProtocol]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status[['container', mwClient.layerProtocol].join(separator)], 'fa-chevron-right': !status['container' + separator + container.layerProtocol]}"></i>
+ <span>Container ETH '{{mwClient.layerProtocol}}'</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner[['container', mwClient.layerProtocol].join(separator)]"></i>
+ </uib-accordion-heading>
+
+ <div class="text-right">
+ <a style="cursor: pointer;" ng-click="mwClient.showDescriptions = !mwClient.showDescriptions">
+ <span ng-show="mwClient.showDescriptions" style="color: #444444">Hide </span>
+ <span ng-show="!mwClient.showDescriptions" style="color: #444444">Show </span>
+ <span style="color: #444444"> descriptions</span>
+ </a>
+ </div>
+ <table class="table" ng-show="mwClient.showDescriptions">
+ <tr>
+ <td style="width: 50%">
+ <div ng-repeat="item in ['LogicalTerminationPoint', 'LayerProtocol', 'MW_EthernetContainer_Pac']">
+ <h4 style="color: #444444;">
+ <b>{{item}}</b>
+ </h4>
+ {{schema[item].description}}
+ </div>
+ </td>
+ <td style="width: 50%">
+ <div ng-repeat="item in ['EthernetContainerConfiguration', 'ethernetContainerConfiguration']">
+ <h4 style="color: #444444;">
+ <b>{{item}}</b>
+ </h4>
+ {{schema[item].description}}
+ </div>
+ </td>
+ </tr>
+ </table>
+
+ <table class="footable table table-hover">
+ <thead>
+ <tr>
+ <th>{{ 'Label' | translate }}</th>
+ <th>{{ 'Required value' | translate }}</th>
+ <th>{{ 'Actual value' | translate }}</th>
+ <th>{{ 'Unit' | translate }}</th>
+ <th ng-show="mwClient.showDescriptions">{{ 'Description' | translate }}</th>
+ </tr>
+ </thead>
+ </tbody>
+ <tr ng-repeat="compare in mwClient.compares" compare="compare"></tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="99" ng-class="text-center">
+ <button class="btn btn-default" title="Operation to planning" ng-click="message('operation2Planning', mwClient)">
+ <i class="icon-forward"></i>
+ </button>
+ <button class="btn btn-default" title="Planning to operation" ng-click="message('planning2Operation', mwClient)">
+ <i class="icon-backward"></i>
+ </button>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+ </div>
+
+ </uib-accordion>
+ </div>
+ </div>
+ </div>
+
+ <div class="container" style="width: 100%">
+ <div class="row">
+ <uib-accordion close-others="oneAtATime">
+ <div uib-accordion-group panel-class="panel-odl" ng-repeat="ne in referenceValues.network.networkElement" is-open="ne.open">
+ <uib-accordion-heading>
+ <i class="pull-left" ng-class="{'icon-angle-down': ne.open, 'icon-angle-right': !ne.open}"></i> <span>Network element: </span> <b>"{{ne.name}}"</b> </uib-accordion-heading>
+ <accordion close-others="oneAtATime">
+ <div uib-accordion-group panel-class="panel-odl" is-open="ne['core-model:network-element'][0].open">
+ <uib-accordion-heading>
+ <i class="pull-left" ng-class="{'icon-angle-down': ne['core-model:network-element'][0].open, 'icon-angle-right': !ne['core-model:network-element'][0].open}"></i> <span>
+ {{ 'Network element' | translate}}
+ <span></uib-accordion-heading>
+1
+
+
+
+</div> <div uib-accordion-group panel-class="panel-odl" ng-repeat="mwps in ne.MW_AirInterface_Pac" is-open="mwps.open"> <uib-accordion-heading>
+<i class="pull-left" ng-class="{'icon-angle-down': mwps.open, 'icon-angle-right': !mwps.open}"></i> <span>
+ LTP ({{mwps.layerProtocol}})
+ <span></uib-accordion-heading>
+
+
+ </div>
+ <div uib-accordion-group panel-class="panel-odl" ng-repeat="mws in ne.MW_PureEthernetStructure_Pac" is-open="mws.open"> <uib-accordion-heading>
+ <i class="pull-left" ng-class="{'icon-angle-down': mws.open, 'icon-angle-right': !mws.open}"></i> <span>
+ LTP ({{mws.layerProtocol}})
+ <span></uib-accordion-heading>
+
+
+ </div>
+ <div uib-accordion-group panel-class="panel-odl" ng-repeat="mwClient in ne.MW_EthernetContainer_Pac" is-open="mwClient.open"> <uib-accordion-heading>
+ <i class="pull-left" ng-class="{'icon-angle-down': mwClient.open, 'icon-angle-right': !mwClient.open}"></i> <span>
+ LTP ({{mwClient.layerProtocol}})
+ <span></uib-accordion-heading>
+ </div>
+ </uib-accordion>
+ <div>
+</div>
+</div>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+ </div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/templates/compare.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/templates/compare.tpl.html
new file mode 100644
index 00000000..c5cbc50a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/mwtnCompare-module/src/main/resources/mwtnCompare/templates/compare.tpl.html
@@ -0,0 +1,12 @@
+<td style="text-align: right;" ng-class="{ 'red': !item.match }">{{['mwtn', item.labelId].join('_').toUpperCase() | translate}}</td>
+<td><b ng-class="{ 'red': !item.match }" ng-bind-html="item.requiredValue"></b></td>
+
+<td>
+ <!-- [sko]: Bug reported by Amy: Of cause item.actualValue === false does not mean "missing"
+ <b ng-show="!item.actualValue">{{ item.missingActualValueLabelId | translate }}</b> -->
+ <b ng-class="{ 'red': !item.match }" ng-bind-html="item.actualValue"></b>
+</td>
+<td>{{ item.unit }}</td>
+<td style="max-width: 300px;" ng-show="item.showDescriptions">
+ {{item.description}}
+</td> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/pom.xml
new file mode 100644
index 00000000..75cedab1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnCompare/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnCompare</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnCompare-module</module>
+ <module>mwtnCompare-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/pom.xml
new file mode 100644
index 00000000..2b8c9823
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnConnect</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnConnect-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnConnect-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnConnect-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..62345db5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,20 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnConnect"/>
+ <property name="url" value="/src/app/mwtnConnect"/>
+ <property name="directory" value="/mwtnConnect"/>
+ <property name="requireJs" value="app/mwtnConnect/mwtnConnect.module"/>
+ <property name="angularJs" value="app.mwtnConnect"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnConnect/mwtnConnect-custom.css</value>
+ <value>src/app/mwtnCommons/mwtnCommons-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/pom.xml
new file mode 100644
index 00000000..c47134aa
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnConnect</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnConnect-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/mwtnConnect.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/mwtnConnect.png
new file mode 100755
index 00000000..7417076f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/mwtnConnect.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/sdncConnect.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/sdncConnect.png
new file mode 100755
index 00000000..4542dc13
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/images/sdncConnect.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect-custom.css
new file mode 100644
index 00000000..1fb5c597
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect-custom.css
@@ -0,0 +1,85 @@
+/**
+ * Add your application related css here
+ * width: 1260px;
+ */
+
+.modal-dialog {
+ width: 690px;
+ margin: 30px auto;
+}
+
+.modal-dialog .modal-lg {
+ min-width: 690px;
+ width: 690px;
+}
+
+.requiredNesGrid span {
+ color: #393939;
+}
+.mwtn-form-control {
+ font-family:'Courier New';
+ /* display: block; */
+ width: 600px;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.428571429;
+ color: #000000;
+ vertical-align: middle;
+ background-color: #eeeeee;
+ background-image: none;
+ border: 1px solid #d5d5d5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ -webkit-transition: all border-color ease-in-out .15s, box-shadow ease-in-out .15s linear;
+ -moz-transition: all border-color ease-in-out .15s, box-shadow ease-in-out .15s linear;
+ -ms-transition: all border-color ease-in-out .15s, box-shadow ease-in-out .15s linear;
+ -o-transition: all border-color ease-in-out .15s, box-shadow ease-in-out .15s linear;
+ transition: all border-color ease-in-out .15s, box-shadow ease-in-out .15s linear;
+}
+
+
+.green {
+ color: darkgreen;
+}
+.green span {
+ color: darkgreen;
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+}
+
+.modal-body h3 {
+ color: #393939;
+}
+
+.modal-body .green span {
+ color: darkgreen;
+}
+
+.requiredNesGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.unknownNesGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.unknownNesGrid .ui-grid-cell-contents span {
+ color: #393939;
+}
+
+.yangCapabilitiesGrid {
+ height: 300px;
+ background-color: white;
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.controller.js
new file mode 100644
index 00000000..c72795c8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.controller.js
@@ -0,0 +1,1143 @@
+/*
+ * 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/mwtnConnect/mwtnConnect.module',
+ 'app/mwtnConnect/mwtnConnect.services',
+ 'app/mwtnCommons/mwtnCommons.module'],
+ function(mwtnConnectApp) {
+
+ mwtnConnectApp.register.controller('mwtnConnectCtrl', ['$scope', '$rootScope', '$timeout', '$window', '$q', 'uiGridConstants', '$uibModal', '$mwtnConnect', '$mwtnLog', 'NetConfServer',
+ function($scope, $rootScope, $timeout, $window, $q, uiGridConstants, $uibModal, $mwtnConnect, $mwtnLog, NetConfServer) {
+
+ var COMPONENT = 'mwtnConnectCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnConnectCtrl started!'});
+
+ $rootScope.section_logo = 'src/app/mwtnConnect/images/sdncConnect.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $mwtnConnect.highlightFilteredHeader;
+
+ $scope.oneAtATime = true;
+ $scope.status = {requiredNes: true};
+ $scope.spinner = {};
+ $scope.spinner.TEST = true;
+
+ var requiredNesConnectionStatusCellTemplate = [
+ '<div class="ui-grid-cell-contents" ng-class="{ \'green\': grid.getCellValue(row, col) === \'connected\'}">',
+ ' <i ng-class="{\'fa fa-link\': grid.getCellValue(row, col) === \'connected\', \'fa fa-chain-broken\': grid.getCellValue(row, col) !== \'connected\'}" aria-hidden="true"></i>',
+ ' <span>{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ var nameCellTemplate = [
+ '<div class="ui-grid-cell-contents">',
+ ' <a href="{{row.entity.webUri}}" target="_blank" title="Access NE web application" ng-show="row.entity.webUri">',
+ ' <i class="fa fa-external-link" aria-hidden="true"></i>',
+ ' <span>{{grid.getCellValue(row, col)}}</span>',
+ ' </a>',
+ ' <span ng-show="!row.entity.webUri">{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ // '<button class="btn btn-primary" ng-click="grid.appScope.edit(row.entity)"><i class="fa fa-pencil"></i></button>',
+ // '<button class="btn btn-default" ng-click="grid.appScope.delete(row.entity)"><i class="fa fa-times mwtnError"></i></button>',
+ var requiredNesActionCellTemplate = [
+ '<span>&nbsp;&nbsp;</span>',
+ '<div class="btn-group">',
+ ' <button class="btn btn-primary" ng-click="grid.appScope.connect(row.entity)" title="Mount"><i class="fa fa-link" aria-hidden="true"></i></button>',
+ ' <button class="btn btn-warning" ng-click="grid.appScope.disconnect(row.entity)" title="Unmount"><i class="fa fa-chain-broken" aria-hidden="true"></i></button>',
+ ' <button class="btn btn-success" ng-click="grid.appScope.showDetails(row.entity)" title="Information"><i class="fa fa-info-circle" aria-hidden="true"></i></button>',
+ '<div class="btn-group">',
+ '<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>',
+ '</div>',
+ ' <a class="btn btn-primary" ng-href="#/pnfFault/{{row.entity.name}}" title="Fault Management" target="fm">F</a>',
+ ' <a class="btn btn-primary" ng-href="#/pnfBrowser/{{row.entity.name}}" title="Configuration Management" target="cm">C</a>',
+ ' <a class="btn btn-default" title="Accounting Management" target="am">A</a>',
+ ' <a class="btn btn-primary" ng-href="#/pnfPerformanceHistory/{{row.entity.name}}" title="Performance Management" target="pm">P</a>',
+ ' <a class="btn btn-default" title="Security Management" target="sm">S</a>',
+ '</div>',
+ '<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>',
+ '<div class="btn-group">',
+ ' <a class="btn btn-primary" ng-href="#/pnfInventory/{{row.entity.name}}" title="Inventory Management" target="im">I</a>',
+ '</div>',
+ '<span>&nbsp;</span>'].join('');
+
+
+ $scope.requiredNesGridOptions = JSON.parse(JSON.stringify($mwtnConnect.gridOptions));
+ $scope.requiredNesGridOptions.rowHeight = 44;
+ $scope.requiredNesGridOptions.columnDefs = [
+ { field: 'connectionStatus', type: 'string', displayName: 'Connection status', headerCellClass: $scope.highlightFilteredHeader, width : 160, cellTemplate: requiredNesConnectionStatusCellTemplate },
+ // { field: 'id', type: 'number', displayName: 'Id', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true , sort: {
+ // direction: uiGridConstants.ASC,
+ // ignoreSort: false,
+ // priority: 0
+ // }},
+ { field: 'name', type: 'string', displayName: 'Name', headerCellClass: $scope.highlightFilteredHeader, width : 230, cellTemplate: nameCellTemplate, pinnedLeft : true , sort: {
+ direction: uiGridConstants.ASC,
+ ignoreSort: false,
+ priority: 0
+ }},
+ { field: 'ipaddress', type: 'number', displayName: 'IP address', headerCellClass: $scope.highlightFilteredHeader, width : 140, cellClass: 'number' },
+ { field: 'port', type: 'number', displayName: 'Port', headerCellClass: $scope.highlightFilteredHeader, width : 80, cellClass: 'number' },
+ { field: 'client', type: 'number', displayName: 'Client', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'username', type: 'string', displayName: 'User name', headerCellClass: $scope.highlightFilteredHeader, width : 100, visible: false },
+ { field: 'password', type: 'string', displayName: 'Password', headerCellClass: $scope.highlightFilteredHeader, width : 100, visible: false },
+ { field: 'radioSignalIds', type: 'string', displayName: 'Radio signal ids', headerCellClass: $scope.highlightFilteredHeader, width : 150, visible: false},
+ {
+ name : 'actions',
+ enableSorting : false,
+ enableFiltering: false,
+ cellTemplate: requiredNesActionCellTemplate,
+ width : 400,
+ pinnedRight : true
+ }
+ ];
+
+ var unknownNesActionCellTemplate = [
+ '<a class="vCenter" ng-class="{attention: grid.appScope.hover, hidden: onfAirInterfaceRevision}" >',
+ '<button class="btn btn-default" ng-show="row.entity[\'node-id\'] !== \'controller-config\'" ng-click="grid.appScope.unmount(row.entity)">Unmount</button>',
+ '<button class="btn btn-primary" ng-show="row.entity[\'node-id\'] !== \'controller-config\' && row.entity.onfCoreModelRevision" ng-click="grid.appScope.addToRequiredNetworkElements(row.entity)">',
+ '<i class="pull-left fa fa-spinner fa-pulse" ng-show="row.entity.spinner"></i>',
+ '<span class="white">{{ "MWTN_MAKE_KNOWN" | translate }}<span>',
+ '</button>',
+ '<button class="btn btn-default" ng-click="grid.appScope.showDetails(row.entity, false)"><i class="fa fa-info-circle" aria-hidden="true"></i></button>',
+ '</a>' ].join('<span>&nbsp;</span>');
+ $scope.unknownNesGridOptions = JSON.parse(JSON.stringify($mwtnConnect.gridOptions));
+ $scope.unknownNesGridOptions.rowHeight = 44;
+ $scope.unknownNesGridOptions.columnDefs = [
+ { field: 'node-id', type: 'string', displayName: 'Name', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 0
+ }},
+ { field: 'netconf-node-topology:host', type: 'number', displayName: 'IP address', headerCellClass: $scope.highlightFilteredHeader, width : 150, cellClass: 'number' },
+ { field: 'netconf-node-topology:port', type: 'number', displayName: 'NetConf port', headerCellClass: $scope.highlightFilteredHeader, width : 120, cellClass: 'number' },
+ { field: 'onfCoreModelRevision', type: 'string', displayName: 'CoreModel revision', headerCellClass: $scope.highlightFilteredHeader, width : 160, cellClass: 'number' },
+ { field: 'onfAirInterfaceRevision', type: 'string', displayName: 'AirInterface revision', headerCellClass: $scope.highlightFilteredHeader, width : 160, cellClass: 'number' },
+ { field: 'netconf-node-topology:connection-status', type: 'string', displayName: 'Connection status', headerCellClass: $scope.highlightFilteredHeader, width : 160 },
+ {
+ name : 'actions',
+ enableSorting : false,
+ enableFiltering: false,
+ cellTemplate: unknownNesActionCellTemplate,
+ width : 330,
+ pinnedRight : true
+ }
+ ];
+
+ /**
+ * Request all defined (required) network elements from database and
+ * update the corresponding table in the ui.
+ */
+ var getRequiredNetworkElements = function() {
+ $mwtnConnect.getRequiredNetworkElements().then(function(networkElements) {
+ $scope.requiredNesGridOptions.data = networkElements;
+ getActualNetworkElements();
+ }, function(error){
+ $scope.requiredNesGridOptions.data = [];
+ });
+ };
+ getRequiredNetworkElements();
+
+ /**
+ * A function, which returns a boolean, which indicates, whether a network
+ * element is required or not.
+ * @param {string} neId - A mount point identifier.
+ * @return {boolean} True, if network element is required in the network, otherwise false.
+ */
+ var isRequired = function(neId) {
+ if ($scope.requiredNesGridOptions.data) {
+ var result = false;
+ $scope.requiredNesGridOptions.data.map(function(rne) {
+ if (rne.name === neId) result = true;
+ });
+ return result;
+ } else {
+ return false;
+ }
+ };
+
+ var setConnectionStatus = function(neId, connectionStatus) {
+ if ($scope.requiredNesGridOptions.data) {
+ $scope.requiredNesGridOptions.data.map(function(rne) {
+ if (rne.name === neId) rne.connectionStatus = connectionStatus;
+ });
+ }
+ };
+
+ var setValues = function(ane) {
+ if ($scope.requiredNesGridOptions.data) {
+
+ var getExtension = function(extensions, name) {
+ if (extensions === undefined) {
+ return undefined;
+ }
+ var result = extensions.filter(function(ex){
+ return ex['value-name'] === name;
+ }).map(function(ex){
+ return ex.value;
+ });
+ if (result.length > 0) {
+ result = result[0];
+ } else {
+ result = undefined;
+ }
+ return result;
+ };
+
+ $scope.requiredNesGridOptions.data.map(function(rne) {
+ // TODO use filter! and avoid push?
+ if (rne.name === ane['node-id']) {
+ rne.connectionStatus = ane['netconf-node-topology:connection-status'];
+ rne.ipaddress = ane['netconf-node-topology:host'];
+ rne.port = ane['netconf-node-topology:port'];
+ rne.client = ane.client;
+
+ rne.onfCapabilities = ane.onfCapabilities;
+
+ var extensions = ['webUri', 'cliAddress', 'appCommand'];
+ extensions.map(function(extension){
+ rne[extension] = undefined;
+ });
+ if (ane.onfCoreModelRevision) {
+ $mwtnConnect.getActualNetworkElement(ane['node-id'], ane.onfCoreModelRevision).then(function(success){
+ success = $mwtnConnect.yangifyObject(success);
+ extensions.map(function(extension){
+ rne[extension] = getExtension(success['network-element'].extension, extension);
+ });
+ }, function(error){
+ // ignore
+ });
+ }
+ }
+ });
+ }
+ };
+
+ var getActualNetworkElements = function() {
+ // aneHash = [];
+ if ($scope.requiredNesGridOptions.data) {
+ $scope.requiredNesGridOptions.data.map(function(ne) {
+ // ne.connectionStatus = 'disconnected';
+ });
+ }
+ $mwtnConnect.getMountPoints().then(function(mountpoints) {
+ $scope.unknownNesGridOptions.data = [];
+ mountpoints.map(function(mountpoint) {
+ if (isRequired(mountpoint['node-id'])) {
+ // setConnectionStatus(ne['node-id'], ne['netconf-node-topology:connection-status']);
+ setValues(mountpoint);
+ } else {
+ // console.log('mountpoint', JSON.stringify(mountpoint));
+ $scope.unknownNesGridOptions.data.push(mountpoint);
+ }
+ });
+ }, function(error){
+ $mwtnLog.info({component: COMPONENT, message: JSON.stringify(error)});
+ });
+ };
+
+ $scope.netconfServer = {};
+
+ /**
+ * 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}} netconfServer - A netConf server object with all connectivity parameters.
+ */
+ $scope.addToRequiredNetworkElements = function(netconfServer) {
+
+ $scope.netconfServer = netconfServer;
+ var neId = netconfServer['node-id'];
+
+ var index = $scope.unknownNesGridOptions.data.map(function(item) {
+ return item['node-id'];
+ }).indexOf(netconfServer['node-id']);
+
+ if (index !== -1 ) {
+ $mwtnConnect.getSingleDocument('mwtn', 'required-networkelement', neId).then(function(doc){
+ // Network element alrady exists in database
+ doc.required = true;
+ $scope.unknownNesGridOptions.data[index].spinner = true;
+ // add to aai
+ // $onapAai.createPnf(neId, doc).then(function(success){
+ // // do nothing
+ // }, function(error) {
+ // // do nothing
+ // });
+ // add to es
+ $mwtnConnect.createSingleDocument('mwtn', 'required-networkelement', neId, doc).then(function(success){
+ $timeout(function() {
+ $scope.status.requiredNes = true;
+ $scope.unknownNesGridOptions.data[index].spinner = false;
+ }, 1000);
+ }, function(error) {
+ $timeout(function() {
+ $scope.status.requiredNes = true;
+ $scope.unknownNesGridOptions.data[index].spinner = false;
+ }, 1000);
+ console.log(JSON.stringify(error));
+ });
+ }, function(error) {
+ // Network element does not exist in database, data inqured from real network element
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnConnect/templates/addToRequired.tpl.html',
+ controller: 'AddToRequiredMessageCtrl',
+ size: 'lg',
+ resolve: {
+ netconfServer: function () {
+ return $scope.netconfServer;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (netconfServer) {
+ $scope.unknownNesGridOptions.data[index].spinner = true;
+ $mwtnConnect.addRequiredNetworkElement(netconfServer).then(function(success){
+ $mwtnLog.info({component: COMPONENT, message: 'Adding to database: ' + netconfServer['node-id']});
+
+ // $onapAai.createPnf(netconfServer['node-id'], success.config.data).then(function(success){
+ // // do nothing
+ // }, function(error) {
+ // // do nothing
+ // });
+
+ $timeout(function() {
+ $scope.status.requiredNes = true;
+ $scope.unknownNesGridOptions.data[index].spinner = false;
+ }, 1000);
+ }, function(error){
+ $scope.unknownNesGridOptions.data[index].spinner = false;
+ $mwtnLog.error({component: COMPONENT, message: JSON.stringify(error)});
+ });
+ }, function () {
+ $mwtnLog.info({component: COMPONENT, message: 'Creation of new planned NetworkElement dismissed!'});
+ });
+ });
+ }
+ };
+
+ $scope.newMountingPoint = {
+ name: 'new-netconf-server',
+ ipaddress: '127.0.0.1',
+ port: 830,
+ username: 'admin',
+ password: 'admin'
+ };
+
+ $scope.mount = function() {
+ $scope.mountError = undefined;
+ $scope.mountSuccess = undefined;
+ $scope.processing = true;
+ $mwtnConnect.mount($scope.newMountingPoint).then(function(success){
+ $scope.processing = false;
+ $scope.mountSuccess = ['NETCONF server', $scope.newMountingPoint.name, 'successfully mounted.'].join(' ');
+ }, function(error){
+ $scope.processing = false;
+ $scope.mountError = ['NETCONF server', $scope.newMountingPoint.name, 'could not be mounted.'].join(' ');
+ });
+ };
+
+ $scope.connect = function(ne) {
+ ne.connectionStatus = 'connecting...';
+ $mwtnConnect.mount(ne).then(function(success){
+ // ne.connectionStatus = 'connected';
+ }, function(error){
+ // ne.connectionStatus = 'connected';
+ });
+ };
+
+ $scope.disconnect = function(ne) {
+ ne.connectionStatus = 'connecting...';
+ $mwtnConnect.unmount(ne.name).then(function(success){
+ ne.connectionStatus = 'disconnected';
+ }, function(error){
+ ne.connectionStatus = 'unknown';
+ });
+ };
+
+ $scope.showDetails = function(ne, required) {
+ $scope.currentNetworkElement = ne;
+ $scope.currentNetworkElement.required = required;
+ if (required !== false) {
+ $scope.currentNetworkElement.required = true;
+ }
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnConnect/templates/mountPointDetails.tpl.html',
+ controller: 'MountPointDetailsCtrl',
+ size: 'lg',
+ resolve: {
+ currentNetworkElement: function () {
+ return $scope.currentNetworkElement;
+ }
+ }
+ });
+
+ modalInstance.result.then(function(success) {
+ if (success.hide || success.delete) {
+ var nodeId = success.hide || success.delete;
+ $scope.requiredNesGridOptions.data.map(function(item, index, array){
+ if (item.name === nodeId) {
+ array.splice(index, 1);
+ }
+ });
+ }
+ $mwtnLog.info({component: COMPONENT, message: 'Mointpoint details closed'});
+ }, function (error) {
+ $mwtnLog.info({component: COMPONENT, message: 'Mointpoint details dismissed!'});
+ });
+ };
+
+ var removeFromNodeList = function(nodeId) {
+ var index = $scope.unknownNesGridOptions.data.length;
+ while (index--) {
+ if ($scope.unknownNesGridOptions.data[index]['node-id'] === nodeId) {
+ $scope.unknownNesGridOptions.data.splice(index, 1);
+ }
+ }
+ };
+
+ $scope.unmount = function(netConfServer) {
+ netConfServer['netconf-node-topology:connection-status'] = 'disconnecting...';
+ $mwtnConnect.unmount(netConfServer['node-id']).then(function(response) {
+ $mwtnLog.info({component: COMPONENT, message: 'Mounting point deleted: ' + netConfServer['node-id'] });
+ removeFromNodeList(netConfServer['node-id']);
+ }, function(error){
+ $mwtnLog.info({component: COMPONENT, message: 'Unmounting of '+netConfServer['node-id']+' failed!'});
+ removeFromNodeList(netConfServer['node-id']);
+ });
+ };
+
+ $scope.edit = function(row) {
+ console.info(JSON.stringify(row));
+ };
+ $scope.delete = function(row) {
+ console.info(JSON.stringify(row));
+ };
+
+ // Connection status log
+ $scope.gridOptionsConnectionStatusLog = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: false,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ maxCount: 0,
+ columnDefs : [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'nodeName', type: 'string', displayName: 'Node name', headerCellClass: $scope.highlightFilteredHeader, width: 200 },
+ { field: 'connectionStatus', type: 'string', displayName: 'Connection status', headerCellClass: $scope.highlightFilteredHeader, width: 500, cellTemplate: requiredNesConnectionStatusCellTemplate }
+ ],
+ data: 'data',
+ onRegisterApi: function(gridApi) {
+ $scope.gridApi = gridApi;
+ $scope.gridApi.core.on.filterChanged( $scope, $scope.filter);
+ $scope.gridApi.core.on.sortChanged( $scope, $scope.sortChanged );
+ $scope.sortChanged($scope.gridApi.grid, [ $scope.gridOptionsConnectionStatusLog.columnDefs[1] ] );
+
+ $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getPage();
+ });
+ }
+ };
+
+ // data visible in connection status log
+ $scope.data = [];
+
+ //stateobject
+ $scope.state = {
+ filter: false,
+ sort: false,
+ lastfilter: null,
+ lastSort: null
+ };
+
+ //filter
+ $scope.filter = function() {
+ var grid = this.grid;
+ var columns=[];
+
+ //get all columns where data was typed in
+ angular.forEach(grid.columns, function(value, key) {
+ if(value.filters[0].term) {
+
+ var col = findColumn(value.displayName);
+ var val = value.filters[0].term;
+
+ switch (col) {
+ case 'event.timeStamp':
+ //convert timestamp to db format
+ val = $mwtnConnect.TimeStampToONFFormat(value.filters[0].term);
+ break;
+ case 'event.type':
+ if ('connected'.startsWith(value.filters[0].term.toLowerCase())) {
+ val = 'ObjectCreationNotificationXml'.toLowerCase();
+ }
+ if ('disconnected'.startsWith(value.filters[0].term.toLowerCase())) {
+ val = 'ObjectDeletionNotificationXml'.toLowerCase();
+ }
+ break;
+ }
+ columns.push({ column: col, value: val }); //create column object
+ }
+ });
+
+ if (columns.length ===0 ) { //all filter data cleared away
+ $scope.state.filter = false;
+ $scope.state.lastfilter = null;
+
+ //get unfiltered data
+ $mwtnConnect.getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ }
+ });
+ } else {
+ //base filter string
+ var filter = {"query": {"bool":{"must":[]}}};
+ //create filter objects
+ var prefixs = columns.map(function(obj){
+ var prefixObj={};
+ prefixObj[obj.column] = obj.value;//add like: {column: "fault.counter", value: "1"} => {"fault.counter":1}
+ return {prefix:prefixObj}; // => {"prefix":{...}}
+ });
+ prefixs.push({"match":{"event.nodeName":"SDN-Controller"}});
+
+ //add objects to must property
+ filter.query.bool.must = prefixs;
+ //save filter
+ $scope.state.lastfilter=filter;
+ $scope.state.filter=true;
+
+ //send data to sdnevents/eventlog/_search
+ $mwtnConnect.getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.total>0) { //only, when hits exist
+ processResponseRecreateList(response);
+ $scope.gridOptionsConnectionStatusLog.totalItems = response.data.hits.total;
+ } else {
+ //clear data from list
+ $scope.data=[];
+ $scope.gridOptionsConnectionStatusLog.totalItems = 0;
+ $scope.gridOptionsConnectionStatusLog.maxCount = 0;
+ $scope.state.filter=false;
+ $scope.state.lastfilter=null;
+ }
+ });
+ }
+ };
+
+ //sort
+ $scope.sortChanged=function(grid, sortColumns){ // sortColumns is an array containing just the column sorted in the grid
+ if (sortColumns.length > 0) {
+ if (sortColumns[0].sort) {
+ var name = sortColumns[0].displayName; // the name of the column sorted
+ var direction = sortColumns[0].sort.direction; // the direction of the column sorted: "desc" or "asc"
+ sort(direction, findColumn(name) );
+ }
+ } else {
+ $scope.state.sort = false;
+ $scope.state.lastSort=null;
+ //get unsorted data
+ $mwtnConnect.getData( ($scope.paginationOptions.pageNumber-1) * $scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function(response) {
+ processResponseRecreateList(response);
+ }, function(error) {
+ processResponseRecreateList([]);
+ });
+ }
+ };
+
+ var processResponseRecreateList = function(response) {
+ if (!response.data || !response.data.hits) {
+ $scope.data = [];
+ $scope.gridOptionsConnectionStatusLog.totalItems = 0; // needed by ui-grid to calculate page number, always update!
+ $scope.gridOptionsConnectionStatusLog.maxCount = 0;
+ return;
+ }
+
+ if($scope.gridOptionsConnectionStatusLog.maxCount < response.data.hits.total){
+ $scope.gridOptionsConnectionStatusLog.maxCount = response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
+ }
+ var list = response.data.hits.hits.map(function(entry) {
+
+ var status = 'unknown';
+ if (entry._source.event.type === 'ObjectCreationNotificationXml' ) {
+ status = 'connected';
+ } else if (entry._source.event.type === 'ObjectDeletionNotificationXml' ) {
+ status = 'disconnected';
+ }
+ return {
+ id: entry._id,
+ timestamp: $mwtnConnect.formatTimeStamp(entry._source.event.timeStamp),
+ nodeName: entry._source.event.objectId,
+ connectionStatus: status
+ };
+ });
+ $scope.data=list;
+ $scope.gridOptionsConnectionStatusLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
+ };
+
+ $scope.paginationOptions = {
+ pageNumber: 1,
+ pageSize: 25,
+ sort: null
+ };
+
+ var getPage = function() {
+ //from, how many, sort, filter
+ $mwtnConnect.getData( ($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function (success) {
+ $scope.gridOptionsConnectionStatusLog.totalItems = success.data.hits.total;
+ processResponseRecreateList(success);
+ }, function(error) {
+ $scope.gridOptionsConnectionStatusLog.totalItems = success.data.hits.total;
+ processResponseRecreateList([]);
+ $mwtnLog.info({component: COMPONENT, message: JSON.stringify(error)});
+ });
+ };
+
+ var processResponseAddToList = function(response) {
+ if (response.data.hits.hits) {
+ if($scope.gridOptionsConnectionStatusLog.maxCount < response.data.hits.total) {
+ $scope.gridOptionsConnectionStatusLog.maxCount = response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
+ }
+ response.data.hits.hits.map(function(entry) {
+ var status = 'disconnected';
+ if (entry._source.event.type === 'ObjectCreationNotificationXml' ) {
+ status = 'connected';
+ }
+ var log = {
+ id: entry._id,
+ timestamp: $mwtnConnect.formatTimeStamp(entry._source.event.timeStamp),
+ nodeName: entry._source.event.objectId,
+ connectionStatus: status
+ };
+ $scope.data.push(log);
+ });
+ }
+ $scope.gridOptionsConnectionStatusLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
+ };
+
+ var sort = function (direction, columnName) {
+
+ var sortObj={};
+ var sort = [ sortObj ];
+ switch (direction) {
+ case uiGridConstants.ASC:
+ //create sort object
+ sortObj[columnName]={order : 'asc'};
+ sort = [ sortObj ];
+ //save last sort
+ $scope.state.lastSort=sort;
+
+ $mwtnConnect.getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ $scope.state.sort=true;
+ }
+ });
+ break;
+
+ case uiGridConstants.DESC:
+ sortObj[columnName]={order : 'desc'};
+ sort = [ sortObj];
+ $scope.state.lastSort=sort;
+
+ $mwtnConnect.getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ $scope.state.sort=true;
+ }
+ });
+ break;
+
+ case undefined:
+
+ $scope.state.sort=false;
+ $scope.state.lastSort=null;
+
+ $mwtnConnect.getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,
+ $scope.paginationOptions.pageSize,
+ $scope.state.lastSort,
+ $scope.state.lastfilter).then(function(response) {
+ processResponseRecreateList(response);
+ });
+ break;
+ }
+ };
+
+ var findColumn= function(name) {
+ if(name === 'Timestamp'){ return 'event.timeStamp'; }
+ else if(name === 'Node name'){ return 'event.objectId'; }
+ else if(name === 'Connection status'){ return 'event.type'; }
+ };
+
+ $scope.paginationStatusMessage = function() {
+
+ var startnum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1;
+ var pagenednum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1+$scope.data.length;
+ if(pagenednum>$scope.gridOptionsConnectionStatusLog.totalItems) pagenednum=pagenednum-1; //reduce by initial added 1
+
+ if($scope.state.filter){
+ var filterTpl = 'Showing {0} to {1} of {2} items (filtered from {3} total items)';
+ return filterTpl.format(startnum, pagenednum, $scope.gridOptionsConnectionStatusLog.totalItems, $scope.gridOptionsConnectionStatusLog.maxCount);
+
+ } else {
+ var defaultTpl = 'Showing {0} to {1} of {2} total items';
+ return defaultTpl.format( startnum, pagenednum, $scope.gridOptionsConnectionStatusLog.maxCount);
+ }
+ };
+
+ $scope.refreshLog = function() {
+
+
+ var from = ($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize;
+ var size = $scope.paginationOptions.pageSize;
+ $scope.processing = true;
+ $scope.spinner.connectionStatusLog = true;
+ $mwtnConnect.getData(from, size, $scope.state.lastSort, $scope.state.lastfilter).then(function(logEntries){
+ $scope.processing = false;
+ $scope.spinner.connectionStatusLog = false;
+ processResponseRecreateList(logEntries);
+ }, function(error){
+ $scope.processing = false;
+ $scope.spinner.connectionStatusLog = false;
+ console.error(JSON.stringify(error));
+ });
+ };
+
+ // browser events
+ $scope.status = {requiredNes : true};
+ $scope.separator = $mwtnConnect.separator; //'&nbsp;'
+ $scope.$watch('status', function(status, oldValue) {
+ Object.keys(status).map(function(key){
+ if (status[key] && status[key] !== oldValue[key]) {
+ switch (key) {
+ case 'requiredNes':
+ getRequiredNetworkElements();
+ break;
+ case 'unkownNes':
+ getActualNetworkElements();
+ break;
+ case 'mount':
+ $scope.mountSuccess = undefined;
+ $scope.mountError = undefined;
+ break;
+ case 'connectionStatusLog':
+ $window.dispatchEvent(new Event("resize"));
+ $scope.refreshLog();
+ break;
+ }
+ }
+ });
+ }, true);
+
+ // odl events
+ // actualNetworkElements - NE added/deleted
+ var listenToActualNetworkElementsNotifications = function(socketLocation) {
+ try {
+ var notificatinSocket = new WebSocket(socketLocation);
+
+ notificatinSocket.onmessage = function(event) {
+ console.log('Event received.');
+ setTimeout(function() {
+ getActualNetworkElements();
+ }, 1000);
+ };
+ notificatinSocket.onerror = function(error) {
+ console.error("Socket error: " + error);
+ };
+ notificatinSocket.onopen = function(event) {
+ console.info("Socket connection opened.");
+ };
+ notificatinSocket.onclose = function(event) {
+ console.info("Socket connection closed.");
+ };
+ } catch (e) {
+ console.error("Error when creating WebSocket" + e);
+ }
+ };
+
+ // var path = '/network-topology:network-topology/network-topology:topology[network-topology:topology-id = "topology-netconf"]';
+ // var path = "/opendaylight-inventory:nodes"; // [sko] works!
+ var path = '/network-topology:network-topology'; // for whatever reason it does not work, but work in Lithium.
+ $mwtnConnect.registerForOdlEvents(path, function(socketLocation) {
+ listenToActualNetworkElementsNotifications(socketLocation);
+ });
+
+ var listenToEventManagerNotifications = function() {
+ $mwtnConnect.getMwtnWebSocketUrl().then(function(success){
+ try {
+ var notificationSocket = new WebSocket(success);
+
+ notificationSocket.onmessage = function(event) {
+ // we process our received event here
+ if (typeof event.data === 'string') {
+ // console.log("Client Received:\n" + event.data);
+ // console.log("---------------------------");
+ $mwtnConnect.formatData(event).then(function(formated) {
+ switch (formated.notifType) {
+ case 'ProblemNotification':
+ case 'AttributeValueChangedNotification':
+ // ignore
+ break;
+ case 'ObjectCreationNotification':
+ case 'ObjectDeletionNotification':
+ if (formated.nodeName === 'SDN-Controller') {
+ $timeout(function() {getActualNetworkElements();}, 500);
+ }
+ break;
+ default:
+ console.error('Missing implementation for', formated.notifType);
+ }
+ }, function(error) {
+ // do nothing
+ });
+ }
+ };
+
+ notificationSocket.onerror = function(error) {
+ console.log("Socket error: " + error);
+ };
+
+ notificationSocket.onopen = function(event) {
+ console.log("Socket connection opened.");
+
+ function subscribe() {
+ if (notificationSocket.readyState === notificationSocket.OPEN) {
+ var data = {
+ 'data' : 'scopes',
+ 'scopes' : [ 'ObjectCreationNotification', 'ObjectDeletionNotification' ]
+ };
+ notificationSocket.send(JSON.stringify(data));
+ }
+ }
+ subscribe();
+ };
+
+ notificationSocket.onclose = function(event) {
+ console.log("Socket connection closed.");
+ };
+ } catch (e) {
+ console.error("Error when creating WebSocket.\n" + e);
+ }
+ }, function(error){
+ console.error("Error when creating WebSocket.\n" + error);
+ });
+ };
+ listenToEventManagerNotifications();
+
+ }]);
+
+ mwtnConnectApp.register.controller('AddToRequiredMessageCtrl', ['$scope', '$uibModalInstance', '$mwtnConnect', 'netconfServer',
+ function ($scope, $uibModalInstance, $mwtnConnect, netconfServer) {
+
+ $scope.netconfServer = netconfServer;
+
+ $mwtnConnect.getMountPoint(netconfServer['node-id']).then(
+ /**
+ * @param {{'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}} mountpoint - The mointpoint form topology-netconf
+ */
+ function(mountpoint) {
+ $scope.netconfServer.username = mountpoint['netconf-node-topology:username'];
+ $scope.netconfServer.password = mountpoint['netconf-node-topology:password'];
+ },
+ function(error){
+ console.log(JSON.stringify(error));
+ }
+ );
+
+ $scope.sites = [];
+ var sort = [ {
+ id : {
+ order : 'asc'
+ }
+ }];
+ $mwtnConnect.getAllData('mwtn', 'site', 0, 20, sort).then(
+ function(sites){
+ // console.log(JSON.stringify(sites));
+ if (sites.data.hits.hits) {
+ sites.data.hits.hits.map(function(site){
+ $scope.sites.push({id:site._source.id, name:site._source.name});
+ });
+ // console.log($scope.sites);
+ }
+ },
+ function(error){
+ $scope.sites = [];
+ }
+ );
+
+ $scope.ok = function () {
+ $uibModalInstance.close($scope.netconfServer);
+ };
+
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss('cancel');
+ };
+
+ $scope.$watch('netconfServer.site', function(newValue, oldValue) {
+ if (newValue !== oldValue) {
+ var sort = [ {
+ id : {
+ order : 'asc'
+ }
+ }];
+ var query = {
+ prefix: {
+ name: newValue
+ }
+ };
+
+ $mwtnConnect.getFilteredSortedData('mwtn', 'site', 0, 20, sort, query).then(
+ function(sites){
+ // console.log(JSON.stringify(sites));
+ if (sites.data.hits.hits) {
+ $scope.sites = sites.data.hits.hits.map(function(site){
+ return {id:site._source.id, name:site._source.name};
+ });
+ // console.log($scope.sites);
+ }
+ },
+ function(error){
+ $scope.sites = [];
+ }
+ );
+ }
+ });
+ }]);
+
+ mwtnConnectApp.register.controller('MountPointDetailsCtrl', ['$scope', '$uibModalInstance', '$uibModal', '$mwtnConnect', '$mwtnLog', 'currentNetworkElement',
+ function ($scope, $uibModalInstance, $uibModal, $mwtnConnect, $mwtnLog, currentNetworkElement) {
+
+ var COMPONENT = 'MountPointDetailsCtrl';
+ // $mwtnLog.info({component: COMPONENT, message: 'MountPointDetailsCtrl started!'});
+
+ $scope.data = {
+ ne: currentNetworkElement,
+ web: {
+ supported: false,
+ protocol: 'http',
+ ipAddress: '127.0.0.1',
+ port: 80,
+ url: '/',
+ getLink : function() {
+ if (currentNetworkElement.webUri) {
+ return currentNetworkElement.webUri;
+ }
+ return [this.protocol,'://', this.ipAddress, this.url ].join('');
+ }
+ },
+ terminal: {
+ supported: false,
+ copied: false,
+ protocol: 'ssh',
+ user: 'cli',
+ ipAddress: '127.0.0.1',
+ getCommand : function() {
+ if (currentNetworkElement.cliAddress) {
+ return currentNetworkElement.cliAddress;
+ }
+ return [this.protocol, ' ', this.user, '@', this.ipAddress].join('');
+ },
+ copyToClipboard : function () {
+ $scope.data.application.copied = false;
+ this.copied = true;
+ var message = 'Copied to clipboard! ' + this.getCommand();
+ $mwtnLog.info({component: COMPONENT, message: message});
+ }
+ },
+ application: {
+ supported: false,
+ copied: false,
+ commandTemplate: 'VendorApp --ne {0}',
+ ipAddress: '127.0.0.1',
+ getCommand : function() {
+ if (currentNetworkElement.appCommand) {
+ return currentNetworkElement.appCommand;
+ }
+ return this.commandTemplate.format(this.ipAddress);
+ },
+ copyToClipboard : function () {
+ $scope.data.terminal.copied = false;
+ $scope.data.application.copied = true;
+ var message = 'Copied to clipboard! ' + this.getCommand();
+ $mwtnLog.info({component: COMPONENT, message: message});
+ }
+ }
+ };
+
+ var nodeId = $scope.data.ne.name || $scope.data.ne['node-id'];
+ $mwtnConnect.getMountPoint(nodeId).then(function(success){
+ $scope.data.mountpoint = success;
+ }, function(error){
+ $scope.data.mountpoint = undefined;
+ });
+
+ if (currentNetworkElement.webUri && currentNetworkElement.webUri !== '') {
+ $scope.data.web.supported = true;
+ $scope.data.web.protocol = currentNetworkElement.webUri.split(':')[0];
+ var matches = currentNetworkElement.webUri.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
+ $scope.data.web.ipAddress = matches && matches[1]; // ipAddress will be null if no match is found
+ }
+ if (currentNetworkElement.cliAddress && currentNetworkElement.cliAddress !== '') {
+ $scope.data.terminal.supported = true;
+ var matches = currentNetworkElement.cliAddress.match(/([^@]+)@([^@]+)/i);
+ $scope.data.terminal.user = matches && matches[1];
+ $scope.data.terminal.ipAddress = matches && matches[2];
+ }
+ if (currentNetworkElement.appCommand && currentNetworkElement.appCommand !== '') {
+ $scope.data.application.supported = true;
+ // [sko] TODO once a mediator supports it
+ }
+
+ $scope.yangCapabilitiesGridOptions = JSON.parse(JSON.stringify($mwtnConnect.gridOptions));
+ $scope.yangCapabilitiesGridOptions.columnDefs = [
+ { field: 'module', type: 'string', displayName: 'module', headerCellClass: $scope.highlightFilteredHeader, width : 600 },
+ { field: 'revision', type: 'string', displayName: 'Revision', headerCellClass: $scope.highlightFilteredHeader, width : 150}
+ ];
+ $scope.yangCapabilitiesGridOptions.data = currentNetworkElement.onfCapabilities;
+
+ // clipboard
+ $scope.supported = false;
+ $scope.error = function (err) {
+ $mwtnLog.error({component: COMPONENT, message: err});
+ };
+
+ $scope.ok = function () {
+ $uibModalInstance.close({ne: currentNetworkElement});
+ };
+
+ $scope.hide = function (ne) {
+ $scope.hideNe = ne;
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnConnect/templates/confirmHide.tpl.html',
+ controller: 'MountPointHideCtrl',
+ size: 'lg',
+ resolve: {
+ hideNe: function () {
+ return $scope.hideNe;
+ }
+ }
+ });
+
+ modalInstance.result.then(
+ function(neId) {
+ $mwtnConnect.getSingleDocument('mwtn', 'required-networkelement', neId).then(
+ function(doc){
+ doc.required = false;
+ $mwtnConnect.createSingleDocument('mwtn', 'required-networkelement', neId, doc).then(
+ function(success){
+ $uibModalInstance.close({hide: neId});
+ },
+ function(error) {
+ $uibModalInstance.close({hide: neId});
+ }
+ );
+ },
+ function(error) {
+ $uibModalInstance.close({hide: neId});
+ }
+ );
+ $mwtnLog.info({component: COMPONENT, message: 'Confirm hide closed'});
+ },
+ function (error) {
+ $mwtnLog.info({component: COMPONENT, message: 'Confirm hide dismissed!'});
+ }
+ );
+ };
+
+ $scope.delete = function (ne) {
+ $scope.deleteNe = ne;
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnConnect/templates/confirmDelete.tpl.html',
+ controller: 'MountPointDeleteCtrl',
+ size: 'lg',
+ resolve: {
+ deleteNe: function () {
+ return $scope.deleteNe;
+ }
+ }
+ });
+
+ modalInstance.result.then(function(success) {
+ // delete from AAi
+ // $onapAai.deletePnf(success).then(function(deleted){
+ // $mwtnLog.info({component: COMPONENT, message: success + ' deleted from AAI.'});
+ // }, function(error){
+ // $mwtnLog.info({component: COMPONENT, message: 'Deletion from AAI failed: ' + success + '\n' + error});
+ // });
+ // delete from ES
+ $mwtnConnect.deleteSingleDocument('mwtn', 'required-networkelement', success).then(function(deleted){
+ $mwtnLog.info({component: COMPONENT, message: success + ' deleted from database.'});
+ $uibModalInstance.close({hide: success});
+ }, function(error){
+ $mwtnLog.info({component: COMPONENT, message: 'Deletion from database failed: ' + success + '\n' + error});
+ });
+ }, function (error) {
+ $mwtnLog.info({component: COMPONENT, message: 'Confirm delete dismissed!'});
+ });
+ };
+
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss('cancel');
+ };
+ }]);
+
+ mwtnConnectApp.register.controller('MountPointHideCtrl', ['$scope', '$uibModalInstance', '$mwtnConnect', '$mwtnLog', 'hideNe',
+ function ($scope, $uibModalInstance, $mwtnConnect, $mwtnLog, hideNe) {
+ $scope.hideNe = hideNe;
+ $scope.ok = function () {
+ $uibModalInstance.close($scope.hideNe.name);
+ };
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss('cancel');
+ };
+
+ }]);
+
+ mwtnConnectApp.register.controller('MountPointDeleteCtrl', ['$scope', '$uibModalInstance', '$mwtnConnect', '$mwtnLog', 'deleteNe',
+ function ($scope, $uibModalInstance, $mwtnConnect, $mwtnLog, deleteNe) {
+ $scope.deleteNe = deleteNe;
+ $scope.ok = function () {
+ $uibModalInstance.close($scope.deleteNe.name);
+ };
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss('cancel');
+ };
+
+ }]);
+
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.module.js
new file mode 100644
index 00000000..c280a956
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnConnectApp = angular.module('app.mwtnConnect', [ 'ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'angular-clipboard' ]);
+
+ mwtnConnectApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+
+ mwtnConnectApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnConnect/mwtnConnect.controller');
+ NavHelperProvider.addToMenu('mwtnConnect', {
+ "link" : "#/connect",
+ "active" : "main.mwtnConnect",
+ "title" : "Connect",
+ "icon" : "fa fa-plug", // Add navigation icon css class here
+ "page" : {
+ "title" : "Connect",
+ "description" : "Connection supervision of physical network function to ONAP SDN-C-4-Wireless"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnConnect', {
+ url: 'connect',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnConnect/mwtnConnect.tpl.html',
+ controller: 'mwtnConnectCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnConnectApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.services.js
new file mode 100644
index 00000000..8f8b55c7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.services.js
@@ -0,0 +1,75 @@
+/*
+ * 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/mwtnConnect/mwtnConnect.module','app/mwtnCommons/mwtnCommons.services'],function(mwtnConnectApp) {
+
+
+ mwtnConnectApp.register.factory('$mwtnConnect', function($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnConnect';
+ $mwtnLog.info({component: COMPONENT, message: '$mwtnConnect started!'});
+
+ var service = {};
+
+ service.addRequiredNetworkElement = $mwtnCommons.addRequiredNetworkElement;
+ service.createSingleDocument = $mwtnDatabase.createSingleDocument;
+ service.deleteSingleDocument = $mwtnDatabase.deleteSingleDocument;
+ service.formatData = $mwtnCommons.formatData;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.getAllData = $mwtnDatabase.getAllData;
+ service.getFilteredSortedData = $mwtnDatabase.getFilteredSortedData;
+ service.getMountPoint = $mwtnCommons.getMountPoint;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.getActualNetworkElement = $mwtnCommons.getActualNetworkElement;
+ service.getRequiredNetworkElements = $mwtnCommons.getRequiredNetworkElements;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.getSingleDocument = $mwtnDatabase.getSingleDocument;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+
+ service.registerForOdlEvents = $mwtnCommons.registerForOdlEvents;
+ service.separator = $mwtnCommons.separator;
+
+ service.mount = $mwtnCommons.mount;
+ service.unmount = $mwtnCommons.unmount;
+ service.yangifyObject = $mwtnCommons.yangifyObject;
+
+
+ service.getData = function(from, size, sort, query){
+ if (!sort) { //default sort value
+ sort = [ { 'event.timeStamp' : {order : 'desc'}}];
+ }
+ if (!query) { //default filter value
+ query= {prefix: {'event.nodeName': 'SDN-Controller'}};
+ }
+ return getFilteredSortedData(from, size, sort, query);
+ };
+
+ var getFilteredSortedData = function(from, size, sort, query){
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredSortedData('sdnevents', 'eventlog', from, size, sort, query).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: 'private getFilteredSortedData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.TimeStampToONFFormat = function(timestamp) {
+ timestamp=timestamp.split('-').join('');
+ timestamp=timestamp.split(':').join('');
+ timestamp=timestamp.split(' ').join('');
+ timestamp=timestamp.replace('UTC','Z');
+ return timestamp;
+ };
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.tpl.html
new file mode 100644
index 00000000..73fc0fcf
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/mwtnConnect.tpl.html
@@ -0,0 +1,150 @@
+<ht-header help-link='sdnr/connect/0.4.0/README.md'></ht-header>
+
+<uib-accordion close-others="oneAtATime">
+
+<div uib-accordion-group class="panel-primary"
+ is-open="status.requiredNes">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.requiredNes, 'fa-chevron-right': !status.requiredNes}"></i>
+ <span>{{'MWTN_REQUIRED_NETWORK_ELEMENTS' | translate}}</span>
+ </uib-accordion-heading>
+ <div id="requiredNesGrid" ui-grid="requiredNesGridOptions"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="requiredNesGrid">
+ </div>
+</div>
+
+<div uib-accordion-group class="panel-default"
+ is-open="status.unkownNes">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.unkownNes, 'fa-chevron-right': !status.unkownNes}"></i>
+ <span>{{'MWTN_UNKNOWN_NETWORK_ELEMENTS' | translate}}</span>
+ </uib-accordion-heading>
+ <div id="unknownNesGrid" ui-grid="unknownNesGridOptions"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="unknownNesGrid">
+ </div>
+</div>
+
+<div uib-accordion-group class="panel-default"
+ is-open="status.mount">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.mount, 'fa-chevron-right': !status.mount}"></i>
+ <span>{{'Mount NETCONF Servers (devices, nodes, mediators, controllers, ...)' | translate}}</span>
+ </uib-accordion-heading>
+ <div class="container">
+ <div class="row" ng-repeat="(key, value) in newMountingPoint">
+ <div class="col-md-2 text-right">
+ <span>{{['mwtn', key].join('_').toUpperCase() | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input type="text" class="form-control"
+ ng-model="newMountingPoint[key]"></input>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6 text-right">
+ <br />
+ <button type="button" class="btn btn-primary" ng-click="mount()">
+ <i class="fa fa-spinner" ng-class="{'fa-pulse':processing}" ng-show="processing" aria-hidden="true"></i>
+ <span>{{'MWTN_MOUNT' | translate}}</span>
+ </button>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <br />
+ <span class="mwtnSuccess" style="color: darkgreen;">{{mountSuccess}}</span>
+ <span class="mwtnError" style="color: red;">{{mountError}}</span>
+ </div>
+ </div>
+ </div>
+</div>
+
+<div uib-accordion-group class="panel-default"
+ is-open="status.connectionStatusLog">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.connectionStatusLog, 'fa-chevron-right': !status.connectionStatusLog}"></i>
+ <span>{{'MWTN_CONNECTION_STATUS_LOG' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.connectionStatusLog"></i>
+ </uib-accordion-heading>
+
+ <div id="mwtnConnectGridConnectionStatusLog"
+ ui-grid="gridOptionsConnectionStatusLog"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnConnectGrid">
+ </div>
+
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="paginationOptions.pageNumber === 1"
+ ng-click="gridApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="paginationOptions.pageNumber === 1"
+ ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}"
+ ng-click="gridApi.pagination.previousPage()"
+
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="paginationOptions.pageNumber"
+ ng-change="seekPage(paginationOptions.pageNumber)"
+ type="text" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridApi.pagination.getTotalPages() }}</span>
+
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridApi.pagination.pageNumber === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridApi.pagination.pageNumber === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.seek(gridApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+
+ <select
+ class="btn btn-default" name="repeatSelect" id="repeatSelect"
+ ng-init="gridOptionsConnectionStatusLog.paginationPageSize = gridOptionsConnectionStatusLog.paginationPageSizes[0]"
+ ng-model="gridOptionsConnectionStatusLog.paginationPageSize"
+ ng-options="option for option in gridOptionsConnectionStatusLog.paginationPageSizes"></select>
+
+ <span class="dark"> items per page </span>
+
+ <span class="pull-right dark">{{ paginationStatusMessage() }}</span>
+
+ </div>
+
+ <div class="text-right">
+ <!--
+ <button type="button" id="clearLog" class="btn btn-warning" ng-click="clearLog()">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span>Clear log...</span>
+ </button>
+ see gird menu Export ...
+ <button type="button" id="saveLog" class="btn btn-default" ng-click="saveLog()">
+ <i class="fa fa-save" aria-hidden="true"></i>
+ <span>Save...</span>
+ </button> -->
+ <button type="button" id="refreshLog" class="btn btn-primary" ng-click="refreshLog()">
+ <span>{{'MWTN_REFRESH' | translate}}</span>
+ </button>
+ </div>
+
+</div>
+
+</uib-accordion>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/addToRequired.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/addToRequired.tpl.html
new file mode 100644
index 00000000..d2a0903a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/addToRequired.tpl.html
@@ -0,0 +1,79 @@
+
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'Add to required NetworkElements' | translate}}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+
+ <div class="container" style="max-width: 600px;">
+
+ <div class="row">
+ <div class="col-md-12">
+ <span>Create a new NetworkElement in planning database as clone of existing real NetworkElement.</span>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_NAME' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input class="form-control" type="text" ng-model="netconfServer['node-id']"></input>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_IPADDRESS' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input class="form-control" type="text" ng-model="netconfServer['netconf-node-topology:host']"></input>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_NETCONF_PORT' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input class="form-control" type="text" ng-model="netconfServer['netconf-node-topology:port']"></input>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_USERNAME' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input class="form-control" type="text" ng-model="netconfServer.username"></input>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_PASSWORD' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <input class="form-control" type="password" ng-model="netconfServer.password"></input>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4 text-right">
+ <span>{{'MWTN_SITE' | translate}}</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <input list="sites" class="form-control" ng-model="netconfServer.site">
+ <datalist id="sites">
+ <option ng-repeat="site in sites" value="{{site.id}}" >{{site.name}}</option>
+ </datalist>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="ok()">{{'MWTN_ADD_TO_REQUIRED_NETWORKELEMENTS' | translate}}</button>
+ <button class="btn btn-warning" type="button" ng-click="cancel()">{{'MWTN_CANCEL' | translate}}</button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmDelete.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmDelete.tpl.html
new file mode 100644
index 00000000..03a7de72
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmDelete.tpl.html
@@ -0,0 +1,23 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'MWTN_DELETE' | translate}}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div class="container" style="max-width: 600px;">
+ <div class="row">
+ <div class="col-md-12">
+ <span>Delete {{node.id}} from the planning database.</span>
+ <br/>
+ <span>All the planning data for this network element will be lost.</span>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-danger" type="button" ng-click="ok()">
+ <i class="fa fa-trash" aria-hidden="true"></i>
+ <span>{{'MWTN_DELETE' | translate}}</span>
+ </button>
+ <button class="btn btn-warning" type="button" ng-click="cancel()">
+ <span>{{'MWTN_CANCEL' | translate}}</span>
+ </button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmHide.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmHide.tpl.html
new file mode 100644
index 00000000..c52ee3f4
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/confirmHide.tpl.html
@@ -0,0 +1,21 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'MWTN_HIDE' | translate}}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div class="container" style="max-width: 600px;">
+ <div class="row">
+ <div class="col-md-12">
+ <span>Remove {{node.id}} from the list of required network elements.</span>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="ok()">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span>{{'MWTN_HIDE' | translate}}</span>
+ </button>
+ <button class="btn btn-warning" type="button" ng-click="cancel()">
+ <span>{{'MWTN_CANCEL' | translate}}</span>
+ </button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/mountPointDetails.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/mountPointDetails.tpl.html
new file mode 100644
index 00000000..56563b4f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/mwtnConnect-module/src/main/resources/mwtnConnect/templates/mountPointDetails.tpl.html
@@ -0,0 +1,125 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{ data.ne.name }}{{ data.ne['node-id'] }}</h3>
+</div>
+<div class="modal-body" id="modal-body" ng-hide="data.ne.required">
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span>{{'MWTN_NETWORKELEMENT' | translate}}</span>
+ </div>
+ <div class="col-md-10">
+ <b>{{data.ne['node-id']}}</b>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span>{{'MWTN_IPADDRESS' | translate}}</span>
+ </div>
+ <div class="col-md-10">
+ <b>{{data.ne['netconf-node-topology:host']}}</b>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span>{{'MWTN_PORT' | translate}}</span>
+ </div>
+ <div class="col-md-10">
+ <b>{{data.ne['netconf-node-topology:port']}}</b>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span>{{'MWTN_USERNAME' | translate}}</span>
+ </div>
+ <div class="col-md-10">
+ <b>{{data.mountpoint['netconf-node-topology:username']}}</b>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span>{{'MWTN_PASSWORD' | translate}}</span>
+ </div>
+ <div class="col-md-10">
+ <b>{{data.mountpoint['netconf-node-topology:password']}}</b>
+ </div>
+ </div>
+</div>
+<div class="modal-body" id="modal-body" ng-show="data.ne.required">
+ <!-- web -->
+ <div ng-show="data.web.supported">
+ <p>
+ <span>The network element supports a native web user interface.</span>
+ <br/>
+ <span> Please use following link:</span>
+ <div class="input-append">
+ <input class="mwtn-form-control" type="text" value="{{ data.web.getLink() }}" readonly></input>
+ <a class="btn btn-default" href="{{ data.web.getLink() }}" target="_blank">
+ <i class="fa fa-external-link" aria-hidden="true"></i>
+ </a>
+ </div>
+ <p>
+ </div>
+ <div ng-show="!data.web.supported">
+ <p>The network element does not support a native web user interface.</p>
+ </div>
+ <!-- terminal -->
+ <hr/>
+ <div ng-show="data.terminal.supported">
+ <p>
+ <span>The network element supports a native terminal or console application.</span>
+ <br/>
+ <span>Please the copy button and paste the command into a terminal window:</span>
+ <p>
+ <div class="input-append">
+ <input class="mwtn-form-control" type="text" value="{{ data.terminal.getCommand() }}" readonly></input>
+ <button class="btn btn-default" type="button" clipboard supported="supported" text="data.terminal.getCommand()" on-copied="data.terminal.copyToClipboard()" on-error="error(err)">
+ <i class="fa fa-clipboard" aria-hidden="true"></i>
+ </button>
+ <span ng-show="data.terminal.copied === true" class="green">Check your clipboard.</span>
+ </div>
+ </div>
+ <div ng-show="!data.web.supported">
+ <p>The network element does not support a native terminal or console application.</p>
+ </div>
+
+ <!-- application -->
+ <hr/>
+ <div ng-show="data.application.supported">
+ <p>
+ <span>The network element can be managed via a pre-installed application.</span>
+ <br/>
+ <span>Please the copy button and paste the command into a terminal window:</span>
+ <p>
+ <div class="input-append">
+ <input class="mwtn-form-control" type="text" value="{{ data.application.getCommand() }}" readonly></input>
+ <button class="btn btn-default" type="button" clipboard supported="supported" text="data.application.getCommand()" on-copied="data.application.copyToClipboard()" on-error="error(err)">
+ <i class="fa fa-clipboard" aria-hidden="true"></i>
+ </button>
+ <span ng-show="data.application.copied === true" class="green">Check your clipboard.</span>
+ </div>
+ </div>
+
+</div>
+<div class="modal-body" id="modal-body">
+ <!-- yang capabilites -->
+ <hr/>
+ <h3>{{ 'MWTN_YANG_CAPABILITIES' | translate }}</h3>
+ <div id="yangCapabilitiesGrid"
+ ui-grid="yangCapabilitiesGridOptions"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="yangCapabilitiesGrid">
+ </div>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-danger" type="button" ng-show="data.ne.required" ng-click="delete(data.ne)">
+ <i class="fa fa-trash" aria-hidden="true"></i>
+ <span>{{'MWTN_DELETE' | translate}}...</span>
+ </button>
+ <button class="btn btn-warning" type="button" ng-show="data.ne.required" ng-click="hide(data.ne)">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span>{{'MWTN_HIDE' | translate}}...</span>
+ </button>
+ <button class="btn btn-primary" type="button" ng-click="ok()">
+ <span>{{'MWTN_CLOSE' | translate}}</span>
+ </button>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/pom.xml
new file mode 100644
index 00000000..273501d5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnConnect/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnConnect</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnConnect-module</module>
+ <module>mwtnConnect-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/pom.xml
new file mode 100644
index 00000000..9a9504ac
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnEvents</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnEvents-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnEvents-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnEvents-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..4cac53b2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnEvents"/>
+ <property name="url" value="/src/app/mwtnEvents"/>
+ <property name="directory" value="/mwtnEvents"/>
+ <property name="requireJs" value="app/mwtnEvents/mwtnEvents.module"/>
+ <property name="angularJs" value="app.mwtnEvents"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnEvents/mwtnEvents-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/pom.xml
new file mode 100644
index 00000000..cf3ec048
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnEvents</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnEvents-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/images/mwtnEvents.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/images/mwtnEvents.png
new file mode 100755
index 00000000..d93e6df5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/images/mwtnEvents.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents-custom.css
new file mode 100644
index 00000000..211adc44
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents-custom.css
@@ -0,0 +1,12 @@
+/**
+ * Add your application related css here
+ */
+.mwtnEventsGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnEventsGrid span {
+ color: #393939;
+}
+ \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.controller.js
new file mode 100644
index 00000000..1a545adb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.controller.js
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Tech Mahindra Ltd. 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/mwtnEvents/mwtnEvents.module', 'app/mwtnEvents/mwtnEvents.services', 'app/mwtnCommons/mwtnCommons.services'],
+ function(mwtnEventsApp) {
+
+ mwtnEventsApp.register
+ .controller(
+ 'mwtnEventsCtrl',
+ [
+ '$scope',
+ '$rootScope',
+ '$mwtnEvents',
+ 'uiGridConstants',
+ function($scope, $rootScope, $mwtnEvents, uiGridConstants) {
+
+ $rootScope.section_logo = 'src/app/mwtnEvents/images/mwtnEvents.png';
+
+ $scope.status = {alarms:true};
+ $scope.oneATime = true;
+
+ $scope.gridOptionsAlarms = JSON.parse(JSON.stringify($mwtnEvents.gridOptions));
+ $scope.gridOptionsAlarms.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ // { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timeStamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 90 },
+ { field: 'nodeName', type: 'string', displayName: 'NetworkElement', headerCellClass: $scope.highlightFilteredHeader, width: 170 },
+ { field: 'objectId', type: 'string', displayName: 'Object', headerCellClass: $scope.highlightFilteredHeader, width: 400 },
+
+ { field: 'problem', type: 'string', displayName: 'Alarm', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 100 }
+ ];
+
+ $scope.gridOptionsAVC = JSON.parse(JSON.stringify($mwtnEvents.gridOptions));
+ $scope.gridOptionsAVC.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ // { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timeStamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 90 },
+ { field: 'nodeName', type: 'string', displayName: 'NetworkElement', headerCellClass: $scope.highlightFilteredHeader, width: 170 },
+ { field: 'objectId', type: 'string', displayName: 'Object', headerCellClass: $scope.highlightFilteredHeader, width: 400 },
+ { field: 'attributeName', type: 'string', displayName: 'Attribute', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'newValue', type: 'string', displayName: 'New value', headerCellClass: $scope.highlightFilteredHeader, width : 140 }
+ ];
+
+ $scope.gridOptionsObject = JSON.parse(JSON.stringify($mwtnEvents.gridOptions));
+ $scope.gridOptionsObject.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ // { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timeStamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 90 },
+ { field: 'nodeName', type: 'string', displayName: 'NetworkElement', headerCellClass: $scope.highlightFilteredHeader, width: 170 },
+ { field: 'objectId', type: 'string', displayName: 'Object', headerCellClass: $scope.highlightFilteredHeader, width: 400 },
+ { field: 'objectType', type: 'string', displayName: 'Type', headerCellClass: $scope.highlightFilteredHeader, width: 400 },
+ { field: 'action', type: 'string', displayName: 'Action', headerCellClass: $scope.highlightFilteredHeader, width: 100 }
+
+ ];
+
+ var listenToNotifications = function() {
+ $mwtnEvents.getMwtnWebSocketUrl().then(function(success){
+
+ try {
+ var notificationSocket = new WebSocket(success);
+
+ notificationSocket.onmessage = function(event) {
+ // we process our received event here
+ if (typeof event.data === 'string') {
+ // console.log("Client Received:\n" + event.data);
+ // console.log("---------------------------");
+ $mwtnEvents.formatData(event).then(function(formated) {
+ switch (formated.notifType) {
+ case 'ProblemNotification':
+ $scope.gridOptionsAlarms.data.push(formated);
+ break;
+ case 'AttributeValueChangedNotification':
+ $scope.gridOptionsAVC.data.push(formated);
+ break;
+ case 'ObjectCreationNotification':
+ formated.action = 'created';
+ if (formated.nodeName.contains('SDN-Controller')) {
+ formated.objectType = 'NETCONF session';
+ }
+ $scope.gridOptionsObject.data.push(formated);
+ break;
+ case 'ObjectDeletionNotification':
+ formated.action = 'deleted';
+ if (formated.nodeName.contains('SDN-Controller')) {
+ formated.objectType = 'NETCONF session';
+ }
+ $scope.gridOptionsObject.data.push(formated);
+ break;
+ default:
+ console.error('Missing implementation for', formated.notifType);
+ }
+ }, function(error) {
+ // do nothing
+ });
+ }
+ };
+
+ notificationSocket.onerror = function(error) {
+ console.log("Socket error: " + error);
+ };
+
+ notificationSocket.onopen = function(event) {
+ console.log("Socket connection opened.");
+ console.log("---------------------------");
+
+ function subscribe() {
+ if (notificationSocket.readyState === notificationSocket.OPEN) {
+ var data = {
+ 'data' : 'scopes',
+ 'scopes' : [ "ObjectCreationNotification",
+ "ObjectDeletionNotification",
+ "AttributeValueChangedNotification",
+ "ProblemNotification" ]
+ };
+ notificationSocket.send(JSON.stringify(data));
+ }
+ }
+ subscribe();
+ };
+
+ notificationSocket.onclose = function(event) {
+ console.log("Socket connection closed.");
+ };
+ } catch (e) {
+ console.error("Error when creating WebSocket.\n" + e);
+ }
+ }, function(error){
+ console.error("Error when creating WebSocket.\n" + error);
+ });
+ };
+ listenToNotifications();
+ } ]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.module.js
new file mode 100644
index 00000000..f059d6d1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.module.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Tech Mahindra Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define([ 'angularAMD', 'app/routingConfig', 'app/core/core.services',
+ 'common/config/env.module' ,
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnEventsApp = angular.module('app.mwtnEvents', [ 'app.core',
+ 'ui.router.state', 'config' ]);
+
+ mwtnEventsApp.config(function($stateProvider, $compileProvider,
+ $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnEventsApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnEvents/mwtnEvents.controller');
+ NavHelperProvider.addToMenu('mwtnEvents', {
+ "link" : "#/pnfEvents",
+ "active" : "main.mwtnEvents",
+ "title" : "pnf Events",
+ "icon" : "fa fa-bolt", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf Events",
+ "description" : "Events"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnEvents', {
+ url : 'mwtnEvents',
+ access : access.admin,
+ views : {
+ 'content' : {
+ templateUrl : 'src/app/mwtnEvents/mwtnEvents.tpl.html',
+ controller : 'mwtnEventsCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnEventsApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.services.js
new file mode 100644
index 00000000..1cd41fb7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.services.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 Tech Mahindra Ltd. 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/mwtnEvents/mwtnEvents.module' ], function(mwtnEventsApp) {
+
+ mwtnEventsApp.register.factory('$mwtnEvents', function($mwtnCommons) {
+
+ var service = {};
+
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.formatData = $mwtnCommons.formatData;
+
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.tpl.html
new file mode 100644
index 00000000..b0a2ed41
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/mwtnEvents.tpl.html
@@ -0,0 +1,45 @@
+<ht-header help-link='sdnr/mwtnEvents/0.4.0/README.md'></ht-header>
+<div class="mwtnError">{{error}}</div>
+
+<uib-accordion close-others="oneATime">
+
+<div uib-accordion-group class="panel-primary" is-open="status.alarms">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.alarms, 'fa-chevron-right': !status.alarms}"></i>
+ <span>{{'MWTN_ALARMS' | translate}}
+ ({{gridOptionsAlarms.data.length}})</span> </uib-accordion-heading>
+
+
+ <div id="mwtnEventsGridAlarms" ui-grid="gridOptionsAlarms"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="mwtnEventsGrid"></div>
+</div>
+
+<div uib-accordion-group class="panel-primary" is-open="status.avc">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.avc, 'fa-chevron-right': !status.avc}"></i>
+ <span>{{'MWTN_ATTRIBUTE_VALUE_CHANGED' | translate}}
+ ({{gridOptionsAVC.data.length}})</span> </uib-accordion-heading>
+
+
+ <div id="mwtnEventsGridAVC" ui-grid="gridOptionsAVC" ui-grid-exporter
+ ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnEventsGrid"></div>
+</div>
+
+<div uib-accordion-group class="panel-primary" is-open="status.object">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.object, 'fa-chevron-right': !status.object}"></i>
+ <span>{{'MWTN_OBJECT_DELETION_CREATION' | translate}}
+ ({{gridOptionsObject.data.length}})</span> </uib-accordion-heading>
+
+ <div id="mwtnEventsGridObject" ui-grid="gridOptionsObject"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="mwtnEventsGrid"></div>
+</div>
+
+</uib-accordion>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/xml2json.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/xml2json.js
new file mode 100644
index 00000000..5ff7e578
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/mwtnEvents-module/src/main/resources/mwtnEvents/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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g, '&#x2F;');
+ else
+ return str;
+ }
+
+ function unescapeXmlChars(str) {
+ return str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&#x2F;/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;
+ };
+
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/pom.xml
new file mode 100644
index 00000000..e898be3c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnEvents/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnEvents</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnEvents-module</module>
+ <module>mwtnEvents-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/pom.xml
new file mode 100644
index 00000000..bceb9084
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnFault</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnFault-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnFault-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnFault-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..2f89a41c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnFault"/>
+ <property name="url" value="/src/app/mwtnFault"/>
+ <property name="directory" value="/mwtnFault"/>
+ <property name="requireJs" value="app/mwtnFault/mwtnFault.module"/>
+ <property name="angularJs" value="app.mwtnFault"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnFault/mwtnFault-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml
new file mode 100644
index 00000000..f0d7215d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnFault</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnFault-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png
new file mode 100755
index 00000000..47bfc70c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/images/mwtnFault.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css
new file mode 100644
index 00000000..7e959b1e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault-custom.css
@@ -0,0 +1,100 @@
+/**
+ * Add your application related css here
+ */
+.global-alarm-status {
+ float: left;
+ margin: 5px;
+ margin-left: 8px;
+}
+
+.global-alarm-status a {
+ color:azure;
+ text-decoration: none;
+}
+
+.global-alarm-status a:visited {
+ color:azure;
+ text-decoration: none;
+}
+
+.global-alarm-status a:hover {
+ color:bisque;
+}
+s
+.mwtn span {
+ color: white;
+}
+.mwtn a span {
+ color: white;
+}
+.Critical {
+ color: red;
+}
+.Major {
+ color: orange;
+}
+.Minor {
+ color: yellow;
+}
+.Warning {
+ color: #428bca;
+}
+.cleared {
+ color: lightgreen;
+}
+
+.mwtnFaultGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnFaultGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.mwtnFaultGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.mwtnFaultGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.mwtnFaultGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.mwtnFaultGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js
new file mode 100644
index 00000000..d29d547d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.controller.js
@@ -0,0 +1,597 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnFault/mwtnFault.module',
+ 'app/mwtnFault/mwtnFault.services',
+ 'app/mwtnFault/mwtnFault.directives'],
+ function(mwtnFaultApp) {
+
+ mwtnFaultApp.register.controller('mwtnFaultCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$mwtnFault', '$mwtnLog', '$http',
+ function(uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $mwtnFault, $mwtnLog, $http) {
+
+
+ var COMPONENT = 'mwtnFaultCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnFaultCtrl started!'});
+
+ $rootScope.section_logo = 'src/app/mwtnFault/images/mwtnFault.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.date = new Date().toISOString().toHumanReadableTimeFormat();
+ $scope.highlightFilteredHeader = $mwtnFault.highlightFilteredHeader;
+ $scope.oneATime = true;
+
+ // var rowTemplate = '<div ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ng-class="[\'ui-grid-cell\', row.entity.type]" ui-grid-cell></div>';
+ var iconCell = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i class="fa {{COL_FIELD}}" aria-hidden="true"></i></div>';
+ var getIconFromSeverity = function(severity) {
+ var mapping = {
+ Cleared : '',
+ NonAlarmed : '',
+ Critical : 'fa-exclamation-triangle',
+ Major : 'fa-exclamation-triangle',
+ Minor : 'fa-exclamation-triangle',
+ Warning : 'fa-times-circle'
+ };
+ return mapping[severity];
+ };
+
+ // Current Problem List
+ $scope.gridOptionsCurrentProblemList = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
+ $scope.gridOptionsCurrentProblemList.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'node', type: 'string', displayName: 'Node name', headerCellClass: $scope.highlightFilteredHeader, width: 200 },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' },
+ { field: 'object', type: 'string', displayName: 'Object Id', headerCellClass: $scope.highlightFilteredHeader, width: 300 },
+ { field: 'problem', type: 'string', displayName: 'Alarm type', headerCellClass: $scope.highlightFilteredHeader, width : 200 },
+ { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 150 }
+
+ ];
+
+ var processCurrentProblemEntries = function(logEntries) {
+ if (logEntries.data.hits.hits) {
+ $scope.gridOptionsCurrentProblemList.data = logEntries.data.hits.hits.map(function(entry){
+ return {
+ id: entry._id,
+ icon: getIconFromSeverity(entry._source.faultCurrent.severity),
+ timestamp: $mwtnFault.formatTimeStamp(entry._source.faultCurrent.timeStamp),
+ node: entry._source.faultCurrent.nodeName,
+ counter: entry._source.faultCurrent.counter,
+ object: entry._source.faultCurrent.objectId,
+ problem: entry._source.faultCurrent.problem,
+ severity: entry._source.faultCurrent.severity,
+ };
+ });
+ $scope.progress.max = logEntries.data.hits.total;
+ $scope.progress.value = $scope.gridOptionsCurrentProblemList.data.length;
+ $scope.progress.show = $scope.gridOptionsCurrentProblemList.data.length < logEntries.data.hits.total;
+ }
+ };
+
+ $scope.refreshCurrentProblemList = function() {
+ // $scope.gridOptionsCurrentProblemList.data = [];
+ var from = 0;
+ var size = 10000;
+ $scope.processing = true;
+ $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){
+ $scope.processing = false;
+ $scope.spinner.currentProblemList = false;
+ processCurrentProblemEntries(logEntries);
+ from = from + size;
+ while (from < $scope.progress.max) {
+ $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){
+ processCurrentProblemEntries(logEntries);
+ }, function(error){
+ console.error(JSON.stringify(error));
+ });
+ from = from + size;
+ }
+ }, function(error){
+ $scope.processing = false;
+ $scope.spinner.currentProblemList = false;
+ console.error(JSON.stringify(error));
+ });
+ };
+
+ // Alarm Notifications
+ $scope.gridOptionsAlarmNotifications = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
+ $scope.gridOptionsAlarmNotifications.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timeStamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 90 },
+ { field: 'nodeName', type: 'string', displayName: 'NetworkElement', headerCellClass: $scope.highlightFilteredHeader, width: 170 },
+ { field: 'objectId', type: 'string', displayName: 'Object', headerCellClass: $scope.highlightFilteredHeader, width: 400 },
+
+ { field: 'problem', type: 'string', displayName: 'Alarm', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 100 }
+ ];
+ var listenToNotifications = function() {
+ $mwtnFault.getMwtnWebSocketUrl().then(function(success){
+ try {
+ var notificationSocket = new WebSocket(success);
+
+ notificationSocket.onmessage = function(event) {
+ // we process our received event here
+ if (typeof event.data === 'string') {
+ // console.log("Client Received:\n" + event.data);
+ // console.log("---------------------------");
+ $mwtnFault.formatData(event).then(function(formated) {
+ switch (formated.notifType) {
+ case 'ProblemNotification':
+ formated.icon = getIconFromSeverity(formated.severity);
+ $scope.gridOptionsAlarmNotifications.data.push(formated);
+ $timeout(function(){$scope.refreshCurrentProblemList();}, 500);
+ break;
+ case 'AttributeValueChangedNotification':
+ case 'ObjectCreationNotification':
+ case 'ObjectDeletionNotification':
+ // ignore
+ break;
+ default:
+ console.error('Missing implementation for', formated.notifType);
+ }
+ }, function(error) {
+ // do nothing
+ });
+ }
+ };
+
+ notificationSocket.onerror = function(error) {
+ console.log("Socket error: " + error);
+ };
+
+ notificationSocket.onopen = function(event) {
+ console.log("Socket connection opened.");
+
+ function subscribe() {
+ if (notificationSocket.readyState === notificationSocket.OPEN) {
+ var data = {
+ 'data' : 'scopes',
+ 'scopes' : [ "ProblemNotification" ]
+ };
+ notificationSocket.send(JSON.stringify(data));
+ }
+ }
+ subscribe();
+ };
+
+ notificationSocket.onclose = function(event) {
+ console.log("Socket connection closed.");
+ };
+ } catch (e) {
+ console.error("Error when creating WebSocket.\n" + e);
+ }
+ }, function(error){
+ console.error("Error when creating WebSocket.\n" + error);
+ });
+ };
+ listenToNotifications();
+
+ // Alarm Log
+ // $scope.gridOptionsAlarmLog = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
+
+ $scope.paginationOptions = {
+ pageNumber: 1,
+ pageSize: 25,
+ sort: null
+ };
+
+ $scope.gridOptionsAlarmLog = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: false,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ columnDefs : [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'node', type: 'string', displayName: 'Node name', headerCellClass: $scope.highlightFilteredHeader, width: 200 },
+ { field: 'counter', type: 'number', displayName: 'Counter', headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' },
+ { field: 'object', type: 'string', displayName: 'Object Id', headerCellClass: $scope.highlightFilteredHeader, width: 300 },
+ { field: 'problem', type: 'string', displayName: 'Alarm type', headerCellClass: $scope.highlightFilteredHeader, width : 200 },
+ { field: 'severity', type: 'string', displayName: 'Severity', headerCellClass: $scope.highlightFilteredHeader, width : 150 }
+ ],
+ data: 'data',
+ onRegisterApi: function(gridApi) {
+ $scope.gridApi = gridApi;
+ $scope.gridApi.core.on.filterChanged( $scope, $scope.filter);
+ $scope.gridApi.core.on.sortChanged( $scope, $scope.sortChanged );
+ $scope.sortChanged($scope.gridApi.grid, [ $scope.gridOptionsAlarmLog.columnDefs[1] ] );
+
+ $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getPage();
+ });
+ }
+};
+
+ //stateobject
+ $scope.state={};
+ $scope.state.filter=false;
+ $scope.state.sort=false;
+ $scope.state.lastfilter=null;
+ $scope.state.lastSort=null;
+
+ $scope.maxCount=0; //value shown on screen
+
+
+ $scope.seekPage= function(page){
+ if(!page){ //catch NaN values
+ page=1;
+ return;
+ }
+ $scope.gridApi.pagination.seek(parseInt(page));
+ };
+
+ $scope.paginationStatusMessage = function() {
+
+ var startnum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1;
+ var pagenednum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1+$scope.data.length;
+ if(pagenednum>$scope.gridOptionsAlarmLog.totalItems) pagenednum=pagenednum-1; //reduce by initial added 1
+
+ if($scope.state.filter){
+ var filterTpl = 'Showing {0} to {1} of {2} items (filtered from {3} total items)';
+ return filterTpl.format(startnum, pagenednum, $scope.gridOptionsAlarmLog.totalItems, $scope.maxCount);
+
+ } else {
+ var defaultTpl = 'Showing {0} to {1} of {2} total items';
+ return defaultTpl.format( startnum, pagenednum, $scope.maxCount);
+ }
+ };
+
+//list visible on screen
+ $scope.data = [];
+
+ var getPage = function() {
+ //from, how many, sort, filter
+ getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize, $scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter)
+ .then(function (data) {
+ $scope.gridOptionsAlarmLog.totalItems = data.data.hits.total;
+ processResponseRecreateList(data);
+ });
+ };
+
+ //filter
+ $scope.filter = function()
+ {
+ var grid = this.grid;
+ var columns=[];
+
+ //get all columns where data was typed in
+ angular.forEach(grid.columns, function(value, key) {
+ if(value.filters[0].term) {
+ var col=findColumn(value.displayName);
+ if(col==="fault.timeStamp"){
+ //convert timestamp to db format
+ var timestamp= $mwtnFault.TimeStampToONFFormat(value.filters[0].term);
+ columns.push({ column: col ,value: timestamp });
+ }
+ else
+ columns.push({ column: col ,value: value.filters[0].term }); //create column object
+ }
+ });
+
+ if(columns.length === 0){ //all filter data cleared away
+ $scope.state.filter=false;
+ $scope.state.lastfilter=null;
+
+ //get unfiltered data
+ getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+
+ }
+ });
+
+ }else{
+ //base filter string
+ var filter={"query":{"bool":{"must":[]}}};
+
+ //create filter objects
+ var prefixs=[];
+ for(var obj of columns){
+ var prefixObj={};
+ prefixObj[obj.column]=obj.value;//add like: {column: "fault.counter", value: "1"} => {"fault.counter":1}
+ prefixs.push({prefix:prefixObj}); // => {"prefix":{...}}
+ }
+
+ //add objects to must property
+ filter.query.bool.must=prefixs;
+
+ //save filter
+ $scope.state.lastfilter=filter;
+ $scope.state.filter=true;
+
+ //send data to sdnevents/faultlog/_search
+ getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.total>0) { //only, when hits exist
+ processResponseRecreateList(response);
+ $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total;
+ }else{
+ //clear data from list
+ $scope.data=[];
+ $scope.gridOptionsAlarmLog.totalItems =0;
+ $scope.state.filter=false;
+ $scope.state.lastfilter=null;
+ }
+ });
+ }
+};
+
+ //sort
+
+ $scope.sortChanged=function(grid, sortColumns){ // sortColumns is an array containing just the column sorted in the grid
+
+
+ if(sortColumns.length>0){
+ if(sortColumns[0].sort){
+ var name = sortColumns[0].displayName; // the name of the column sorted
+ var direction = sortColumns[0].sort.direction; // the direction of the column sorted: "desc" or "asc"
+ sort(direction,findColumn(name));
+ }
+ }else{
+ $scope.state.sort=false;
+ $scope.state.lastSort=null;
+
+ //get unsorted data
+ getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ }
+ });
+ }
+ };
+
+ function sort(direction, columnName){
+
+ var sortObj={};
+ var sort = [ sortObj];
+ switch(direction) {
+ case uiGridConstants.ASC:
+
+ //create sort object
+ sortObj[columnName]={order : 'asc'};
+ sort = [ sortObj];
+ //save last sort
+ $scope.state.lastSort=sort;
+
+ getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ $scope.state.sort=true;
+ }
+ });
+
+ break;
+
+ case uiGridConstants.DESC:
+
+ sortObj[columnName]={order : 'desc'};
+ sort = [ sortObj];
+ $scope.state.lastSort=sort;
+
+ getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ $scope.state.sort=true;
+ }
+ });
+ break;
+
+ case undefined:
+
+ $scope.state.sort=false;
+ $scope.state.lastSort=null;
+
+ getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter)
+ .then(function(response) {
+ if (response.data.hits.hits) {
+ processResponseRecreateList(response);
+ }
+ });
+
+ break;
+ }
+ }
+
+ var findColumn = function(name) {
+
+ if(name==="Timestamp"){ return "fault.timeStamp"; }
+ else if(name==="Node name"){ return "fault.nodeName"; }
+ else if(name==="Counter"){ return "fault.counter"; }
+ else if(name==="Object Id"){ return "fault.objectId"; }
+ else if(name==="Alarm type"){return "fault.problem"; }
+ else if(name==="Severity"){ return "fault.severity"; }
+
+ };
+
+ var getData = function(from, size, sort, query){
+ if(sort === null){ //default sort value
+ sort = [ { "fault.timeStamp" : {order : 'desc'}}];
+ }
+ if(query === null){ //default filter value
+ query= {match_all: {}};
+ }
+ return $mwtnFault.getFilteredSortedData(from, size, sort, query);
+ };
+
+ var processResponseAddToList=function(response) {
+ if (response.data.hits.hits) {
+ response.data.hits.hits.map(function(entry){
+ var log = {
+ id: entry._id,
+ icon: getIconFromSeverity(entry._source.fault.severity),
+ timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp),
+ node: entry._source.fault.nodeName,
+ counter: entry._source.fault.counter,
+ object: entry._source.fault.objectId,
+ problem: entry._source.fault.problem,
+ severity: entry._source.fault.severity,
+ };
+
+ $scope.data.push(log);
+ });
+
+ $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
+ if($scope.maxCount<response.data.hits.total){
+ $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
+ }
+ }};
+
+ function processResponseRecreateList(response){
+ var list=[];
+ response.data.hits.hits.map(function(entry){
+ var log = {
+ id: entry._id,
+ icon: getIconFromSeverity(entry._source.fault.severity),
+ timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp),
+ node: entry._source.fault.nodeName,
+ counter: entry._source.fault.counter,
+ object: entry._source.fault.objectId,
+ problem: entry._source.fault.problem,
+ severity: entry._source.fault.severity,
+ };
+
+ list.push(log);
+ });
+ $scope.data=list;
+ $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
+ if($scope.maxCount<response.data.hits.total){
+ $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
+ }
+ }
+
+ $scope.refreshLog = function() {
+
+ var from = ($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize;
+ var size = $scope.paginationOptions.pageSize;
+ $scope.processing = true;
+ getData(from, size,$scope.state.lastSort,$scope.state.lastfilter).then(function(logEntries){
+ $scope.processing = false;
+ $scope.spinner.alarmLog = false;
+ processResponseRecreateList(logEntries);
+
+ }, function(error){
+ $scope.processing = false;
+ $scope.spinner.alarmLog = false;
+ console.error(JSON.stringify(error));
+ });
+ };
+
+ // [sko] TODO check from here on
+ $scope.progress = {
+ show: true
+ };
+
+ $scope.clearLog = function () {
+
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnFault/templates/clearLogConfirmation.tpl.html',
+ controller: 'ClearFaultLogCtrl',
+ size: 'lg',
+ resolve: {
+ now: function () {
+ var onfDateAndTime = new Date().toISOString().replace(/-/g, '').replace(/T/g, '').replace(/:/g, '').substring(0,16) + 'Z';
+ return {timestamp: onfDateAndTime};
+ }
+ }
+ });
+
+ modalInstance.result.then(function (now) {
+ var spec = {
+ functionId : 'sdnevents',
+ docType : 'faultlog',
+ query: {
+ match_all: {}
+ }
+ };
+ $mwtnFault.deleteDocType(spec).then(function(deleted){
+ //set all to 'null' (empty)
+ $scope.data = [];
+ $scope.maxCount=0;
+ $scope.gridOptionsAlarmLog.totalItems=0;
+
+ $timeout( function() { $scope.refreshLog(); getPage(); }, 1000);
+
+ $mwtnLog.info({component: COMPONENT, message: 'Fault log cleared!'});
+ }, function(error){
+ $mwtnLog.error({component: COMPONENT, message:JSON.stringify(error)});
+ });
+ }, function () {
+ $mwtnLog.info({component: COMPONENT, message: 'Clear fault log dismissed!'});
+ });
+ };
+
+
+ // UI events
+ $scope.status = {currentProblemList: true};
+ $scope.spinner = {currentProblemList: false};
+ $scope.$watch('status', function(status, oldValue) {
+ Object.keys(status).map(function(key){
+ if (status[key] !== oldValue[key]) {
+ $scope.spinner[key] = status[key];
+
+ switch (key) {
+ case 'currentProblemList':
+ if (status[key]) {
+ $scope.refreshCurrentProblemList();
+ }
+ break;
+ case 'alarmNotifications':
+ $scope.spinner[key] = false;
+ break;
+ case 'alarmLog':
+ $scope.refreshLog();
+ break;
+ default:
+ $mwtnLog.error({component: COMPONENT, message: key + ' is not implemented!'});
+ }
+ }
+ });
+ }, true);
+
+ // init
+ $scope.refreshCurrentProblemList();
+
+ getPage();
+
+ }]);
+
+ mwtnFaultApp.register.controller('ClearFaultLogCtrl', ['$scope', '$uibModalInstance', '$mwtnFault', 'now',
+ function ($scope, $uibModalInstance, $mwtnFault, now) {
+
+ $scope.now = $mwtnFault.formatTimeStamp(now.timestamp);
+ $scope.processing = false;
+
+ $scope.ok = function () {
+ $uibModalInstance.close(now);
+ $scope.processing = true;
+ };
+
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss();
+ };
+ }]);
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js
new file mode 100644
index 00000000..ef1c3897
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.directives.js
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define([ 'app/mwtnCommons/mwtnCommons.module'], function(mwtnCommonsApp) {
+ mwtnCommonsApp.register.directive('alarmStatus', function() {
+ return {
+ restrict : 'E',
+ templateUrl : 'src/app/mwtnFault/templates/alarmStatus.tpl.html',
+ controller : ['$scope', '$mwtnCommons', '$mwtnDatabase', '$timeout', function($scope, $mwtnCommons, $mwtnDatabase, $timeout){
+
+ $scope.link = '#/pnfFault/';
+
+ $scope.nodeCount = 0;
+
+ $scope.alarmStatus = {
+ Critical:0,
+ Major:0,
+ Minor:0,
+ Warning:0,
+ };
+
+ $scope.getAlarmStatusSum = function(){
+ var sum = 0;
+ Object.keys($scope.alarmStatus).map(function(severity) {
+ sum = sum + $scope.alarmStatus[severity];
+ });
+ return sum;
+ };
+
+ // Update: request the number of alarms in current alarm list per severity
+ var update = function() {
+ $mwtnCommons.getMountPoints().then(function(mountpoints) {
+ $scope.nodeCount = mountpoints.filter(function(mountpoint) {
+ return mountpoint['netconf-node-topology:connection-status'] === 'connected';
+ }).length;
+ });
+ var functionId = 'sdnevents';
+ var docType = 'faultcurrent';
+ var aggregations = {
+ "size":0,
+ "aggregations": {
+ "severity": {
+ "terms": {
+ "field": "faultCurrent.severity"
+ }
+ }
+ }
+ };
+ $mwtnDatabase.getAggregations(functionId, docType, aggregations).then(function (success) {
+ var found = success.data.aggregations['severity'].buckets.map(function(bucket){
+ $scope.alarmStatus[bucket.key] = bucket.doc_count;
+ return bucket.key;
+ });
+ Object.keys($scope.alarmStatus).map(function(key){
+ if (!found.contains(key)) {
+ $scope.alarmStatus[key] = 0;
+ }
+ });
+ }, function (error) {
+ console.error(error);
+ $scope.alarmStatus = {
+ Critical:0,
+ Major:0,
+ Minor:0,
+ Warning:0,
+ };
+ });
+
+
+ // Object.keys($scope.alarmStatus).map(function(severity) {
+ // // usage of the ElasticSearch Count API
+ // $mwtnDatabase.getBase('sdnevents').then(function(success) {
+ // var databaseRequest = {
+ // base : success.base,
+ // method : 'POST',
+ // command: '_count',
+ // index: success.index,
+ // docType: 'faultcurrent',
+ // query: {
+ // match: {
+ // 'faultCurrent.severity': severity
+ // }
+ // }
+ // };
+ // $mwtnDatabase.genericRequest(databaseRequest).then(function(success){
+ // $scope.alarmStatus[severity] = success.data.count;
+ // }, function(error){
+ // console.error('severity', severity, error);
+ // });
+ // }, function(error) {
+ // console.error('severity', severity, error);
+ // });
+ // });
+ };
+ update();
+
+ var listenToNotifications = function() {
+ $mwtnCommons.getMwtnWebSocketUrl().then(function(success){
+ try {
+ var notificationSocket = new WebSocket(success);
+
+ notificationSocket.onmessage = function(event) {
+ // we process our received event here
+ if (typeof event.data === 'string') {
+ // console.log('Client Received:\n', event.data);
+ $mwtnCommons.formatData(event).then(function(formated) {
+ switch (formated.notifType) {
+ case 'ProblemNotification':
+ $timeout(function(){update();}, 500);
+ break;
+ case 'AttributeValueChangedNotification':
+ case 'ObjectCreationNotification':
+ case 'ObjectDeletionNotification':
+ // ignore
+ break;
+ default:
+ console.error('Missing implementation for', formated.notifType);
+ }
+ }, function(error) {
+ // do nothing
+ });
+ }
+ };
+
+ notificationSocket.onerror = function(error) {
+ console.log("Socket error: " + error);
+ };
+
+ notificationSocket.onopen = function(event) {
+ console.log("Socket connection opened.");
+ function subscribe() {
+ if (notificationSocket.readyState === notificationSocket.OPEN) {
+ var data = {
+ 'data' : 'scopes',
+ 'scopes' : [ "ProblemNotification" ]
+ };
+ notificationSocket.send(JSON.stringify(data));
+ }
+ }
+ subscribe();
+ };
+
+ notificationSocket.onclose = function(event) {
+ console.log("Socket connection closed.");
+ };
+ } catch (e) {
+ console.error("Error when creating WebSocket.\n" + e);
+ }
+ }, function(error){
+ console.error("Error when creating WebSocket.\n" + error);
+ });
+ };
+ listenToNotifications();
+ }]
+ };
+ });
+
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js
new file mode 100644
index 00000000..0da8e76d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnFaultApp = angular.module('app.mwtnFault', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ mwtnFaultApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnFaultApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/mwtnFault/mwtnFault.controller');
+ NavHelperProvider.addToMenu('mwtnFault', {
+ "link" : "#/pnfFault/",
+ "active" : "main.mwtnFault",
+ "title" : "pnf Fault",
+ "icon" : "fa fa-bell", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf Fault",
+ "description" : "mwtnFault"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnFault', {
+ url: 'pnfFault/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnFault/mwtnFault.tpl.html',
+ controller: 'mwtnFaultCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnFaultApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js
new file mode 100644
index 00000000..f07e4d04
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.services.js
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnFault/mwtnFault.module','app/mwtnCommons/mwtnCommons.services'],function(mwtnFaultApp) {
+
+ mwtnFaultApp.register.factory('$mwtnFault', function($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.formatData = $mwtnCommons.formatData;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.deleteDocType = $mwtnDatabase.deleteDocType;
+
+
+ service.TimeStampToONFFormat=function(timestamp){
+
+ timestamp=timestamp.split('-').join('');
+ timestamp=timestamp.split(':').join('');
+ timestamp=timestamp.split(' ').join('');
+ timestamp=timestamp.replace('UTC','Z');
+ return timestamp;
+ };
+
+ service.getAllLogEntries = function(from, size) {
+ var sort = [ {
+ "fault.timeStamp" : {
+ order : 'desc'
+ }
+ }];
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnFault.getAllLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getAllLogEntriesWithSort= function(from, size, sort){
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnFault.getAllLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getFilteredSortedData=function(from, size, sort,query){
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredSortedData('sdnevents', 'faultlog', from, size,sort, query).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnFault.getFilteredSortedData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+
+ };
+
+ service.getFilteredData= function(from, size, query){
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredData('sdnevents', 'faultlog', from, size, query).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnFault.getFilteredData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getAllCurrentProblemEntries = function(from, size) {
+ var sort = [ {
+ "faultCurrent.timeStamp" : {
+ order : 'desc'
+ }
+ }];
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultcurrent', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnFault.getAllCurrentLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html
new file mode 100644
index 00000000..dd23d262
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/mwtnFault.tpl.html
@@ -0,0 +1,119 @@
+<ht-header help-link='sdnr/pnfFault/0.4.0/README.md'></ht-header>
+<div class="mwtnError">{{error}}</div>
+
+<uib-accordion close-others="oneATime">
+
+<div uib-accordion-group class="panel-primary" is-open="status.currentProblemList">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.currentProblemList, 'fa-chevron-right': !status.currentProblemList}"></i>
+ <span>{{'MWTN_CURRENT_PROBLEM_LIST' | translate}}
+ ({{gridOptionsCurrentProblemList.data.length}})</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.currentProblemList"></i>
+ </uib-accordion-heading>
+
+
+ <div id="mwtnFaultGridCurrentProblemList" ui-grid="gridOptionsCurrentProblemList" ui-grid-exporter
+ ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnFaultGrid"></div>
+</div>
+
+<div uib-accordion-group class="panel-primary" is-open="status.alarmNotifications">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.alarmNotifications, 'fa-chevron-right': !status.alarmNotifications}"></i>
+ <span>{{'MWTN_ALARM_NOTIFICATIONS' | translate}}
+ ({{gridOptionsAlarmNotifications.data.length}} since {{date}})</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.alarmNotifications"></i>
+ </uib-accordion-heading>
+
+
+ <div id="mwtnFaultGridAlarmNotifications" ui-grid="gridOptionsAlarmNotifications"
+ ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="mwtnFaultGrid"></div>
+</div>
+
+<div uib-accordion-group class="panel-primary" is-open="status.alarmLog">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.alarmLog, 'fa-chevron-right': !status.alarmLog}"></i>
+ <span>{{'MWTN_ALARM_LOG' | translate}}
+ ({{maxCount}})</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.alarmLog"></i>
+ </uib-accordion-heading>
+
+ <div id="mwtnFaultGridAlarmLog"
+ ui-grid="gridOptionsAlarmLog"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnFaultGrid">
+ </div>
+
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="paginationOptions.pageNumber === 1"
+ ng-click="gridApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="paginationOptions.pageNumber === 1"
+ ng-class="{'cancelCursor':paginationOptions.pageNumber === 1}"
+ ng-click="gridApi.pagination.previousPage()"
+
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsAlarmLog.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsAlarmLog.paginationCurrentPage)"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridApi.pagination.getTotalPages() }}</span>
+
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsAlarmLog.paginationCurrentPage === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsAlarmLog.paginationCurrentPage === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.seek(gridApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+
+ <select
+ class="btn btn-default" name="repeatSelect" id="repeatSelect"
+ ng-init="gridOptionsAlarmLog.paginationPageSize = gridOptionsAlarmLog.paginationPageSizes[0]"
+ ng-model="gridOptionsAlarmLog.paginationPageSize"
+ ng-options="option for option in gridOptionsAlarmLog.paginationPageSizes"></select>
+
+ <span class="dark"> items per page </span>
+
+ <span class="pull-right dark">{{ paginationStatusMessage() }}</span>
+
+ </div>
+
+ <div class="text-right">
+ <button type="button" id="clearLog" class="btn btn-warning" ng-click="clearLog()">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span>Clear log...</span>
+ </button>
+ <!--
+ see gird menu Export ...
+ <button type="button" id="saveLog" class="btn btn-default" ng-click="saveLog()">
+ <i class="fa fa-save" aria-hidden="true"></i>
+ <span>Save...</span>
+ </button> -->
+ <button type="button" id="refreshLog" class="btn btn-primary" ng-click="refreshLog()">
+ <span>{{'MWTN_REFRESH' | translate}}</span>
+ </button>
+ </div>
+
+ </div>
+</uib-accordion>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html
new file mode 100644
index 00000000..b57a614c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/alarmStatus.tpl.html
@@ -0,0 +1,21 @@
+<div class="text-right margin5 mwtn global-alarm-status">
+ <a href="{{link}}" title="{{'MWTN_NODES' | translate}}">
+ <span>{{ 'MWTN_NODES' | translate }}:</span>
+ <i class="fa fa-link cleared" aria-hidden="true"></i>
+ <span> {{nodeCount}} </span>
+ <span> || </span>
+ </a>
+ <a href="{{link}}" title="{{'MWTN_NODES' | translate}}">
+ <span>{{ 'MWTN_ALARM_STATUS' | translate }}:</span>
+ </a>
+ <a href="{{link}}" ng-repeat="(key, value) in alarmStatus" title="{{key}}">
+ <span ng-show="$index !== 0"> | </span>
+ <i class="fa fa-exclamation-triangle" ng-class="{ {{key}} : value !== 0, 'cleared': value === 0}" aria-hidden="true" ></i>
+ <span> {{value}} </span>
+ </a>
+ <a href="{{link}}" title="{{key}}">
+ <span> | </span>
+ <span>{{ 'MWTN_SUM' | translate }}: </span>
+ <span> {{getAlarmStatusSum()}} </span>
+ </a>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html
new file mode 100644
index 00000000..3e58a3a4
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/mwtnFault-module/src/main/resources/mwtnFault/templates/clearLogConfirmation.tpl.html
@@ -0,0 +1,17 @@
+
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'Clear Log Confirmation' | translate}}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <p>
+ <span>All alarm log entries will be deleted.</span>
+ </p>
+ <p>Please make sure, you have exported the log entries, otherwise they will get lost.</p>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="ok()">
+ <i class="pull-left fa fa-spinner fa-pulse" ng-show="processing"></i>
+ <span>{{'Clear log' | translate}}</span>
+ </button>
+ <button class="btn btn-warning" type="button" ng-click="cancel()">{{'Cancel' | translate}}</button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/pom.xml
new file mode 100644
index 00000000..64df3af1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnFault/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnFault</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnFault-module</module>
+ <module>mwtnFault-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/pom.xml
new file mode 100644
index 00000000..ea013df3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnInventory</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnInventory-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnInventory-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnInventory-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..1075069c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnInventory"/>
+ <property name="url" value="/src/app/mwtnInventory"/>
+ <property name="directory" value="/mwtnInventory"/>
+ <property name="requireJs" value="app/mwtnInventory/mwtnInventory.module"/>
+ <property name="angularJs" value="app.mwtnInventory"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnInventory/mwtnInventory-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/pom.xml
new file mode 100644
index 00000000..5a72f5e9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnInventory</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnInventory-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+
+ </project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.html
new file mode 100755
index 00000000..5b0f5f65
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.html
@@ -0,0 +1,37 @@
+<div uib-accordion-group="" class="panel-primary" template-url="src/app/mwtnInventory/templates/accordeonHeader.tpl.html"
+ heading="{{equipment.uuid + ' | '+ equipment.name || equipment.label }}">
+ <div class="row">
+ <div class="col">
+ Manufacturer: <br /> <b> {{ equipment.manufacturer.id }} </b>
+ </div>
+ <div class="col">
+ Serial: <br /> <b> {{ equipment.manufacturer.serial }} </b>
+ </div>
+
+ <div class="col">
+ Version: <br /> <b> {{ equipment.manufacturer.version }} </b>
+ </div>
+ <div class="col">
+ Date: <br /> <b> {{ equipment.manufacturer.date | date }} </b>
+ </div>
+
+ <div class="col">
+ Description: <br /> <b> {{ equipment.manufacturer.description }} </b>
+ </div>
+ <div class="col">
+ Part Type Id: <br /> <b> {{ equipment.manufacturer.partTypeIdentifier }} </b>
+ </div>
+
+ <div class="col">
+ Model Identifier: <br /> <b> {{ equipment.manufacturer.modelIdentifier }} </b>
+ </div>
+ <div class="col">
+ Type Name: <br /> <b> {{ equipment.manufacturer.partTypeIdetypeNamentifier }} </b>
+ </div>
+ </div>
+ <div class="row">
+ <mwtn-equipment-group equipments="equipment.children" />
+ </div>
+ <div class="row">
+ </div>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.ts
new file mode 100755
index 00000000..0ea067c9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipment.ts
@@ -0,0 +1,28 @@
+declare var angular: angular.IAngularStatic;
+
+import { Equipment } from '../models/equipment';
+
+const mwtnInventory = angular.module('app.mwtnInventory');
+
+const EquipmentDirective = () => {
+ return {
+ templateUrl: 'src/app/mwtnInventory/components/equipment.html',
+ controller: 'mwtnEquipmentCtrl',
+ controllerAs: 'vm',
+ scope: {
+ equipment: "="
+ }
+ }
+};
+
+mwtnInventory.directive('mwtnEquipment', EquipmentDirective);
+
+export class EquipmentController {
+ constructor(private $scope: ng.IScope & { equipment: Equipment }) {
+
+ }
+
+
+}
+
+mwtnInventory.controller('mwtnEquipmentCtrl', ['$scope', EquipmentController]);
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.html
new file mode 100755
index 00000000..ad43bff9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.html
@@ -0,0 +1,5 @@
+<div class="app-mwtnInventory-components-equipmentGroup">
+<uib-accordion close-others="false">
+ <mwtn-equipment ng-repeat="eq in equipments" equipment="eq" />
+</uib-accordion>
+</div >
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.ts
new file mode 100755
index 00000000..ee0945d5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/components/equipmentGroup.ts
@@ -0,0 +1,41 @@
+declare var angular: angular.IAngularStatic;
+
+import { Equipment } from '../models/equipment';
+
+const mwtnInventory = angular.module('app.mwtnInventory');
+
+const EquipmentGroupDirective = ($compile) => {
+ return {
+ templateUrl: 'src/app/mwtnInventory/components/equipmentGroup.html',
+ controller: 'mwtnEquipmentGroupCtrl',
+ controllerAs: 'vm',
+ scope: {
+ equipments: "="
+ },
+ // HACK: for angular 1.4. compatibility
+ compile: function (tElement, tAttr, transclude) {
+ var contents = tElement.contents().remove();
+ var compiledContents;
+ return function (scope, iElement, iAttr) {
+ if (!compiledContents) {
+ compiledContents = $compile(contents, transclude);
+ }
+ compiledContents(scope, function (clone, scope) {
+ iElement.append(clone);
+ });
+ };
+ }
+ }
+};
+
+mwtnInventory.directive('mwtnEquipmentGroup', ['$compile', EquipmentGroupDirective]);
+
+export class EquipmentGroupController {
+ constructor(private $scope: ng.IScope & { equipments: Equipment[] }) {
+ //console.log("EquipmentGroupController", $scope.equipments);
+
+ }
+
+}
+
+mwtnInventory.controller('mwtnEquipmentGroupCtrl', ['$scope', EquipmentGroupController]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/images/mwtnInventory.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/images/mwtnInventory.png
new file mode 100755
index 00000000..02e626d2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/images/mwtnInventory.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/models/equipment.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/models/equipment.ts
new file mode 100755
index 00000000..edc4fc5b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/models/equipment.ts
@@ -0,0 +1,6 @@
+export class Equipment {
+ uuid: string;
+ name: string;
+ label: string;
+ children: Equipment[];
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory-custom.css
new file mode 100644
index 00000000..2eb9261d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory-custom.css
@@ -0,0 +1,31 @@
+
+.app-mwtnInventory * {
+ box-sizing: border-box;
+}
+
+.app-mwtnInventory .col {
+ height: 70px;
+ width: 12.5%;
+ float: left;
+ padding: 15px;
+}
+
+.app-mwtnInventory .row::after {
+ content: "";
+ clear: both;
+ display: table;
+}
+
+@media (max-width: 1600px) {
+ .app-mwtnInventory .col { width: 25%; }
+
+}
+
+@media (max-width: 1200px) {
+ .app-mwtnInventory .col { width: 33.3%; }
+}
+
+.app-mwtnInventory-components-equipmentGroup {
+ padding-left: 15px;
+ padding-right: 15px;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.js
new file mode 100644
index 00000000..fa6a85f8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.js
@@ -0,0 +1,372 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __generator = (this && this.__generator) || function (thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [0, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+};
+define("mwtnInventory.service", ["require", "exports", "angularAMD"], function (require, exports, angular) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var mwtnInventory = angular.module('app.mwtnInventory');
+ var ExtensionResult = /** @class */ (function () {
+ function ExtensionResult() {
+ }
+ return ExtensionResult;
+ }());
+ var InventoryService = /** @class */ (function () {
+ function InventoryService($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+ var _this = this;
+ this.$q = $q;
+ this.$mwtnCommons = $mwtnCommons;
+ this.$mwtnDatabase = $mwtnDatabase;
+ this.$mwtnLog = $mwtnLog;
+ /**
+ * Helperfunction to detect and convert the 'value-name-group' .
+ * @param propertyName Name of the object property.
+ * @param propertyValue Value of the object property.
+ * @param valueName Optional: The value-name to be used instaed of the propertyName.
+ * @returns A simplified property value if this is a 'value-name-group' otherwhise the propertyValue. */
+ this.convertValue = function (propertyName, propertyValue, valueName) {
+ if (valueName === void 0) { valueName = ''; }
+ if (propertyValue && propertyValue instanceof Array && propertyValue.length == 1 && (valueName == null ||
+ propertyValue[0]["value-name"] === propertyName ||
+ propertyValue[0]["value-name"] === valueName)) {
+ return propertyValue[0]["value"];
+ }
+ return propertyValue;
+ };
+ /**
+ * Converts an API object to a simplified local object.
+ * @param apiResult The API object to convert.
+ * @param valueName Optional: The value-name to be used instaed of the propertyName.
+ * @returns The simplified local object.
+ */
+ this.convertObject = function (apiResult, valueName) {
+ if (valueName === void 0) { valueName = ''; }
+ if (apiResult instanceof Array) {
+ return apiResult.map(function (elm) { return _this.convertObject(elm, valueName); });
+ }
+ else if (apiResult instanceof Object) {
+ var keys = Object.keys(apiResult);
+ var result_1 = {};
+ keys.forEach(function (key) {
+ var value = _this.convertValue(key, apiResult[key], valueName);
+ result_1[key] = (value instanceof Object || value instanceof Array)
+ ? _this.convertObject(value)
+ : value;
+ });
+ return result_1;
+ }
+ return apiResult;
+ };
+ }
+ /** Requests all active moint points */
+ InventoryService.prototype.getConnectedMountpoints = function () {
+ return this.$mwtnCommons.getMountPoints().then(function (mountpoints) {
+ //console.log(mountpoints);
+ return mountpoints.reduce(function (acc, cur, ind, arr) {
+ if (cur['netconf-node-topology:connection-status'] === 'connected')
+ acc.push(cur["node-id"]);
+ return acc;
+ }, []);
+ });
+ };
+ /**
+ * Requests all 'root identifiers' for the given 'node id'.
+ * @param nodeId The id of the node to request the root identifiers for.
+ * @returns A q.Promise containing an array of all root identifiers for the requested node id.
+ * */
+ InventoryService.prototype.getRootIdentifiers = function (nodeId) {
+ var _this = this;
+ var request = {
+ url: "operational/network-topology:network-topology/topology/topology-netconf/node/" + nodeId + "/yang-ext:mount/core-model:network-element/extension/top-level-equipment",
+ method: "GET"
+ };
+ return this.$mwtnCommons.genericRequest(request).then(function (result) {
+ if (result && result.status == 200 && result.data) {
+ var topLevelEquipment = _this.convertObject(result.data, 'top-level-equipment');
+ var rootIdentifiers = topLevelEquipment && topLevelEquipment.extension && topLevelEquipment.extension.split(',');
+ return rootIdentifiers && rootIdentifiers.map(function (identifier) { return identifier && identifier.trim(); });
+ }
+ return null;
+ }, function (err) { return (null); });
+ };
+ /**
+ * Requests the detail information for the given combination of 'nodeId' and 'equipmentIdentifier'.
+ * @param nodeId The id of the root node.
+ * @param identifier The identifier to request the details for.
+ * @returns A q.Promise containing an object with all the details.
+ * */
+ InventoryService.prototype.getEquipmentDetails = function (nodeId, identifier) {
+ var _this = this;
+ var request = {
+ url: "operational/network-topology:network-topology/topology/topology-netconf/node/" + nodeId + "/yang-ext:mount/core-model:equipment/" + identifier,
+ method: "GET"
+ };
+ return this.$mwtnCommons.genericRequest(request).then(function (result) {
+ if (result && result.status == 200 && result.data) {
+ return _this.convertObject(result.data);
+ }
+ return null;
+ }, function (err) { return (null); });
+ };
+ /**
+ * Requests the conditional information for the given combination of 'nodeId' and 'equipmentIdentifier'.
+ * @param nodeId The id of the root node.
+ * @param identifier The identifier to request the conditionals for.
+ * @returns A q.Promise containing an object with all the conditional informations.
+ * */
+ InventoryService.prototype.getEquipmentConditionals = function (nodeId, identifier) {
+ var _this = this;
+ var request = {
+ url: "operational/network-topology:network-topology/topology/topology-netconf/node/" + nodeId + "/yang-ext:mount/onf-core-model-conditional-packages:equipment-pac/" + identifier,
+ method: "GET"
+ };
+ return this.$mwtnCommons.genericRequest(request).then(function (result) {
+ if (result && result.status == 200 && result.data) {
+ return _this.convertObject(result.data);
+ }
+ return {"equipment-pac":[]};
+ }, function (err) { return ({"equipment-pac":[]}); });
+ };
+ return InventoryService;
+ }());
+ exports.InventoryService = InventoryService;
+ mwtnInventory.service('mwtnInventoryService', ["$q", "$mwtnCommons", "$mwtnDatabase", "$mwtnLog", InventoryService]);
+});
+define("models/equipment", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var Equipment = /** @class */ (function () {
+ function Equipment() {
+ }
+ return Equipment;
+ }());
+ exports.Equipment = Equipment;
+});
+define("components/equipment", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var mwtnInventory = angular.module('app.mwtnInventory');
+ var EquipmentDirective = function () {
+ return {
+ templateUrl: 'src/app/mwtnInventory/components/equipment.html',
+ controller: 'mwtnEquipmentCtrl',
+ controllerAs: 'vm',
+ scope: {
+ equipment: "="
+ }
+ };
+ };
+ mwtnInventory.directive('mwtnEquipment', EquipmentDirective);
+ var EquipmentController = /** @class */ (function () {
+ function EquipmentController($scope) {
+ this.$scope = $scope;
+ }
+ return EquipmentController;
+ }());
+ exports.EquipmentController = EquipmentController;
+ mwtnInventory.controller('mwtnEquipmentCtrl', ['$scope', EquipmentController]);
+});
+define("components/equipmentGroup", ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var mwtnInventory = angular.module('app.mwtnInventory');
+ var EquipmentGroupDirective = function ($compile) {
+ return {
+ templateUrl: 'src/app/mwtnInventory/components/equipmentGroup.html',
+ controller: 'mwtnEquipmentGroupCtrl',
+ controllerAs: 'vm',
+ scope: {
+ equipments: "="
+ },
+ // HACK: for angular 1.4. compatibility
+ compile: function (tElement, tAttr, transclude) {
+ var contents = tElement.contents().remove();
+ var compiledContents;
+ return function (scope, iElement, iAttr) {
+ if (!compiledContents) {
+ compiledContents = $compile(contents, transclude);
+ }
+ compiledContents(scope, function (clone, scope) {
+ iElement.append(clone);
+ });
+ };
+ }
+ };
+ };
+ mwtnInventory.directive('mwtnEquipmentGroup', ['$compile', EquipmentGroupDirective]);
+ var EquipmentGroupController = /** @class */ (function () {
+ function EquipmentGroupController($scope) {
+ //console.log("EquipmentGroupController", $scope.equipments);
+ this.$scope = $scope;
+ }
+ return EquipmentGroupController;
+ }());
+ exports.EquipmentGroupController = EquipmentGroupController;
+ mwtnInventory.controller('mwtnEquipmentGroupCtrl', ['$scope', EquipmentGroupController]);
+});
+define( ["require", "exports", "mwtnInventory.service", "components/equipment", "components/equipmentGroup"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var mwtnInventory = angular.module('app.mwtnInventory');
+ var MwtnInventoryCtrl = /** @class */ (function () {
+ function MwtnInventoryCtrl($rootScope, $scope, $state, $timeout, mwtnInventoryService) {
+ var _this = this;
+ this.$rootScope = $rootScope;
+ this.$scope = $scope;
+ this.$state = $state;
+ this.$timeout = $timeout;
+ this.mwtnInventoryService = mwtnInventoryService;
+ // todo: change this
+ $rootScope.section_logo = 'src/app/mwtnInventory/images/mwtnInventory.png';
+ $scope.loading = false;
+ $scope.message = "Empty";
+ $scope.equipments = [];
+ $scope.selectedMountPoint = null;
+ $scope.activeMountPoints = [];
+ var getAllChildEquipments = function (equipmentsRootId, equimentIds) { return __awaiter(_this, void 0, void 0, function () {
+ var equipmentObjects, equipmentConditionals, results;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ if (!equimentIds || !equimentIds.length) {
+ return [2 /*return*/, []];
+ }
+ return [4 /*yield*/, Promise.all(equimentIds.map(function (id) {
+ return mwtnInventoryService.getEquipmentDetails(equipmentsRootId, id);
+ }))];
+ case 1:
+ equipmentObjects = (_a.sent()).map(function (eq) { return (eq["equipment"][0]); });
+ return [4 /*yield*/, Promise.all(equimentIds.map(function (id) {
+ return mwtnInventoryService.getEquipmentConditionals(equipmentsRootId, id);
+ }))];
+ case 2:
+ equipmentConditionals = (_a.sent()).map(function (eq) { return (eq["equipment-pac"][0]); });
+ return [4 /*yield*/, Promise.all(equipmentObjects.map(function (eq) {
+ var fruNames = (eq["contained-holder"] || []).map(function (ch) { return ch["occupying-fru"]; }).filter(function (fru) { return !!fru; });
+ return getAllChildEquipments(equipmentsRootId, fruNames);
+ }))];
+ case 3:
+ results = _a.sent();
+ return [2 /*return*/, equipmentObjects.reduce(function (acc, cur, ind, arr) {
+ var conditional = equipmentConditionals[ind] || null;
+ // ensure EVERY property can be null or undefined
+ var manufacturedThing = cur['manufactured-thing'];
+ var equipmentType = manufacturedThing && manufacturedThing['equipment-type'];
+ var manufacturerProperties = manufacturedThing && manufacturedThing['manufacturer-properties'];
+ var equipmentInstance = manufacturedThing && manufacturedThing['equipment-instance'];
+ var card = {
+ name: cur.name,
+ label: cur.label,
+ uuid: cur.uuid,
+ manufacturer: {
+ version: equipmentType && equipmentType["version"],
+ description: equipmentType && equipmentType["description"],
+ partTypeIdentifier: equipmentType && equipmentType["part-type-identifier"],
+ modelIdentifier: equipmentType && equipmentType["model-identifier"],
+ partTypeIdetypeNamentifier: equipmentType && equipmentType["type-name"],
+ id: manufacturerProperties && manufacturerProperties['manufacturer-identifier'],
+ date: equipmentInstance && equipmentInstance['manufacture-date'] && Date.parse(equipmentInstance && equipmentInstance['manufacture-date']),
+ serial: equipmentInstance && equipmentInstance['serial-number']
+ },
+ conditional: conditional
+ };
+ (results[ind].length ? card['children'] = results[ind] : null);
+ acc.push(card);
+ return acc;
+ }, [])];
+ }
+ });
+ }); };
+ var pleaseSelect = "... please select a mount point";
+ var refresh = function (equipmentsRootId) { return __awaiter(_this, void 0, void 0, function () {
+ var rootIdentifiers, equipments, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0: return [4 /*yield*/, mwtnInventoryService.getRootIdentifiers(equipmentsRootId)];
+ case 1:
+ rootIdentifiers = _b.sent();
+ _a = rootIdentifiers;
+ if (!_a) return [3 /*break*/, 3];
+ return [4 /*yield*/, getAllChildEquipments(equipmentsRootId, rootIdentifiers)];
+ case 2:
+ _a = (_b.sent());
+ _b.label = 3;
+ case 3:
+ equipments = _a;
+ $timeout(function () {
+ $scope.equipments = equipments;
+ });
+ return [2 /*return*/];
+ }
+ });
+ }); };
+ mwtnInventoryService.getConnectedMountpoints().then(function (res) {
+ $scope.activeMountPoints = [pleaseSelect].concat(res);
+ $scope.selectedMountPoint = $scope.selectedMountPoint || pleaseSelect;
+ });
+ $scope.$watch(function () { return ($state.params.nodeId); }, function (newVal, oldVal) {
+ $scope.selectedMountPoint = newVal;
+ });
+ $scope.$watch("selectedMountPoint", function (newVal, oldVal) { return __awaiter(_this, void 0, void 0, function () {
+ var _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ if (!newVal || newVal === pleaseSelect) {
+ $scope.equipments = [];
+ return [2 /*return*/];
+ }
+ if ($scope.activeMountPoints[0] === pleaseSelect) {
+ _a = $scope.activeMountPoints, $scope.activeMountPoints = _a.slice(1);
+ }
+ $scope.loading = true;
+ if ($state.params.nodeId !== newVal) {
+ $state.go('main.mwtnInventory', { nodeId: newVal }, { notify: false });
+ }
+ return [4 /*yield*/, refresh(newVal).catch(function (err) {
+ $timeout(function () { $scope.equipments = null; });
+ })];
+ case 1:
+ _b.sent();
+ $timeout(function () { $scope.loading = false; });
+ return [2 /*return*/];
+ }
+ });
+ }); });
+ }
+ return MwtnInventoryCtrl;
+ }());
+ mwtnInventory.controller('mwtnInventoryCtrl', ['$rootScope', '$scope', '$state', '$timeout', 'mwtnInventoryService', MwtnInventoryCtrl]);
+});
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXd0bkludmVudG9yeS5jb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2FwcC9td3RuSW52ZW50b3J5L213dG5JbnZlbnRvcnkuc2VydmljZS50cyIsInNyYy9hcHAvbXd0bkludmVudG9yeS9tb2RlbHMvZXF1aXBtZW50LnRzIiwic3JjL2FwcC9td3RuSW52ZW50b3J5L2NvbXBvbmVudHMvZXF1aXBtZW50LnRzIiwic3JjL2FwcC9td3RuSW52ZW50b3J5L2NvbXBvbmVudHMvZXF1aXBtZW50R3JvdXAudHMiLCJzcmMvYXBwL213dG5JbnZlbnRvcnkvbXd0bkludmVudG9yeS5jb250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBRUEsSUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBRTFEO1FBQUE7UUFJQSxDQUFDO1FBQUQsc0JBQUM7SUFBRCxDQUFDLEFBSkQsSUFJQztJQW1CRDtRQUNFLDBCQUFvQixFQUFnQixFQUFVLFlBQTJCLEVBQVUsYUFBYSxFQUFVLFFBQVE7WUFBbEgsaUJBRUM7WUFGbUIsT0FBRSxHQUFGLEVBQUUsQ0FBYztZQUFVLGlCQUFZLEdBQVosWUFBWSxDQUFlO1lBQVUsa0JBQWEsR0FBYixhQUFhLENBQUE7WUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFBO1lBSWxIOzs7OztvSEFLd0c7WUFDaEcsaUJBQVksR0FBRyxVQUFDLFlBQW9CLEVBQUUsYUFBa0IsRUFBRSxTQUFzQjtnQkFBdEIsMEJBQUEsRUFBQSxjQUFzQjtnQkFDdEYsRUFBRSxDQUFDLENBQUMsYUFBYSxJQUFJLGFBQWEsWUFBWSxLQUFLLElBQUksYUFBYSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FDbEYsU0FBUyxJQUFJLElBQUk7b0JBQ2pCLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsS0FBSyxZQUFZO29CQUMvQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssU0FBUyxDQUM5QyxDQUFDLENBQUMsQ0FBQztvQkFDRCxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNuQyxDQUFDO2dCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUM7WUFDdkIsQ0FBQyxDQUFBO1lBRUQ7Ozs7O2NBS0U7WUFDTSxrQkFBYSxHQUFHLFVBQUMsU0FBYyxFQUFFLFNBQXNCO2dCQUF0QiwwQkFBQSxFQUFBLGNBQXNCO2dCQUM3RCxFQUFFLENBQUMsQ0FBQyxTQUFTLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDL0IsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBQSxHQUFHLElBQU0sTUFBTSxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlFLENBQUM7Z0JBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsWUFBWSxNQUFNLENBQUMsQ0FBQyxDQUFDO29CQUN2QyxJQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNwQyxJQUFJLFFBQU0sR0FBRyxFQUFFLENBQUM7b0JBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBQSxHQUFHO3dCQUNkLElBQU0sS0FBSyxHQUFHLEtBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQzt3QkFDaEUsUUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxZQUFZLE1BQU0sSUFBSSxLQUFLLFlBQVksS0FBSyxDQUFDOzRCQUMvRCxDQUFDLENBQUMsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7NEJBQzNCLENBQUMsQ0FBQyxLQUFLLENBQUM7b0JBQ1osQ0FBQyxDQUFDLENBQUM7b0JBQ0gsTUFBTSxDQUFDLFFBQU0sQ0FBQztnQkFDaEIsQ0FBQztnQkFDRCxNQUFNLENBQUMsU0FBUyxDQUFDO1lBQ25CLENBQUMsQ0FBQTtRQXhDRCxDQUFDO1FBMENELHVDQUF1QztRQUNoQyxrREFBdUIsR0FBOUI7WUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQU0sQ0FBQyxJQUFJLENBQUMsVUFBQyxXQUFpQjtnQkFDbkUsMkJBQTJCO2dCQUMzQixNQUFNLENBQVcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFDLEdBQWEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUc7b0JBQy9ELEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyx5Q0FBeUMsQ0FBQyxLQUFLLFdBQVcsQ0FBQzt3QkFBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO29CQUM3RixNQUFNLENBQUMsR0FBRyxDQUFDO2dCQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNULENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVEOzs7O2FBSUs7UUFDRSw2Q0FBa0IsR0FBekIsVUFBMEIsTUFBYztZQUF4QyxpQkFlQztZQWJDLElBQU0sT0FBTyxHQUFzQjtnQkFDakMsR0FBRyxFQUFFLGtGQUFnRixNQUFNLDZFQUEwRTtnQkFDckssTUFBTSxFQUFFLEtBQUs7YUFDZCxDQUFDO1lBRUYsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFrQixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQyxNQUFNO2dCQUM1RSxFQUFFLENBQUMsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ2xELElBQU0saUJBQWlCLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUM7b0JBQ2pGLElBQU0sZUFBZSxHQUFHLGlCQUFpQixJQUFJLGlCQUFpQixDQUFDLFNBQVMsSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNuSCxNQUFNLENBQUMsZUFBZSxJQUFJLGVBQWUsQ0FBQyxHQUFHLENBQUMsVUFBQSxVQUFVLElBQUksT0FBQSxVQUFVLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxFQUEvQixDQUErQixDQUFDLENBQUM7Z0JBQy9GLENBQUM7Z0JBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQztZQUNkLENBQUMsRUFBRSxVQUFBLEdBQUcsSUFBSSxPQUFBLENBQUMsSUFBSSxDQUFDLEVBQU4sQ0FBTSxDQUFDLENBQUM7UUFDcEIsQ0FBQztRQUVEOzs7OzthQUtLO1FBQ0UsOENBQW1CLEdBQTFCLFVBQTJCLE1BQWMsRUFBRSxVQUFrQjtZQUE3RCxpQkFXQztZQVZDLElBQU0sT0FBTyxHQUFzQjtnQkFDakMsR0FBRyxFQUFFLGtGQUFnRixNQUFNLDZDQUF3QyxVQUFZO2dCQUMvSSxNQUFNLEVBQUUsS0FBSzthQUNkLENBQUM7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQWtCLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLE1BQU07Z0JBQzVFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDbEQsTUFBTSxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDZCxDQUFDLEVBQUUsVUFBQSxHQUFHLElBQUksT0FBQSxDQUFDLElBQUksQ0FBQyxFQUFOLENBQU0sQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFFRDs7Ozs7YUFLSztRQUNFLG1EQUF3QixHQUEvQixVQUFnQyxNQUFjLEVBQUUsVUFBa0I7WUFBbEUsaUJBV0M7WUFWQyxJQUFNLE9BQU8sR0FBc0I7Z0JBQ2pDLEdBQUcsRUFBRSxrRkFBZ0YsTUFBTSwwRUFBcUUsVUFBWTtnQkFDNUssTUFBTSxFQUFFLEtBQUs7YUFDZCxDQUFDO1lBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFrQixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQyxNQUFNO2dCQUM1RSxFQUFFLENBQUMsQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ2xELE1BQU0sQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDekMsQ0FBQztnQkFDRCxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ2QsQ0FBQyxFQUFFLFVBQUEsR0FBRyxJQUFJLE9BQUEsQ0FBQyxJQUFJLENBQUMsRUFBTixDQUFNLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQ0gsdUJBQUM7SUFBRCxDQUFDLEFBbkhELElBbUhDO0lBbkhZLDRDQUFnQjtJQW9IN0IsYUFBYSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7Ozs7O0lDL0lySDtRQUFBO1FBS0EsQ0FBQztRQUFELGdCQUFDO0lBQUQsQ0FBQyxBQUxELElBS0M7SUFMWSw4QkFBUzs7Ozs7SUNJdEIsSUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBRTFELElBQU0sa0JBQWtCLEdBQUc7UUFDekIsTUFBTSxDQUFDO1lBQ0wsV0FBVyxFQUFFLGlEQUFpRDtZQUM5RCxVQUFVLEVBQUUsbUJBQW1CO1lBQy9CLFlBQVksRUFBRSxJQUFJO1lBQ2xCLEtBQUssRUFBRTtnQkFDTCxTQUFTLEVBQUUsR0FBRzthQUNmO1NBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQztJQUVGLGFBQWEsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLGtCQUFrQixDQUFDLENBQUM7SUFFN0Q7UUFDRSw2QkFBb0IsTUFBNEM7WUFBNUMsV0FBTSxHQUFOLE1BQU0sQ0FBc0M7UUFFaEUsQ0FBQztRQUdILDBCQUFDO0lBQUQsQ0FBQyxBQU5ELElBTUM7SUFOWSxrREFBbUI7SUFRaEMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7Ozs7O0lDdkIvRSxJQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFMUQsSUFBTSx1QkFBdUIsR0FBRyxVQUFDLFFBQVE7UUFDdkMsTUFBTSxDQUFDO1lBQ0wsV0FBVyxFQUFFLHNEQUFzRDtZQUNuRSxVQUFVLEVBQUUsd0JBQXdCO1lBQ3BDLFlBQVksRUFBRSxJQUFJO1lBQ2xCLEtBQUssRUFBRTtnQkFDTCxVQUFVLEVBQUUsR0FBRzthQUNoQjtZQUNELHVDQUF1QztZQUN2QyxPQUFPLEVBQUUsVUFBVSxRQUFRLEVBQUUsS0FBSyxFQUFFLFVBQVU7Z0JBQzVDLElBQUksUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDNUMsSUFBSSxnQkFBZ0IsQ0FBQztnQkFDckIsTUFBTSxDQUFDLFVBQVUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLO29CQUNyQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQzt3QkFDdEIsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDcEQsQ0FBQztvQkFDRCxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsVUFBVSxLQUFLLEVBQUUsS0FBSzt3QkFDNUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDekIsQ0FBQyxDQUFDLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO1lBQ0osQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDLENBQUM7SUFFRixhQUFhLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLENBQUMsVUFBVSxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQztJQUVyRjtRQUNFLGtDQUFvQixNQUErQztZQUNqRSw2REFBNkQ7WUFEM0MsV0FBTSxHQUFOLE1BQU0sQ0FBeUM7UUFHbkUsQ0FBQztRQUVILCtCQUFDO0lBQUQsQ0FBQyxBQU5ELElBTUM7SUFOWSw0REFBd0I7SUFRckMsYUFBYSxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLFFBQVEsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7Ozs7O0lDakN6RixJQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFVMUQ7UUFDRSwyQkFBb0IsVUFBVSxFQUFVLE1BQTJCLEVBQVUsTUFBTSxFQUFVLFFBQVEsRUFBVSxvQkFBc0M7WUFBckosaUJBOEZDO1lBOUZtQixlQUFVLEdBQVYsVUFBVSxDQUFBO1lBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBcUI7WUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFBO1lBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBQTtZQUFVLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBa0I7WUFDbkosb0JBQW9CO1lBQ3BCLFVBQVUsQ0FBQyxZQUFZLEdBQUcsZ0RBQWdELENBQUM7WUFFM0UsTUFBTSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDdkIsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDekIsTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7WUFDdkIsTUFBTSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztZQUVqQyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1lBRTlCLElBQU0scUJBQXFCLEdBQUcsVUFBTyxnQkFBd0IsRUFBRSxXQUFxQjs7Ozs7NEJBQ2xGLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0NBQ3hDLE1BQU0sZ0JBQUMsRUFBRSxFQUFDOzRCQUNaLENBQUM7NEJBQ3lCLHFCQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFBLEVBQUU7b0NBQzVELE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQztnQ0FDeEUsQ0FBQyxDQUFDLENBQUMsRUFBQTs7NEJBRkcsZ0JBQWdCLEdBQUcsQ0FBQyxTQUV2QixDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUEsRUFBRSxJQUFJLE9BQUEsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBcEIsQ0FBb0IsQ0FBQzs0QkFFTCxxQkFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBQSxFQUFFO29DQUNqRSxNQUFNLENBQUMsb0JBQW9CLENBQUMsd0JBQXdCLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0NBQzdFLENBQUMsQ0FBQyxDQUFDLEVBQUE7OzRCQUZHLHFCQUFxQixHQUFHLENBQUMsU0FFNUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFBLEVBQUUsSUFBSSxPQUFBLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQXhCLENBQXdCLENBQUM7NEJBRTFCLHFCQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLFVBQUEsRUFBRTtvQ0FDckQsSUFBSSxRQUFRLEdBQWEsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBQSxFQUFFLElBQUksT0FBQSxFQUFFLENBQUMsZUFBZSxDQUFDLEVBQW5CLENBQW1CLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxDQUFDLENBQUMsR0FBRyxFQUFMLENBQUssQ0FBQyxDQUFDO29DQUM1RyxNQUFNLENBQUMscUJBQXFCLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0NBQzNELENBQUMsQ0FBQyxDQUFDLEVBQUE7OzRCQUhDLE9BQU8sR0FBRyxTQUdYOzRCQUVILHNCQUFPLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUc7b0NBQ2hELElBQUksV0FBVyxHQUFHLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQztvQ0FDckQsa0RBQWtEO29DQUNsRCxJQUFJLGlCQUFpQixHQUFHLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO29DQUNsRCxJQUFJLGFBQWEsR0FBRyxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO29DQUM3RSxJQUFJLHNCQUFzQixHQUFHLGlCQUFpQixJQUFJLGlCQUFpQixDQUFDLHlCQUF5QixDQUFDLENBQUM7b0NBQy9GLElBQUksaUJBQWlCLEdBQUcsaUJBQWlCLElBQUksaUJBQWlCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztvQ0FFckYsSUFBSSxJQUFJLEdBQUc7d0NBQ1QsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO3dDQUNkLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSzt3Q0FDaEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO3dDQUNkLFlBQVksRUFBRTs0Q0FDWixPQUFPLEVBQUUsYUFBYSxJQUFJLGFBQWEsQ0FBQyxTQUFTLENBQUM7NENBQ2xELFdBQVcsRUFBRSxhQUFhLElBQUksYUFBYSxDQUFDLGFBQWEsQ0FBQzs0Q0FDMUQsa0JBQWtCLEVBQUUsYUFBYSxJQUFJLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQzs0Q0FDMUUsZUFBZSxFQUFFLGFBQWEsSUFBSSxhQUFhLENBQUMsa0JBQWtCLENBQUM7NENBQ25FLDBCQUEwQixFQUFFLGFBQWEsSUFBSSxhQUFhLENBQUMsV0FBVyxDQUFDOzRDQUN2RSxFQUFFLEVBQUUsc0JBQXNCLElBQUksc0JBQXNCLENBQUMseUJBQXlCLENBQUM7NENBQy9FLElBQUksRUFBRSxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLElBQUksaUJBQWlCLENBQUMsa0JBQWtCLENBQUMsQ0FBQzs0Q0FDMUksTUFBTSxFQUFFLGlCQUFpQixJQUFJLGlCQUFpQixDQUFDLGVBQWUsQ0FBQzt5Q0FDaEU7d0NBQ0QsV0FBVyxFQUFFLFdBQVc7cUNBQ3pCLENBQUM7b0NBQ0YsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQ0FDL0QsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQ0FDZixNQUFNLENBQUMsR0FBRyxDQUFDO2dDQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBQzs7O2lCQUNSLENBQUE7WUFFRCxJQUFNLFlBQVksR0FBRyw2QkFBNkIsQ0FBQztZQUVuRCxJQUFNLE9BQU8sR0FBRyxVQUFPLGdCQUF3Qjs7OztnQ0FDdkIscUJBQU0sb0JBQW9CLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLENBQUMsRUFBQTs7NEJBQWpGLGVBQWUsR0FBRyxTQUErRDs0QkFDcEUsS0FBQSxlQUFlLENBQUE7cUNBQWYsd0JBQWU7NEJBQUkscUJBQU0scUJBQXFCLENBQUMsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLEVBQUE7O2tDQUE5RCxTQUE4RDs7OzRCQUE5RixVQUFVLEtBQW9GOzRCQUNsRyxRQUFRLENBQUM7Z0NBQ1AsTUFBTSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7NEJBQ2pDLENBQUMsQ0FBQyxDQUFDOzs7O2lCQUNKLENBQUM7WUFFRixvQkFBb0IsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFBLEdBQUc7Z0JBQ3JELE1BQU0sQ0FBQyxpQkFBaUIsSUFBSSxZQUFZLFNBQUssR0FBRyxDQUFDLENBQUU7Z0JBQ25ELE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLElBQUksWUFBWSxDQUFDO1lBQ3hFLENBQUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFNLE9BQUEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUF0QixDQUFzQixFQUFFLFVBQUMsTUFBYyxFQUFFLE1BQWM7Z0JBQ3pFLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUM7WUFDckMsQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLFVBQU8sTUFBYyxFQUFFLE1BQWM7Ozs7OzRCQUN2RSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztnQ0FDdkMsTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7Z0NBQ3ZCLE1BQU0sZ0JBQUM7NEJBQ1QsQ0FBQzs0QkFDRCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztnQ0FDakQsNkJBQTBELEVBQXZELHNDQUEyQixDQUE2Qjs0QkFDN0QsQ0FBQzs0QkFDRCxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQzs0QkFDdEIsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztnQ0FDcEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDOzRCQUN6RSxDQUFDOzRCQUNELHFCQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBQSxHQUFHO29DQUM3QixRQUFRLENBQUMsY0FBUSxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNoRCxDQUFDLENBQUMsRUFBQTs7NEJBRkYsU0FFRSxDQUFDOzRCQUNILFFBQVEsQ0FBQyxjQUFRLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Ozs7aUJBQzdDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDSCx3QkFBQztJQUFELENBQUMsQUFoR0QsSUFnR0M7SUFFRCxhQUFhLENBQUMsVUFBVSxDQUFDLG1CQUFtQixFQUFFLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLHNCQUFzQixFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFuZ3VsYXIgZnJvbSAnYW5ndWxhckFNRCc7XG5cbmNvbnN0IG13dG5JbnZlbnRvcnkgPSBhbmd1bGFyLm1vZHVsZSgnYXBwLm13dG5JbnZlbnRvcnknKTtcblxuY2xhc3MgRXh0ZW5zaW9uUmVzdWx0IHtcbiAgcHVibGljIGV4dGVuc2lvbjogW1xuICAgIHsgXCJ2YWx1ZS1uYW1lXCI6IHN0cmluZywgXCJ2YWx1ZVwiOiBzdHJpbmcgfVxuICBdXG59XG5cbmludGVyZmFjZSBHZW5lcmljR2V0UmVxdWVzdCB7XG4gIHVybDogc3RyaW5nO1xuICBtZXRob2Q6IFwiR0VUXCI7XG59XG5cbmludGVyZmFjZSBHZW5lcmljUG9zdFJlcXVlc3Q8VD4ge1xuICB1cmw6IHN0cmluZztcbiAgbWV0aG9kOiBcIlBPU1RcIjtcbiAgZGF0YTogVFxufVxuXG5pbnRlcmZhY2UgQ29tbW9uU2VydmljZSB7XG4gIGdlbmVyaWNSZXF1ZXN0PFRSZXN1bHQ+KHJlcXVlc3Q6IEdlbmVyaWNHZXRSZXF1ZXN0KTogbmcuSVByb21pc2U8bmcuSUh0dHBSZXNwb25zZTxUUmVzdWx0Pj47XG4gIGdlbmVyaWNSZXF1ZXN0PFRSZXF1ZXN0LCBUUmVzdWx0PihyZXF1ZXN0OiBHZW5lcmljUG9zdFJlcXVlc3Q8VFJlcXVlc3Q+KTogbmcuSVByb21pc2U8bmcuSUh0dHBSZXNwb25zZTxUUmVzdWx0Pj47XG4gIGdldE1vdW50UG9pbnRzPFRSZXN1bHQ+KCk6IG5nLklQcm9taXNlPFRSZXN1bHQ+O1xufVxuXG5leHBvcnQgY2xhc3MgSW52ZW50b3J5U2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgJHE6IG5nLklRU2VydmljZSwgcHJpdmF0ZSAkbXd0bkNvbW1vbnM6IENvbW1vblNlcnZpY2UsIHByaXZhdGUgJG13dG5EYXRhYmFzZSwgcHJpdmF0ZSAkbXd0bkxvZykge1xuXG4gIH1cblxuICAvKiogXG4gICAqIEhlbHBlcmZ1bmN0aW9uIHRvIGRldGVjdCBhbmQgY29udmVydCB0aGUgJ3ZhbHVlLW5hbWUtZ3JvdXAnIC5cbiAgICogQHBhcmFtIHByb3BlcnR5TmFtZSBOYW1lIG9mIHRoZSBvYmplY3QgcHJvcGVydHkuXG4gICAqIEBwYXJhbSBwcm9wZXJ0eVZhbHVlIFZhbHVlIG9mIHRoZSBvYmplY3QgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB2YWx1ZU5hbWUgT3B0aW9uYWw6IFRoZSB2YWx1ZS1uYW1lIHRvIGJlIHVzZWQgaW5zdGFlZCBvZiB0aGUgcHJvcGVydHlOYW1lLlxuICAgKiBAcmV0dXJucyBBIHNpbXBsaWZpZWQgcHJvcGVydHkgdmFsdWUgaWYgdGhpcyBpcyBhICd2YWx1ZS1uYW1lLWdyb3VwJyBvdGhlcndoaXNlIHRoZSBwcm9wZXJ0eVZhbHVlLiAqL1xuICBwcml2YXRlIGNvbnZlcnRWYWx1ZSA9IChwcm9wZXJ0eU5hbWU6IHN0cmluZywgcHJvcGVydHlWYWx1ZTogYW55LCB2YWx1ZU5hbWU6IHN0cmluZyA9ICcnKTogYW55ID0+IHtcbiAgICBpZiAocHJvcGVydHlWYWx1ZSAmJiBwcm9wZXJ0eVZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgcHJvcGVydHlWYWx1ZS5sZW5ndGggPT0gMSAmJiAoXG4gICAgICB2YWx1ZU5hbWUgPT0gbnVsbCB8fFxuICAgICAgcHJvcGVydHlWYWx1ZVswXVtcInZhbHVlLW5hbWVcIl0gPT09IHByb3BlcnR5TmFtZSB8fFxuICAgICAgcHJvcGVydHlWYWx1ZVswXVtcInZhbHVlLW5hbWVcIl0gPT09IHZhbHVlTmFtZSlcbiAgICApIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlWzBdW1widmFsdWVcIl07XG4gICAgfVxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xuICB9XG5cbiAgLyoqIFxuICAgKiAgQ29udmVydHMgYW4gQVBJIG9iamVjdCB0byBhIHNpbXBsaWZpZWQgbG9jYWwgb2JqZWN0LlxuICAgKiAgQHBhcmFtIGFwaVJlc3VsdCBUaGUgQVBJIG9iamVjdCB0byBjb252ZXJ0LlxuICAgKiAgQHBhcmFtIHZhbHVlTmFtZSBPcHRpb25hbDogVGhlIHZhbHVlLW5hbWUgdG8gYmUgdXNlZCBpbnN0YWVkIG9mIHRoZSBwcm9wZXJ0eU5hbWUuXG4gICAqICBAcmV0dXJucyBUaGUgc2ltcGxpZmllZCBsb2NhbCBvYmplY3QuXG4gICovXG4gIHByaXZhdGUgY29udmVydE9iamVjdCA9IChhcGlSZXN1bHQ6IGFueSwgdmFsdWVOYW1lOiBzdHJpbmcgPSAnJyk6IGFueSA9PiB7XG4gICAgaWYgKGFwaVJlc3VsdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICByZXR1cm4gYXBpUmVzdWx0Lm1hcChlbG0gPT4geyByZXR1cm4gdGhpcy5jb252ZXJ0T2JqZWN0KGVsbSwgdmFsdWVOYW1lKTsgfSk7XG4gICAgfSBlbHNlIGlmIChhcGlSZXN1bHQgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhhcGlSZXN1bHQpO1xuICAgICAgbGV0IHJlc3VsdCA9IHt9O1xuICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jb252ZXJ0VmFsdWUoa2V5LCBhcGlSZXN1bHRba2V5XSwgdmFsdWVOYW1lKTtcbiAgICAgICAgcmVzdWx0W2tleV0gPSAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QgfHwgdmFsdWUgaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgICAgICA/IHRoaXMuY29udmVydE9iamVjdCh2YWx1ZSlcbiAgICAgICAgICA6IHZhbHVlO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gYXBpUmVzdWx0O1xuICB9XG5cbiAgLyoqIFJlcXVlc3RzIGFsbCBhY3RpdmUgbW9pbnQgcG9pbnRzICovXG4gIHB1YmxpYyBnZXRDb25uZWN0ZWRNb3VudHBvaW50cygpOiBuZy5JUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIHJldHVybiB0aGlzLiRtd3RuQ29tbW9ucy5nZXRNb3VudFBvaW50czx7fT4oKS50aGVuKChtb3VudHBvaW50czoge31bXSkgPT4ge1xuICAgICAgLy9jb25zb2xlLmxvZyhtb3VudHBvaW50cyk7XG4gICAgICByZXR1cm4gPHN0cmluZ1tdPm1vdW50cG9pbnRzLnJlZHVjZSgoYWNjOiBzdHJpbmdbXSwgY3VyLCBpbmQsIGFycikgPT4ge1xuICAgICAgICBpZiAoY3VyWyduZXRjb25mLW5vZGUtdG9wb2xvZ3k6Y29ubmVjdGlvbi1zdGF0dXMnXSA9PT0gJ2Nvbm5lY3RlZCcpIGFjYy5wdXNoKGN1cltcIm5vZGUtaWRcIl0pO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgW10pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIFxuICAgKiBSZXF1ZXN0cyBhbGwgJ3Jvb3QgaWRlbnRpZmllcnMnIGZvciB0aGUgZ2l2ZW4gJ25vZGUgaWQnLlxuICAgKiBAcGFyYW0gbm9kZUlkIFRoZSBpZCBvZiB0aGUgbm9kZSB0byByZXF1ZXN0IHRoZSByb290IGlkZW50aWZpZXJzIGZvci5cbiAgICogQHJldHVybnMgQSBxLlByb21pc2UgY29udGFpbmluZyBhbiBhcnJheSBvZiBhbGwgcm9vdCBpZGVudGlmaWVycyBmb3IgdGhlIHJlcXVlc3RlZCBub2RlIGlkLlxuICAgKiAqL1xuICBwdWJsaWMgZ2V0Um9vdElkZW50aWZpZXJzKG5vZGVJZDogc3RyaW5nKTogbmcuSVByb21pc2U8c3RyaW5nW10+IHtcblxuICAgIGNvbnN0IHJlcXVlc3Q6IEdlbmVyaWNHZXRSZXF1ZXN0ID0ge1xuICAgICAgdXJsOiBgb3BlcmF0aW9uYWwvbmV0d29yay10b3BvbG9neTpuZXR3b3JrLXRvcG9sb2d5L3RvcG9sb2d5L3RvcG9sb2d5LW5ldGNvbmYvbm9kZS8ke25vZGVJZH0veWFuZy1leHQ6bW91bnQvY29yZS1tb2RlbDpuZXR3b3JrLWVsZW1lbnQvZXh0ZW5zaW9uL3RvcC1sZXZlbC1lcXVpcG1lbnRgLFxuICAgICAgbWV0aG9kOiBcIkdFVFwiXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLiRtd3RuQ29tbW9ucy5nZW5lcmljUmVxdWVzdDxFeHRlbnNpb25SZXN1bHQ+KHJlcXVlc3QpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuc3RhdHVzID09IDIwMCAmJiByZXN1bHQuZGF0YSkge1xuICAgICAgICBjb25zdCB0b3BMZXZlbEVxdWlwbWVudCA9IHRoaXMuY29udmVydE9iamVjdChyZXN1bHQuZGF0YSwgJ3RvcC1sZXZlbC1lcXVpcG1lbnQnKTtcbiAgICAgICAgY29uc3Qgcm9vdElkZW50aWZpZXJzID0gdG9wTGV2ZWxFcXVpcG1lbnQgJiYgdG9wTGV2ZWxFcXVpcG1lbnQuZXh0ZW5zaW9uICYmIHRvcExldmVsRXF1aXBtZW50LmV4dGVuc2lvbi5zcGxpdCgnLCcpO1xuICAgICAgICByZXR1cm4gcm9vdElkZW50aWZpZXJzICYmIHJvb3RJZGVudGlmaWVycy5tYXAoaWRlbnRpZmllciA9PiBpZGVudGlmaWVyICYmIGlkZW50aWZpZXIudHJpbSgpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0sIGVyciA9PiAobnVsbCkpO1xuICB9XG5cbiAgLyoqIFxuICAgKiBSZXF1ZXN0cyB0aGUgZGV0YWlsIGluZm9ybWF0aW9uIGZvciB0aGUgZ2l2ZW4gY29tYmluYXRpb24gb2YgJ25vZGVJZCcgYW5kICdlcXVpcG1lbnRJZGVudGlmaWVyJy5cbiAgICogQHBhcmFtIG5vZGVJZCBUaGUgaWQgb2YgdGhlIHJvb3Qgbm9kZS5cbiAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIGlkZW50aWZpZXIgdG8gcmVxdWVzdCB0aGUgZGV0YWlscyBmb3IuXG4gICAqIEByZXR1cm5zIEEgcS5Qcm9taXNlIGNvbnRhaW5pbmcgYW4gb2JqZWN0IHdpdGggYWxsIHRoZSBkZXRhaWxzLlxuICAgKiAqL1xuICBwdWJsaWMgZ2V0RXF1aXBtZW50RGV0YWlscyhub2RlSWQ6IHN0cmluZywgaWRlbnRpZmllcjogc3RyaW5nKTogbmcuSVByb21pc2U8e30+IHtcbiAgICBjb25zdCByZXF1ZXN0OiBHZW5lcmljR2V0UmVxdWVzdCA9IHtcbiAgICAgIHVybDogYG9wZXJhdGlvbmFsL25ldHdvcmstdG9wb2xvZ3k6bmV0d29yay10b3BvbG9neS90b3BvbG9neS90b3BvbG9neS1uZXRjb25mL25vZGUvJHtub2RlSWR9L3lhbmctZXh0Om1vdW50L2NvcmUtbW9kZWw6ZXF1aXBtZW50LyR7aWRlbnRpZmllcn1gLFxuICAgICAgbWV0aG9kOiBcIkdFVFwiXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy4kbXd0bkNvbW1vbnMuZ2VuZXJpY1JlcXVlc3Q8RXh0ZW5zaW9uUmVzdWx0PihyZXF1ZXN0KS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LnN0YXR1cyA9PSAyMDAgJiYgcmVzdWx0LmRhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udmVydE9iamVjdChyZXN1bHQuZGF0YSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LCBlcnIgPT4gKG51bGwpKTtcbiAgfVxuXG4gIC8qKiBcbiAgICogUmVxdWVzdHMgdGhlIGNvbmRpdGlvbmFsIGluZm9ybWF0aW9uIGZvciB0aGUgZ2l2ZW4gY29tYmluYXRpb24gb2YgJ25vZGVJZCcgYW5kICdlcXVpcG1lbnRJZGVudGlmaWVyJy5cbiAgICogQHBhcmFtIG5vZGVJZCBUaGUgaWQgb2YgdGhlIHJvb3Qgbm9kZS5cbiAgICogQHBhcmFtIGlkZW50aWZpZXIgVGhlIGlkZW50aWZpZXIgdG8gcmVxdWVzdCB0aGUgY29uZGl0aW9uYWxzIGZvci5cbiAgICogQHJldHVybnMgQSBxLlByb21pc2UgY29udGFpbmluZyBhbiBvYmplY3Qgd2l0aCBhbGwgdGhlIGNvbmRpdGlvbmFsIGluZm9ybWF0aW9ucy5cbiAgICogKi9cbiAgcHVibGljIGdldEVxdWlwbWVudENvbmRpdGlvbmFscyhub2RlSWQ6IHN0cmluZywgaWRlbnRpZmllcjogc3RyaW5nKTogbmcuSVByb21pc2U8e30+IHtcbiAgICBjb25zdCByZXF1ZXN0OiBHZW5lcmljR2V0UmVxdWVzdCA9IHtcbiAgICAgIHVybDogYG9wZXJhdGlvbmFsL25ldHdvcmstdG9wb2xvZ3k6bmV0d29yay10b3BvbG9neS90b3BvbG9neS90b3BvbG9neS1uZXRjb25mL25vZGUvJHtub2RlSWR9L3lhbmctZXh0Om1vdW50L29uZi1jb3JlLW1vZGVsLWNvbmRpdGlvbmFsLXBhY2thZ2VzOmVxdWlwbWVudC1wYWMvJHtpZGVudGlmaWVyfWAsXG4gICAgICBtZXRob2Q6IFwiR0VUXCJcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLiRtd3RuQ29tbW9ucy5nZW5lcmljUmVxdWVzdDxFeHRlbnNpb25SZXN1bHQ+KHJlcXVlc3QpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuc3RhdHVzID09IDIwMCAmJiByZXN1bHQuZGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb252ZXJ0T2JqZWN0KHJlc3VsdC5kYXRhKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0sIGVyciA9PiAobnVsbCkpO1xuICB9XG59XG5td3RuSW52ZW50b3J5LnNlcnZpY2UoJ213dG5JbnZlbnRvcnlTZXJ2aWNlJywgW1wiJHFcIiwgXCIkbXd0bkNvbW1vbnNcIiwgXCIkbXd0bkRhdGFiYXNlXCIsIFwiJG13dG5Mb2dcIiwgSW52ZW50b3J5U2VydmljZV0pO1xuIiwiZXhwb3J0IGNsYXNzIEVxdWlwbWVudCB7XG4gIHV1aWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICBjaGlsZHJlbjogRXF1aXBtZW50W107XG59IiwiZGVjbGFyZSB2YXIgYW5ndWxhcjogYW5ndWxhci5JQW5ndWxhclN0YXRpYzsgIFxuXG5pbXBvcnQgeyBFcXVpcG1lbnQgfSBmcm9tICcuLi9tb2RlbHMvZXF1aXBtZW50JztcblxuY29uc3QgbXd0bkludmVudG9yeSA9IGFuZ3VsYXIubW9kdWxlKCdhcHAubXd0bkludmVudG9yeScpO1xuXG5jb25zdCBFcXVpcG1lbnREaXJlY3RpdmUgPSAoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgdGVtcGxhdGVVcmw6ICdzcmMvYXBwL213dG5JbnZlbnRvcnkvY29tcG9uZW50cy9lcXVpcG1lbnQuaHRtbCcsXG4gICAgY29udHJvbGxlcjogJ213dG5FcXVpcG1lbnRDdHJsJyxcbiAgICBjb250cm9sbGVyQXM6ICd2bScsXG4gICAgc2NvcGU6IHtcbiAgICAgIGVxdWlwbWVudDogXCI9XCJcbiAgICB9XG4gIH1cbn07XG5cbm13dG5JbnZlbnRvcnkuZGlyZWN0aXZlKCdtd3RuRXF1aXBtZW50JywgRXF1aXBtZW50RGlyZWN0aXZlKTtcblxuZXhwb3J0IGNsYXNzIEVxdWlwbWVudENvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlICRzY29wZTogbmcuSVNjb3BlICYgeyBlcXVpcG1lbnQ6IEVxdWlwbWVudCB9KSB7XG4gICBcbiAgfVxuXG4gXG59XG5cbm13dG5JbnZlbnRvcnkuY29udHJvbGxlcignbXd0bkVxdWlwbWVudEN0cmwnLCBbJyRzY29wZScsIEVxdWlwbWVudENvbnRyb2xsZXJdKTtcbiIsImRlY2xhcmUgdmFyIGFuZ3VsYXI6IGFuZ3VsYXIuSUFuZ3VsYXJTdGF0aWM7IFxuXG5pbXBvcnQgeyBFcXVpcG1lbnQgfSBmcm9tICcuLi9tb2RlbHMvZXF1aXBtZW50JztcblxuY29uc3QgbXd0bkludmVudG9yeSA9IGFuZ3VsYXIubW9kdWxlKCdhcHAubXd0bkludmVudG9yeScpO1xuXG5jb25zdCBFcXVpcG1lbnRHcm91cERpcmVjdGl2ZSA9ICgkY29tcGlsZSkgPT4ge1xuICByZXR1cm4ge1xuICAgIHRlbXBsYXRlVXJsOiAnc3JjL2FwcC9td3RuSW52ZW50b3J5L2NvbXBvbmVudHMvZXF1aXBtZW50R3JvdXAuaHRtbCcsXG4gICAgY29udHJvbGxlcjogJ213dG5FcXVpcG1lbnRHcm91cEN0cmwnLFxuICAgIGNvbnRyb2xsZXJBczogJ3ZtJyxcbiAgICBzY29wZToge1xuICAgICAgZXF1aXBtZW50czogXCI9XCJcbiAgICB9LFxuICAgIC8vIEhBQ0s6IGZvciBhbmd1bGFyIDEuNC4gY29tcGF0aWJpbGl0eVxuICAgIGNvbXBpbGU6IGZ1bmN0aW9uICh0RWxlbWVudCwgdEF0dHIsIHRyYW5zY2x1ZGUpIHtcbiAgICAgIHZhciBjb250ZW50cyA9IHRFbGVtZW50LmNvbnRlbnRzKCkucmVtb3ZlKCk7XG4gICAgICB2YXIgY29tcGlsZWRDb250ZW50cztcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoc2NvcGUsIGlFbGVtZW50LCBpQXR0cikge1xuICAgICAgICBpZiAoIWNvbXBpbGVkQ29udGVudHMpIHtcbiAgICAgICAgICBjb21waWxlZENvbnRlbnRzID0gJGNvbXBpbGUoY29udGVudHMsIHRyYW5zY2x1ZGUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbXBpbGVkQ29udGVudHMoc2NvcGUsIGZ1bmN0aW9uIChjbG9uZSwgc2NvcGUpIHtcbiAgICAgICAgICBpRWxlbWVudC5hcHBlbmQoY2xvbmUpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfVxuICB9XG59O1xuXG5td3RuSW52ZW50b3J5LmRpcmVjdGl2ZSgnbXd0bkVxdWlwbWVudEdyb3VwJywgWyckY29tcGlsZScsIEVxdWlwbWVudEdyb3VwRGlyZWN0aXZlXSk7XG5cbmV4cG9ydCBjbGFzcyBFcXVpcG1lbnRHcm91cENvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlICRzY29wZTogbmcuSVNjb3BlICYgeyBlcXVpcG1lbnRzOiBFcXVpcG1lbnRbXSB9KSB7XG4gICAgLy9jb25zb2xlLmxvZyhcIkVxdWlwbWVudEdyb3VwQ29udHJvbGxlclwiLCAkc2NvcGUuZXF1aXBtZW50cyk7XG4gICAgXG4gIH1cblxufVxuXG5td3RuSW52ZW50b3J5LmNvbnRyb2xsZXIoJ213dG5FcXVpcG1lbnRHcm91cEN0cmwnLCBbJyRzY29wZScsIEVxdWlwbWVudEdyb3VwQ29udHJvbGxlcl0pOyIsImRlY2xhcmUgdmFyIGFuZ3VsYXI6IGFuZ3VsYXIuSUFuZ3VsYXJTdGF0aWM7IFxuXG5pbXBvcnQgeyBJbnZlbnRvcnlTZXJ2aWNlIH0gZnJvbSBcIi4vbXd0bkludmVudG9yeS5zZXJ2aWNlXCI7IFxuaW1wb3J0IFwiLi9td3RuSW52ZW50b3J5LnNlcnZpY2VcIjtcbmltcG9ydCBcIi4vY29tcG9uZW50cy9lcXVpcG1lbnRcIjtcbmltcG9ydCBcIi4vY29tcG9uZW50cy9lcXVpcG1lbnRHcm91cFwiO1xuXG5jb25zdCBtd3RuSW52ZW50b3J5ID0gYW5ndWxhci5tb2R1bGUoJ2FwcC5td3RuSW52ZW50b3J5Jyk7XG5cbmludGVyZmFjZSBJTXd0bkludmVudG9yeVNjb3BlIGV4dGVuZHMgbmcuSVNjb3BlIHtcbiAgbWVzc2FnZTogc3RyaW5nLFxuICBlcXVpcG1lbnRzOiB7fVtdO1xuICBsb2FkaW5nOiBib29sZWFuO1xuICBhY3RpdmVNb3VudFBvaW50czogc3RyaW5nW107XG4gIHNlbGVjdGVkTW91bnRQb2ludDogc3RyaW5nO1xufVxuXG5jbGFzcyBNd3RuSW52ZW50b3J5Q3RybCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgJHJvb3RTY29wZSwgcHJpdmF0ZSAkc2NvcGU6IElNd3RuSW52ZW50b3J5U2NvcGUsIHByaXZhdGUgJHN0YXRlLCBwcml2YXRlICR0aW1lb3V0LCBwcml2YXRlIG13dG5JbnZlbnRvcnlTZXJ2aWNlOiBJbnZlbnRvcnlTZXJ2aWNlKSB7XG4gICAgLy8gdG9kbzogY2hhbmdlIHRoaXNcbiAgICAkcm9vdFNjb3BlLnNlY3Rpb25fbG9nbyA9ICdzcmMvYXBwL213dG5JbnZlbnRvcnkvaW1hZ2VzL213dG5JbnZlbnRvcnkucG5nJztcblxuICAgICRzY29wZS5sb2FkaW5nID0gZmFsc2U7XG4gICAgJHNjb3BlLm1lc3NhZ2UgPSBcIkVtcHR5XCI7XG4gICAgJHNjb3BlLmVxdWlwbWVudHMgPSBbXTtcbiAgICAkc2NvcGUuc2VsZWN0ZWRNb3VudFBvaW50ID0gbnVsbDtcblxuICAgICRzY29wZS5hY3RpdmVNb3VudFBvaW50cyA9IFtdO1xuXG4gICAgY29uc3QgZ2V0QWxsQ2hpbGRFcXVpcG1lbnRzID0gYXN5bmMgKGVxdWlwbWVudHNSb290SWQ6IHN0cmluZywgZXF1aW1lbnRJZHM6IHN0cmluZ1tdKSA9PiB7XG4gICAgICBpZiAoIWVxdWltZW50SWRzIHx8ICFlcXVpbWVudElkcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgY29uc3QgZXF1aXBtZW50T2JqZWN0cyA9IChhd2FpdCBQcm9taXNlLmFsbChlcXVpbWVudElkcy5tYXAoaWQgPT4ge1xuICAgICAgICByZXR1cm4gbXd0bkludmVudG9yeVNlcnZpY2UuZ2V0RXF1aXBtZW50RGV0YWlscyhlcXVpcG1lbnRzUm9vdElkLCBpZCk7XG4gICAgICB9KSkpLm1hcChlcSA9PiAoZXFbXCJlcXVpcG1lbnRcIl1bMF0pKTtcblxuICAgICAgY29uc3QgZXF1aXBtZW50Q29uZGl0aW9uYWxzID0gKGF3YWl0IFByb21pc2UuYWxsKGVxdWltZW50SWRzLm1hcChpZCA9PiB7XG4gICAgICAgIHJldHVybiBtd3RuSW52ZW50b3J5U2VydmljZS5nZXRFcXVpcG1lbnRDb25kaXRpb25hbHMoZXF1aXBtZW50c1Jvb3RJZCwgaWQpO1xuICAgICAgfSkpKS5tYXAoZXEgPT4gKGVxW1wiZXF1aXBtZW50LXBhY1wiXVswXSkpO1xuICAgICAgXG4gICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGVxdWlwbWVudE9iamVjdHMubWFwKGVxID0+IHtcbiAgICAgICAgbGV0IGZydU5hbWVzOiBzdHJpbmdbXSA9IChlcVtcImNvbnRhaW5lZC1ob2xkZXJcIl0gfHwgW10pLm1hcChjaCA9PiBjaFtcIm9jY3VweWluZy1mcnVcIl0pLmZpbHRlcihmcnUgPT4gISFmcnUpO1xuICAgICAgICByZXR1cm4gZ2V0QWxsQ2hpbGRFcXVpcG1lbnRzKGVxdWlwbWVudHNSb290SWQsIGZydU5hbWVzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGVxdWlwbWVudE9iamVjdHMucmVkdWNlKChhY2MsIGN1ciwgaW5kLCBhcnIpID0+IHtcbiAgICAgICAgbGV0IGNvbmRpdGlvbmFsID0gZXF1aXBtZW50Q29uZGl0aW9uYWxzW2luZF0gfHwgbnVsbDtcbiAgICAgICAgLy8gZW5zdXJlIEVOVkVSWSBwcm9wZXJ0eSBjYW4gYmUgbnVsbCBvciB1bmRlZmluZWRcbiAgICAgICAgbGV0IG1hbnVmYWN0dXJlZFRoaW5nID0gY3VyWydtYW51ZmFjdHVyZWQtdGhpbmcnXTtcbiAgICAgICAgbGV0IGVxdWlwbWVudFR5cGUgPSBtYW51ZmFjdHVyZWRUaGluZyAmJiBtYW51ZmFjdHVyZWRUaGluZ1snZXF1aXBtZW50LXR5cGUnXTtcbiAgICAgICAgbGV0IG1hbnVmYWN0dXJlclByb3BlcnRpZXMgPSBtYW51ZmFjdHVyZWRUaGluZyAmJiBtYW51ZmFjdHVyZWRUaGluZ1snbWFudWZhY3R1cmVyLXByb3BlcnRpZXMnXTtcbiAgICAgICAgbGV0IGVxdWlwbWVudEluc3RhbmNlID0gbWFudWZhY3R1cmVkVGhpbmcgJiYgbWFudWZhY3R1cmVkVGhpbmdbJ2VxdWlwbWVudC1pbnN0YW5jZSddO1xuXG4gICAgICAgIGxldCBjYXJkID0ge1xuICAgICAgICAgIG5hbWU6IGN1ci5uYW1lLFxuICAgICAgICAgIGxhYmVsOiBjdXIubGFiZWwsXG4gICAgICAgICAgdXVpZDogY3VyLnV1aWQsXG4gICAgICAgICAgbWFudWZhY3R1cmVyOiB7XG4gICAgICAgICAgICB2ZXJzaW9uOiBlcXVpcG1lbnRUeXBlICYmIGVxdWlwbWVudFR5cGVbXCJ2ZXJzaW9uXCJdLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGVxdWlwbWVudFR5cGUgJiYgZXF1aXBtZW50VHlwZVtcImRlc2NyaXB0aW9uXCJdLFxuICAgICAgICAgICAgcGFydFR5cGVJZGVudGlmaWVyOiBlcXVpcG1lbnRUeXBlICYmIGVxdWlwbWVudFR5cGVbXCJwYXJ0LXR5cGUtaWRlbnRpZmllclwiXSxcbiAgICAgICAgICAgIG1vZGVsSWRlbnRpZmllcjogZXF1aXBtZW50VHlwZSAmJiBlcXVpcG1lbnRUeXBlW1wibW9kZWwtaWRlbnRpZmllclwiXSxcbiAgICAgICAgICAgIHBhcnRUeXBlSWRldHlwZU5hbWVudGlmaWVyOiBlcXVpcG1lbnRUeXBlICYmIGVxdWlwbWVudFR5cGVbXCJ0eXBlLW5hbWVcIl0sXG4gICAgICAgICAgICBpZDogbWFudWZhY3R1cmVyUHJvcGVydGllcyAmJiBtYW51ZmFjdHVyZXJQcm9wZXJ0aWVzWydtYW51ZmFjdHVyZXItaWRlbnRpZmllciddLFxuICAgICAgICAgICAgZGF0ZTogZXF1aXBtZW50SW5zdGFuY2UgJiYgZXF1aXBtZW50SW5zdGFuY2VbJ21hbnVmYWN0dXJlLWRhdGUnXSAmJiBEYXRlLnBhcnNlKGVxdWlwbWVudEluc3RhbmNlICYmIGVxdWlwbWVudEluc3RhbmNlWydtYW51ZmFjdHVyZS1kYXRlJ10pLFxuICAgICAgICAgICAgc2VyaWFsOiBlcXVpcG1lbnRJbnN0YW5jZSAmJiBlcXVpcG1lbnRJbnN0YW5jZVsnc2VyaWFsLW51bWJlciddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb25kaXRpb25hbDogY29uZGl0aW9uYWxcbiAgICAgICAgfTtcbiAgICAgICAgKHJlc3VsdHNbaW5kXS5sZW5ndGggPyBjYXJkWydjaGlsZHJlbiddID0gcmVzdWx0c1tpbmRdIDogbnVsbCk7XG4gICAgICAgIGFjYy5wdXNoKGNhcmQpO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgW10pO1xuICAgIH1cblxuICAgIGNvbnN0IHBsZWFzZVNlbGVjdCA9IFwiUGxlYXNlIHNlbGVjdCBhIG1vdW50IHBvaW50XCI7XG5cbiAgICBjb25zdCByZWZyZXNoID0gYXN5bmMgKGVxdWlwbWVudHNSb290SWQ6IHN0cmluZykgPT4ge1xuICAgICAgbGV0IHJvb3RJZGVudGlmaWVycyA9IGF3YWl0IG13dG5JbnZlbnRvcnlTZXJ2aWNlLmdldFJvb3RJZGVudGlmaWVycyhlcXVpcG1lbnRzUm9vdElkKTtcbiAgICAgIGxldCBlcXVpcG1lbnRzID0gcm9vdElkZW50aWZpZXJzICYmIGF3YWl0IGdldEFsbENoaWxkRXF1aXBtZW50cyhlcXVpcG1lbnRzUm9vdElkLCByb290SWRlbnRpZmllcnMpO1xuICAgICAgJHRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAkc2NvcGUuZXF1aXBtZW50cyA9IGVxdWlwbWVudHM7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgbXd0bkludmVudG9yeVNlcnZpY2UuZ2V0Q29ubmVjdGVkTW91bnRwb2ludHMoKS50aGVuKHJlcyA9PiB7XG4gICAgICAkc2NvcGUuYWN0aXZlTW91bnRQb2ludHMgPSBbcGxlYXNlU2VsZWN0LCAuLi5yZXNdIDtcbiAgICAgICRzY29wZS5zZWxlY3RlZE1vdW50UG9pbnQgPSAkc2NvcGUuc2VsZWN0ZWRNb3VudFBvaW50IHx8IHBsZWFzZVNlbGVjdDtcbiAgICB9KTtcblxuICAgICRzY29wZS4kd2F0Y2goKCkgPT4gKCRzdGF0ZS5wYXJhbXMubm9kZUlkKSwgKG5ld1ZhbDogc3RyaW5nLCBvbGRWYWw6IHN0cmluZykgPT4ge1xuICAgICAgJHNjb3BlLnNlbGVjdGVkTW91bnRQb2ludCA9IG5ld1ZhbDtcbiAgICB9KTtcblxuICAgICRzY29wZS4kd2F0Y2goXCJzZWxlY3RlZE1vdW50UG9pbnRcIiwgYXN5bmMgKG5ld1ZhbDogc3RyaW5nLCBvbGRWYWw6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKCFuZXdWYWwgfHwgbmV3VmFsID09PSBwbGVhc2VTZWxlY3QpIHtcbiAgICAgICAgJHNjb3BlLmVxdWlwbWVudHMgPSBbXTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCRzY29wZS5hY3RpdmVNb3VudFBvaW50c1swXSA9PT0gcGxlYXNlU2VsZWN0KSB7XG4gICAgICAgIFssIC4uLiRzY29wZS5hY3RpdmVNb3VudFBvaW50c10gPSAkc2NvcGUuYWN0aXZlTW91bnRQb2ludHM7XG4gICAgICB9IFxuICAgICAgJHNjb3BlLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgaWYgKCRzdGF0ZS5wYXJhbXMubm9kZUlkICE9PSBuZXdWYWwpIHtcbiAgICAgICAgJHN0YXRlLmdvKCdtYWluLm13dG5JbnZlbnRvcnknLCB7IG5vZGVJZDogbmV3VmFsIH0sIHsgbm90aWZ5OiBmYWxzZSB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHJlZnJlc2gobmV3VmFsKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAkdGltZW91dCgoKSA9PiB7ICRzY29wZS5lcXVpcG1lbnRzID0gbnVsbDsgfSk7XG4gICAgICB9KTtcbiAgICAgICR0aW1lb3V0KCgpID0+IHsgJHNjb3BlLmxvYWRpbmcgPSBmYWxzZTsgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxubXd0bkludmVudG9yeS5jb250cm9sbGVyKCdtd3RuSW52ZW50b3J5Q3RybCcsIFsnJHJvb3RTY29wZScsICckc2NvcGUnLCAnJHN0YXRlJywgJyR0aW1lb3V0JywgJ213dG5JbnZlbnRvcnlTZXJ2aWNlJywgTXd0bkludmVudG9yeUN0cmxdKTtcbiJdfQ== \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.ts
new file mode 100644
index 00000000..f4cb3e86
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.controller.ts
@@ -0,0 +1,116 @@
+declare var angular: angular.IAngularStatic;
+
+import { InventoryService } from "./mwtnInventory.service";
+import "./mwtnInventory.service";
+import "./components/equipment";
+import "./components/equipmentGroup";
+
+const mwtnInventory = angular.module('app.mwtnInventory');
+
+interface IMwtnInventoryScope extends ng.IScope {
+ message: string,
+ equipments: {}[];
+ loading: boolean;
+ activeMountPoints: string[];
+ selectedMountPoint: string;
+}
+
+class MwtnInventoryCtrl {
+ constructor(private $rootScope, private $scope: IMwtnInventoryScope, private $state, private $timeout, private mwtnInventoryService: InventoryService) {
+ // todo: change this
+ $rootScope.section_logo = 'src/app/mwtnInventory/images/mwtnInventory.png';
+
+ $scope.loading = false;
+ $scope.message = "Empty";
+ $scope.equipments = [];
+ $scope.selectedMountPoint = null;
+
+ $scope.activeMountPoints = [];
+
+ const getAllChildEquipments = async (equipmentsRootId: string, equimentIds: string[]) => {
+ if (!equimentIds || !equimentIds.length) {
+ return [];
+ }
+ const equipmentObjects = (await Promise.all(equimentIds.map(id => {
+ return mwtnInventoryService.getEquipmentDetails(equipmentsRootId, id);
+ }))).map(eq => (eq["equipment"][0]));
+
+ const equipmentConditionals = (await Promise.all(equimentIds.map(id => {
+ return mwtnInventoryService.getEquipmentConditionals(equipmentsRootId, id);
+ }))).map(eq => (eq["equipment-pac"][0]));
+
+ let results = await Promise.all(equipmentObjects.map(eq => {
+ let fruNames: string[] = (eq["contained-holder"] || []).map(ch => ch["occupying-fru"]).filter(fru => !!fru);
+ return getAllChildEquipments(equipmentsRootId, fruNames);
+ }));
+
+ return equipmentObjects.reduce((acc, cur, ind, arr) => {
+ let conditional = equipmentConditionals[ind] || null;
+ // ensure ENVERY property can be null or undefined
+ let manufacturedThing = cur['manufactured-thing'];
+ let equipmentType = manufacturedThing && manufacturedThing['equipment-type'];
+ let manufacturerProperties = manufacturedThing && manufacturedThing['manufacturer-properties'];
+ let equipmentInstance = manufacturedThing && manufacturedThing['equipment-instance'];
+
+ let card = {
+ name: cur.name,
+ label: cur.label,
+ uuid: cur.uuid,
+ manufacturer: {
+ version: equipmentType && equipmentType["version"],
+ description: equipmentType && equipmentType["description"],
+ partTypeIdentifier: equipmentType && equipmentType["part-type-identifier"],
+ modelIdentifier: equipmentType && equipmentType["model-identifier"],
+ partTypeIdetypeNamentifier: equipmentType && equipmentType["type-name"],
+ id: manufacturerProperties && manufacturerProperties['manufacturer-identifier'],
+ date: equipmentInstance && equipmentInstance['manufacture-date'] && Date.parse(equipmentInstance && equipmentInstance['manufacture-date']),
+ serial: equipmentInstance && equipmentInstance['serial-number']
+ },
+ conditional: conditional
+ };
+ (results[ind].length ? card['children'] = results[ind] : null);
+ acc.push(card);
+ return acc;
+ }, []);
+ }
+
+ const pleaseSelect = "Please select a mount point";
+
+ const refresh = async (equipmentsRootId: string) => {
+ let rootIdentifiers = await mwtnInventoryService.getRootIdentifiers(equipmentsRootId);
+ let equipments = rootIdentifiers && await getAllChildEquipments(equipmentsRootId, rootIdentifiers);
+ $timeout(() => {
+ $scope.equipments = equipments;
+ });
+ };
+
+ mwtnInventoryService.getConnectedMountpoints().then(res => {
+ $scope.activeMountPoints = [pleaseSelect, ...res] ;
+ $scope.selectedMountPoint = $scope.selectedMountPoint || pleaseSelect;
+ });
+
+ $scope.$watch(() => ($state.params.nodeId), (newVal: string, oldVal: string) => {
+ $scope.selectedMountPoint = newVal;
+ });
+
+ $scope.$watch("selectedMountPoint", async (newVal: string, oldVal: string) => {
+ if (!newVal || newVal === pleaseSelect) {
+ $scope.equipments = [];
+ return;
+ }
+ if ($scope.activeMountPoints[0] === pleaseSelect) {
+ [, ...$scope.activeMountPoints] = $scope.activeMountPoints;
+ }
+ $scope.loading = true;
+ if ($state.params.nodeId !== newVal) {
+ $state.go('main.mwtnInventory', { nodeId: newVal }, { notify: false });
+ }
+ await refresh(newVal).catch(err => {
+ $timeout(() => { $scope.equipments = null; });
+ });
+ $timeout(() => { $scope.loading = false; });
+ });
+ }
+}
+
+mwtnInventory.controller('mwtnInventoryCtrl', ['$rootScope', '$scope', '$state', '$timeout', 'mwtnInventoryService', MwtnInventoryCtrl]);
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.js
new file mode 100644
index 00000000..5e104941
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.js
@@ -0,0 +1,33 @@
+define( ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.mwtnInventory = angular.module('app.mwtnInventory', ['app.core']);
+ exports.mwtnInventory.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+ //$translatePartialLoaderProvider.addPart('app/mwtnInventory/locale/locale');
+ NavHelperProvider.addControllerUrl('app/mwtnInventory/mwtnInventory.controller');
+ NavHelperProvider.addToMenu('mwtnInventory', {
+ "link": "#/pnfInventory/",
+ "active": "main.mwtnInventory",
+ "title": "pnf Inventory",
+ "icon": "fa fa-book",
+ "page": {
+ "title": "pnf Inventory",
+ "description": "mwtnInventory"
+ }
+ });
+ $stateProvider.state('main.mwtnInventory', {
+ url: 'pnfInventory/:nodeId?',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/mwtnInventory/mwtnInventory.tpl.html',
+ controller: 'mwtnInventoryCtrl'
+ }
+ }
+ });
+ });
+});
+/* non ES6 export */
+// export = mwtnInventory;
+// export default mwtnInventory;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXd0bkludmVudG9yeS5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcmMvYXBwL213dG5JbnZlbnRvcnkvbXd0bkludmVudG9yeS5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0lBR2EsUUFBQSxhQUFhLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFFL0UscUJBQWEsQ0FBQyxNQUFNLENBQUMsVUFBVSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxrQkFBa0IsRUFBRSwrQkFBK0I7UUFFbkwsNkVBQTZFO1FBRTdFLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDakYsaUJBQWlCLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRTtZQUMzQyxNQUFNLEVBQUUsa0JBQWtCO1lBQzFCLFFBQVEsRUFBRSxvQkFBb0I7WUFDOUIsT0FBTyxFQUFFLGdCQUFnQjtZQUN6QixNQUFNLEVBQUUsYUFBYTtZQUNyQixNQUFNLEVBQUU7Z0JBQ04sT0FBTyxFQUFFLFdBQVc7Z0JBQ3BCLGFBQWEsRUFBRSxlQUFlO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsY0FBYyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTtZQUN6QyxHQUFHLEVBQUUsd0JBQXdCO1lBQzdCLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFO2dCQUNMLFNBQVMsRUFBRTtvQkFDVCxXQUFXLEVBQUUsOENBQThDO29CQUMzRCxVQUFVLEVBQUUsbUJBQW1CO2lCQUNoQzthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7O0FBRUgsb0JBQW9CO0FBQ3BCLDZCQUE2QjtBQUM3QixnQ0FBZ0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBpbXBvcnQgKiBhcyBhbmd1bGFyIGZyb20gJ2FuZ3VsYXJBTUQnO1xuZGVjbGFyZSB2YXIgYW5ndWxhcjogYW5ndWxhci5JQW5ndWxhclN0YXRpYzsgXG5cbmV4cG9ydCBjb25zdCBtd3RuSW52ZW50b3J5ID0gYW5ndWxhci5tb2R1bGUoJ2FwcC5td3RuSW52ZW50b3J5JywgWydhcHAuY29yZSddKTtcblxubXd0bkludmVudG9yeS5jb25maWcoZnVuY3Rpb24gKCRzdGF0ZVByb3ZpZGVyLCAkY29tcGlsZVByb3ZpZGVyLCAkY29udHJvbGxlclByb3ZpZGVyLCAkcHJvdmlkZSwgTmF2SGVscGVyUHJvdmlkZXIsICRodHRwUHJvdmlkZXIsICR0cmFuc2xhdGVQcm92aWRlciwgJHRyYW5zbGF0ZVBhcnRpYWxMb2FkZXJQcm92aWRlcikge1xuXG4gIC8vJHRyYW5zbGF0ZVBhcnRpYWxMb2FkZXJQcm92aWRlci5hZGRQYXJ0KCdhcHAvbXd0bkludmVudG9yeS9sb2NhbGUvbG9jYWxlJyk7XG5cbiAgTmF2SGVscGVyUHJvdmlkZXIuYWRkQ29udHJvbGxlclVybCgnYXBwL213dG5JbnZlbnRvcnkvbXd0bkludmVudG9yeS5jb250cm9sbGVyJyk7XG4gIE5hdkhlbHBlclByb3ZpZGVyLmFkZFRvTWVudSgnbXd0bkludmVudG9yeScsIHtcbiAgICBcImxpbmtcIjogXCIjL213dG5JbnZlbnRvcnkvXCIsXG4gICAgXCJhY3RpdmVcIjogXCJtYWluLm13dG5JbnZlbnRvcnlcIixcbiAgICBcInRpdGxlXCI6IFwiTVdUTiBJbnZlbnRvcnlcIixcbiAgICBcImljb25cIjogXCJmYSAgZmEtYm9va1wiLCAgLy8gQWRkIG5hdmlnYXRpb24gaWNvbiBjc3MgY2xhc3MgaGVyZVxuICAgIFwicGFnZVwiOiB7XG4gICAgICBcInRpdGxlXCI6IFwiTVdUTiBEZW1vXCIsXG4gICAgICBcImRlc2NyaXB0aW9uXCI6IFwibXd0bkludmVudG9yeVwiXG4gICAgfVxuICB9KTtcblxuICAkc3RhdGVQcm92aWRlci5zdGF0ZSgnbWFpbi5td3RuSW52ZW50b3J5Jywge1xuICAgIHVybDogJ213dG5JbnZlbnRvcnkvOm5vZGVJZD8nLFxuICAgIGFjY2VzczogMixcbiAgICB2aWV3czoge1xuICAgICAgJ2NvbnRlbnQnOiB7XG4gICAgICAgIHRlbXBsYXRlVXJsOiAnc3JjL2FwcC9td3RuSW52ZW50b3J5L213dG5JbnZlbnRvcnkudHBsLmh0bWwnLFxuICAgICAgICBjb250cm9sbGVyOiAnbXd0bkludmVudG9yeUN0cmwnXG4gICAgICB9XG4gICAgfVxuICB9KTtcbn0pO1xuXG4vKiBub24gRVM2IGV4cG9ydCAqL1xuLy8gZXhwb3J0ID0gbXd0bkludmVudG9yeTsgICBcbi8vIGV4cG9ydCBkZWZhdWx0IG13dG5JbnZlbnRvcnk7Il19 \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.ts
new file mode 100644
index 00000000..6fee7005
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.module.ts
@@ -0,0 +1,36 @@
+// import * as angular from 'angularAMD';
+declare var angular: angular.IAngularStatic;
+
+export const mwtnInventory = angular.module('app.mwtnInventory', ['app.core']);
+
+mwtnInventory.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+
+ //$translatePartialLoaderProvider.addPart('app/mwtnInventory/locale/locale');
+
+ NavHelperProvider.addControllerUrl('app/mwtnInventory/mwtnInventory.controller');
+ NavHelperProvider.addToMenu('mwtnInventory', {
+ "link": "#/pnfInventory/",
+ "active": "main.mwtnInventory",
+ "title": "pnf Inventory",
+ "icon": "fa fa-book", // Add navigation icon css class here
+ "page": {
+ "title": "pnf Inventory",
+ "description": "mwtnInventory"
+ }
+ });
+
+ $stateProvider.state('main.mwtnInventory', {
+ url: 'pnfInventory/:nodeId?',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/mwtnInventory/mwtnInventory.tpl.html',
+ controller: 'mwtnInventoryCtrl'
+ }
+ }
+ });
+});
+
+/* non ES6 export */
+// export = mwtnInventory;
+// export default mwtnInventory; \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.service.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.service.ts
new file mode 100644
index 00000000..be381a4c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.service.ts
@@ -0,0 +1,144 @@
+import * as angular from 'angularAMD';
+
+const mwtnInventory = angular.module('app.mwtnInventory');
+
+class ExtensionResult {
+ public extension: [
+ { "value-name": string, "value": string }
+ ]
+}
+
+interface GenericGetRequest {
+ url: string;
+ method: "GET";
+}
+
+interface GenericPostRequest<T> {
+ url: string;
+ method: "POST";
+ data: T
+}
+
+interface CommonService {
+ genericRequest<TResult>(request: GenericGetRequest): ng.IPromise<ng.IHttpResponse<TResult>>;
+ genericRequest<TRequest, TResult>(request: GenericPostRequest<TRequest>): ng.IPromise<ng.IHttpResponse<TResult>>;
+ getMountPoints<TResult>(): ng.IPromise<TResult>;
+}
+
+export class InventoryService {
+ constructor(private $q: ng.IQService, private $mwtnCommons: CommonService, private $mwtnDatabase, private $mwtnLog) {
+
+ }
+
+ /**
+ * Helperfunction to detect and convert the 'value-name-group' .
+ * @param propertyName Name of the object property.
+ * @param propertyValue Value of the object property.
+ * @param valueName Optional: The value-name to be used instaed of the propertyName.
+ * @returns A simplified property value if this is a 'value-name-group' otherwhise the propertyValue. */
+ private convertValue = (propertyName: string, propertyValue: any, valueName: string = ''): any => {
+ if (propertyValue && propertyValue instanceof Array && propertyValue.length == 1 && (
+ valueName == null ||
+ propertyValue[0]["value-name"] === propertyName ||
+ propertyValue[0]["value-name"] === valueName)
+ ) {
+ return propertyValue[0]["value"];
+ }
+ return propertyValue;
+ }
+
+ /**
+ * Converts an API object to a simplified local object.
+ * @param apiResult The API object to convert.
+ * @param valueName Optional: The value-name to be used instaed of the propertyName.
+ * @returns The simplified local object.
+ */
+ private convertObject = (apiResult: any, valueName: string = ''): any => {
+ if (apiResult instanceof Array) {
+ return apiResult.map(elm => { return this.convertObject(elm, valueName); });
+ } else if (apiResult instanceof Object) {
+ const keys = Object.keys(apiResult);
+ let result = {};
+ keys.forEach(key => {
+ const value = this.convertValue(key, apiResult[key], valueName);
+ result[key] = (value instanceof Object || value instanceof Array)
+ ? this.convertObject(value)
+ : value;
+ });
+ return result;
+ }
+ return apiResult;
+ }
+
+ /** Requests all active moint points */
+ public getConnectedMountpoints(): ng.IPromise<string[]> {
+ return this.$mwtnCommons.getMountPoints<{}>().then((mountpoints: {}[]) => {
+ //console.log(mountpoints);
+ return <string[]>mountpoints.reduce((acc: string[], cur, ind, arr) => {
+ if (cur['netconf-node-topology:connection-status'] === 'connected') acc.push(cur["node-id"]);
+ return acc;
+ }, []);
+ });
+ }
+
+ /**
+ * Requests all 'root identifiers' for the given 'node id'.
+ * @param nodeId The id of the node to request the root identifiers for.
+ * @returns A q.Promise containing an array of all root identifiers for the requested node id.
+ * */
+ public getRootIdentifiers(nodeId: string): ng.IPromise<string[]> {
+
+ const request: GenericGetRequest = {
+ url: `operational/network-topology:network-topology/topology/topology-netconf/node/${nodeId}/yang-ext:mount/core-model:network-element/extension/top-level-equipment`,
+ method: "GET"
+ };
+
+ return this.$mwtnCommons.genericRequest<ExtensionResult>(request).then((result) => {
+ if (result && result.status == 200 && result.data) {
+ const topLevelEquipment = this.convertObject(result.data, 'top-level-equipment');
+ const rootIdentifiers = topLevelEquipment && topLevelEquipment.extension && topLevelEquipment.extension.split(',');
+ return rootIdentifiers && rootIdentifiers.map(identifier => identifier && identifier.trim());
+ }
+ return null;
+ }, err => (null));
+ }
+
+ /**
+ * Requests the detail information for the given combination of 'nodeId' and 'equipmentIdentifier'.
+ * @param nodeId The id of the root node.
+ * @param identifier The identifier to request the details for.
+ * @returns A q.Promise containing an object with all the details.
+ * */
+ public getEquipmentDetails(nodeId: string, identifier: string): ng.IPromise<{}> {
+ const request: GenericGetRequest = {
+ url: `operational/network-topology:network-topology/topology/topology-netconf/node/${nodeId}/yang-ext:mount/core-model:equipment/${identifier}`,
+ method: "GET"
+ };
+ return this.$mwtnCommons.genericRequest<ExtensionResult>(request).then((result) => {
+ if (result && result.status == 200 && result.data) {
+ return this.convertObject(result.data);
+ }
+ return null;
+ }, err => (null));
+ }
+
+ /**
+ * Requests the conditional information for the given combination of 'nodeId' and 'equipmentIdentifier'.
+ * @param nodeId The id of the root node.
+ * @param identifier The identifier to request the conditionals for.
+ * @returns A q.Promise containing an object with all the conditional informations.
+ * */
+ public getEquipmentConditionals(nodeId: string, identifier: string): ng.IPromise<{}> {
+ const request: GenericGetRequest = {
+ url: `operational/network-topology:network-topology/topology/topology-netconf/node/${nodeId}/yang-ext:mount/onf-core-model-conditional-packages:equipment-pac/${identifier}`,
+ method: "GET"
+ };
+ return this.$mwtnCommons.genericRequest<ExtensionResult>(request).then((result) => {
+ if (result && result.status == 200 && result.data) {
+ return this.convertObject(result.data);
+ }
+ return null;
+ }, err => (null));
+ }
+}
+mwtnInventory.service('mwtnInventoryService', ["$q", "$mwtnCommons", "$mwtnDatabase", "$mwtnLog", InventoryService]);
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.services.js
new file mode 100644
index 00000000..25f1f61c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.services.js
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnInventory/mwtnInventory.module','app/mwtnCommons/mwtnCommons.services'],function(mwtnInventoryApp) {
+
+ mwtnInventoryApp.register.factory('$mwtnInventory', function($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.formatData = $mwtnCommons.formatData;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.deleteDocType = $mwtnDatabase.deleteDocType;
+
+
+ service.TimeStampToONFFormat=function(timestamp){
+
+ timestamp=timestamp.split('-').join('');
+ timestamp=timestamp.split(':').join('');
+ timestamp=timestamp.split(' ').join('');
+ timestamp=timestamp.replace('UTC','Z');
+ return timestamp;
+ };
+
+ service.getAllLogEntries = function(from, size) {
+ var sort = [ {
+ "fault.timeStamp" : {
+ order : 'desc'
+ }
+ }];
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnInventory.getAllLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getAllLogEntriesWithSort= function(from, size, sort){
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultlog', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnInventory.getAllLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getFilteredSortedData=function(from, size, sort,query){
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredSortedData('sdnevents', 'faultlog', from, size,sort, query).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnInventory.getFilteredSortedData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+
+ };
+
+ service.getFilteredData= function(from, size, query){
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredData('sdnevents', 'faultlog', from, size, query).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnInventory.getFilteredData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.getAllCurrentProblemEntries = function(from, size) {
+ var sort = [ {
+ "faultCurrent.timeStamp" : {
+ order : 'desc'
+ }
+ }];
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('sdnevents', 'faultcurrent', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnInventory.getAllCurrentLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.tpl.html
new file mode 100644
index 00000000..4a7504a8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/mwtnInventory.tpl.html
@@ -0,0 +1,16 @@
+<ht-header help-link='sdnr/pnfInventory/0.4.0/README.md'></ht-header>
+<div class="app-mwtnInventory">
+ <div class="col-md-12 form-group">
+ <select class="form-control" ng-model="selectedMountPoint" ng-options="x for x in activeMountPoints | orderBy" ng-disabled="loading"> </select>
+ </div>
+ <div ng-if="!loading && equipments != null && equipments.length > 0" >
+ <mwtn-equipment-group equipments="equipments" />
+ </div>
+ <div class="col-md-12" ng-if="!loading && equipments == null" ><h2>This device does not support inventory</h2></div>
+ <div class="col-md-12" ng-if="loading" ><h2>Loading ... </h2></div>
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/_ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/_
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/_
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/accordeonHeader.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/accordeonHeader.tpl.html
new file mode 100644
index 00000000..1bf88a9c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/mwtnInventory-module/src/main/resources/mwtnInventory/templates/accordeonHeader.tpl.html
@@ -0,0 +1,13 @@
+<div role="tab" id="{{::headingId}}" aria-selected="{{isOpen}}" class="panel-heading" ng-keypress="toggleOpen($event)">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0" class="accordion-toggle"
+ ng-click="toggleOpen()" uib-accordion-transclude="heading" ng-disabled="isDisabled" uib-tabindex-toggle>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': isOpen, 'fa-chevron-right': !isOpen}"></i>
+ <span uib-accordion-header ng-class="{'text-muted': isDisabled}">{{heading}}</span>
+ </a>
+ </h4>
+</div>
+<div id="{{::panelId}}" aria-labelledby="{{::headingId}}" aria-hidden="{{!isOpen}}" role="tabpanel" class="panel-collapse collapse"
+ uib-collapse="!isOpen">
+ <div class="panel-body" ng-transclude></div>
+ </div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/pom.xml
new file mode 100644
index 00000000..bec94c14
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnInventory/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnInventory</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnInventory-module</module>
+ <module>mwtnInventory-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/pom.xml
new file mode 100644
index 00000000..ab98f462
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnLog</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnLog-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnLog-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnLog-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..cf298447
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnLog"/>
+ <property name="url" value="/src/app/mwtnLog"/>
+ <property name="directory" value="/mwtnLog"/>
+ <property name="requireJs" value="app/mwtnLog/mwtnLog.module"/>
+ <property name="angularJs" value="app.mwtnLog"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnLog/mwtnLog-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/pom.xml
new file mode 100644
index 00000000..72264b86
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnLog</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnLog-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/images/mwtnLog.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/images/mwtnLog.png
new file mode 100755
index 00000000..8d0bcad5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/images/mwtnLog.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog-custom.css
new file mode 100644
index 00000000..47c5864d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog-custom.css
@@ -0,0 +1,58 @@
+/**
+ * Add your application related css here
+ */
+.owl .uib-tab a {
+ border: 1px solid #000;
+ background-color: white;
+ color: #3276b1;
+}
+
+.owl .uib-tab.active a {
+ background-color: #3276b1;
+ color: white;
+}
+
+.mwtnLogGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnLogGrid span {
+ color: #393939;
+}
+
+.mwtnLogGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.mwtnLogGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.mwtnLogGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.mwtnLogGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.controller.js
new file mode 100644
index 00000000..c4135e6b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.controller.js
@@ -0,0 +1,151 @@
+/*
+ * 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/mwtnLog/mwtnLog.module',
+ 'app/mwtnLog/mwtnLog.services',
+ 'app/mwtnCommons/mwtnCommons.module'],
+ function(mwtnLogApp) {
+
+ mwtnLogApp.register.controller('mwtnLogCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$mwtnCommons', '$mwtnLogView', '$mwtnLog' ,
+ function(uiGridConstants, $uibModal, $scope, $rootScope, $mwtnCommons, $mwtnLogView, $mwtnLog) {
+
+ var COMPONENT = 'mwtnLogCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnLogCtrl started!'});
+ // $mwtnLog.error({component: COMPONENT, message: 'Just a test of logging an error.'});
+ // $mwtnLog.warning({component: COMPONENT, message: 'Just a test of logging a warning.'});
+ // $mwtnLog.debug({component: COMPONENT, message: 'Just a test of logging debug information.'});
+
+ $rootScope.section_logo = 'src/app/mwtnLog/images/mwtnLog.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $mwtnLogView.highlightFilteredHeader;
+
+ var rowTemplate = '<div ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ng-class="[\'ui-grid-cell\', row.entity.type]" ui-grid-cell></div>';
+ var iconCell = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i ng-class="{\'fa\':true, \'{{COL_FIELD}}\':true}" aria-hidden="true"></i></div>';
+
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnLogView.gridOptions));
+ $scope.gridOptions.rowTemplate = rowTemplate;
+ $scope.gridOptions.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'icon', type: 'string', displayName: '', headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
+ { field: 'timestamp', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
+ direction: uiGridConstants.DESC,
+ priority: 1
+ } },
+ { field: 'type', type: 'string', displayName: 'Type', headerCellClass: $scope.highlightFilteredHeader, width: 70 },
+ { field: 'component', type: 'string', displayName: 'Component', headerCellClass: $scope.highlightFilteredHeader, width : 200 },
+ { field: 'message', type: 'string', displayName: 'Message', headerCellClass: $scope.highlightFilteredHeader, width : 500 }
+ ];
+
+ $scope.progress = {
+ show: true,
+ max: 200,
+ value: 160
+ };
+
+ $scope.clearLog = function () {
+
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnLog/templates/clearLogConfirmation.tpl.html',
+ controller: 'ClearLogCtrl',
+ size: 'lg',
+ resolve: {
+ now: function () {
+ return new Date().toISOString();
+ }
+ }
+ });
+
+ modalInstance.result.then(function () {
+ var spec = {
+ functionId : 'mwtn',
+ docType : 'log',
+ query: {
+ match_all: {}
+ }
+ };
+ $mwtnLogView.deleteDocType(spec).then(function(deleted){
+ $scope.gridOptions.data = [];
+ $mwtnLog.info({component: COMPONENT, message: 'Log cleared!'});
+ }, function(error){
+ $mwtnLog.error({component: COMPONENT, message:JSON.stringify(error)});
+ });
+ }, function () {
+ $mwtnLog.info({component: COMPONENT, message: 'Mount dismissed!'});
+ });
+ };
+
+ var getIconFromType = function(type) {
+ var mapping = {
+ debug : '',
+ info : 'fa-info-circle',
+ warning : 'fa-exclamation-triangle',
+ error : 'fa-times-circle'
+ };
+ return mapping[type];
+ };
+
+ var processLogEntries = function(logEntries) {
+ if (logEntries.data.hits.hits) {
+ logEntries.data.hits.hits.map(function(entry){
+ var log = {
+ id: entry._id,
+ icon: getIconFromType(entry._source.type),
+ timestamp: entry._source.timestamp,
+ type: entry._source.type,
+ component: entry._source.component,
+ message: entry._source.message,
+ };
+ $scope.gridOptions.data.push(log);
+ });
+ $scope.progress.max = logEntries.data.hits.total;
+ $scope.progress.value = $scope.gridOptions.data.length;
+ $scope.progress.show = $scope.gridOptions.data.length < logEntries.data.hits.total;
+ }
+ };
+
+ $scope.refreshLog = function() {
+ $scope.gridOptions.data = [];
+ var from = 0;
+ var size = 100;
+ $scope.processing = true;
+ $mwtnLogView.getAllLogEntries(from, size).then(function(logEntries){
+ $scope.processing = false;
+ processLogEntries(logEntries);
+ from = from + size;
+ while (from < $scope.progress.max) {
+ $mwtnLogView.getAllLogEntries(from, size).then(function(logEntries){
+ processLogEntries(logEntries);
+ }, function(error){
+ console.error(JSON.stringify(error));
+ });
+ from = from + size;
+ }
+ }, function(error){
+ console.error(JSON.stringify(error));
+ });
+ };
+ $scope.refreshLog();
+
+ }]);
+
+ mwtnLogApp.register.controller('ClearLogCtrl', ['$scope', '$uibModalInstance',
+ function ($scope, $uibModalInstance) {
+
+ $scope.ok = function () {
+ $uibModalInstance.close('ok');
+ };
+
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss('cancel');
+ };
+ }]);
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.module.js
new file mode 100644
index 00000000..faece4fc
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnLogApp = angular.module('app.mwtnLog', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns' ]);
+
+ mwtnLogApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnLogApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/mwtnLog/mwtnLog.controller');
+ NavHelperProvider.addToMenu('mwtnLog', {
+ "link" : "#/mwtnLog",
+ "active" : "main.mwtnLog",
+ "title" : "Logs",
+ "icon" : "fa fa-list", // Add navigation icon css class here
+ "page" : {
+ "title" : "Logs",
+ "description" : "mwtnLog"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnLog', {
+ url: 'mwtnLog',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnLog/mwtnLog.tpl.html',
+ controller: 'mwtnLogCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnLogApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.services.js
new file mode 100644
index 00000000..ef900e2a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.services.js
@@ -0,0 +1,40 @@
+/*
+ * 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/mwtnLog/mwtnLog.module','app/mwtnCommons/mwtnCommons.services'],function(mwtnLogApp) {
+
+ mwtnLogApp.register.factory('$mwtnLogView', function($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.deleteDocType = $mwtnDatabase.deleteDocType;
+
+
+ service.getAllLogEntries = function(from, size) {
+ var sort = [ {
+ timestamp : {
+ order : 'desc'
+ }
+ }];
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData('mwtn', 'log', from, size, sort).then(function(success){
+ deferred.resolve(success);
+ }, function(error){
+ $mwtnLog.error({component: '$mwtnLogView.getAllLogEntries', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.tpl.html
new file mode 100644
index 00000000..f20f154b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/mwtnLog.tpl.html
@@ -0,0 +1,26 @@
+<ht-header help-link='sdnr/mwtnLog/0.4.0/README.md'></ht-header>
+<div id="mwtnLogGrid" ui-grid="gridOptions" ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns
+ class="mwtnLogGrid"></div>
+ <uib-progressbar ng-show="progress.show" class="progress-striped" type="warning" max="progress.max" value="progress.value" ><i>{{progress.value}} / {{progress.max}}</i></uib-progressbar>
+
+<div class="text-right">
+ <br/>
+ <button type="button" id="clearLog" class="btn btn-warning" ng-click="clearLog()">
+ <i class="fa fa-times" aria-hidden="true"></i>
+ <span>Clear log</span>
+ </button>
+ <!-- see gird menu Export ...
+ <button type="button" id="saveLog" class="btn btn-primary" ng-click="saveLog()">
+ <i class="fa fa-save" aria-hidden="true"></i>
+ <span>Save...</span>
+ </button> -->
+ <button type="button" id="refreshLog" class="btn btn-primary" ng-click="refreshLog()">
+ <i class="fa fa-refresh" ng-class="{'fa-pulse':processing}" aria-hidden="true"></i>
+ <span>{{'MWTN_REFRESH' | translate}}</span>
+ </button>
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/templates/clearLogConfirmation.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/templates/clearLogConfirmation.tpl.html
new file mode 100644
index 00000000..cdd87c6a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/mwtnLog-module/src/main/resources/mwtnLog/templates/clearLogConfirmation.tpl.html
@@ -0,0 +1,12 @@
+
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{'Clear Log Confirmation' | translate}}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <p>All log entries stored in the database will be deleted.</p>
+ <p>Please make, sure you have exported the log entries, otherwise they will get lost.</p>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="ok()">{{'Clear log' | translate}}</button>
+ <button class="btn btn-warning" type="button" ng-click="cancel()">{{'Cancel' | translate}}</button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/pom.xml
new file mode 100644
index 00000000..ebae8300
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnLog/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnLog</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnLog-module</module>
+ <module>mwtnLog-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/pom.xml
new file mode 100644
index 00000000..0d668ac1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnMediator</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnMediator-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnMediator-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnMediator-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..100f6e7c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnMediator"/>
+ <property name="url" value="/src/app/mwtnMediator"/>
+ <property name="directory" value="/mwtnMediator"/>
+ <property name="requireJs" value="app/mwtnMediator/mwtnMediator.module"/>
+ <property name="angularJs" value="app.mwtnMediator"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnMediator/mwtnMediator-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/pom.xml
new file mode 100644
index 00000000..9269bf11
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnMediator</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnMediator-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/class.mediator.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/class.mediator.js
new file mode 100644
index 00000000..b87a465b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/class.mediator.js
@@ -0,0 +1,569 @@
+function MediatorConfig(obj) {
+ if (obj !== undefined) {
+ this.Name = obj.Name;
+ this.DeviceType = obj.DeviceType;
+ this.DeviceIp = obj.DeviceIp;
+ this.DevicePort = 'DevicePort' in obj?obj.DevicePort:161;
+ this.TrapsPort = obj.TrapPort;
+ this.IsNetConfConnected = obj.IsNCConnected;
+ this.IsNetworkElementConnected = obj.IsNeConnected;
+ this.NeModel = obj.NeXMLFile;
+ this.NetconfPort = obj.NcPort;
+ this.PID = obj.pid;
+ this.IsLocked = obj.islocked;
+ this.Autorun = obj.autorun;
+ this.FirewallRuleActive = obj.fwactive;
+ this.OpenDaylightConfigs = obj.ODLConfig;
+ } else {
+ this.Name ="";
+ this.DeviceType = -1;
+ this.DeviceIp = "";
+ this.DevicePort = 161;
+ this.TrapsPort = 0;
+ this.IsNetConfConnected = false;
+ this.IsNetworkElementConnected = false;
+ this.NeModel = "";
+ this.NetconfPort = 0;
+ this.PID =0;
+ this.IsLocked = false;
+ this.Autorun = false;
+ this.FirewallRuleActive = false;
+ this.OpenDaylightConfigs=[];
+ }
+ this.DeviceTypeString = this.getDeviceTypeString();
+ this.ConnectionStatus = {Netconf:this.IsNetConfConnected,NetworkElement:this.IsNetworkElementConnected}
+
+}
+MediatorConfig.prototype.refreshData = function(obj)
+{
+ if(obj!==undefined)
+ {
+ //this.Name = obj.Name;
+ this.DeviceType = obj.DeviceType;
+ this.DeviceIp = obj.DeviceIp;
+ this.DevicePort = 'DevicePort' in obj?obj.DevicePort:161;
+ this.TrapsPort = obj.TrapPort;
+ this.IsNetConfConnected = obj.IsNCConnected;
+ this.IsNetworkElementConnected = obj.IsNeConnected;
+ this.NeModel = obj.NeXMLFile;
+ this.NetconfPort = obj.NcPort;
+ this.PID = obj.pid;
+ this.IsLocked = obj.islocked;
+ this.Autorun = false;
+ this.FirewallRuleActive = obj.fwactive;
+ this.OpenDaylightConfigs = obj.ODLConfig;
+ }
+ this.DeviceTypeString = this.getDeviceTypeString();
+ this.ConnectionStatus = {Netconf:this.IsNetConfConnected,NetworkElement:this.IsNetworkElementConnected}
+
+}
+MediatorConfig.prototype.getDeviceTypeString = function()
+{
+ var i;
+ for(i=0;i<MediatorConfig.DeviceTypes.length;i++)
+ {
+ if(MediatorConfig.DeviceTypes[i].Value==this.DeviceType)
+ return MediatorConfig.DeviceTypes[i].Name;
+ }
+ return "unknown";
+}
+/* enum for devicetypes */
+MediatorConfig.DEVICETYPE_SIMULATOR =0;
+
+
+function MediatorConfigStatus(obj){
+ this.Status=obj.Status;
+ this.Name=obj.Name;
+};
+MediatorConfigStatus.STATUS_OKAY = 1;
+MediatorConfigStatus.STATUS_CORRUPTED = 2;
+MediatorConfigStatus.STATUS_LOCKED = 3;
+MediatorConfigStatus.STATUS_REPAIRED = 4;
+MediatorConfigStatus.StatusTypes=[
+ {Value:MediatorConfigStatus.STATUS_OKAY,Name:"Okay"},
+ {Value:MediatorConfigStatus.STATUS_CORRUPTED,Name:"Corrupted"},
+ {Value:MediatorConfigStatus.STATUS_LOCKED,Name:"Locked"},
+ {Value:MediatorConfigStatus.STATUS_REPAIRED,Name:"Repaired"}
+];
+
+/* Names for enum for devicetypes */
+MediatorConfig.DeviceTypes=[
+{Value:MediatorConfig.DEVICETYPE_SIMULATOR,Name:"Simulator"}];
+
+MediatorConfig.prototype.IsRunning = function() {
+ return this.PID > 0;
+}
+MediatorConfig.prototype.TestParams = function() {
+ if(this.Name===undefined || this.Name.length<=0)
+ throw "Name is not given";
+ // Name without spaces
+ var inValidName = /\s/;
+ if(inValidName.test(this.Name))
+ throw "Name cannot have whitespaces";
+ // DeviceType: int from 0 to ...
+ if(this.DeviceType<0 || this.DeviceType>MediatorConfig.DeviceTypes[MediatorConfig.DeviceTypes.length-1].Value)
+ throw "DeviceType is not set";
+ // DeviceIp: valid IP-Address
+ var validIpTest =/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;
+ if(!validIpTest.test(this.DeviceIp))
+ throw "IP-Address is not valid";
+ // TrapsPort: valid Port
+ if(this.TrapsPort<=0 || this.TrapsPort>65535)
+ throw "TrapsPort is not valid";
+ // NeModel: valid XMLFilename
+ if(this.NeModel===undefined || this.NeModel.length<=0)
+ throw "NE XML Filename is not valid";
+ // NetconfPort: valid Port
+ if(this.NetconfPort<=0 || this.NetconfPort>65535)
+ throw "Netconf Port is not valid";
+
+ return true;
+}
+function PortRange(a)
+{
+ if(a!==undefined)
+ {
+ this.Min=a[0];
+ this.Max=a[1];
+ }
+ else
+ {
+ this.Min=0;
+ this.Max=0;
+ }
+}
+function JavaMemParam(str)
+{
+ if(str!==undefined)
+ {
+
+
+ }
+}
+function ServerConfig(obj){
+ if (obj !== undefined) {
+ this.HomeDir = obj.home;
+ this.Host = obj.host;
+ this.Port = obj.port;
+ this.NetconfRange=new PortRange(obj.ncrange);
+ this.SnmpRange = new PortRange(obj.snmprange);
+ this.JmxRange = new PortRange(obj.jmxrange);
+ this.LogLevel = obj.loglevel;
+ this.LogFile = obj.logfile;
+ this.MediatorLogLevel = obj.mediator-loglevel;
+ this.MediatorDevicePingTimeout=obj.mediator-devicepingtimeout;
+ this.MediatorSnmpLatency = obj.mediator-snmplatency;
+ this.MediatorMemory = new JavaMemParam(obj.mediator-memory);
+ }
+ else
+ {
+ this.HomeDir = "";
+ this.Host = "";
+ this.Port = 0;
+ this.NetconfRange=new PortRange();
+ this.SnmpRange = new PortRange();
+ this.JmxRange = new PortRange();
+ this.LogLevel = "";
+ this.LogFile = "";
+ this.MediatorLogLevel = "";
+ this.MediatorDevicePingTimeout=0;
+ this.MediatorSnmpLatency = 0;
+ this.MediatorMemory = new JavaMemParam();
+ }
+}
+function MediatorServer(url) {
+ this._root = url;
+ // if(this._root.endsWith("/"))
+ this._root = this._root + "/";
+ this._mediatorConfigs = [];
+ this._neXMLFilenames = undefined;
+ this.defaultODLConfig = {Server:"sendateodl5.fritz.box",Port:8181,User:"admin",Password:"admin"};
+
+}
+MediatorServer.prototype.getConfigs = function(){return this._mediatorConfigs;}
+
+MediatorServer.prototype.SetDefaultODLConfig = function(cfg)
+{
+ this.defaultODLConfig = cfg;
+}
+MediatorServer.prototype.GetDefaultODLConfig = function()
+{
+ return this.defaultODLConfig;
+}
+MediatorServer.prototype.refreshConfig = function(configs,cb)
+{
+ var changed = [];
+ if(this._mediatorConfigs===undefined)
+ {
+ if(cb!==undefined)
+ cb(changed);
+ return;
+ }
+ if(configs!==undefined && configs.length>0)
+ {
+ var i,j;
+ for(i=0;i<configs.length;i++)
+ {
+ //find config in array by name
+ for(j=0;j<this._mediatorConfigs.length;j++)
+ {
+ if(this._mediatorConfigs[j].Name==configs[i].Name)
+ {
+ //refresh data
+ this._mediatorConfigs[j].refreshData(configs[i]);
+ changed.push(configs[i]);
+ break;
+ }
+ }
+ }
+ }
+ if(cb!==undefined)
+ cb(changed);
+}
+MediatorServer.prototype.onConfigsReceived = function(configJSONArray) {
+ this._mediatorConfigs = [];
+ for (var i = 0; i < configJSONArray.length; i++) {
+ var c = new MediatorConfig(configJSONArray[i]);
+ this._mediatorConfigs.push(c);
+ }
+}
+MediatorServer.prototype.onNeXMLReceived = function(neXMLFilenamesArray) {
+ this._neXMLFilenames = neXMLFilenamesArray;
+}
+
+MediatorServer.prototype.LoadNetworkElementXMLFiles = function(cb,cbError) {
+ var _self = this;
+ this.post("getnemodels", function(response) {
+ if (response.code == 1) {
+ _self.onNeXMLReceived(response.data);
+ if (cb !== undefined)
+ cb(_self._neXMLFilenames);
+ } else
+ {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.LoadLogs = function(name,cb,cbError)
+{
+ var _self = this;
+ this.post("getlog&name="+name,function(response){
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else
+ { _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.LoadAvailableNCPorts = function(cb,cbError)
+{
+ var _self = this;
+ this.post("getncports",function(response){
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else
+ { _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.LoadAvailableSnmpPorts = function(cb,cbError)
+{
+ var _self = this;
+ this.post("getsnmpports",function(response){
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ }
+ else
+ {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.StartMediator = function(name, cb, cbError) {
+ var _self = this;
+ this.post("start",{name:name}, function(response) {
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.StopMediator = function(name, cb, cbError) {
+ var _self = this;
+ this.post("stop",{name:name}, function(response) {
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.ReloadConfig = function(name,cb,cbError)
+{
+ var _self = this;
+ this.post("getconfig",{name:name},function(response){
+ if (response.code == 1) {
+ _self.refreshConfig(response.data,function(changes){
+ if (cb !== undefined)
+ cb(changes);
+ });
+ } else {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+
+}
+MediatorServer.prototype.LoadConfigs = function(cb,cbError) {
+ var _self = this;
+ this.post("getconfig", function(response) {
+ if (response.code == 1) {
+ _self.onConfigsReceived(response.data);
+ if (cb !== undefined)
+ cb(_self._mediatorConfigs);
+ } else {
+ _self.log(response.data);
+ }
+
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.Repair = function(cb,cbError)
+{
+ var _self = this;
+ this.post("repair", function(response) {
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else {
+ _self.log(response.data);
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.LoadVersion = function(cb,cbError)
+{
+ var _self = this;
+ this.post("version", function(response) {
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(response.data);
+ } else {
+ _self.log(response.data);
+ }
+
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+/*
+ * name: <String> deviceType: <int> deviceip: <Ipv4-String> trapsPort:<int>
+ * nexml:<String> ncport:<int> cb: callback-function
+ */
+MediatorServer.prototype.CreateMediator = function(name,devicetype,deviceip,deviceport,trapsPort,nexml,ncport, cb, cbError) {
+
+ var obj;
+ try
+ {
+ obj=new MediatorConfig({
+ Name:name,
+ DeviceType:devicetype,
+ DeviceIp:deviceip,
+ DevicePort:deviceport,
+ TrapPort:trapsPort,
+ NeXMLFile:nexml,
+ NcPort:ncport
+ });
+ obj.TestParams();
+ }
+ catch(e)
+ {
+ if(cbError!==undefined)
+ cbError(e);
+ }
+ this.post("create", {
+ config : JSON.stringify({
+ Name : obj.Name,
+ DeviceType : obj.DeviceType,
+ DeviceIp : obj.DeviceIp,
+ DevicePort : obj.DevicePort,
+ TrapPort : obj.TrapsPort,
+ NeXMLFile : obj.NeModel,
+ NcPort : obj.NetconfPort,
+ ODLConfig:[this.defaultODLConfig]
+ })
+ }, function(response) {
+ if(response.code==1)
+ {
+ if(cb!==undefined)
+ cb(true)
+ }
+ else
+ {
+ if(cbError!==undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.DeleteMediator = function(name, cb, cbError)
+{
+ var _self = this;
+ this.post('delete', {name:name}, function(response){
+ if(response.code==1)
+ {
+ if(cb!==undefined)
+ cb(true);
+ }
+ else
+ {
+ if(cb!==undefined)
+ cb(response.data);
+ }
+
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+MediatorServer.prototype.ClearLock = function(name, cb, cbError) {
+ var _self = this;
+ this.post("clearlock", {
+ name : name
+ }, function(response) {
+ if (response.code == 1) {
+ if (cb !== undefined)
+ cb(true);
+ } else {
+ _self.log(response.data);
+ if (cbError !== undefined)
+ cbError(response.data);
+ }
+ },function(err){
+ if(cbError!==undefined)
+ cbError(err);
+ });
+}
+/*
+ * do post request
+ *
+ * @params task
+ */
+MediatorServer.prototype.post = function(task, data, callback,callbackError) {
+ var _self = this;
+ if (typeof (data) === "function")
+ {
+ callbackError = callback;
+ callback = data;
+ }
+ var cb=function(r) {
+ if (callback !== undefined) {
+ try {
+ if (typeof (r) === "string")
+ r = JSON.parse(r);
+ callback(r);
+ } catch (e) {
+ _self.log(e);
+ if(callbackError!==undefined)
+ callbackError(e);
+ }
+ }
+ };
+
+ if(this.usejQueryv3)
+ {
+ $.post({
+ url : this._root + "api/?task=" + task,
+ data : data,
+ success : cb
+ });
+ }
+ else //jquery 1.x
+ {
+ if(typeof(data)=== "function")
+ {
+ $.post(this._root + "api/?task=" + task,cb).done(function() {
+ _self.log( "second success" );
+ })
+ .fail(function(e) {
+ _self.log( "error" +e);
+ if(callbackError!==undefined)
+ callbackError(e);
+ })
+ .always(function() {
+ _self.log( "finished" );
+ });
+ }
+ else
+ {
+ $.post(this._root + "api/?task=" + task,data,cb).done(function() {
+ _self.log( "second success" );
+ })
+ .fail(function(e) {
+ _self.log( "error" +e);
+ if(callbackError!==undefined)
+ callbackError(e);
+ })
+ .always(function() {
+ _self.log( "finished" );
+ });
+ }
+ }
+}
+
+MediatorServer.prototype._error = function(message) {
+ console.log(message);
+}
+MediatorServer.prototype.log = function(message) {
+// console.log(message);
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/images/mwtnMediator.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/images/mwtnMediator.png
new file mode 100755
index 00000000..f7c2a6c0
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/images/mwtnMediator.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator-custom.css
new file mode 100644
index 00000000..15a684f1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator-custom.css
@@ -0,0 +1,69 @@
+/**
+ * Add your application related css here
+ */
+.mwtnMediatorGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnMediatorGrid span {
+ color: #393939;
+}
+span.mwtnMediatorStatusRunning{
+ color: darkgreen;
+}
+span.mwtnMediatorStatusNotRunning{
+ color: darkred;
+}
+span.mwtnMediatorCStatusIcon{
+ font-size:2rem;
+ vertical-align:middle;
+}
+span.mwtnMediatorOStatusIcon{
+ font-size:2.5rem;
+ vertical-align:middle;
+}
+
+#mediatorserver-list{
+ list-style-type:none;
+ padding:0;
+ margin:0;
+ display:block;
+
+}
+#mediatorserver-list > li
+{
+ padding:0.3rem;
+ display:block;
+ position:relative;
+}
+#mediatorserver-list > li:nth-child(even)
+{
+ background:#FFF;
+}
+#mediatorserver-list > li:nth-child(odd)
+{
+ background:#EEE;
+}
+#mediatorserver-list > li.selected
+{
+ background:#EBFF7F;
+}
+#mediatorserver-list > li > span.desc
+{
+ display:block;
+}
+#mediatorserver-list > li > div.icons
+{
+ position:absolute;
+ right:0;top:0;bottom:0;width:auto;
+}
+#mediatorserver-list > li > div.icons > span.fa
+{
+ position:relative;margin-right:.6rem;margin-top:.3rem;font-size:2rem;cursor:pointer;
+}
+#mediatorserver-list > li > div.icons > span.fa:hover
+{
+ font-weight:bold;
+}
+.acc-mediatorlog > .panel-group .panel-body{padding:0;} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.controller.js
new file mode 100644
index 00000000..5f35ba66
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.controller.js
@@ -0,0 +1,613 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnMediator/mwtnMediator.module',
+ 'app/mwtnMediator/mwtnMediator.services'],
+ function(mwtnMediatorApp) {
+
+ var mediatorServer;
+ var autoRefresh;
+ mwtnMediatorApp.register.controller('mwtnMediatorCtrl', ['$scope', '$rootScope','$uibModal', '$mwtnLog', '$mwtnMediator',
+ function($scope, $rootScope, $uibModal, $mwtnLog, $mwtnMediator) {
+ autoRefresh=false;
+ var COMPONENT = 'mwtnMediatorCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnMediatorCtrl started!'});
+ $rootScope.section_logo = 'src/app/mwtnMediator/images/mwtnMediator.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+ $scope.highlightFilteredHeader = $mwtnMediator.highlightFilteredHeader;
+
+
+
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnMediator.gridOptions));
+ $scope.gridOptions.rowHeight = 44;
+
+ var statusCellTemplate = [
+ '<div class="ui-grid-cell-contents">',
+ '<span class="mwtnMediatorStatusRunning" ng-show="grid.getCellValue(row, col)>0">running ({{grid.getCellValue(row, col)}})</span>',
+ '<span class="mwtnMediatorStatusNotRunning" ng-show="grid.getCellValue(row, col)==0">stopped</span>',
+ '</div>'
+ ].join('');
+ var connectionStatusCellTemplate = [
+ '<div class="ui-grid-cell-contents">',
+ '<span class="fa fa-server mwtnMediatorOStatusIcon" style="margin-right:-0.5rem;"></span>',
+ '<span class="fa fa-check-circle-o mwtnMediatorCStatusIcon" style="color:green;" ng-show="grid.getCellValue(row, col).Netconf"></span>',
+ '<span class="fa fa-times-circle-o mwtnMediatorCStatusIcon" style="color:red;" ng-show="!grid.getCellValue(row, col).Netconf"></span>',
+ '<span class="fa fa-minus mwtnMediatorCStatusIcon" style="color:green;font-weight:bold;" ng-show="grid.getCellValue(row, col).Netconf"></span>',
+ '<span class="fa fa-ellipsis-h mwtnMediatorCStatusIcon" style="color:red;font-weight:bold;" ng-show="!grid.getCellValue(row, col).Netconf"></span>',
+ '<span class="fa fa-dot-circle-o mwtnMediatorCStatusIcon" style="font-size:3rem;color:#666;"></span>',
+ '<span class="fa fa-minus mwtnMediatorCStatusIcon" style="color:green;font-weight:bold;" ng-show="grid.getCellValue(row, col).NetworkElement"></span>',
+ '<span class="fa fa-ellipsis-h mwtnMediatorCStatusIcon" style="color:red;font-weight:bold;" ng-show="!grid.getCellValue(row, col).NetworkElement"></span>',
+ '<span class="fa fa-check-circle-o mwtnMediatorCStatusIcon" style="color:green;" ng-show="grid.getCellValue(row, col).NetworkElement"></span>',
+ '<span class="fa fa-times-circle-o mwtnMediatorCStatusIcon" style="color:red;" ng-show="!grid.getCellValue(row, col).NetworkElement"></span>',
+ '<span class="fa fa-wifi mwtnMediatorOStatusIcon" style="margin-left:-0.5rem;"></span>',
+ '</div>'].join('');
+
+ var requiredNesActionCellTemplate = [
+ '<a class="vCenter" ng-class="{attention: grid.appScope.hover}" >',
+ '<button class="btn btn-primary" ng-click="grid.appScope.startMediator(row.entity)">Start</button>',
+ '<button class="btn btn-default" ng-click="grid.appScope.stopMediator(row.entity)">Stop</button>',
+ '<button class="btn btn-default" ng-click="grid.appScope.showDetails(row.entity)"><i class="fa fa-info-circle" aria-hidden="true"></i></button>',
+ '</a>' ].join('<span>&nbsp;</span>');
+
+ $scope.gridOptions.columnDefs = [
+ { field: 'Name', type: 'string', displayName: 'Mediator', headerCellClass: $scope.highlightFilteredHeader, width : 200 },
+ { field: 'PID', type: 'int', name: 'Status', cellTemplate:statusCellTemplate, headerCellClass: $scope.highlightFilteredHeader, width : 120 },
+ { field: 'DeviceIp', type: 'string', displayName: 'IP address', headerCellClass: $scope.highlightFilteredHeader, width : 120 },
+ {
+ field: 'ConnectionStatus',
+ type: 'object',
+ name: 'Connection',
+ enableSorting : false,
+ enableFiltering: false,
+ cellTemplate:connectionStatusCellTemplate,
+ width : 150
+ },
+ { name : 'actions',
+ enableSorting : false,
+ enableFiltering: false,
+ cellTemplate: requiredNesActionCellTemplate,
+ width : 280,
+ pinnedRight : true
+ }
+ ];
+
+
+
+ var refreshMediators = function()
+ {
+ var i=$('#btn_refreshMediators > i');
+ i.addClass("fa-spin");
+ console.log("refresh mediators list");
+ if(mediatorServer!==undefined)
+ {
+ mediatorServer.LoadConfigs(function(configs){
+ $scope.data = configs;
+ $scope.$apply();
+ i.removeClass("fa-spin");
+ },
+ function(err){
+ $scope.data = [];
+ $scope.$apply();
+ i.removeClass("fa-spin");
+ console.log("cannot reach mediatorserver:"+err);
+ });
+ }
+ }
+ var refreshMediator = function(name)
+ {
+ console.log("refresh mediators list");
+ if(mediatorServer!==undefined)
+ {
+ mediatorServer.ReloadConfig(name,function(changes){
+ $scope.$apply();
+ },
+ function(err){
+ console.log("cannot reach mediatorserver:"+err);
+ });
+ }
+ }
+ var onServerSelectedChanged = function(item){
+ var serverURL;
+ if(item!==undefined)
+ {
+ if(typeof(item)==='object')
+ serverURL=item.url;
+ else if(typeof(item)==='string')
+ {
+ try
+ {
+ $mwtnMediator.getServerData(parseInt(item)).then(function(data){
+ if(data!==undefined)
+ {
+ serverURL=data.url;
+ mediatorServer = new MediatorServer(serverURL);
+ $mwtnLog.info({component: COMPONENT, message: 'loading server configs for '+serverURL});
+ refreshMediators();
+ }
+ else
+ console.log("search for server data failed. should never happened")
+ });
+ }
+ catch(e)
+ {"error loading server:n"+console.log(e);}
+ }
+ }
+ }
+
+ /* GUI Events =======================================*/
+ $scope.onAutoRefreshChanged = function()
+ {
+ autoRefresh = $('#ckbx_mediatorAutorefresh').prop('checked');
+ console.log("set autorefresh to "+autoRefresh);
+ }
+ $scope.editMediatorServers = function()
+ {
+ var modalInstance = $uibModal.open({
+ animation:true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnMediator/templates/mediatorServerConfigCtrl.tpl.html',
+ controller: 'MediatorServerConfigCtrl',
+ size: 'lg',
+ resolve: {
+ currentElement: function () {
+ return $scope.currentElement;
+ }
+ }
+
+ });
+ }
+ $scope.createNewMediator = function()
+ {
+ if(mediatorServer!==undefined)
+ {
+ console.log("create new mediator");
+ var modalInstance = $uibModal.open({
+ animation:true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnMediator/templates/mediatorCreateNew.tpl.html',
+ controller: 'MediatorNewCtrl',
+ size: 'lg',
+ resolve: {
+ currentElement: function () {
+ return $scope.currentElement;
+ }
+ }
+
+ });
+ }
+ else
+ {
+ console.log("no mediatorserver selected");
+ }
+ }
+ $scope.refreshMediators = refreshMediators;
+
+ $scope.startMediator = function(el)
+ {
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled',true);
+ console.log("starting mediator "+el.Name+" ...");
+ if(mediatorServer!==undefined)
+ {
+ mediatorServer.StartMediator(el.Name,function(res){
+ refreshMediator(el.Name);
+ //console.log(res);
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled',false);
+ // console.log("error starting mediator");
+ });
+ }
+ }
+ $scope.stopMediator = function(el)
+ {
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled',true);
+ console.log("stopping mediator "+el.Name+" ...");
+ if(mediatorServer!==undefined)
+ {
+ mediatorServer.StopMediator(el.Name,function(res){
+ refreshMediator(el.Name);
+ //console.log(res);
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled',false);
+ // console.log("error stopping mediator");
+ });
+ }
+ }
+ $scope.showDetails = function(el)
+ {
+ $scope.currentElement = el;
+ var modalInstance = $uibModal.open({
+ animation:true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/mwtnMediator/templates/mediatorDetails.tpl.html',
+ controller: 'MediatorDetailsCtrl',
+ size: 'lg',
+ resolve: {
+ currentElement: function () {
+ return $scope.currentElement;
+ }
+ }
+
+ });
+ }
+ $scope.onchangeserver = function(){
+ autoRefresh=false;
+ $('#ckbx_mediatorAutorefresh').prop('checked',autoRefresh);
+ onServerSelectedChanged($scope.medserver);
+ }
+ /* End of GUI Events===========================*/
+
+
+ $scope.gridOptions.data = 'data';
+ $scope.options={
+
+ }
+
+ //load mediator servers from database
+ $mwtnMediator.getServerData().then(function(data){
+ //set as option source for GUI selector
+ $scope.options.medservers=data;
+ //autoselect first item
+ if(data!==undefined && data.length>0)
+ {
+ onServerSelectedChanged(data[0]);
+ //$scope.medserver=
+ }
+ });
+ var timer = setInterval(function(){
+ if(autoRefresh && mediatorServer!==undefined)
+ {
+ refreshMediators();
+ }
+
+ },30000);
+
+ }]);
+
+
+ /************************************************************************************
+ * medaitorDetails Controller definition
+ ************************************************************************************/
+ mwtnMediatorApp.register.controller('MediatorDetailsCtrl', ['$scope', '$uibModalInstance', '$uibModal', '$mwtnConnect', '$mwtnLog', '$mwtnMediator','currentElement',
+ function ($scope, $uibModalInstance, $uibModal, $mwtnConnect, $mwtnLog, $mwtnMediator, currentElement) {
+
+ var COMPONENT = 'MediatorDetailsCtrl';
+ var element = currentElement;
+ var error = function(msg)
+ {
+ $scope.statusmessage='';
+ $scope.errormessage=msg;
+ $scope.$apply();
+ }
+ var status = function(msg)
+ {
+ $scope.statusmessage=msg;
+ $scope.errormessage='';
+ $scope.$apply();
+ }
+ var reloadDelayed = function()
+ {
+ setTimeout(function(){
+ mediatorServer.ReloadConfig(element.Name,function(res){
+ $scope.$apply();
+ },function(err){error(err);});
+ },1000);
+ }
+ var refreshLogs = function()
+ {
+ mediatorServer.LoadLogs(currentElement.Name,function(res){
+ $scope.logdata=res;
+ $scope.$apply();
+
+ },function(err){
+ $scope.logdata=[];
+ $scope.$apply();
+ });
+ }
+ $scope.statusmessage='';
+ $scope.errormessage='';
+ $scope.logGridOptions = JSON.parse(JSON.stringify($mwtnMediator.logGridOptions));
+ //$scope.logGridOptions.rowHeight = 44;
+ $scope.logGridOptions.columnDefs = [
+ { field: 'ts', type: 'string', displayName: 'Timestamp', headerCellClass: $scope.highlightFilteredHeader, width : 180 },
+ { field: 'lvl', type: 'String', displayName: 'LogLevel', headerCellClass: $scope.highlightFilteredHeader, width : 90 },
+ { field: 'src', type: 'string', displayName: 'Source', headerCellClass: $scope.highlightFilteredHeader, width : 120 },
+ { field: 'msg', type: 'string', displayName: 'Message', headerCellClass: $scope.highlightFilteredHeader, width : 300 },
+
+ ];
+ $scope.logGridOptions.data = 'logdata';
+ // $mwtnLog.info({component: COMPONENT, message: 'MediatorDetailsCtrl started!'});
+ $scope.data = {
+ el:currentElement
+ };
+ $scope.ok = function () {
+ $uibModalInstance.close({el: currentElement});
+ };
+ $scope.start = function(){
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ mediatorServer.StartMediator(element.Name,function(res){
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ status(res);
+ reloadDelayed();
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(err);
+
+ });
+ };
+ $scope.stop = function(){
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ mediatorServer.StopMediator(element.Name,function(res){
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ status(res);
+ reloadDelayed();
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(err);
+
+ });
+ };
+ $scope.delete = function(){
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ if(confirm("Do you really want to delete this mediator?"))
+ {
+ mediatorServer.DeleteMediator(element.Name,function(res){
+ status(res);
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(err);
+ });
+ }
+ else
+ {
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ }
+ };
+ $scope.unlock = function(){
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ mediatorServer.ClearLock(element.Name,function(res){
+ status(res);
+ reloadDelayed();
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(err);
+ });
+ }
+ refreshLogs();
+ }
+ ]);
+ /************************************************************************************
+ * medaitorCreateNew Controller definition
+ ************************************************************************************/
+ mwtnMediatorApp.register.controller('MediatorNewCtrl', ['$scope', '$uibModalInstance', '$uibModal', '$mwtnConnect', '$mwtnLog',
+ function ($scope, $uibModalInstance, $uibModal, $mwtnConnect, $mwtnLog) {
+
+ var COMPONENT = 'MediatorNewCtrl';
+ // $mwtnLog.info({component: COMPONENT, message: COMPONENT + ' started!'});
+ var status = function(msg)
+ {
+ $scope.statusmessage=msg;
+ $scope.errormessage="";
+ $scope.$apply();
+ }
+ var error = function(msg)
+ {
+ $scope.statusmessage="";
+ $scope.errormessage=msg;
+ $scope.$apply();
+ }
+ $scope.options={
+ nexmlmodel:[],
+ nedevicetype:MediatorConfig.DeviceTypes
+ };
+ $scope.mediator={name:'',devicetype:0,remoteip:'',remoteport:161,trapsport:0,ncport:0,nexml:''};
+ $scope.odlconfig=mediatorServer.GetDefaultODLConfig();
+ $scope.odlsavebtn={enabled:false};
+
+ //=======load data
+ mediatorServer.LoadNetworkElementXMLFiles(function(xmlNames){
+ $scope.options.nexmlmodel=xmlNames;
+ $scope.$apply();
+ },function(err){
+ error(err);
+ });
+ mediatorServer.LoadAvailableNCPorts(function(portValues){
+ if(portValues!==undefined && portValues.length>0)
+ {
+ $scope.mediator.ncport = portValues[0];
+ }
+ },function(err){error(err);});
+ mediatorServer.LoadAvailableSnmpPorts(function(portValues){
+ if(portValues!==undefined && portValues.length>0)
+ {
+ $scope.mediator.trapsport = portValues[0];
+ }
+ },function(err){error(err);});
+
+
+ $scope.errormessage='';
+ $scope.statusmessage='';
+
+ //====handle events========
+ $scope.odledit = function(){
+ $scope.odlsavebtn.enabled=true;
+ console.log("enable odl configs")
+ $scope.$apply();
+ }
+ $scope.odlsave = function(){
+ mediatorServer.SetDefaultODLConfig($scope.odlconfig);
+ }
+ $scope.ok = function () {
+ var btn=$(this);
+ if(btn!==undefined)
+ btn.prop('disabled', true);
+ mediatorServer.CreateMediator($scope.mediator.name,
+ $scope.mediator.devicetype,
+ $scope.mediator.remoteip,
+ $scope.mediator.remoteport,
+ $scope.mediator.trapsport,
+ $scope.mediator.nexml,
+ $scope.mediator.ncport,
+ function(e){
+ if(e==true)
+ {
+ status("mediator created");
+ setTimeout(function(){$uibModalInstance.close();},2000);
+ }
+ else
+ {
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(e);
+
+ }
+ },function(err){
+ if(btn!==undefined)
+ btn.prop('disabled', false);
+ error(err);
+
+ });
+
+ };
+ $scope.cancel = function(){
+ $uibModalInstance.close();
+ };
+
+ }
+ ]);
+ /************************************************************************************
+ * medaitorServerConfig Controller definition
+ ************************************************************************************/
+ mwtnMediatorApp.register.controller('MediatorServerConfigCtrl', ['$scope', '$uibModalInstance', '$uibModal', '$mwtnConnect', '$mwtnLog', '$mwtnMediator',
+ function ($scope, $uibModalInstance, $uibModal, $mwtnConnect, $mwtnLog, $mwtnMediator) {
+
+ var COMPONENT = 'MediatorServerConfigCtrl';
+ // $mwtnLog.info({component: COMPONENT, message: COMPONENT + ' started!'});
+ var onServerRowSelect = function(obj,id)
+ {
+ if(obj!=undefined)
+ $(obj).addClass("selected");
+ var tbxId=$('#tbx_mediatorserver-id');
+ var tbxName=$('#tbx_mediatorserver-name');
+ var tbxHost = $('#tbx_mediatorserver-host');
+ var tbxVersion = $('#tbx_mediatorserver-version');
+ var tbxVersionMed = $('#tbx_mediatorserver-medversion');
+ tbxId.prop('disabled',true);
+ tbxName.prop('disabled',true);
+ tbxHost.prop('disabled',true);
+ tbxVersion.prop('disabled',true);
+ tbxVersionMed.prop('disabled',true);
+
+ $mwtnMediator.getServerData(id).then(function(data){
+ if(data!==undefined)
+ {
+ tbxId.val(data.id);
+ tbxName.val(data.name);
+ tbxHost.val(data.url);
+ tbxVersion.val("");
+ tbxVersionMed.val("");
+ var s=new MediatorServer(data.url);
+ s.LoadVersion(function(d){
+ tbxVersion.val(d.server);
+ tbxVersionMed.val(d.mediator);
+
+ },function(err){
+
+ });
+ }
+ });
+ }
+ var create = function(host,name,port)
+ {
+ var url=host+":"+port;
+ $mwtnMediator.addServer(name,url).then(function(data){
+ reload();
+ });
+ }
+ var onEdit = function(id)
+ {
+ var tbxName=$('#tbx_mediatorserver-name');
+ var tbxHost = $('#tbx_mediatorserver-host');
+ tbxName.prop('disabled',false);
+ tbxHost.prop('disabled',false);
+
+ }
+ var onDelete = function(id)
+ {
+ if(confirm("Do you really want to delete?"))
+ {
+ // console.log("delete server with id="+id);
+ $mwtnMediator.removeServer(id).then(function(){reload();});
+ }
+ }
+ var reload = function(){
+ $mwtnMediator.getServerData().then(function(data){
+
+ //fill table
+ var list=$('#mediatorserver-list');
+ list.html('');
+ if(data!==undefined && data.length>0)
+ {
+ for(var i=0;i<data.length;i++)
+ {
+ var desc=$('<span class="desc" id="item_'+data[i].id+'">'+data[i].name+'</span>');
+ var li=$('<li></li>');
+ var iconsbox=$('<div class="icons"></div>');
+ var edit=$('<span class="fa fa-edit" id="item_edit_'+data[i].id+'"></span>');
+ var del=$('<span class="fa fa-trash-o" id="item_del_'+data[i].id+'"></span>');
+ iconsbox.html([edit,del]);
+ li.html([desc,iconsbox]);
+ if(i==0)
+ li.addClass("selected");
+ //register click handlers
+ desc.click(function(){
+ $('#mediatorserver-list > li').removeClass('selected');
+ onServerRowSelect(this.parentNode,$(this).prop('id').substr(5));
+ });
+ edit.click(function(){
+ onEdit($(this).prop('id').substr(10));
+ });
+ del.click(function(){
+ onDelete($(this).prop('id').substr(9));
+ });
+ list.append(li);
+ }
+ onServerRowSelect(undefined,data[0].id);
+ }
+ });
+ }
+ reload();
+ $scope.close = function(){
+ $uibModalInstance.close();
+ };
+ }]);
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.module.js
new file mode 100644
index 00000000..19c9142d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.module.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module',
+ 'app/mwtnCommons/bower_components/angular-clipboard/angular-clipboard',
+ 'src/app/mwtnMediator/class.mediator.js'], function(ng) {
+ var mwtnMediatorApp = angular.module('app.mwtnMediator', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'angular-clipboard']);
+
+ mwtnMediatorApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnMediatorApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnMediator/mwtnMediator.controller');
+ NavHelperProvider.addToMenu('mwtnMediator', {
+ "link" : "#/pnfMediator",
+ "active" : "main.mwtnMediator",
+ "title" : "pnf Mediator",
+ "icon" : "fa fa-globe", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf Mediator",
+ "description" : "mwtnMediator"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnMediator', {
+ url: 'pnfMediator',
+ access: access.admin,
+ views : {
+ content : {
+ templateUrl: 'src/app/mwtnMediator/templates/frame.tpl.html',
+ controller: 'mwtnMediatorCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnMediatorApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.services.js
new file mode 100644
index 00000000..363b79a8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/mwtnMediator.services.js
@@ -0,0 +1,113 @@
+/*
+ * @copyright 2017 highstreet technologies 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/mwtnMediator/mwtnMediator.module'],function(mwtnMediatorApp) {
+
+ mwtnMediatorApp.register.factory('$mwtnMediator', function($http, $q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnMediator';
+ $mwtnLog.info({component: COMPONENT, message: '$mwtnMediator started!'});
+
+ var service = {};
+
+ // import of mwtnCommons
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+
+ service.getAllData = $mwtnDatabase.getAllData;
+ service.getFilteredSortedData = $mwtnDatabase.getFilteredSortedData;
+ service.logGridOptions = $mwtnCommons.gridOptions;
+
+ // service specific functions
+ service.getServerData = function(id){
+ var deferred = $q.defer();
+ var functionid="mwtn";
+ var type="mediator-server";
+ var sort = [ { 'id' : {order : 'asc'}}];
+
+ if(id===undefined)//get all
+ $mwtnDatabase.getAllData(functionid,type,0,99,sort,null).then(function(success){
+ var list=[];
+ success.data.hits.hits.map(function(entry){
+ var row = {
+ id: entry._source.id,
+ url: entry._source.url,
+ name: entry._source.name
+ };
+ list.push(row);
+ });
+ deferred.resolve(list);
+ }, function(error){
+ $mwtnLog.error({component: 'private getAlldata', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ else //get by id
+ $mwtnDatabase.getFilteredSortedData(functionid,type,0,99,sort,{'match':{'id':id}}).then(function(success){
+ var list=[];
+ success.data.hits.hits.map(function(entry){
+ var row = {
+ id: entry._source.id,
+ url: entry._source.url,
+ name: entry._source.name
+ };
+ list.push(row);
+ });
+ deferred.resolve(list.length>0?list[0]:undefined);
+ }, function(error){
+ $mwtnLog.error({component: 'private getFilteredSortedData', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+
+ return deferred.promise;
+
+
+ };
+ /*
+ service.getMaxId = function(){
+ var deferred = $q.defer();
+ $mwtnDatabase.getAllData(functionid,type,0,99,sort,{'match'}).then(function(success){
+
+ return deferred.promise;
+ };
+ */
+ service.addServer = function(name,url){
+ var deferred = $q.defer();
+ var functionId="mwtn";
+ var docType="mediator-server";
+ //check params
+ var data={name:name,url:url};
+ //check if contains
+ //insert into db
+ $mwtnDatabase.createSingleDocument(functionId, docType, id, data).then(function(success){
+
+
+ deferred.resolve(data);
+ },function(error){
+ $mwtnLog.error({component: 'private addServer', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+ service.removeServer = function(id){
+ var deferred = $q.defer();
+ var functionId="mwtn";
+ var docType="mediator-server";
+
+ $mwtnDatabase.deleteSingleDocument(functionId, docType, id).then(function(success){
+ deferred.resolve(data);
+ },function(error){
+ $mwtnLog.error({component: 'private removeServer', message: JSON.stringify(error.data)});
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/frame.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/frame.tpl.html
new file mode 100644
index 00000000..debf0c21
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/frame.tpl.html
@@ -0,0 +1,49 @@
+<ht-header help-link='sdnr/pnfMediator/0.4.0/README.md'></ht-header>
+<div class=""></div>
+<div class="owl container" style="width: 100%;">
+ <div class="row">
+ <div class="col-md-4">
+ <div id="mvtnMediatorServerSelector">
+ <select class="form-control" ng-model="medserver" ng-change="onchangeserver()" >
+ <option ng-repeat="option in options.medservers" value="{{option.id}}">{{option.name}}({{option.url}})</option>
+ </select>
+ </div>
+ </div>
+ <div class="col-md-8">
+ <div style="float:left;display:inline-block;">
+ <button class="btn btn-default" ng-click="editMediatorServers()"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></button>
+ </div>
+ <div style="float:right;display:inline-block;">
+ <div class="checkbox" style="display:inline-block;">
+ <label style="color:white;"><input type="checkbox" id="ckbx_mediatorAutorefresh" ng-click="onAutoRefreshChanged()" value="">AutoRefresh</label>
+ </div>
+ <button class="btn btn-default" ng-click="createNewMediator()"><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
+ <button class="btn btn-default" id="btn_refreshMediators" ng-click="refreshMediators()"><i class="fa fa-refresh" aria-hidden="true"></i></button>
+
+ </div>
+
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <hr class="ng-scope" />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <div id="mwtnMediatorGrid"
+ ui-grid="gridOptions"
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns
+ class="mwtnMediatorGrid"></div>
+ </div>
+ </div>
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorCreateNew.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorCreateNew.tpl.html
new file mode 100644
index 00000000..5934eb8b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorCreateNew.tpl.html
@@ -0,0 +1,99 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{ data.el.Name }}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div class="row">
+ <div class="col-md-3"><span>Name:</span></div>
+ <div class="col-md-9">
+ <input type="text" class="form-control" ng-model="mediator.name" />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span>DeviceType:</div>
+ <div class="col-md-9">
+ <select class="form-control" ng-model="mediator.devicetype" >
+ <option ng-repeat="option in options.nedevicetype" value="{{option.Value}}">{{option.Name}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span>IP address:</div>
+ <div class="col-md-9">
+ <input type="text" ng-model="mediator.remoteip" class="form-control" style="display:inline-block;width:70%;"/>
+ <span>&nbsp;:&nbsp;</span>
+ <input type="text" ng-model="mediator.remoteport" class="form-control" style="display:inline-block;width:25%;float:right;"/>
+
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span>TrapsPort:</div>
+ <div class="col-md-9">
+ <input type="number" class="form-control" ng-model="mediator.trapsport" />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span>NetconfPort:</div>
+ <div class="col-md-9">
+ <input type="number" class="form-control" ng-model="mediator.ncport" />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span>NeModel:</div>
+ <div class="col-md-9">
+ <select class="form-control" ng-model="mediator.nexml">
+ <option ng-repeat="option in options.nexmlmodel" value="{{option}}">{{option}}</option>
+ </select>
+ </div>
+ </div>
+ <hr class="row" />
+ <div class="row">
+ <uib-accordion close-others="oneAtATime">
+ <div uib-accordion-group class="panel-default" is-open="false">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': false, 'fa-chevron-right': true}"></i>
+ <span>{{'ODL Connection Config' | translate}}</span>
+ </uib-accordion-heading>
+ <div class="" style="position:relative;">
+ <button class="btn btn-default" ng-click="odledit()" style="position:absolute;top:1rem;right:1rem;"><i class="fa fa-edit"></i></button>
+ <div class="row">
+ <div class="col-md-3"><span >Hostname:</span></div>
+ <div class="col-md-6"><input ng-disabled="!odlsavebtn.enabled" class="form-control" type="text" ng-model="odlconfig.Server" /></div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span >Port:</span></div>
+ <div class="col-md-6"><input ng-disabled="!odlsavebtn.enabled" class="form-control" type="text" ng-model="odlconfig.Port" /></div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span >Username:</span></div>
+ <div class="col-md-6"><input ng-disabled="!odlsavebtn.enabled" class="form-control" type="text" ng-model="odlconfig.User" /></div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"><span >Password:</span></div>
+ <div class="col-md-6"><input ng-disabled="!odlsavebtn.enabled" class="form-control" type="text" ng-model="odlconfig.Password" /></div>
+ </div>
+ <div class="row">
+ <div class="col-md-3"></div>
+ <div class="col-md-6"><button class="btn btn-default" ng-click="odlsave()" ng-disabled="!odlsavebtn.enabled">Save</button></div>
+ </div>
+
+ </div>
+</div>
+ </uib-accordion>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <span style="display:block;text-align:right;color:#0F0;">{{statusmessage}}</span>
+ <span style="display:block;text-align:right;color:#F00;">{{errormessage}}</span>
+ </div>
+ </div>
+
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="ok()">
+ <span>{{'MWTN_MED_ADD' | translate}}</span>
+ </button>
+ <button class="btn btn-danger" type="button" ng-show="true" ng-click="cancel()">
+ <i class="fa fa-trash" aria-hidden="true"></i>
+ <span>{{'MWTN_CANCEL' | translate}}...</span>
+ </button>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorDetails.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorDetails.tpl.html
new file mode 100644
index 00000000..5223df03
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorDetails.tpl.html
@@ -0,0 +1,96 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{ data.el.Name }}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div class="row">
+ <div class="col-xs-3"><span>DeviceType:</span></div>
+ <div class="col-xs-9"><span>{{data.el.DeviceTypeString}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>DeviceIP:</span></div>
+ <div class="col-xs-9"><span>{{data.el.DeviceIp}}:{{data.el.DevicePort}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>TrapsPort:</span></div>
+ <div class="col-xs-9"><span>{{data.el.TrapsPort}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>NetconfPort:</span></div>
+ <div class="col-xs-9"><span>{{data.el.NetconfPort}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>NeXMLModel:</span></div>
+ <div class="col-xs-9"><span>{{data.el.NeModel}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>Status:</span></div>
+ <div class="col-xs-9">
+ <span class="mwtnMediatorStatusRunning" ng-show="{{data.el.PID}}>0">running ({{data.el.PID}})</span>
+ <span class="mwtnMediatorStatusNotRunning" ng-show="{{data.el.PID}}==0">stopped</span>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>Locked:</span></div>
+ <div class="col-xs-9"><span>{{data.el.IsLocked}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>NetconfConnected:</span></div>
+ <div class="col-xs-9"><span>{{data.el.IsNetConfConnected}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>NEConnected:</span></div>
+ <div class="col-xs-9"><span>{{data.el.IsNetworkElementConnected}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>Firewall Configured:</span></div>
+ <div class="col-xs-9"><span>{{data.el.FirewallRuleActive}}</span></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-3"><span>Autorun:</span></div>
+ <div class="col-xs-9"><span>{{data.el.Autorun}}</span></div>
+ </div>
+ <div class="row">
+ <uib-accordion close-others="oneAtATime" class="acc-mediatorlog">
+ <div uib-accordion-group class="panel-default" is-open="false">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': false, 'fa-chevron-right': true}"></i>
+ <span>{{'Logs' | translate}}</span>
+ </uib-accordion-heading>
+ <div id="mwtnLogGrid"
+ ui-grid="logGridOptions"
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns
+ class="mwtnLogGrid"></div>
+
+</div>
+ </uib-accordion>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <span style="display:block;text-align:right;color:#0F0;">{{statusmessage}}</span>
+ <span style="display:block;text-align:right;color:#F00;">{{errormessage}}</span>
+ </div>
+ </div>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-default" type="button" ng-show="{{data.el.IsLocked}}" ng-click="unlock()">
+ <i class="fa fa-lock" aria-hidden="true"></i>
+ <span>{{'Unlock' | translate}}</span>
+ </button>
+ <button class="btn btn-danger" type="button" ng-show="true" ng-click="delete()">
+ <i class="fa fa-trash" aria-hidden="true"></i>
+ <span>{{'MWTN_MED_DELETE' | translate}}...</span>
+ </button>
+ <button class="btn btn-primary" type="button" ng-show="true" ng-click="start()">
+ <span>{{'MWTN_MED_START' | translate}}...</span>
+ </button>
+ <button class="btn btn-primary" type="button" ng-show="true" ng-click="stop()">
+ <span>{{'MWTN_MED_STOP' | translate}}...</span>
+ </button>
+ <button class="btn btn-primary" type="button" ng-click="ok()">
+ <span>{{'MWTN_MED_CLOSE' | translate}}</span>
+ </button>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorServerConfigCtrl.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorServerConfigCtrl.tpl.html
new file mode 100644
index 00000000..c3e96585
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/mwtnMediator-module/src/main/resources/mwtnMediator/templates/mediatorServerConfigCtrl.tpl.html
@@ -0,0 +1,41 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">{{ data.el.Name }}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div class="row">
+ <div class="col-xs-12 col-lg-6">
+ <h3>MediatorServers:</h3>
+ <ul id="mediatorserver-list" >
+ </ul>
+ </div>
+ <div class="col-xs-6 col-lg-6">
+ <h3>Configuration:</h3>
+ <div id="mediatorserver-details">
+ <div class="row">
+ <div class="col-xs-5"><span style="float:right;">Id:</span></div>
+ <div class="col-xs-7"><input type="text" id="tbx_mediatorserver-id" name="mediatorserver-id" value="" /></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-5"><span style="float:right;">Name:</span></div>
+ <div class="col-xs-7"><input type="text" id="tbx_mediatorserver-name" name="mediatorserver-name" value="" /></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-5"><span style="float:right;">Host:</span></div>
+ <div class="col-xs-7"><input type="text" id="tbx_mediatorserver-host" name="mediatorserver-host" value="" /></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-5"><span style="float:right;">Version:</span></div>
+ <div class="col-xs-7"><input type="text" id="tbx_mediatorserver-version" name="mediatorserver-version" value="" /></div>
+ </div>
+ <div class="row">
+ <div class="col-xs-5"><span style="float:right;">MediatorVersion:</span></div>
+ <div class="col-xs-7"><input type="text" id="tbx_mediatorserver-medversion" name="mediatorserver-medversion" value="" /></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <hr class="row" />
+ <div class="row">
+ <button class="btn btn-primary" ng-click="close()">Close</button>
+ </div>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/pom.xml
new file mode 100644
index 00000000..d19f85ed
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnMediator/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnMediator</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnMediator-module</module>
+ <module>mwtnMediator-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/pom.xml
new file mode 100644
index 00000000..0b03bf59
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceCurrent</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceCurrent-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceCurrent-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnPerformanceCurrent-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..4f73e930
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnPerformanceCurrent"/>
+ <property name="url" value="/src/app/mwtnPerformanceCurrent"/>
+ <property name="directory" value="/mwtnPerformanceCurrent"/>
+ <property name="requireJs" value="app/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module"/>
+ <property name="angularJs" value="app.mwtnPerformanceCurrent"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnPerformanceCurrent/mwtnPerformanceCurrent-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/pom.xml
new file mode 100644
index 00000000..2573f41a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceCurrent</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceCurrent-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/images/mwtnPerformance.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/images/mwtnPerformance.png
new file mode 100755
index 00000000..5517f5b1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/images/mwtnPerformance.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent-custom.css
new file mode 100644
index 00000000..5e3cf838
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent-custom.css
@@ -0,0 +1,13 @@
+/**
+ * Add your application related css here
+ */
+
+.mwtnCurrentGrid{
+ height: 600px;
+ background-color: white;
+ color:black;
+}
+
+.mwtnCurrentGrid span{
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.controller.js
new file mode 100644
index 00000000..bffc77be
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.controller.js
@@ -0,0 +1,741 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module',
+ 'app/mwtnPerformanceCurrent/mwtnPerformanceCurrent.services'],
+ function (mwtnPerformanceCurrentApp) {
+
+ mwtnPerformanceCurrentApp.register.controller('mwtnPerformanceCurrentCtrl', ['$scope', '$rootScope', '$window', '$translate', '$mwtnLog', '$mwtnPerformanceCurrent', 'uiGridConstants', 'OnfNetworkElement',
+ function ($scope, $rootScope, $window, $translate, $mwtnLog, $mwtnPerformanceCurrent, uiGridConstants, OnfNetworkElement) {
+
+ var COMPONENT = 'mwtnPerformanceCurrent';
+ $mwtnLog.info({ component: COMPONENT, message: 'mwtnPerformanceCurrent started!' });
+
+ $rootScope.section_logo = 'src/app/mwtnPerformanceCurrent/images/mwtnPerformance.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var radioSignalMap = new Map(); //holds uuid/singalid
+
+ var initPac = {
+ layerProtocol: 'unknown'
+ };
+
+ $scope.layerProtocol = 'MWPS';
+ $scope.layerProtocols = ['MWPS', 'ETC'];
+
+ var updateNe = function (data) {
+ if (!data) return;
+
+ // update onfNetworkElement
+ switch (data.revision) {
+ case '2016-03-23':
+ $mwtnLog.info({ component: COMPONENT, message: 'Revision ' + data.revision + 'not supported!' });
+ break;
+ default: //4. PoC
+ $scope.onfNetworkElement = JSON.parse(JSON.stringify(data['network-element']));
+ $scope.onfLtps = data['network-element'].ltp;
+ $scope.onfNetworkElement.ltpRefList = undefined;
+ }
+
+ // update onfLTPs
+ var order = $mwtnPerformanceCurrent.layerProtocolNameOrder;
+ $scope.onfLtps.sort(function (a, b) {
+ if (order[a.lp[0]['layer-protocol-name']] < order[b.lp[0]['layer-protocol-name']]) return -1;
+ if (order[a.lp[0]['layer-protocol-name']] > order[b.lp[0]['layer-protocol-name']]) return 1;
+ if (a.lp[0].uuid < b.lp[0].uuid) return -1;
+ if (a.lp[0].uuid > b.lp[0].uuid) return 1;
+ return 0;
+ });
+
+ // calculate conditional packages
+ $scope.airinterfaces = [];
+ $scope.ethernets = [];
+ $scope.tdms = [];
+ $scope.onfLtps.map(function (ltp) {
+ var lpId = ltp.lp[0].uuid;
+
+
+
+ switch (ltp.lp[0]['layer-protocol-name']) {
+ case "MWPS":
+ var init = JSON.parse(JSON.stringify(initPac));
+ init.layerProtocol = lpId;
+ $scope.airinterfaces.push(init);
+
+ break;
+ case "ETH-CTP":
+ case "ETC":
+ var init = JSON.parse(JSON.stringify(initPac));
+ init.layerProtocol = lpId;
+ $scope.ethernets.push(init);
+ break;
+
+ default:
+ $mwtnLog.info({ component: COMPONENT, message: 'The layerProtocol ' + ltp.lp[0]['layer-protocol-name'] + ' is not supported (yet)!' });
+ }
+ });
+
+ data.revision = undefined;
+ };
+
+ var updateAirInterface = function (data, key) {
+ // console.log(JSON.stringify(data), lpId);
+
+ if (Object.keys(data)[0].startsWith('air-interface-current-performance')) {
+
+ $scope.jsonvalue.push(data);
+ var label = new OnfNetworkElement($scope.onfNetworkElement).getLpById(data['layer-protocol']).getLabel() || data['layer-protocol'];
+ var radioSignal = radioSignalMap.get(data['layer-protocol'])
+ var list = data['air-interface-current-performance']['current-performance-data-list'] || data['air-interface-current-performance']['current-performance-data'];
+ list.map(function(item) {
+
+
+ var timestamp = $mwtnPerformanceCurrent.formatTimeStamp(item.timestamp);
+
+ switch (key) {
+
+ case 'performance826':
+ $scope.performance826.push({
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ es: item['performance-data'].es,
+ ses: item['performance-data'].ses,
+ uas: item['performance-data'].unavailability,
+ radioSignal: radioSignal
+ });
+ break;
+
+ case 'receiveLevel':
+ $scope.receiveLevel.push({
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ rxmin: checkData(item['performance-data']['rx-level-min']),
+ rxmax: checkData(item['performance-data']['rx-level-max']),
+ rxavg: checkData(item['performance-data']['rx-level-avg']),
+ radioSignal: radioSignal
+ });
+ break;
+
+ case 'transmissionLevel':
+
+ $scope.transmissionLevel.push({
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ txmin: checkData(item['performance-data']['tx-level-min']),
+ txmax: checkData(item['performance-data']['tx-level-max']),
+ txavg: checkData(item['performance-data']['tx-level-avg']),
+ radioSignal: radioSignal
+ });
+
+ break;
+
+ case 'modulation':
+
+ $scope.modulation.push(
+ {
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ time2S: checkData(item['performance-data']['time2-states-s']),
+ time2: checkData(item['performance-data']['time2-states']),
+ time2L: checkData(item['performance-data']['time2-states-l']),
+ time4S: checkData(item['performance-data']['time4-states-s']),
+ time4: checkData(item['performance-data']['time4-states']),
+ time4L: checkData(item['performance-data']['time4-states-l']),
+ time16S: checkData(item['performance-data']['time16-states-s']),
+ time16: checkData(item['performance-data']['time16-states']),
+ time16L: checkData(item['performance-data']['time16-states-l']),
+ time32S: checkData(item['performance-data']['time32-states-s']),
+ time32: checkData(item['performance-data']['time32-states']),
+ time32L: checkData(item['performance-data']['time32-states-l']),
+ time64S: checkData(item['performance-data']['time64-states-s']),
+ time64: checkData(item['performance-data']['time64-states']),
+ time64L: checkData(item['performance-data']['time64-states-l']),
+ time128S: checkData(item['performance-data']['time128-states-s']),
+ time128: checkData(item['performance-data']['time128-states']),
+ time128L: checkData(item['performance-data']['time128-states-l']),
+ time256S: checkData(item['performance-data']['time256-states-s']),
+ time256: checkData(item['performance-data']['time256-states']),
+ time256L: checkData(item['performance-data']['time256-states-l']),
+ time512S: checkData(item['performance-data']['time512-states-s']),
+ time512: checkData(item['performance-data']['time512-states']),
+ time512L: checkData(item['performance-data']['time512-states-l']),
+ time1024S: checkData(item['performance-data']['time1024-states-s']),
+ time1024: checkData(item['performance-data']['time1024-states']),
+ time1024L: checkData(item['performance-data']['time1024-states-l']),
+ time2048S: checkData(item['performance-data']['time2048-states-s']),
+ time2048: checkData(item['performance-data']['time2048-states']),
+ time2048L: checkData(item['performance-data']['time2048-states-l']),
+ time4096S: checkData(item['performance-data']['time4096-states-s']),
+ time4096: checkData(item['performance-data']['time4096-states']),
+ time4096L: checkData(item['performance-data']['time4096-states-l']),
+ time8192S: checkData(item['performance-data']['time8192-states-s']),
+ time8192: checkData(item['performance-data']['time8192-states']),
+ time8192L: checkData(item['performance-data']['time8192-states-l']),
+ radioSignal: radioSignal
+ });
+
+ break;
+
+ case 'temperature':
+
+ $scope.temperature.push({
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ rfTempMin: item['performance-data']['rf-temp-min'],
+ rfTempAvg: item['performance-data']['rf-temp-avg'],
+ rfTempMax: item['performance-data']['rf-temp-max'],
+ radioSignal: radioSignal
+ });
+ break;
+
+ case 'snir':
+
+ $scope.snir.push({
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ snirMin: item['performance-data']['snir-min'],
+ snirAvg: item['performance-data']['snir-avg'],
+ snirMax: item['performance-data']['snir-max'],
+ radioSignal: radioSignal
+ }
+ );
+
+ break;
+
+ case 'crossPolarDiscrimination':
+
+ $scope.cpdData.push({
+
+ timestamp: timestamp,
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ id: label,
+ period: item['granularity-period'],
+ xpdMin: item['performance-data']['xpd-min'],
+ xpdAvg: item['performance-data']['xpd-avg'],
+ xpdMax: item['performance-data']['xpd-max'],
+ radioSignal: radioSignal
+ });
+
+ break;
+ }
+
+ });
+
+ }
+ };
+
+ var updateContainer = function (lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ var label = new OnfNetworkElement($scope.onfNetworkElement).getLpById(data['layer-protocol']).getLabel() || data['layer-protocol'];
+
+ if (Object.keys(data)[0].contains('ethernet-container')) {
+ $scope.ethernetJsonValue.push(data);
+
+ var list = data['ethernet-container-current-performance']['current-performance-data-list'] || data['ethernet-container-current-performance']['current-performance-data']
+ list.map(function (item) {
+
+ $scope.performanceEthernetContainer.push({
+ timestamp: $mwtnPerformanceCurrent.formatTimeStamp(item['timestamp']),
+ elapsedTime: checkData(item['elapsed-time']),
+ suspectInterval: item['suspect-interval-flag'],
+ scannerId: item['scanner-id'],
+ period: item['granularity-period'],
+ txEthernetBytesMaxS: checkData(item['performance-data']['tx-ethernet-bytes-max-s']),
+ txEthernetBytesMaxM: checkData(item['performance-data']['tx-ethernet-bytes-max-m']),
+ txEthernetBytesSum: checkData(item['performance-data']['tx-ethernet-bytes-sum']),
+ id: label
+ });
+ });
+ }
+ };
+
+ //replace -1 with undefined in json data
+ var checkData = function (value) {
+ if (value === -1 || value === undefined) return undefined;
+ else return value;
+ };
+
+ //perf log configuration
+ $scope.gridOptionsPerformance826 = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'es', type: 'string', displayName: 'ES', width: 70 },
+ { field: 'ses', type: 'string', displayName: 'SES', width: 70 },
+ { field: 'uas', type: 'string', displayName: 'UAS', width: 70 }
+ ],
+ data: 'performance826'
+ };
+
+ //receive lvl configuration
+ $scope.gridOptionsReceiveLevel = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rxmin', type: 'string', displayName: 'Rx min [dBm]', width: 90 },
+ { field: 'rxavg', type: 'string', displayName: 'Rx avg [dBm]', width: 90 },
+ { field: 'rxmax', type: 'string', displayName: 'Rx max [dBm]', width: 90 }
+
+ ],
+ data: 'receiveLevel'
+ };
+
+ //transmission lvl configuration
+ $scope.gridOptionsTransmissionLevel = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'txmin', type: 'string', displayName: 'Tx min [dBm]', width: 90 },
+ { field: 'txavg', type: 'string', displayName: 'Tx avg [dBm]', width: 90 },
+ { field: 'txmax', type: 'string', displayName: 'Tx max [dBm]', width: 90 }
+
+ ],
+ data: 'transmissionLevel'
+ };
+
+ //modulation configuration
+ $scope.gridOptionsModulation = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'time2S', type: 'string', displayName: 'QAM2S', width: 90 },
+ { field: 'time2', type: 'string', displayName: 'QAM2', width: 90 },
+ { field: 'time2L', type: 'string', displayName: 'QAM2L', width: 90 },
+ { field: 'time4S', type: 'string', displayName: 'QAM4S', width: 90 },
+ { field: 'time4', type: 'string', displayName: 'QAM4', width: 90 },
+ { field: 'time4L', type: 'string', displayName: 'QAM4L', width: 90 },
+ { field: 'time16S', type: 'string', displayName: 'QAM16S', width: 90 },
+ { field: 'time16', type: 'string', displayName: 'QAM16', width: 90 },
+ { field: 'time16L', type: 'string', displayName: 'QAM16L', width: 90 },
+ { field: 'time32S', type: 'string', displayName: 'QAM32S', width: 90 },
+ { field: 'time32', type: 'string', displayName: 'QAM32', width: 90 },
+ { field: 'time32L', type: 'string', displayName: 'QAM32L', width: 90 },
+ { field: 'time64S', type: 'string', displayName: 'QAM64S', width: 90 },
+ { field: 'time64', type: 'string', displayName: 'QAM64', width: 90 },
+ { field: 'time64L', type: 'string', displayName: 'QAM64L', width: 90 },
+ { field: 'time128S', type: 'string', displayName: 'QAM128S', width: 90 },
+ { field: 'time128', type: 'string', displayName: 'QAM128', width: 90 },
+ { field: 'time128L', type: 'string', displayName: 'QAM128L', width: 90 },
+ { field: 'time256S', type: 'string', displayName: 'QAM256S', width: 90 },
+ { field: 'time256', type: 'string', displayName: 'QAM256', width: 90 },
+ { field: 'time256L', type: 'string', displayName: 'QAM256L', width: 90 },
+ { field: 'time512S', type: 'string', displayName: 'QAM512S', width: 90 },
+ { field: 'time512', type: 'string', displayName: 'QAM512', width: 90 },
+ { field: 'time512L', type: 'string', displayName: 'QAM512L', width: 90 },
+ { field: 'time1024S', type: 'string', displayName: 'QAM1024S', width: 90 },
+ { field: 'time1024', type: 'string', displayName: 'QAM1024', width: 90 },
+ { field: 'time1024L', type: 'string', displayName: 'QAM1024L', width: 90 },
+ { field: 'time2048S', type: 'string', displayName: 'QAM2048S', width: 90 },
+ { field: 'time2048', type: 'string', displayName: 'QAM2048', width: 90 },
+ { field: 'time2048L', type: 'string', displayName: 'QAM2048L', width: 90 },
+ { field: 'time4096S', type: 'string', displayName: 'QAM4096S', width: 90 },
+ { field: 'time4096', type: 'string', displayName: 'QAM4096', width: 90 },
+ { field: 'time4096L', type: 'string', displayName: 'QAM4096L', width: 90 },
+ { field: 'time8192S', type: 'string', displayName: 'QAM8192S', width: 90 },
+ { field: 'time8192', type: 'string', displayName: 'QAM8192', width: 90 },
+ { field: 'time8192L', type: 'string', displayName: 'QAM8192L', width: 90 }
+
+ ],
+ data: 'modulation', onRegisterApi: function (gridApi) {
+ $scope.gridApi = gridApi;
+ }
+ };
+
+ //temperature configuration
+ $scope.gridOptionsTemperature = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rfTempMin', type: 'string', displayName: 'Rf Temp Min [&deg;C]', width: 90 },
+ { field: 'rfTempAvg', type: 'string', displayName: 'Rf Temp Avg [&deg;C]', width: 90 },
+ { field: 'rfTempMax', type: 'string', displayName: 'Rf Temp Max [&deg;C]', width: 90 }
+
+ ],
+ data: 'temperature'
+ }
+
+ //SNIR configuration
+ $scope.gridOptionsSnir = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false},
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'snirMin', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MIN'),'[dB]'].join(' '), width: 90 },
+ { field: 'snirAvg', type: 'string', displayName: [$translate.instant('MWTN_SNIR_AVG'),'[dB]'].join(' '), width: 90 },
+ { field: 'snirMax', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MAX'),'[dB]'].join(' '), width: 90 }
+ ],
+ data: 'snir'
+ }
+
+ //CPD Configuration
+ $scope.gridOptionsCrossPolarDiscrimination = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'radioSignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'xpdMin', type: 'string', displayName: 'CPD min [dB]', width: 90 },
+ { field: 'xpdAvg', type: 'string', displayName: 'CPD avg [dB]', width: 90 },
+ { field: 'xpdMax', type: 'string', displayName: 'CPD max [dB]', width: 90 }
+
+ ],
+ data: 'cpdData'
+ }
+
+ //ethernet perf configuration
+ $scope.gridOptionsPerformanceEthernetContainer = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LP'), width: 300 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'Request time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'elapsedTime', type: 'string', displayName: 'Elapsed Time', width: 100 },
+ { field: 'period', type: 'string', displayName: 'Period', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'txEthernetBytesMaxS', type: 'number', displayName: 'Tx BytesMaxS', width: 90 },
+ { field: 'txEthernetBytesMaxM', type: 'number', displayName: 'Tx BytesMaxM', width: 90 },
+ { field: 'txEthernetBytesSum', type: 'number', displayName: 'Tx BytesSum', width: 90 }
+
+ ],
+ data: 'performanceEthernetContainer'
+ };
+
+ var updatePart = function (spec, data, key) {
+ switch (spec.pacId) {
+ case 'ne':
+ updateNe(data);
+ break;
+
+ case 'airinterface':
+ console.log(JSON.stringify(spec, JSON.stringify(data)));
+ updateAirInterface(data, key);
+ break;
+
+ case 'container':
+ updateContainer(spec.layerProtocolId, spec.partId, data);
+ break;
+
+ }
+ };
+
+ var refreshAirInterface = function (key) {
+ //get performance data from interfaces
+ for (var interf of $scope.airinterfaces) {
+ var airIterfaceSpec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: 'airinterface',
+ partId: 'CurrentPerformance',
+ layerProtocolId: interf.layerProtocol
+ };
+ $mwtnPerformanceCurrent.getPacParts(airIterfaceSpec).then(function (data) {
+ var yangfiedObj = $mwtnPerformanceCurrent.yangifyObject(data);
+ updatePart(airIterfaceSpec, yangfiedObj, key);
+ });
+ }
+ };
+
+ $scope.collapseAll = function () {
+ // close all groups
+ Object.keys($scope.status).map(function (group) {
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function (group) {
+ $scope.spinner[group] = false;
+ });
+ };
+
+ // events
+ $scope.status = { performanceEthernetContainer: true };
+ $scope.spinner = {};
+ $scope.separator = $mwtnPerformanceCurrent.separator; //'&nbsp;'
+
+ //get data on ne selection
+ $scope.$watch('networkElement', function (neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+ $scope.collapseAll();
+
+ // clear lists visible on screen
+ $scope.performance826 = [];
+ $scope.receiveLevel = [];
+ $scope.transmissionLevel = [];
+ $scope.modulation = [];
+ $scope.temperature = [];
+ $scope.snir = [];
+ $scope.cpdData = [];
+ $scope.jsonvalue = [];
+ $scope.performanceEthernetContainer = [];
+ $scope.ethernetJsonValue = [];
+
+ var revision;
+ $scope.networkElements.map(function (ne) {
+ if (ne.id === neId) revision = ne.revision;
+ });
+ $scope.networkElementId = neId;
+ $scope.revision = revision;
+
+ var spec = {
+ nodeId: neId,
+ revision: revision,
+ pacId: 'ne'
+ };
+
+ //get ne data
+ $mwtnPerformanceCurrent.getPacParts(spec).then(function (success) {
+ var yangfiedObj = $mwtnPerformanceCurrent.yangifyObject(success);
+
+ updatePart(spec, yangfiedObj);
+
+ //get performance data from interfaces
+ $scope.airinterfaces.map(function(airInterface) {
+
+ //get configuration for airinterfaces
+ var airIterfaceSpec = {
+ nodeId: neId,
+ revision: revision,
+ pacId: 'airinterface',
+ partId: 'Configuration',
+ layerProtocolId: airInterface.layerProtocol
+ };
+
+ //get radioSignalID and add it to map
+ $mwtnPerformanceCurrent.getPacParts(airIterfaceSpec).then(function (data) {
+ var yangfiedObj = $mwtnPerformanceCurrent.yangifyObject(data);
+ radioSignalMap.set(yangfiedObj['layer-protocol'], yangfiedObj['air-interface-configuration']['radio-signal-id']);
+ });
+ });
+
+ }, function (error) {
+ updatePart(spec, error);
+ });
+ }
+ });
+
+ $scope.$watch('layerProtocol', function (newValue, oldValue) {
+
+ if (newValue && oldValue !== "" && newValue !== oldValue) {
+ $scope.collapseAll();
+ }
+
+ }, true);
+
+ //update data within tables on accordion - open
+ $scope.$watch('status', function (status, oldValue) {
+ Object.keys(status).map(function (key) {
+ if ($scope.networkElementId && status[key] && status[key] !== oldValue[key]) {
+ switch (key) {
+
+ case 'performance826':
+ $scope.performance826 = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'receiveLevel':
+ $scope.receiveLevel = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'transmissionLevel':
+ $scope.transmissionLevel = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'modulation':
+ $scope.modulation = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'temperature':
+ $scope.temperature = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'snir':
+ $scope.snir = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'crossPolarDiscrimination':
+ $scope.cpdData = [];
+ refreshAirInterface(key);
+ break;
+
+ case 'performanceEthernetContainer':
+ $scope.performanceEthernetContainer = [];
+ $scope.ethernetJsonValue = [];
+
+ //get performance data for ethernet
+ $scope.ethernets.map(function (item) {
+ var ethernetSpec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: 'container',
+ partId: 'CurrentPerformance',
+ layerProtocolId: item.layerProtocol
+ };
+
+ $mwtnPerformanceCurrent.getPacParts(ethernetSpec).then(function (data) {
+ var yangfiedObj = $mwtnPerformanceCurrent.yangifyObject(data);
+ updatePart(ethernetSpec, yangfiedObj);
+ });
+ });
+ break;
+
+ }
+ $window.dispatchEvent(new Event("resize"));
+ }
+ });
+ }, true);
+
+ }]);
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module.js
new file mode 100644
index 00000000..e0e4e2fb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnPerformanceCurrentApp = angular.module('app.mwtnPerformanceCurrent', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'ui.router.state','ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.pagination','ui.grid.autoResize']);
+
+ mwtnPerformanceCurrentApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnPerformanceCurrentApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnPerformanceCurrent/mwtnPerformanceCurrent.controller');
+ NavHelperProvider.addToMenu('mwtnPerformanceCurrent', {
+ "link" : "#/pnfPerformanceCurrent",
+ "active" : "main.mwtnPerformanceCurrent",
+ "title" : "pnf PM Current",
+ "icon" : "fa fa-bar-chart", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf PM Current",
+ "description" : "mwtnPerformanceCurrent"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnPerformanceCurrent', {
+ url: 'pnfPerformanceCurrent',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnPerformanceCurrent/mwtnPerformanceCurrent.tpl.html',
+ controller: 'mwtnPerformanceCurrentCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnPerformanceCurrentApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.services.js
new file mode 100644
index 00000000..d7adb5a6
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.services.js
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 HCL Inc. 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/mwtnPerformanceCurrent/mwtnPerformanceCurrent.module'],function(mwtnPerformanceCurrentApp) {
+
+ mwtnPerformanceCurrentApp.register.factory('$mwtnPerformanceCurrent', function($mwtnCommons, $mwtnLog) {
+
+ var COMPONENT = '$mwtnPerformanceCurrent';
+ $mwtnLog.info({component: COMPONENT, message: '$mwtnPerformanceCurrent started!'});
+
+ var service = {};
+
+ service.separator = $mwtnCommons.separator;
+ service.parts = $mwtnCommons.parts;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.layerProtocolNameOrder = $mwtnCommons.layerProtocolNameOrder;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+
+ service.yangifyObject=$mwtnCommons.yangifyObject;
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.tpl.html
new file mode 100644
index 00000000..a212971e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/mwtnPerformanceCurrent-module/src/main/resources/mwtnPerformanceCurrent/mwtnPerformanceCurrent.tpl.html
@@ -0,0 +1,119 @@
+<ht-header help-link='sdnr/pnfPerformance/0.4.0/README.md'></ht-header>
+<mwtn-select-network-element></mwtn-select-network-element>
+
+<div class="owl container" ng-if="networkElements.lenght !== 0 && networkElement" style="width: 100%">
+ <div class="row">
+ <div class="col-md-3">
+ <div class="form-group">
+ <select class="form-control" ng-model="layerProtocol">
+ <option ng-repeat="protocol in layerProtocols">{{protocol}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="col-md-2">
+ <span class="white">{{'Select Layer Protocol' }}</span>
+ </div>
+ </div>
+ <div class="row" ng-if="layerProtocol === 'MWPS' ">
+ <div class="col">
+ <uib-accordion close-others="oneATime">
+ <div uib-accordion-group class="panel-primary" is-open="status.performance826">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.performance826, 'fa-chevron-right': !status.performance826}"></i>
+ <span>Performance Data G.826</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.performance826"></i>
+ </uib-accordion-heading>
+
+ <div id="mwtnFaultGridAlarmLog" ui-grid="gridOptionsPerformance826" ui-grid-pagination ui-grid-exporter ui-grid-selection
+ ui-grid-pinning ui-grid-resize-columns ui-grid-auto-resize ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.receiveLevel">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.receiveLevel, 'fa-chevron-right': !status.receiveLevel}"></i>
+ <span>Receive Level</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.receiveLevel"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsReceiveLevel" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-auto-resize ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.transmissionLevel">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.transmissionLevel, 'fa-chevron-right': !status.transmissionLevel}"></i>
+ <span>Transmission Power</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.transmissionLevel"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsTransmissionLevel" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-auto-resize ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.modulation">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.modulation, 'fa-chevron-right': !status.modulation}"></i>
+ <span>Adaptive Modulation</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.modulation"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsModulation" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.temperature">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.temperature, 'fa-chevron-right': !status.temperature}"></i>
+ <span>Temperature</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.temperature"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsTemperature" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnFaultGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.snir">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.snir, 'fa-chevron-right': !status.snir}"></i>
+ <span>{{'MWTN_SINR' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.snir"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsSnir" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.crossPolarDiscrimination">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.crossPolarDiscrimination, 'fa-chevron-right': !status.crossPolarDiscrimination}"></i>
+ <span>Cross Polar Discrimination</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.crossPolarDiscrimination"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsCrossPolarDiscrimination" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+
+ </div>
+ </uib-accordion>
+ </div>
+ </div>
+ <div class="row" ng-if="layerProtocol === 'ETC' ">
+ <div class="col">
+ <uib-accordion close-others="oneATime">
+ <div uib-accordion-group class="panel-primary" is-open="status.performanceEthernetContainer">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.performanceEthernetContainer, 'fa-chevron-right': !status.performanceEthernetContainer}"></i>
+ <span>Performance Data</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.performanceEthernetContainer"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsPerformanceEthernetContainer" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-auto-resize ui-grid-move-columns class="mwtnCurrentGrid">
+ </div>
+ </div>
+ </uib-accordion>
+ </div>
+ </div>
+</div>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/pom.xml
new file mode 100644
index 00000000..7f2c1e52
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceCurrent/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceCurrent</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnPerformanceCurrent-module</module>
+ <module>mwtnPerformanceCurrent-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/pom.xml
new file mode 100644
index 00000000..feb32631
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceHistory</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceHistory-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceHistory-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnPerformanceHistory-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..3288e4f1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnPerformanceHistory"/>
+ <property name="url" value="/src/app/mwtnPerformanceHistory"/>
+ <property name="directory" value="/mwtnPerformanceHistory"/>
+ <property name="requireJs" value="app/mwtnPerformanceHistory/mwtnPerformanceHistory.module"/>
+ <property name="angularJs" value="app.mwtnPerformanceHistory"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnPerformanceHistory/mwtnPerformanceHistory-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/pom.xml
new file mode 100644
index 00000000..9665ca86
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceHistory</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceHistory-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/images/mwtnPerformance.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/images/mwtnPerformance.png
new file mode 100755
index 00000000..5517f5b1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/images/mwtnPerformance.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory-custom.css
new file mode 100644
index 00000000..43663034
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory-custom.css
@@ -0,0 +1,13 @@
+/**
+ * Add your application related css here
+ */
+
+ .mwtnHistoryGrid {
+ height: 600px;
+ background-color: white;
+ color:black;
+}
+
+.mwtnHistoryGrid span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.controller.js
new file mode 100644
index 00000000..6a5a2e9a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.controller.js
@@ -0,0 +1,1196 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnPerformanceHistory/mwtnPerformanceHistory.module',
+ 'app/mwtnPerformanceHistory/mwtnPerformanceHistory.services'],
+ function (mwtnPerformanceHistoryoryApp) {
+
+ mwtnPerformanceHistoryoryApp.register.controller('mwtnPerformanceHistoryCtrl', ['$scope', '$rootScope', '$window', '$translate', '$mwtnLog', '$mwtnPerformanceHistory', 'uiGridConstants', 'OnfNetworkElement',
+ function ($scope, $rootScope, $window, $translate, $mwtnLog, $mwtnPerformanceHistory, uiGridConstants, OnfNetworkElement) {
+
+ var COMPONENT = 'mwtnPerformanceHistory';
+ $mwtnLog.info({ component: COMPONENT, message: 'mwtn historical Performance started!' });
+
+ $rootScope.section_logo = 'src/app/mwtnPerformanceHistory/images/mwtnPerformance.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var globalFilter;
+
+ $scope.selecteditem = {};
+
+ //time selector
+ $scope.selecteditem.timePeriod = "15 minutes";
+ $scope.timePeriods = ["15 minutes", "24 hours"];
+
+ //interface selector
+ $scope.selecteditem.selectedLtpId = undefined;
+ $scope.availableLtpIds = [];
+
+ //stateobject
+ $scope.state = {};
+ $scope.state.filter = false;
+ $scope.state.sort = false;
+ $scope.state.lastfilter = null;
+ $scope.state.lastSort = null;
+ $scope.state.grid = null;
+
+ //perf log configuration
+ $scope.gridOptionsPerformance826 = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+
+ { field: 'es', type: 'string', displayName: 'ES', width: 70 },
+ { field: 'ses', type: 'string', displayName: 'SES', width: 70 },
+ { field: 'uas', type: 'string', displayName: 'UAS', width: 70 }
+
+ ],
+ data: 'performance826',
+ onRegisterApi: function (gridApi) {
+ $scope.performancegridApi = gridApi;
+ $scope.performancegridApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.performancegridApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.performancegridApi.grid, [$scope.gridOptionsPerformance826.columnDefs[1]]);
+
+ $scope.performancegridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsPerformance826);
+ });
+ }
+ };
+
+ //receive lvl configuration
+ $scope.gridOptionsReceiveLevel = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rxmin', type: 'string', displayName: 'Rx min', width: 90 },
+ { field: 'rxavg', type: 'string', displayName: 'Rx avg', width: 90 },
+ { field: 'rxmax', type: 'string', displayName: 'Rx max', width: 90 }
+ ],
+ data: 'receiveLevel',
+ onRegisterApi: function (gridApi) {
+ $scope.recvGridApi = gridApi;
+ $scope.recvGridApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.recvGridApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.recvGridApi.grid, [$scope.gridOptionsReceiveLevel.columnDefs[1]]);
+
+ $scope.recvGridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsReceiveLevel);
+ });
+ }
+ };
+
+ //transmission lvl configuration
+ $scope.gridOptionsTransmissionLevel = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'txmin', type: 'string', displayName: 'Tx min', width: 90 },
+ { field: 'txavg', type: 'string', displayName: 'Tx avg', width: 90 },
+ { field: 'txmax', type: 'string', displayName: 'Tx max', width: 90 }
+ ],
+ data: 'transmissionLevel',
+ onRegisterApi: function (gridApi) {
+ $scope.transmissionGridApi = gridApi;
+ $scope.transmissionGridApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.transmissionGridApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.transmissionGridApi.grid, [$scope.gridOptionsTransmissionLevel.columnDefs[1]]);
+
+ $scope.transmissionGridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsTransmissionLevel);
+ });
+ }
+ };
+
+ //modulation configuration
+ $scope.gridOptionsModulation = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'time2S', type: 'string', displayName: 'QAM2S', width: 90 },
+ { field: 'time2', type: 'string', displayName: 'QAM2', width: 90 },
+ { field: 'time2L', type: 'string', displayName: 'QAM2L', width: 90 },
+ { field: 'time4S', type: 'string', displayName: 'QAM4S', width: 90 },
+ { field: 'time4', type: 'string', displayName: 'QAM4', width: 90 },
+ { field: 'time4L', type: 'string', displayName: 'QAM4L', width: 90 },
+ { field: 'time16S', type: 'string', displayName: 'QAM16S', width: 90 },
+ { field: 'time16', type: 'string', displayName: 'QAM16', width: 90 },
+ { field: 'time16L', type: 'string', displayName: 'QAM16L', width: 90 },
+ { field: 'time32S', type: 'string', displayName: 'QAM32S', width: 90 },
+ { field: 'time32', type: 'string', displayName: 'QAM32', width: 90 },
+ { field: 'time32L', type: 'string', displayName: 'QAM32L', width: 90 },
+ { field: 'time64S', type: 'string', displayName: 'QAM64S', width: 90 },
+ { field: 'time64', type: 'string', displayName: 'QAM64', width: 90 },
+ { field: 'time64L', type: 'string', displayName: 'QAM64L', width: 90 },
+ { field: 'time128S', type: 'string', displayName: 'QAM128S', width: 90 },
+ { field: 'time128', type: 'string', displayName: 'QAM128', width: 90 },
+ { field: 'time128L', type: 'string', displayName: 'QAM128L', width: 90 },
+ { field: 'time256S', type: 'string', displayName: 'QAM256S', width: 90 },
+ { field: 'time256', type: 'string', displayName: 'QAM256', width: 90 },
+ { field: 'time256L', type: 'string', displayName: 'QAM256L', width: 90 },
+ { field: 'time512S', type: 'string', displayName: 'QAM512S', width: 90 },
+ { field: 'time512', type: 'string', displayName: 'QAM512', width: 90 },
+ { field: 'time512L', type: 'string', displayName: 'QAM512L', width: 90 },
+ { field: 'time1024S', type: 'string', displayName: 'QAM1024S', width: 90 },
+ { field: 'time1024', type: 'string', displayName: 'QAM1024', width: 90 },
+ { field: 'time1024L', type: 'string', displayName: 'QAM1024L', width: 90 },
+ { field: 'time2048S', type: 'string', displayName: 'QAM2048S', width: 90 },
+ { field: 'time2048', type: 'string', displayName: 'QAM2048', width: 90 },
+ { field: 'time2048L', type: 'string', displayName: 'QAM2048L', width: 90 },
+ { field: 'time4096S', type: 'string', displayName: 'QAM4096S', width: 90 },
+ { field: 'time4096', type: 'string', displayName: 'QAM4096', width: 90 },
+ { field: 'time4096L', type: 'string', displayName: 'QAM4096L', width: 90 },
+ { field: 'time8192S', type: 'string', displayName: 'QAM8192S', width: 90 },
+ { field: 'time8192', type: 'string', displayName: 'QAM8192', width: 90 },
+ { field: 'time8192L', type: 'string', displayName: 'QAM8192L', width: 90 }
+
+
+ ],
+ data: 'modulation',
+ onRegisterApi: function (gridApi) {
+ $scope.gridApi = gridApi;
+ $scope.gridApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.gridApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.gridApi.grid, [$scope.gridOptionsModulation.columnDefs[1]]);
+
+ $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsModulation);
+ });
+ }
+ };
+
+ //temperature configuration
+ $scope.gridOptionsTemperature = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rfTempMin', type: 'string', displayName: 'Rf Temp Min [&deg;C]', width: 90 },
+ { field: 'rfTempAvg', type: 'string', displayName: 'Rf Temp Avg [&deg;C]', width: 90 },
+ { field: 'rfTempMax', type: 'string', displayName: 'Rf Temp Max [&deg;C]', width: 90 }
+
+ ],
+ data: 'temperature',
+ onRegisterApi: function (gridApi) {
+ $scope.gridTemperatureApi = gridApi;
+ $scope.gridTemperatureApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.gridTemperatureApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.gridTemperatureApi.grid, [$scope.gridOptionsTemperature.columnDefs[1]]);
+
+ $scope.gridTemperatureApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsTemperature);
+ });
+ }
+ }
+
+ //SNIR configuration
+ $scope.gridOptionsSnir = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'snirMin', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MIN'),'[dB]'].join(' '), width: 90 },
+ { field: 'snirAvg', type: 'string', displayName: [$translate.instant('MWTN_SNIR_AVG'),'[dB]'].join(' '), width: 90 },
+ { field: 'snirMax', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MAX'),'[dB]'].join(' '), width: 90 }
+ ],
+ data: 'snir',
+ onRegisterApi: function (gridApi) {
+ $scope.gridSNIRApi = gridApi;
+ $scope.gridSNIRApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.gridSNIRApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.gridSNIRApi.grid, [$scope.gridOptionsSnir.columnDefs[1]]);
+
+ $scope.gridSNIRApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsSnir);
+ });
+ }
+ }
+
+ //CPD Configuration
+ $scope.gridOptionsCrossPolarDiscrimination = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'xpdMin', type: 'string', displayName: 'CPD min [dB]', width: 90 },
+ { field: 'xpdAvg', type: 'string', displayName: 'CPD avg [dB]', width: 90 },
+ { field: 'xpdMax', type: 'string', displayName: 'CPD max [dB]', width: 90 }
+
+ ],
+ data: 'crossPolarDiscrimination',
+ onRegisterApi: function (gridApi) {
+ $scope.gridXpdApi = gridApi;
+ $scope.gridXpdApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.gridXpdApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.gridOptionsCrossPolarDiscrimination, [$scope.gridOptionsCrossPolarDiscrimination.columnDefs[1]]);
+
+ $scope.gridXpdApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsCrossPolarDiscrimination);
+ });
+ }
+ }
+
+ //ethernet perf configuration
+ $scope.gridOptionsPerformanceEthernetContainer = {
+ paginationPageSizes: [25, 100, 1000, 10000],
+ paginationPageSize: 25,
+ useExternalPagination: true,
+ useExternalSorting: true,
+ enablePaginationControls: true,
+ enableFiltering: true,
+ useExternalFiltering: true,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90, visible: false },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ {
+ field: 'timestamp', type: 'string', displayName: 'End time', width: 200, sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ }
+ },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'txEthernetBytesMaxS', type: 'number', displayName: 'Tx BytesMaxS', width: 90 },
+ { field: 'txEthernetBytesMaxM', type: 'number', displayName: 'Tx BytesMaxM', width: 90 },
+ { field: 'txEthernetBytesSum', type: 'number', displayName: 'Tx BytesSum', width: 90 }
+
+ ],
+ data: 'performanceEthernetContainer',
+ onRegisterApi: function (gridApi) {
+ $scope.gridPerfEthernetApi = gridApi;
+ $scope.gridPerfEthernetApi.core.on.filterChanged($scope, $scope.filter);
+ $scope.gridPerfEthernetApi.core.on.sortChanged($scope, $scope.sortChanged);
+ $scope.sortChanged($scope.gridPerfEthernetApi.grid, [$scope.gridOptionsPerformanceEthernetContainer.columnDefs[1]]);
+
+ $scope.gridPerfEthernetApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ getPage($scope.gridOptionsPerformanceEthernetContainer);
+ });
+ }
+ };
+
+ //filter
+ $scope.filter = function () {
+ var grid = this.grid;
+ var columns = [];
+
+ //get all columns where data was typed in
+ angular.forEach(grid.columns, function (value, key) {
+ if (value.filters[0].term) {
+ var col = findColumn(value.field);
+ if (col === "time-stamp") {
+ //convert timestamp to db format
+ var timestamp = $mwtnPerformanceHistory.TimeStampToONFFormat(value.filters[0].term);
+ columns.push({ column: col, value: timestamp });
+ }
+ else
+ columns.push({ column: col, value: value.filters[0].term }); //create column object
+ }
+ });
+
+ if (columns.length == 0) { //all filter data cleared away
+ $scope.state.filter = false;
+ $scope.state.lastfilter = null;
+
+ //get unfiltered data
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, null, null).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, grid.options);
+
+ }
+ });
+
+ } else {
+ //base filter string
+ var filter = { "query": { "bool": { "must": [] } } };
+
+ //create filter objects
+ var prefixs = [];
+ prefixs.push({ prefix: globalFilter });
+
+ columns.map(function (obj) {
+ var prefixObj = {};
+ prefixObj[obj.column] = obj.value;//add like: {column: "fault.counter", value: "1"} => {"fault.counter":1}
+ prefixs.push({ prefix: prefixObj }); // => {"prefix":{...}}
+ });
+
+ //add objects to must property
+ filter.query.bool.must = prefixs;
+
+ //save filter
+ $scope.state.lastfilter = filter;
+ $scope.state.filter = true;
+
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, filter, null).then(function (response) {
+ if (response.data.hits.total > 0) { //only, when hits exist
+ processRequestInGrid(response, grid.options);
+ //$scope.gridOptionsAlarmLog.totalItems = response.data.hits.total;
+ } else {
+ //clear data from list
+ $scope[grid.options.data] = [];
+ grid.options.totalItems = 0;
+
+ }
+ });
+ }
+ };
+
+ $scope.sortChanged = function (grid, sortColumns) { // sortColumns is an array containing just the column sorted in the grid
+
+
+ if (sortColumns && sortColumns.length > 0) {
+ if (sortColumns[0].sort) {
+ var name = sortColumns[0].field; // the field (name) of the column sorted
+ var direction = sortColumns[0].sort.direction // the direction of the column sorted: "desc" or "asc"
+ sort(direction, findColumn(name), grid);
+ }
+ } else if (sortColumns) {
+ $scope.state.sort = false;
+ $scope.state.lastSort = null;
+
+ //get unsorted data
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, null, null).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, grid.options);
+ }
+ });
+ }
+ };
+
+ var sort = function (direction, columnName, grid) {
+ switch (direction) {
+ case uiGridConstants.ASC:
+
+ //create sort object
+ var sortObj = {};
+ sortObj[columnName] = { order: 'asc' };
+ var sort = [sortObj];
+ //save last sort
+ $scope.state.lastSort = sort;
+
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, null, sort).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, grid.options);
+ $scope.state.sort = true;
+
+ }
+ });
+
+ break;
+
+ case uiGridConstants.DESC:
+
+ var sortObj = {};
+ sortObj[columnName] = { order: 'desc' };
+ var sort = [sortObj];
+ $scope.state.lastSort = sort;
+
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, null, sort).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, grid.options);
+ $scope.state.sort = true;
+ }
+ });
+ break;
+
+ case undefined:
+
+ $scope.state.sort = false;
+ $scope.state.lastSort = null;
+
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid.options, null, null)
+ .then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, grid.options);
+ }
+ });
+
+ break;
+ }
+ }
+
+ function findColumn(name) {
+
+ if (name === "timestamp") { return "time-stamp"; }
+ else if (name === "layerprotocol") { return "layer-protocol-name"; }
+ else if (name === "id") { return "uuid-interface"; }
+ else if (name === "suspectInterval") { return "suspect-interval-flag"; }
+ else if (name === "scannerId") { return "scanner-id"; }
+ else if (name === "radiosignal") { return "radio-signal-id"; }
+ else if (name === "es") { return "performance-data.es"; }
+ else if (name === "ses") { return "performance-data.ses"; }
+ else if (name === "uas") { return "performance-data.unavailability"; }
+ else if (name === "rxmin") { return "performance-data.rx-level-min"; }
+ else if (name === "rxmax") { return "performance-data.rx-level-max"; }
+ else if (name === "rxavg") { return "performance-data.rx-level-avg"; }
+ else if (name === "txmin") { return "performance-data.tx-level-min"; }
+ else if (name === "txmax") { return "performance-data.tx-level-max"; }
+ else if (name === "txavg") { return "performance-data.tx-level-avg"; }
+ else if (name === "Tx BytesMaxS") { return "performance-data.tx-ethernet-bytes-max-s"; }
+ else if (name === "Tx BytesMaxM") { return "performance-data.tx-ethernet-bytes-max-m"; }
+ else if (name === "Tx BytesSum") { return "performance-data.tx-ethernet-bytes-sum"; }
+ else if (name === "xpdMin") { return "performance-data.xpd-min"; }
+ else if (name === "xpdAvg") { return "performance-data.xpd-avg"; }
+ else if (name === "xpdMax") { return "performance-data.xpd-max"; }
+ else if (name === "snirMin") { return "performance-data.snir-min"; }
+ else if (name === "snirAvg") { return "performance-data.snir-avg"; }
+ else if (name === "snirMax") { return "performance-data.snir-max"; }
+ else if (name === "rfTempMin") { return "performance-data.rf-temp-min"; }
+ else if (name === "rfTempAvg") { return "performance-data.rf-temp-avg"; }
+ else if (name === "rfTempMax") { return "performance-data.rf-temp-max"; }
+ else if (name === "time2S") { return "performance-data.time2-states-s"; }
+ else if (name === "time2") { return "performance-data.time2-states"; }
+ else if (name === "time2L") { return "performance-data.time2-states-l"; }
+ else if (name === "time4S") { return "performance-data.time4-states-s"; }
+ else if (name === "time4") { return "performance-data.time4-states"; }
+ else if (name === "time4L") { return "performance-data.time4-states-l"; }
+ else if (name === "time16S") { return "performance-data.time16-states-s"; }
+ else if (name === "time16") { return "performance-data.time16-states"; }
+ else if (name === "time16L") { return "performance-data.time16-states-l"; }
+ else if (name === "time32S") { return "performance-data.time32-states-s"; }
+ else if (name === "time32") { return "performance-data.time32-states"; }
+ else if (name === "time32L") { return "performance-data.time32-states-l"; }
+ else if (name === "time64S") { return "performance-data.time64-states-s"; }
+ else if (name === "time64") { return "performance-data.time64-states"; }
+ else if (name === "time64L") { return "performance-data.time64-states-l"; }
+ else if (name === "time128S") { return "performance-data.time128-states-s"; }
+ else if (name === "time128") { return "performance-data.time128-states"; }
+ else if (name === "time128L") { return "performance-data.time128-states-l"; }
+ else if (name === "time256S") { return "performance-data.time256-states-s"; }
+ else if (name === "time256") { return "performance-data.time256-states"; }
+ else if (name === "time256L") { return "performance-data.time256-states-l"; }
+ else if (name === "time512S") { return "performance-data.time512-states-s"; }
+ else if (name === "time512") { return "performance-data.time512-states"; }
+ else if (name === "time512L") { return "performance-data.time512-states-l"; }
+ else if (name === "time1024S") { return "performance-data.time1024-states-s"; }
+ else if (name === "time1024") { return "performance-data.time1024-states"; }
+ else if (name === "time1024L") { return "performance-data.time1024-states-l"; }
+ else if (name === "time2048S") { return "performance-data.time2048-states-s"; }
+ else if (name === "time2048") { return "performance-data.time2048-states"; }
+ else if (name === "time2048L") { return "performance-data.time2048-states-l"; }
+ else if (name === "time4096S") { return "performance-data.time4096-states-s"; }
+ else if (name === "time4096") { return "performance-data.time4096-states"; }
+ else if (name === "time4096L") { return "performance-data.time4096-states-l"; }
+ else if (name === "time8192S") { return "performance-data.time8192-states-s"; }
+ else if (name === "time8192") { return "performance-data.time8192-states"; }
+ else if (name === "time8192L") { return "performance-data.time8192-states-l"; }
+
+
+ };
+
+ var checkData = function (value) {
+ if (value === -1 || value === undefined) return undefined;
+ else return value;
+ };
+
+ var getPage = function (grid) {
+
+ //from, how many, sort, filter
+ getData($scope.state.lastSort, $scope.state.lastfilter, grid, null, null)
+ .then(function (data) {
+
+ processRequestInGrid(data, grid);
+ });
+ };
+
+ var processRequestInGrid = function (response, grid) {
+ // console.log(grid.data);
+ switch (grid.data) {
+ case "performance826":
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ es: checkData(entry._source['performance-data'].es),
+ ses: checkData(entry._source['performance-data'].ses),
+ uas: checkData(entry._source['performance-data'].unavailability),
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.performance826 = list;
+ $scope.gridOptionsPerformance826.totalItems = response.data.hits.total;
+ break;
+ case "transmissionLevel":
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ txmin: checkData(entry._source['performance-data']['tx-level-min']),
+ txavg: checkData(entry._source['performance-data']['tx-level-avg']),
+ txmax: checkData(entry._source['performance-data']['tx-level-max']),
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.transmissionLevel = list;
+ $scope.gridOptionsTransmissionLevel.totalItems = response.data.hits.total;
+
+ break;
+ case "receiveLevel":
+
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rxmin: checkData(entry._source['performance-data']['rx-level-min']),
+ rxavg: checkData(entry._source['performance-data']['rx-level-avg']),
+ rxmax: checkData(entry._source['performance-data']['rx-level-max']),
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.receiveLevel = list;
+ $scope.gridOptionsReceiveLevel.totalItems = response.data.hits.total;
+
+ break;
+ case "modulation":
+
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ time2S: checkData(entry._source['performance-data']['time2-states-s']),
+ time2: checkData(entry._source['performance-data']['time2-states']),
+ time2L: checkData(entry._source['performance-data']['time2-states-l']),
+ time4S: checkData(entry._source['performance-data']['time4-states-s']),
+ time4: checkData(entry._source['performance-data']['time4-states']),
+ time4L: checkData(entry._source['performance-data']['time4-states-l']),
+ time16S: checkData(entry._source['performance-data']['time16-states-s']),
+ time16: checkData(entry._source['performance-data']['time16-states']),
+ time16L: checkData(entry._source['performance-data']['time16-states-l']),
+ time32S: checkData(entry._source['performance-data']['time32-states-s']),
+ time32: checkData(entry._source['performance-data']['time32-states']),
+ time32L: checkData(entry._source['performance-data']['time32-states-l']),
+ time64S: checkData(entry._source['performance-data']['time64-states-s']),
+ time64: checkData(entry._source['performance-data']['time64-states']),
+ time64L: checkData(entry._source['performance-data']['time64-states-l']),
+ time128S: checkData(entry._source['performance-data']['time128-states-s']),
+ time128: checkData(entry._source['performance-data']['time128-states']),
+ time128L: checkData(entry._source['performance-data']['time128-states-l']),
+ time256S: checkData(entry._source['performance-data']['time256-states-s']),
+ time256: checkData(entry._source['performance-data']['time256-states']),
+ time256L: checkData(entry._source['performance-data']['time256-states-l']),
+ time512S: checkData(entry._source['performance-data']['time512-states-s']),
+ time512: checkData(entry._source['performance-data']['time512-states']),
+ time512L: checkData(entry._source['performance-data']['time512-states-l']),
+ time1024S: checkData(entry._source['performance-data']['time1024-states-s']),
+ time1024: checkData(entry._source['performance-data']['time1024-states']),
+ time1024L: checkData(entry._source['performance-data']['time1024-states-l']),
+ time2048S: checkData(entry._source['performance-data']['time2048-states-s']),
+ time2048: checkData(entry._source['performance-data']['time2048-states']),
+ time2048L: checkData(entry._source['performance-data']['time2048-states-l']),
+ time4096S: checkData(entry._source['performance-data']['time4096-states-s']),
+ time4096: checkData(entry._source['performance-data']['time4096-states']),
+ time4096L: checkData(entry._source['performance-data']['time4096-states-l']),
+ time8192S: checkData(entry._source['performance-data']['time8192-states-s']),
+ time8192: checkData(entry._source['performance-data']['time8192-states']),
+ time8192L: checkData(entry._source['performance-data']['time8192-states-l']),
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.modulation = list;
+ $scope.gridOptionsModulation.totalItems = response.data.hits.total;
+
+ break;
+
+ case "temperature":
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rfTempMin: entry._source['performance-data']['rf-temp-min'],
+ rfTempAvg: entry._source['performance-data']['rf-temp-avg'],
+ rfTempMax: entry._source['performance-data']['rf-temp-max'],
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.temperature = list;
+ $scope.gridOptionsTemperature.totalItems = response.data.hits.total;
+
+ break;
+
+ case "snir":
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ snirMin: entry._source['performance-data']['snir-min'],
+ snirAvg: entry._source['performance-data']['snir-avg'],
+ snirMax: entry._source['performance-data']['snir-max'],
+ radiosignal: entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+ $scope.snir = list;
+ $scope.gridOptionsSnir.totalItems = response.data.hits.total;
+
+ break;
+
+ case "crossPolarDiscrimination":
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ xpdMin: entry._source['performance-data']['xpd-min'],
+ xpdAvg: entry._source['performance-data']['xpd-avg'],
+ xpdMax: entry._source['performance-data']['xpd-max'],
+ radiosignal: entry._source['radio-signal-id']
+
+ };
+
+ list.push(item);
+
+ });
+ $scope.crossPolarDiscrimination = list;
+ $scope.gridOptionsCrossPolarDiscrimination.totalItems = response.data.hits.total;
+
+ break;
+
+
+ case "performanceEthernetContainer":
+
+ var list = [];
+
+ response.data.hits.hits.map(function (entry) {
+ var item = {
+ timestamp: $mwtnPerformanceHistory.formatTimeStamp(entry._source['time-stamp']),
+ id: $scope.onfNetworkElement.getLpById(entry._source['uuid-interface']).getLabel() || entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ period: entry._source['granularity-period'],
+ txEthernetBytesMaxS: checkData(entry._source['performance-data']['tx-ethernet-bytes-max-s']),
+ txEthernetBytesMaxM: checkData(entry._source['performance-data']['tx-ethernet-bytes-max-m']),
+ txEthernetBytesSum: checkData(entry._source['performance-data']['tx-ethernet-bytes-sum'])
+
+ };
+
+ list.push(item);
+
+ });
+ $scope.performanceEthernetContainer = list;
+ $scope.gridOptionsPerformanceEthernetContainer.totalItems = response.data.hits.total;
+
+ break;
+ }
+ };
+
+ var getData = function (sort, query, grid, currFilter, currSort) {
+
+ // console.log(grid);
+ var pagesize;
+ var pagenr;
+
+ switch (grid.data) { //get pagesize / nr according to current grid (else everything gets messy => wana get next page in grid a, get next page for grid b too)
+ case 'performance826':
+ pagesize = $scope.gridOptionsPerformance826.paginationPageSize;
+ pagenr = $scope.gridOptionsPerformance826.paginationCurrentPage;
+ break;
+
+ case 'receiveLevel':
+ pagesize = $scope.gridOptionsReceiveLevel.paginationPageSize;
+ pagenr = $scope.gridOptionsReceiveLevel.paginationCurrentPage;
+ break;
+
+ case 'transmissionLevel':
+ pagesize = $scope.gridOptionsTransmissionLevel.paginationPageSize;
+ pagenr = $scope.gridOptionsTransmissionLevel.paginationCurrentPage;
+ break;
+
+ case 'modulation':
+ pagesize = $scope.gridOptionsModulation.paginationPageSize;
+ pagenr = $scope.gridOptionsModulation.paginationCurrentPage;
+ break;
+
+ case 'temperature':
+ pagesize = $scope.gridOptionsTemperature.paginationPageSize;
+ pagenr = $scope.gridOptionsTemperature.paginationCurrentPage;
+ break;
+
+ case 'snir':
+ pagesize = $scope.gridOptionsSnir.paginationPageSize;
+ pagenr = $scope.gridOptionsSnir.paginationCurrentPage;
+ break;
+
+ case 'crossPolarDiscrimination':
+ pagesize = $scope.gridOptionsCrossPolarDiscrimination.paginationPageSize;
+ pagenr = $scope.gridOptionsCrossPolarDiscrimination.paginationCurrentPage;
+ break;
+
+ case 'performanceEthernetContainer':
+ pagesize = $scope.gridOptionsPerformanceEthernetContainer.paginationPageSize;
+ pagenr = $scope.gridOptionsPerformanceEthernetContainer.paginationCurrentPage;
+ break;
+
+ default:
+ $mwtnLog.warning({component: COMPONENT, message: ['Unexpected grid.data', grid.data, '!'].join(' ')});
+ }
+
+ if (grid !== undefined) {
+
+ if ($scope.state.grid === null || $scope.state.grid === undefined) {
+ $scope.state.grid = grid.data;
+ }
+
+ //check, if sort/filter params are for current grid
+ if ($scope.state.grid !== grid.data) {
+ $scope.state.sort = false;
+ $scope.state.lastSort = null;
+ $scope.state.filter = false;
+ $scope.state.lastfilter = null;
+ if (currSort !== null) {
+ sort = currSort;
+ } else {
+ sort = null;
+ }
+
+ if (currFilter !== null) {
+ query = currFilter;
+ } else {
+ query = null;
+ }
+
+ //update current grid
+ $scope.state.grid = grid.data;
+ }
+ }
+
+ if (!sort) { //default sort value
+ sort = [{ 'time-stamp': { order: 'desc' } }];
+ //sort=[];
+ }
+ if (!query) { //default filter value
+ query = { query: { bool: { must: [{ prefix: globalFilter }] } } };
+ }
+
+ //add layer protocol selector to filter query
+ var localQuery = angular.copy(query); //copy the object for adding layerprotocol locally
+ var lpn = $scope.layerProtocol;
+ if (lpn === 'ETC' && $scope.revision.contains('2016')) lpn = 'ETH-CTP';
+ localQuery.query.bool.must.push({ prefix: { "layer-protocol-name": lpn } });
+
+ //add interface selector to filter query
+ if ($scope.selecteditem.selectedLtpId) {
+ localQuery.query.bool.must.push({ prefix: { "uuid-interface": $scope.selecteditem.selectedLtpId } });
+ }
+
+ var selected15minPeriod = true;
+ if ($scope.selecteditem.timePeriod !== $scope.timePeriods[0]) selected15minPeriod = false;
+ console.warn('selected15minPeriod', selected15minPeriod);
+ return $mwtnPerformanceHistory.getFilteredSortedData((pagenr - 1) * pagesize, pagesize, sort, localQuery, selected15minPeriod);
+ };
+
+ /**
+ * function to calculate the current open tab
+ * @param status - Object of current tab opening information
+ * @param previousStatus - optional Object of previous tab opening information
+ * @return latest opened tab key or undefined, in case none is currently open
+ */
+ var getKey = function(status, previousStatus) {
+ var result = Object.keys(status).filter(function(key){
+ return status[key] === true && !(previousStatus && previousStatus[key])
+ });
+ if (result.length > 0) {
+ return result[0];
+ }
+ }
+
+ // events
+ $scope.status = { performance826: true, performanceEthernetContainer: false };
+ $scope.spinner = {};
+
+ $scope.$watch(function() {
+ return $scope.selecteditem;
+ }, function (newValue, oldValue) {
+ console.warn('selecteditem###', newValue, oldValue, $scope.networkElementId );
+
+ if (newValue.selectedLtpId && newValue.selectedLtpId !== oldValue.selectedLtpId && $scope.onfNetworkElement) {
+ $scope.layerProtocol = $scope.onfNetworkElement.getLpById(newValue.selectedLtpId).getLayer();
+
+ $scope.performance826 = [];
+ $scope.receiveLevel = [];
+ $scope.transmissionLevel = [];
+ $scope.modulation = [];
+ $scope.temperature = [];
+ $scope.performanceEthernetContainer = [];
+ $scope.snir = [];
+ $scope.crossPolarDiscrimination = [];
+ $scope.jsonvalue = [];
+
+ // if all tabs are closed - open first.
+ var isOneTabOpen = Object.keys($scope.status).filter(function(key){
+ return $scope.status[key] === true;
+ }).length > 0;
+ if (!isOneTabOpen) {
+ $scope.status = { performance826: $scope.layerProtocol === 'MWPS', performanceEthernetContainer: $scope.layerProtocol === 'ETC' };
+ }
+ }
+
+ chooseGrid(getKey($scope.status));
+
+ }, true);
+
+
+ $scope.$watch('status', function (status, oldValue) {
+ console.warn('status', status, oldValue,$scope.networkElementId );
+ if ($scope.networkElementId && status && status !== oldValue) {
+ chooseGrid(getKey(status, oldValue));
+ }
+ }, true);
+
+
+ // $scope.$watch(function(){
+ // $scope.selecteditem.timePeriod;
+ // }, function (newValue, oldValue) {
+ // console.warn('timePeriod', status, oldValue,$scope.networkElementId );
+ // if (newValue && oldValue !== "" && newValue !== oldValue) {
+ // chooseGrid(getKey($scope.status));
+ // }
+ // }, true);
+
+ $scope.collapseAll = function () {
+ // close all groups
+ Object.keys($scope.status).map(function (group) {
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function (group) {
+ $scope.spinner[group] = false;
+ });
+ };
+
+ var order = $mwtnPerformanceHistory.layerProtocolNameOrder;
+
+ /**
+ * @function updateNe
+ * A function, which updates onfNetworkElement by new data.
+ * @param {*} data New data recieved from OpenDaylight via RestConf
+ */
+ var updateNe = function(data) {
+ if (!data) return;
+ // update onfNetworkElement
+ switch ($scope.revision) {
+ case '2016-08-09':
+ case '2016-08-11':
+ case '2016-09-01':
+ case '2017-02-17':
+ case '2017-03-20':
+ case '2017-03-24':
+ // console.log(JSON.stringify(data));
+ $scope.onfNetworkElement = new OnfNetworkElement(data['network-element']);
+ $scope.onfLtps = $scope.onfNetworkElement.getLogicalTerminationPoints().filter(function(ltp){
+ return ltp.getLayer() === 'MWPS' || ltp.getLayer() === 'ETC';
+ }).sort(function(a, b){
+ if(order[a.getLayer()] < order[b.getLayer()]) return 1;
+ if(order[a.getLayer()] > order[b.getLayer()]) return -1;
+ if(a.getId() < b.getId()) return -1;
+ if(a.getId() > b.getId()) return 1;
+ return 0;
+ });
+ $scope.availableLtpIds = $scope.onfLtps.map(function(ltp){
+ return {key: ltp.getLayerProtocols()[0].getId(), label:ltp.getLabel()};
+ });
+ if ($scope.availableLtpIds.length > 0) {
+ $scope.selecteditem.selectedLtpId = $scope.availableLtpIds[0].key;
+ }
+ break;
+ default:
+ $mwtnLog.info({component: COMPONENT, message: ['The ONF Microwave Model revision', $scope.revision, ' is not supported (yet)!'].join(' ')});
+ $scope.onfNetworkElement = {};
+ $scope.onfLtps = {};
+ }
+ };
+
+ var updatePart = function(spec, data) {
+ switch (spec.pacId) {
+ case 'ne':
+ updateNe(data);
+ break;
+ }
+ };
+
+ //get data on ne selection
+ $scope.$watch('networkElement', function (neId, oldValue) {
+ console.warn('networkElement', neId, oldValue,$scope.networkElementId );
+
+ if (neId && neId !== '' && neId !== oldValue) {
+ $scope.selecteditem.selectedLtpId = undefined;
+ var revision;
+ $scope.networkElements.map(function (ne) {
+ if (ne.id === neId) revision = ne.revision;
+ });
+ $scope.networkElementId = neId;
+ $scope.revision = revision;
+
+ //get data
+ var filter = { "query": { "bool": { "must": [{ "prefix": { "node-name": $scope.networkElementId } }] } } };
+ // var filter={"query":{"bool":{"must":[{"prefix":{"node-name": "new"}}]}}}; //first part of my local simulator name
+ globalFilter = filter.query.bool.must[0].prefix;
+ $scope.state.filter = true;
+ $scope.state.lastfilter = filter;
+ $scope.state.sort = false;
+ $scope.state.lastSort = null;
+
+ // get onf network element data
+ var spec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: 'ne'
+ };
+ console.warn('PM HIstory getPacPMHistory', JSON.stringify(spec));
+ $mwtnPerformanceHistory.getPacParts(spec).then(function(success){
+ $scope.collapseAll();
+ // console.warn('PM HIstory getPacPMHistory', JSON.stringify(success));
+ updatePart(spec, $mwtnPerformanceHistory.yangifyObject(success));
+ }, function(error){
+ console.error(JSON.stringify(error));
+ $scope.collapseAll();
+ updatePart(spec, error);
+ });
+ }
+ });
+
+ var chooseGrid = function (key) {
+ if (!$scope.networkElementId || !key) return;
+
+ switch (key) {
+
+ case 'performance826':
+ getData(null, null, $scope.gridOptionsPerformance826).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsPerformance826);
+ }
+ });
+ break;
+
+ case 'receiveLevel':
+ getData(null, null, $scope.gridOptionsReceiveLevel).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsReceiveLevel);
+ }
+ });
+ break;
+
+ case 'transmissionLevel':
+ getData(null, null, $scope.gridOptionsTransmissionLevel).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsTransmissionLevel);
+ }
+ });
+ break;
+
+ case 'modulation':
+ getData(null, null, $scope.gridOptionsModulation).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsModulation);
+ }
+ });
+ break;
+
+ case 'temperature':
+ getData(null, null, $scope.gridOptionsTemperature).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsTemperature);
+ }
+ });
+ break;
+
+ case 'snir':
+ getData(null, null, $scope.gridOptionsSnir).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsSnir);
+ }
+ });
+ break;
+
+ case 'crossPolarDiscrimination':
+ getData(null, null, $scope.gridOptionsCrossPolarDiscrimination).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsCrossPolarDiscrimination);
+ }
+ });
+ break;
+
+ case 'performanceEthernetContainer':
+ getData(null, null, $scope.gridOptionsPerformanceEthernetContainer).then(function (response) {
+ if (response.data.hits.hits) {
+ processRequestInGrid(response, $scope.gridOptionsPerformanceEthernetContainer);
+ }
+ });
+ break;
+ }
+ $window.dispatchEvent(new Event("resize"));
+ };
+ }]);
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.module.js
new file mode 100644
index 00000000..4199ae62
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.module.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnPerformanceHistoryApp = angular.module('app.mwtnPerformanceHistory', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'ui.router.state','ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.pagination']);
+
+ mwtnPerformanceHistoryApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnPerformanceHistoryApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnPerformanceHistory/mwtnPerformanceHistory.controller');
+ NavHelperProvider.addToMenu('mwtnPerformanceHistory', {
+ "link" : "#/pnfPerformanceHistory/",
+ "active" : "main.mwtnPerformanceHistory",
+ "title" : "pnf PM History",
+ "icon" : "fa fa-bar-chart", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf PM History",
+ "description" : "mwtnHistoricalPerformance"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnPerformanceHistory', {
+ url: 'pnfPerformanceHistory/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnPerformanceHistory/mwtnPerformanceHistory.tpl.html',
+ controller: 'mwtnPerformanceHistoryCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnPerformanceHistoryApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.services.js
new file mode 100644
index 00000000..94aeb935
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.services.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 HCL Inc. 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/mwtnPerformanceHistory/mwtnPerformanceHistory.module'], function (mwtnPerformanceHistoryoryApp) {
+
+ mwtnPerformanceHistoryoryApp.register.factory('$mwtnPerformanceHistory', function ($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnPerformanceHistory';
+ $mwtnLog.info({ component: COMPONENT, message: '$mwtnPerformanceHistory started!' });
+
+ var service = {};
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.layerProtocolNameOrder = $mwtnCommons.layerProtocolNameOrder;
+
+ service.yangifyObject = $mwtnCommons.yangifyObject;
+
+ service.TimeStampToONFFormat = function (timestamp) {
+ timestamp = timestamp.split('-').join('');
+ timestamp = timestamp.split(':').join('');
+ timestamp = timestamp.split(' ').join('');
+ timestamp = timestamp.replace('UTC', 'Z');
+ return timestamp;
+ };
+
+ service.getFilteredSortedData = function (from, size, sort, query, selected15minPeriod) {
+ var func = function () {
+ if (selected15minPeriod) {
+ return $mwtnDatabase.getFilteredSortedData('sdnperformance', 'historicalperformance15min', from, size, sort, query);
+ } else {
+ return $mwtnDatabase.getFilteredSortedData('sdnperformance', 'historicalperformance24h', from, size, sort, query);
+ }
+ };
+ var deferred = $q.defer();
+ func().then(function (success) {
+ deferred.resolve(success);
+ }, function (error) {
+ $mwtnLog.error({ component: '$mwtnHistPerformance.getFilteredSortedData', message: JSON.stringify(error.data) });
+ deferred.reject(error)
+ });
+ return deferred.promise;
+
+ };
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.tpl.html
new file mode 100644
index 00000000..bb5f6e46
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/mwtnPerformanceHistory-module/src/main/resources/mwtnPerformanceHistory/mwtnPerformanceHistory.tpl.html
@@ -0,0 +1,127 @@
+<ht-header help-link='sdnr/pnfPerformance/0.4.0/README.md'></ht-header>
+<mwtn-select-network-element></mwtn-select-network-element>
+
+<div class="owl container" ng-if="networkElements.lenght !== 0 && networkElement" style="width: 100%">
+
+ <div class="row" ng-show="networkElements.lenght !== 0">
+ <div class="col-md-3">
+ <div class="form-group">
+ <select class="form-control" ng-model="selecteditem.selectedLtpId">
+ <option ng-repeat="ltp in availableLtpIds" value="{{ltp.key}}">{{ltp.label}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="col-md-3">
+ <span class="white">{{'MWTN_SELECT_LTP' | translate }}</span>
+ </div>
+ <div class="col-md-2">
+ <div class="form-group">
+ <select class="form-control" ng-model="selecteditem.timePeriod">
+ <option ng-repeat="time in timePeriods">{{time}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="col-md-2">
+ <span class="white">{{'MWTN_TIME_PERIOD' | translate}}</span>
+ </div>
+ </div>
+
+ <div class="row" ng-show="selecteditem.selectedLtpId">
+ <div class="col-md-12">
+ <uib-accordion close-others="true">
+ <div uib-accordion-group class="panel-primary" is-open="status.performance826" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.performance826, 'fa-chevron-right': !status.performance826}"></i>
+ <span>Performance Data G.826</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.performance826"></i>
+ </uib-accordion-heading>
+
+ <div id="mwtnFaultGridAlarmLog" ui-grid="gridOptionsPerformance826" ui-grid-pagination ui-grid-exporter ui-grid-selection
+ ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.receiveLevel" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.receiveLevel, 'fa-chevron-right': !status.receiveLevel}"></i>
+ <span>Receive Level</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.receiveLevel"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsReceiveLevel" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.transmissionLevel" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.transmissionLevel, 'fa-chevron-right': !status.transmissionLevel}"></i>
+ <span>Transmission Power</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.transmissionLevel"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsTransmissionLevel" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.modulation" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.modulation, 'fa-chevron-right': !status.modulation}"></i>
+ <span>Adaptive Modulation</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.modulation"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsModulation" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.temperature" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.temperature, 'fa-chevron-right': !status.temperature}"></i>
+ <span>Temperature</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.temperature"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsTemperature" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.snir" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.snir, 'fa-chevron-right': !status.snir}"></i>
+ <span>{{'MWTN_SINR' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.snir"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsSnir" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+ <div uib-accordion-group class="panel-primary" is-open="status.crossPolarDiscrimination" ng-show="layerProtocol==='MWPS'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.crossPolarDiscrimination, 'fa-chevron-right': !status.crossPolarDiscrimination}"></i>
+ <span>Cross Polar Discrimination</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.crossPolarDiscrimination"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsCrossPolarDiscrimination" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.performanceEthernetContainer" ng-show="layerProtocol==='ETC'">
+ <uib-accordion-heading> <i class="pull-left fa" ng-class="{'fa-chevron-down': status.performanceEthernetContainer, 'fa-chevron-right': !status.performanceEthernetContainer}"></i>
+ <span>Performance Data</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.performanceEthernetContainer"></i>
+ </uib-accordion-heading>
+
+ <div ui-grid="gridOptionsPerformanceEthernetContainer" ui-grid-pagination ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns
+ ui-grid-auto-resize ui-grid-move-columns class="mwtnHistoryGrid">
+ </div>
+ </div>
+
+ </uib-accordion>
+ </div>
+ </div>
+</div>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/pom.xml
new file mode 100644
index 00000000..2d6ced8c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceHistory/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceHistory</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnPerformanceHistory-module</module>
+ <module>mwtnPerformanceHistory-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/pom.xml
new file mode 100644
index 00000000..ebc28975
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceLink</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceLink-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceLink-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnPerformanceLink-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..0f87a770
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnPerformanceLink"/>
+ <property name="url" value="/src/app/mwtnPerformanceLink"/>
+ <property name="directory" value="/mwtnPerformanceLink"/>
+ <property name="requireJs" value="app/mwtnPerformanceLink/mwtnPerformanceLink.module"/>
+ <property name="angularJs" value="app.mwtnPerformanceLink"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnPerformanceLink/mwtnPerformanceLink-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/pom.xml
new file mode 100644
index 00000000..7be5f5f2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnPerformanceLink</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnPerformanceLink-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/images/mwtnPerformance.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/images/mwtnPerformance.png
new file mode 100755
index 00000000..5517f5b1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/images/mwtnPerformance.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink-custom.css
new file mode 100644
index 00000000..eafc20b5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink-custom.css
@@ -0,0 +1,17 @@
+/**
+ * Add your application related css here
+ */
+
+.mwtnLinkGrid {
+ height: 600px;
+ background-color: white;
+ color:black;
+}
+
+.mwtnLinkGrid span {
+ color: #393939;
+}
+
+.ht-pagination span{
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.controller.js
new file mode 100644
index 00000000..bb3ac9c2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.controller.js
@@ -0,0 +1,3346 @@
+/*
+ * 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/mwtnPerformanceLink/mwtnPerformanceLink.module',
+ 'app/mwtnPerformanceLink/mwtnPerformanceLink.services'],
+ function (mwtnPerformanceLinkApp) {
+
+ mwtnPerformanceLinkApp.register.controller('mwtnPerformanceLinkCtrl', ['$scope', '$rootScope', '$window', '$translate', '$mwtnLog', '$mwtnPerformanceLink', 'uiGridConstants',
+ function ($scope, $rootScope, $window, $translate, $mwtnLog, $mwtnPerformanceLink, uiGridConstants) {
+
+ var COMPONENT = 'mwtnPerformanceLink';
+ $mwtnLog.info({ component: COMPONENT, message: 'mwtn Link Performance started!' });
+
+ $rootScope.section_logo = 'src/app/mwtnPerformanceLink/images/mwtnPerformance.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var globalFilter;
+
+ //time selector
+ $scope.timePeriod = "15 minutes";
+ $scope.timePeriods = ["15 minutes", "24 hours"];
+
+ //interface selector
+ $scope.selectedLtpIdA = 'Select LTP';
+ $scope.selectedLtpIdB = 'Select LTP';
+ $scope.availableLtpIdsA = ['Select LTP'];
+ $scope.availableLtpIdsB = ['Select LTP'];
+
+ var formatTimeStamp = function(timeStamp) {
+ var result = $mwtnPerformanceLink.formatTimeStamp(timeStamp);
+ // 2017-06-22 14:52:21.0 UTC -> 2017-06-22 14:52 UTC
+ var array = result.split(' ');
+ if (array && array.length === 3) {
+ result = [array[0], array[1].slice(0,-5), array[2]].join(' ');
+ }
+ return result;
+ };
+
+ var initNodeList = function (nodes) {
+ $scope.networkElements = [];
+ nodes.map(function (ne) {
+ // revision detection should go to commons
+ if (ne['netconf-node-topology:connection-status'] === 'connected' && ne['netconf-node-topology:available-capabilities'] && ne['netconf-node-topology:available-capabilities']['available-capability']) {
+ ne['netconf-node-topology:available-capabilities']['available-capability'].map(function (cap) {
+ if (cap.contains('CoreModel-CoreNetworkModule-ObjectClasses')) {
+ ne.onfCoreModelRevision = cap.split('?revision=')[1].substring(0, 10);
+ } else if (cap.contains('MicrowaveModel-ObjectClasses-AirInterface')) {
+ ne.onfAirInterfaceRevision = cap.split('?revision=')[1].substring(0, 10);
+ } else if (!ne.onfAirInterfaceRevision && cap.contains('MicrowaveModel-ObjectClasses')) {
+ ne.onfAirInterfaceRevision = cap.split('?revision=')[1].substring(0, 10);
+ }
+ });
+ if (ne.onfAirInterfaceRevision) {
+ $scope.networkElements.push({ id: ne['node-id'], revision: ne.onfAirInterfaceRevision });
+ }
+ }
+ });
+ $scope.networkElements.sort(function (a, b) {
+ if (a.id < b.id) return -1;
+ if (a.id > b.id) return 1;
+ return 0;
+ });
+
+ // select one of the nodes
+ // var select = parseInt(Math.random() * $scope.networkElements.length);
+ // $scope.networkElementA = $scope.networkElements[select].id;
+ // $scope.networkElementB = $scope.networkElements[select].id;
+ };
+
+ var initLinkIds = function () {
+ var functionId = 'sdnperformance';
+ var docType = 'historicalperformance15min';
+ if ($scope.timePeriod !== $scope.timePeriods[0]) {
+ docType = 'historicalperformance24h';
+ }
+ var aggregations = {
+ "size":0,
+ "aggregations": {
+ "radio-signal-id": {
+ "terms": {
+ "field": "radio-signal-id"
+ }
+ }
+ }
+ };
+ $mwtnPerformanceLink.getAggregations(functionId, docType, aggregations).then(function (success) {
+ $scope.linkIds = success.data.aggregations['radio-signal-id'].buckets.map(function(bucket){
+ return bucket.key;
+ });
+ }, function (error) {
+ console.log(error);
+ $scope.linkIds = [];
+ });
+ };
+
+ $mwtnPerformanceLink.getMountPoints().then(function (mountpoints) {
+ initNodeList(mountpoints);
+ initLinkIds();
+ }, function (error) {
+ $scope.networkElements = [];
+ });
+
+ //table stuff
+
+ //data visible on screen
+ $scope.performance826 = [];
+ $scope.receiveLevel = [];
+ $scope.transmissionLevel = [];
+ $scope.modulation = [];
+ $scope.temperature = [];
+ $scope.snir = [];
+ $scope.crossPolarDiscrimination = [];
+
+ $scope.paginationOptions = {
+ pageNumber: 1,
+ pageSize: 2,
+ sort: null
+ };
+
+ //page sizes, based on time period
+ $scope.pageSizes = function () {
+ var arr;
+ if ($scope.timePeriod && $scope.timePeriod === "15 minutes") {
+
+ arr = [96, (96 * 2), (96 * 7)];
+
+ } else {
+ arr = [7, 30, (30 * 3), (30 * 6), (30 * 12)];
+ }
+ return arr;
+ };
+
+ //init page sizes
+ $scope.selectPageSize = function () {
+
+ if ($scope.timePeriod && $scope.timePeriod === "15 minutes") {
+
+ return 96;
+
+ } else {
+ return 7;
+ }
+
+ };
+
+ $scope.itemsMessage = function () {
+ if ($scope.timePeriod && $scope.timePeriod === "15 minutes") {
+ return "15 minutes items per page";
+ } else {
+ return "24 hours items per page";
+ }
+ };
+
+
+ $scope.paginationStatusMessage = function (grid) {
+ if (grid === 'receiveLevel') {
+ let start = ($scope.gridOptionsReceiveLevel.paginationCurrentPage - 1) * $scope.gridOptionsReceiveLevel.paginationPageSize + 1;
+ let end = ($scope.gridOptionsReceiveLevel.paginationCurrentPage - 1) * $scope.gridOptionsReceiveLevel.paginationPageSize + 1 + $scope.receiveLevel.length - 1;
+ let total = $scope.gridOptionsReceiveLevel.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+ }
+ else if (grid === 'transmissionLevel') {
+ let start = ($scope.gridOptionsTransmissionLevel.paginationCurrentPage - 1) * $scope.gridOptionsTransmissionLevel.paginationPageSize + 1;
+ let end = ($scope.gridOptionsTransmissionLevel.paginationCurrentPage - 1) * $scope.gridOptionsTransmissionLevel.paginationPageSize + 1 + $scope.transmissionLevel.length - 1;
+ let total = $scope.gridOptionsTransmissionLevel.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+ }
+ else if (grid === 'modulation') {
+ let start = ($scope.gridOptionsModulation.paginationCurrentPage - 1) * $scope.gridOptionsModulation.paginationPageSize + 1;
+ let end = ($scope.gridOptionsModulation.paginationCurrentPage - 1) * $scope.gridOptionsModulation.paginationPageSize + 1 + $scope.modulation.length - 1;
+ let total = $scope.gridOptionsModulation.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+
+ } else if (grid === 'temperature') {
+ let start = ($scope.gridOptionsTemperature.paginationCurrentPage - 1) * $scope.gridOptionsTemperature.paginationPageSize + 1;
+ let end = ($scope.gridOptionsTemperature.paginationCurrentPage - 1) * $scope.gridOptionsTemperature.paginationPageSize + 1 + $scope.temperature.length - 1;
+ let total = $scope.gridOptionsTemperature.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+
+ } else if (grid === 'snir') {
+ let start = ($scope.gridOptionsSnir.paginationCurrentPage - 1) * $scope.gridOptionsSnir.paginationPageSize + 1;
+ let end = ($scope.gridOptionsSnir.paginationCurrentPage - 1) * $scope.gridOptionsSnir.paginationPageSize + 1 + $scope.snir.length - 1;
+ let total = $scope.gridOptionsSnir.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+
+ } else if (grid === 'crossPolarDiscrimination') {
+ let start = ($scope.gridOptionsCrossPolarDiscrimination.paginationCurrentPage - 1) * $scope.gridOptionsCrossPolarDiscrimination.paginationPageSize + 1;
+ let end = ($scope.gridOptionsCrossPolarDiscrimination.paginationCurrentPage - 1) * $scope.gridOptionsCrossPolarDiscrimination.paginationPageSize + 1 + $scope.crossPolarDiscrimination.length - 1;
+ let total = $scope.gridOptionsCrossPolarDiscrimination.totalItems;
+ let message = "Showing {0} to {1} of {2} items";
+ return message.format(start, end, total);
+ }
+ };
+
+ //seek page based on grid
+ $scope.seekPage = function (page, grid) {
+ if (!page) {
+ page = 1;
+ return;
+ }
+ switch (grid) {
+ case 'receiveLevel': $scope.recvGridApi.pagination.seek(parseInt(page));
+ break;
+
+ case 'transmissionLevel': $scope.transmissionGridApi.pagination.seek(parseInt(page));
+ break;
+
+ case 'modulation': $scope.gridApi.pagination.seek(parseInt(page));
+ break;
+
+ case 'temperature': $scope.gridTemperatureApi.pagination.seek(parseInt(page));
+ break;
+
+ case 'snir': $scope.gridSNIRApi.pagination.seek(parseInt(page));
+ break;
+
+ case 'crossPolarDiscrimination': $scope.gridXpdApi.pagination.seek(parseInt(page));
+ break;
+ }
+
+ };
+ //table configuration
+
+ //receive lvl configuration
+ $scope.gridOptionsReceiveLevel = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rxmina', type: 'string', displayName: 'Rx min A', width: 90 },
+ { field: 'rxavga', type: 'string', displayName: 'Rx avg A', width: 90 },
+ { field: 'rxmaxa', type: 'string', displayName: 'Rx max A', width: 90 },
+ { field: 'rxminb', type: 'string', displayName: 'Rx min B', width: 90 },
+ { field: 'rxavgb', type: 'string', displayName: 'Rx avg B', width: 90 },
+ { field: 'rxmaxb', type: 'string', displayName: 'Rx max B', width: 90 }
+ ],
+ data: 'receiveLevel',
+ onRegisterApi: function (gridApi) {
+ $scope.recvGridApi = gridApi;
+ $scope.recvGridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "receiveLevel");
+ });
+ }
+ };
+
+ $scope.gridOptionsTransmissionLevel = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'txmina', type: 'string', displayName: 'Tx min A', width: 90 },
+ { field: 'txavga', type: 'string', displayName: 'Tx avg A', width: 90 },
+ { field: 'txmaxa', type: 'string', displayName: 'Tx max A', width: 90 },
+ { field: 'txminb', type: 'string', displayName: 'Tx min B', width: 90 },
+ { field: 'txavgb', type: 'string', displayName: 'Tx avg B', width: 90 },
+ { field: 'txmaxb', type: 'string', displayName: 'Tx max B', width: 90 }
+ ],
+ data: 'transmissionLevel',
+ onRegisterApi: function (gridApi) {
+ $scope.transmissionGridApi = gridApi;
+ $scope.transmissionGridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "transmissionLevel");
+ });
+ }
+ };
+
+ $scope.gridOptionsModulation = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'time2Sa', type: 'string', displayName: 'QAM2S A', width: 90 },
+ { field: 'time2a', type: 'string', displayName: 'QAM2 A', width: 90 },
+ { field: 'time2La', type: 'string', displayName: 'QAM2L A', width: 90 },
+ { field: 'time4Sa', type: 'string', displayName: 'QAM4S A', width: 90 },
+ { field: 'time4a', type: 'string', displayName: 'QAM4 A', width: 90 },
+ { field: 'time4La', type: 'string', displayName: 'QAM4L A', width: 90 },
+ { field: 'time16Sa', type: 'string', displayName: 'QAM16S A', width: 90 },
+ { field: 'time16a', type: 'string', displayName: 'QAM16 A', width: 90 },
+ { field: 'time16La', type: 'string', displayName: 'QAM16L A', width: 90 },
+ { field: 'time32Sa', type: 'string', displayName: 'QAM32S A', width: 90 },
+ { field: 'time32a', type: 'string', displayName: 'QAM32 A', width: 90 },
+ { field: 'time32La', type: 'string', displayName: 'QAM32L A', width: 90 },
+ { field: 'time64Sa', type: 'string', displayName: 'QAM64S A', width: 90 },
+ { field: 'time64a', type: 'string', displayName: 'QAM64 A', width: 90 },
+ { field: 'time64La', type: 'string', displayName: 'QAM64L A', width: 90 },
+ { field: 'time128Sa', type: 'string', displayName: 'QAM128S A', width: 90 },
+ { field: 'time128a', type: 'string', displayName: 'QAM128 A', width: 90 },
+ { field: 'time128La', type: 'string', displayName: 'QAM128L A', width: 90 },
+ { field: 'time256Sa', type: 'string', displayName: 'QAM256S A', width: 90 },
+ { field: 'time256a', type: 'string', displayName: 'QAM256 A', width: 90 },
+ { field: 'time256La', type: 'string', displayName: 'QAM256L A', width: 90 },
+ { field: 'time512Sa', type: 'string', displayName: 'QAM512S A', width: 90 },
+ { field: 'time512a', type: 'string', displayName: 'QAM512 A', width: 90 },
+ { field: 'time512La', type: 'string', displayName: 'QAM512L A', width: 90 },
+ { field: 'time1024Sa', type: 'string', displayName: 'QAM1024S A', width: 90 },
+ { field: 'time1024a', type: 'string', displayName: 'QAM1024 A', width: 90 },
+ { field: 'time1024La', type: 'string', displayName: 'QAM1024L A', width: 90 },
+ { field: 'time2048Sa', type: 'string', displayName: 'QAM2048S A', width: 90 },
+ { field: 'time2048a', type: 'string', displayName: 'QAM2048 A', width: 90 },
+ { field: 'time2048La', type: 'string', displayName: 'QAM2048L A', width: 90 },
+ { field: 'time4096Sa', type: 'string', displayName: 'QAM4096S A', width: 90 },
+ { field: 'time4096a', type: 'string', displayName: 'QAM4096 A', width: 90 },
+ { field: 'time4096La', type: 'string', displayName: 'QAM4096L A', width: 90 },
+ { field: 'time8192Sa', type: 'string', displayName: 'QAM8192S A', width: 90 },
+ { field: 'time8192a', type: 'string', displayName: 'QAM8192 A', width: 90 },
+ { field: 'time8192La', type: 'string', displayName: 'QAM8192L A', width: 90 },
+
+ { field: 'time2Sb', type: 'string', displayName: 'QAM2S B', width: 90 },
+ { field: 'time2b', type: 'string', displayName: 'QAM2 B', width: 90 },
+ { field: 'time2Lb', type: 'string', displayName: 'QAM2L B', width: 90 },
+ { field: 'time4Sb', type: 'string', displayName: 'QAM4S B', width: 90 },
+ { field: 'time4b', type: 'string', displayName: 'QAM4 B', width: 90 },
+ { field: 'time4Lb', type: 'string', displayName: 'QAM4L B', width: 90 },
+ { field: 'time16Sb', type: 'string', displayName: 'QAM16S B', width: 90 },
+ { field: 'time16b', type: 'string', displayName: 'QAM16 B', width: 90 },
+ { field: 'time16Lb', type: 'string', displayName: 'QAM16L B', width: 90 },
+ { field: 'time32Sb', type: 'string', displayName: 'QAM32S B', width: 90 },
+ { field: 'time32b', type: 'string', displayName: 'QAM32 B', width: 90 },
+ { field: 'time32Lb', type: 'string', displayName: 'QAM32L B', width: 90 },
+ { field: 'time64Sb', type: 'string', displayName: 'QAM64S B', width: 90 },
+ { field: 'time64b', type: 'string', displayName: 'QAM64 B', width: 90 },
+ { field: 'time64Lb', type: 'string', displayName: 'QAM64L B', width: 90 },
+ { field: 'time128Sb', type: 'string', displayName: 'QAM128S B', width: 90 },
+ { field: 'time128b', type: 'string', displayName: 'QAM128 B', width: 90 },
+ { field: 'time128Lb', type: 'string', displayName: 'QAM128L B', width: 90 },
+ { field: 'time256Sb', type: 'string', displayName: 'QAM256S B', width: 90 },
+ { field: 'time256b', type: 'string', displayName: 'QAM256 B', width: 90 },
+ { field: 'time256Lb', type: 'string', displayName: 'QAM256L B', width: 90 },
+ { field: 'time512Sb', type: 'string', displayName: 'QAM512S B', width: 90 },
+ { field: 'time512b', type: 'string', displayName: 'QAM512 B', width: 90 },
+ { field: 'time512Lb', type: 'string', displayName: 'QAM512L B', width: 90 },
+ { field: 'time1024Sb', type: 'string', displayName: 'QAM1024S B', width: 90 },
+ { field: 'time1024b', type: 'string', displayName: 'QAM1024 B', width: 90 },
+ { field: 'time1024Lb', type: 'string', displayName: 'QAM1024L B', width: 90 },
+ { field: 'time2048Sb', type: 'string', displayName: 'QAM2048S B', width: 90 },
+ { field: 'time2048b', type: 'string', displayName: 'QAM2048 B', width: 90 },
+ { field: 'time2048Lb', type: 'string', displayName: 'QAM2048L B', width: 90 },
+ { field: 'time4096Sb', type: 'string', displayName: 'QAM4096S B', width: 90 },
+ { field: 'time4096b', type: 'string', displayName: 'QAM4096 B', width: 90 },
+ { field: 'time4096Lb', type: 'string', displayName: 'QAM4096L B', width: 90 },
+ { field: 'time8192Sb', type: 'string', displayName: 'QAM8192S B', width: 90 },
+ { field: 'time8192b', type: 'string', displayName: 'QAM8192 B', width: 90 },
+ { field: 'time8192Lb', type: 'string', displayName: 'QAM8192L B', width: 90 }
+ ],
+ data: 'modulation',
+ onRegisterApi: function (gridApi) {
+ $scope.gridApi = gridApi;
+ $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "modulation");
+ });
+ }
+ };
+
+ $scope.gridOptionsTemperature = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'rfTempMina', type: 'string', displayName: 'Rf Temp Min A [&deg;C]', width: 90 },
+ { field: 'rfTempAvga', type: 'string', displayName: 'Rf Temp Avg A[&deg;C]', width: 90 },
+ { field: 'rfTempMaxa', type: 'string', displayName: 'Rf Temp Max A [&deg;C]', width: 90 },
+ { field: 'rfTempMinb', type: 'string', displayName: 'Rf Temp Min B [&deg;C]', width: 90 },
+ { field: 'rfTempAvgb', type: 'string', displayName: 'Rf Temp Avg B [&deg;C]', width: 90 },
+ { field: 'rfTempMaxb', type: 'string', displayName: 'Rf Temp Max B [&deg;C]', width: 90 }
+
+ ],
+ data: 'temperature',
+ onRegisterApi: function (gridApi) {
+ $scope.gridTemperatureApi = gridApi;
+ $scope.gridTemperatureApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "temperature");
+ });
+ }
+ };
+
+ $scope.gridOptionsSnir = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: 'Termination point', width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'snirMin', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MIN'), 'A', '[dB]'].join(' '), width: 90 },
+ { field: 'snirAvg', type: 'string', displayName: [$translate.instant('MWTN_SNIR_AVG'), 'A', '[dB]'].join(' '), width: 90 },
+ { field: 'snirMax', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MAX'), 'A', '[dB]'].join(' '), width: 90 },
+ { field: 'snirMin', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MIN'), 'B', '[dB]'].join(' '), width: 90 },
+ { field: 'snirAvg', type: 'string', displayName: [$translate.instant('MWTN_SNIR_AVG'), 'B', '[dB]'].join(' '), width: 90 },
+ { field: 'snirMax', type: 'string', displayName: [$translate.instant('MWTN_SNIR_MAX'), 'B', '[dB]'].join(' '), width: 90 }
+ ],
+ data: 'snir',
+ onRegisterApi: function (gridApi) {
+ $scope.gridSNIRApi = gridApi;
+ $scope.gridSNIRApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "snir");
+ });
+ }
+ };
+
+
+ $scope.gridOptionsCrossPolarDiscrimination = {
+ paginationPageSizes: $scope.pageSizes(),
+ paginationPageSize: $scope.selectPageSize(),
+ useExternalPagination: true,
+ enablePaginationControls: false,
+ enableFiltering: false,
+ enableSorting: false,
+ enableGridMenu: true,
+ columnDefs: [
+ { field: 'layerProtocol', type: 'string', displayName: 'Layer Protocol Name', width: 90, visible: false },
+ { field: 'id', type: 'string', displayName: $translate.instant('MWTN_LTP'), width: 200, visible: false },
+ { field: 'radiosignal', type: 'string', displayName: 'Radio Signal Id', width: 90 },
+ { field: 'scannerId', type: 'string', displayName: 'Scanner Id', width: 90 },
+ { field: 'timestamp', type: 'string', displayName: 'End time', width: 200 },
+ { field: 'suspectInterval', type: 'string', displayName: 'Suspect Interval Flag', width: 100 },
+ { field: 'xpdMina', type: 'string', displayName: 'CPD min A [dB]', width: 90 },
+ { field: 'xpdAvga', type: 'string', displayName: 'CPD avg A [dB]', width: 90 },
+ { field: 'xpdMaxa', type: 'string', displayName: 'CPD max A [dB]', width: 90 },
+ { field: 'xpdMinb', type: 'string', displayName: 'CPD min B [dB]', width: 90 },
+ { field: 'xpdAvgb', type: 'string', displayName: 'CPD avg B [dB]', width: 90 },
+ { field: 'xpdMaxb', type: 'string', displayName: 'CPD max B [dB]', width: 90 }
+ ],
+ data: 'crossPolarDiscrimination',
+ onRegisterApi: function (gridApi) {
+ $scope.gridXpdApi = gridApi;
+ $scope.gridXpdApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
+ $scope.paginationOptions.pageNumber = newPage;
+ $scope.paginationOptions.pageSize = pageSize;
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, "crossPolarDiscrimination");
+ });
+ }
+ };
+
+ //sanitize -1 to no value
+ var checkData = function (value) {
+ if (value === -1 || value === undefined) return undefined;
+ else return value;
+ };
+
+ var calculateMissingTimestamp = function (lastTimestamp, missingNr) {
+ var dateInMS = Date.parse(lastTimestamp);
+ return new Date(dateInMS + ((missingNr * 15) * 60000))
+ .toISOString()
+ .toHumanReadableTimeFormat()
+ .replace('.000', '.0');
+ };
+
+ var processResponseForGrid = function (dataA, dataB, grid) {
+ // console.log(grid);
+ switch (grid) {
+ case "transmissionLevel":
+ var list = [];
+ var lookupMap = new Map(); //add data based on timestamp
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index); //add timestamp and index to map
+ var item = {
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ txmina: checkData(entry._source['performance-data']['tx-level-min']),
+ txavga: checkData(entry._source['performance-data']['tx-level-avg']),
+ txmaxa: checkData(entry._source['performance-data']['tx-level-max']),
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+ list.push(item);
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp); //look for timestamp in map
+ if (index !== undefined) { //if a timestamp was found
+ list[index].txminb = checkData(entry._source['performance-data']['tx-level-min']); //add data to b side of element
+ list[index].txavgb = checkData(entry._source['performance-data']['tx-level-avg']);
+ list[index].txmaxb = checkData(entry._source['performance-data']['tx-level-max']);
+ } else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) { //look, if first element in list is same (first element in map is never found against an equals)
+ list[0].txminb = checkData(entry._source['performance-data']['tx-level-min']); //add data to b side of element
+ list[0].txavgb = checkData(entry._source['performance-data']['tx-level-avg']);
+ list[0].txmaxb = checkData(entry._source['performance-data']['tx-level-max']);
+ }
+ else { //add new element for b side to list
+ list.push({
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ txminb: checkData(entry._source['performance-data']['tx-level-min']),
+ txavgb: checkData(entry._source['performance-data']['tx-level-avg']),
+ txmaxb: checkData(entry._source['performance-data']['tx-level-max']),
+ 'radiosignal': entry._source['radio-signal-id']
+ });
+ }
+ }
+ });
+
+ $scope.transmissionLevel = list; //add list to databound table list
+ $scope.gridOptionsTransmissionLevel.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+ break;
+
+ case "receiveLevel":
+
+ var list = [];
+ var lookupMap = new Map();
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index);
+ var item = {
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rxmina: checkData(entry._source['performance-data']['rx-level-min']),
+ rxavga: checkData(entry._source['performance-data']['rx-level-avg']),
+ rxmaxa: checkData(entry._source['performance-data']['rx-level-max']),
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp);
+ if (index !== undefined) {
+ list[index].rxminb = checkData(entry._source['performance-data']['rx-level-min']);
+ list[index].rxavgb = checkData(entry._source['performance-data']['rx-level-avg']);
+ list[index].rxmaxb = checkData(entry._source['performance-data']['rx-level-max']);
+ } else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) {
+ list[0].rxminb = checkData(entry._source['performance-data']['rx-level-min']);
+ list[0].rxavgb = checkData(entry._source['performance-data']['rx-level-avg']);
+ list[0].rxmaxb = checkData(entry._source['performance-data']['rx-level-max']);
+ } else {
+ list.push({
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rxminb: checkData(entry._source['performance-data']['rx-level-min']),
+ rxavgb: checkData(entry._source['performance-data']['rx-level-avg']),
+ rxmaxb: checkData(entry._source['performance-data']['rx-level-max']),
+ 'radiosignal': entry._source['radio-signal-id']
+ });
+ }
+ }
+
+ });
+
+
+ $scope.receiveLevel = list;
+ $scope.gridOptionsReceiveLevel.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+
+ break;
+
+ case "modulation":
+
+ var list = [];
+
+ var lookupMap = new Map();
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index);
+ var item = {
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ 'time2Sa': checkData(entry._source['performance-data']['time2-states-s']),
+ 'time2a': checkData(entry._source['performance-data']['time2-states']),
+ 'time2La': checkData(entry._source['performance-data']['time2-states-l']),
+ 'time4Sa': checkData(entry._source['performance-data']['time4-states-s']),
+ 'time4a': checkData(entry._source['performance-data']['time4-states']),
+ 'time4La': checkData(entry._source['performance-data']['time4-states-l']),
+ 'time16Sa': checkData(entry._source['performance-data']['time16-states-s']),
+ 'time16a': checkData(entry._source['performance-data']['time16-states']),
+ 'time16La': checkData(entry._source['performance-data']['time16-states-l']),
+ 'time32Sa': checkData(entry._source['performance-data']['time32-states-s']),
+ 'time32a': checkData(entry._source['performance-data']['time32-states']),
+ 'time32La': checkData(entry._source['performance-data']['time32-states-l']),
+ 'time64Sa': checkData(entry._source['performance-data']['time64-states-s']),
+ 'time64a': checkData(entry._source['performance-data']['time64-states']),
+ 'time64La': checkData(entry._source['performance-data']['time64-states-l']),
+ 'time128Sa': checkData(entry._source['performance-data']['time128-states-s']),
+ 'time128a': checkData(entry._source['performance-data']['time128-states']),
+ 'time128La': checkData(entry._source['performance-data']['time128-states-l']),
+ 'time256Sa': checkData(entry._source['performance-data']['time256-states-s']),
+ 'time256a': checkData(entry._source['performance-data']['time256-states']),
+ 'time256La': checkData(entry._source['performance-data']['time256-states-l']),
+ 'time512Sa': checkData(entry._source['performance-data']['time512-states-s']),
+ 'time512a': checkData(entry._source['performance-data']['time512-states']),
+ 'time512La': checkData(entry._source['performance-data']['time512-states-l']),
+ 'time1024Sa': checkData(entry._source['performance-data']['time1024-states-s']),
+ 'time1024a': checkData(entry._source['performance-data']['time1024-states']),
+ 'time1024La': checkData(entry._source['performance-data']['time1024-states-l']),
+ 'time2048Sa': checkData(entry._source['performance-data']['time2048-states-s']),
+ 'time2048a': checkData(entry._source['performance-data']['time2048-states']),
+ 'time2048La': checkData(entry._source['performance-data']['time2048-states-l']),
+ 'time4096Sa': checkData(entry._source['performance-data']['time4096-states-s']),
+ 'time4096a': checkData(entry._source['performance-data']['time4096-states']),
+ 'time4096La': checkData(entry._source['performance-data']['time4096-states-l']),
+ 'time8192Sa': checkData(entry._source['performance-data']['time8192-states-s']),
+ 'time8192a': checkData(entry._source['performance-data']['time8192-states']),
+ 'time8192La': checkData(entry._source['performance-data']['time8192-states-l']),
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp);
+ if (index !== undefined) {
+
+ list[index].time2Sb = checkData(entry._source['performance-data']['time2-states-s']);
+ list[index].time2b = checkData(entry._source['performance-data']['time2-states']);
+ list[index].time2Lb = checkData(entry._source['performance-data']['time2-states-l']);
+ list[index].time4Sb = checkData(entry._source['performance-data']['time4-states-s']);
+ list[index].time4b = checkData(entry._source['performance-data']['time4-states']);
+ list[index].time4Lb = checkData(entry._source['performance-data']['time4-states-l']);
+ list[index].time16Sb = checkData(entry._source['performance-data']['time16-states-s']);
+ list[index].time16b = checkData(entry._source['performance-data']['time16-states']);
+ list[index].time16Lb = checkData(entry._source['performance-data']['time16-states-l']);
+ list[index].time32Sb = checkData(entry._source['performance-data']['time32-states-s']);
+ list[index].time32b = checkData(entry._source['performance-data']['time32-states']);
+ list[index].time32Lb = checkData(entry._source['performance-data']['time32-states-l']);
+ list[index].time64Sb = checkData(entry._source['performance-data']['time64-states-s']);
+ list[index].time64b = checkData(entry._source['performance-data']['time64-states']);
+ list[index].time64Lb = checkData(entry._source['performance-data']['time64-states-l']);
+ list[index].time128Sb = checkData(entry._source['performance-data']['time128-states-s']);
+ list[index].time128b = checkData(entry._source['performance-data']['time128-states']);
+ list[index].time128Lb = checkData(entry._source['performance-data']['time128-states-l']);
+ list[index].time256Sb = checkData(entry._source['performance-data']['time256-states-s']);
+ list[index].time256b = checkData(entry._source['performance-data']['time256-states']);
+ list[index].time256Lb = checkData(entry._source['performance-data']['time256-states-l']);
+ list[index].time512Sb = checkData(entry._source['performance-data']['time512-states-s']);
+ list[index].time512b = checkData(entry._source['performance-data']['time512-states']);
+ list[index].time512Lb = checkData(entry._source['performance-data']['time512-states-l']);
+ list[index].time1024Sb = checkData(entry._source['performance-data']['time1024-states-s']);
+ list[index].time1024b = checkData(entry._source['performance-data']['time1024-states']);
+ list[index].time1024Lb = checkData(entry._source['performance-data']['time1024-states-l']);
+ list[index].time2048Sb = checkData(entry._source['performance-data']['time2048-states-s']);
+ list[index].time2048b = checkData(entry._source['performance-data']['time2048-states']);
+ list[index].time2048Lb = checkData(entry._source['performance-data']['time2048-states-l']);
+ list[index].time4096Sb = checkData(entry._source['performance-data']['time4096-states-s']);
+ list[index].time4096b = checkData(entry._source['performance-data']['time4096-states']);
+ list[index].time4096Lb = checkData(entry._source['performance-data']['time4096-states-l']);
+ list[index].time8192Sb = checkData(entry._source['performance-data']['time8192-states-s']);
+ list[index].time8192b = checkData(entry._source['performance-data']['time8192-states']);
+ list[index].time8192Lb = checkData(entry._source['performance-data']['time8192-states-l']);
+ } else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) {
+ list[index].time2Sb = checkData(entry._source['performance-data']['time2-states-s']);
+ list[0].time2b = checkData(entry._source['performance-data']['time2-states']);
+ list[0].time2Lb = checkData(entry._source['performance-data']['time2-states-l']);
+ list[0].time4Sb = checkData(entry._source['performance-data']['time4-states-s']);
+ list[0].time4b = checkData(entry._source['performance-data']['time4-states']);
+ list[0].time4Lb = checkData(entry._source['performance-data']['time4-states-l']);
+ list[0].time16Sb = checkData(entry._source['performance-data']['time16-states-s']);
+ list[0].time16b = checkData(entry._source['performance-data']['time16-states']);
+ list[0].time16Lb = checkData(entry._source['performance-data']['time16-states-l']);
+ list[0].time32Sb = checkData(entry._source['performance-data']['time32-states-s']);
+ list[0].time32b = checkData(entry._source['performance-data']['time32-states']);
+ list[0].time32Lb = checkData(entry._source['performance-data']['time32-states-l']);
+ list[0].time64Sb = checkData(entry._source['performance-data']['time64-states-s']);
+ list[0].time64b = checkData(entry._source['performance-data']['time64-states']);
+ list[0].time64Lb = checkData(entry._source['performance-data']['time64-states-l']);
+ list[0].time128Sb = checkData(entry._source['performance-data']['time128-states-s']);
+ list[0].time128b = checkData(entry._source['performance-data']['time128-states']);
+ list[0].time128Lb = checkData(entry._source['performance-data']['time128-states-l']);
+ list[0].time256Sb = checkData(entry._source['performance-data']['time256-states-s']);
+ list[0].time256b = checkData(entry._source['performance-data']['time256-states']);
+ list[0].time256Lb = checkData(entry._source['performance-data']['time256-states-l']);
+ list[0].time512Sb = checkData(entry._source['performance-data']['time512-states-s']);
+ list[0].time512b = checkData(entry._source['performance-data']['time512-states']);
+ list[0].time512Lb = checkData(entry._source['performance-data']['time512-states-l']);
+ list[0].time1024Sb = checkData(entry._source['performance-data']['time1024-states-s']);
+ list[0].time1024b = checkData(entry._source['performance-data']['time1024-states']);
+ list[0].time1024Lb = checkData(entry._source['performance-data']['time1024-states-l']);
+ list[0].time2048Sb = checkData(entry._source['performance-data']['time2048-states-s']);
+ list[0].time2048b = checkData(entry._source['performance-data']['time2048-states']);
+ list[0].time2048Lb = checkData(entry._source['performance-data']['time2048-states-l']);
+ list[0].time4096Sb = checkData(entry._source['performance-data']['time4096-states-s']);
+ list[0].time4096b = checkData(entry._source['performance-data']['time4096-states']);
+ list[0].time4096Lb = checkData(entry._source['performance-data']['time4096-states-l']);
+ list[0].time8192Sb = checkData(entry._source['performance-data']['time8192-states-s']);
+ list[0].time8192b = checkData(entry._source['performance-data']['time8192-states']);
+ list[0].time8192Lb = checkData(entry._source['performance-data']['time8192-states-l']);
+ }
+ else {
+ var item = {
+ timestamp: timeStamp,
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ 'time2Sb': checkData(entry._source['performance-data']['time2-states-s']),
+ 'time2b': checkData(entry._source['performance-data']['time2-states']),
+ 'time2Lb': checkData(entry._source['performance-data']['time2-states-l']),
+ 'time4Sb': checkData(entry._source['performance-data']['time4-states-s']),
+ 'time4b': checkData(entry._source['performance-data']['time4-states']),
+ 'time4Lb': checkData(entry._source['performance-data']['time4-states-l']),
+ 'time16Sb': checkData(entry._source['performance-data']['time16-states-s']),
+ 'time16b': checkData(entry._source['performance-data']['time16-states']),
+ 'time16Lb': checkData(entry._source['performance-data']['time16-states-l']),
+ 'time32Sb': checkData(entry._source['performance-data']['time32-states-s']),
+ 'time32b': checkData(entry._source['performance-data']['time32-states']),
+ 'time32Lb': checkData(entry._source['performance-data']['time32-states-l']),
+ 'time64Sb': checkData(entry._source['performance-data']['time64-states-s']),
+ 'time64b': checkData(entry._source['performance-data']['time64-states']),
+ 'time64Lb': checkData(entry._source['performance-data']['time64-states-l']),
+ 'time128Sb': checkData(entry._source['performance-data']['time128-states-s']),
+ 'time128b': checkData(entry._source['performance-data']['time128-states']),
+ 'time128Lb': checkData(entry._source['performance-data']['time128-states-l']),
+ 'time256Sb': checkData(entry._source['performance-data']['time256-states-s']),
+ 'time256b': checkData(entry._source['performance-data']['time256-states']),
+ 'time256Lb': checkData(entry._source['performance-data']['time256-states-l']),
+ 'time512Sb': checkData(entry._source['performance-data']['time512-states-s']),
+ 'time512b': checkData(entry._source['performance-data']['time512-states']),
+ 'time512Lb': checkData(entry._source['performance-data']['time512-states-l']),
+ 'time1024Sb': checkData(entry._source['performance-data']['time1024-states-s']),
+ 'time1024b': checkData(entry._source['performance-data']['time1024-states']),
+ 'time1024Lb': checkData(entry._source['performance-data']['time1024-states-l']),
+ 'time2048Sb': checkData(entry._source['performance-data']['time2048-states-s']),
+ 'time2048b': checkData(entry._source['performance-data']['time2048-states']),
+ 'time2048Lb': checkData(entry._source['performance-data']['time2048-states-l']),
+ 'time4096Sb': checkData(entry._source['performance-data']['time4096-states-s']),
+ 'time4096b': checkData(entry._source['performance-data']['time4096-states']),
+ 'time4096Lb': checkData(entry._source['performance-data']['time4096-states-l']),
+ 'time8192Sb': checkData(entry._source['performance-data']['time8192-states-s']),
+ 'time8192b': checkData(entry._source['performance-data']['time8192-states']),
+ 'time8192Lb': checkData(entry._source['performance-data']['time8192-states-l']),
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+ }
+ }
+ });
+ $scope.modulation = list;
+ $scope.gridOptionsModulation.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+
+ break;
+
+ case "temperature":
+
+ var list = [];
+ var lookupMap = new Map();
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index);
+ var item = {
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rfTempMina: entry._source['performance-data']['rf-temp-min'],
+ rfTempAvga: entry._source['performance-data']['rf-temp-avg'],
+ rfTempMaxa: entry._source['performance-data']['rf-temp-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp);
+ if (index !== undefined) {
+ list[index].rfTempMinb = entry._source['performance-data']['rf-temp-min'];
+ list[index].rfTempMaxb = entry._source['performance-data']['rf-temp-max'];
+ list[index].rfTempAvgb = entry._source['performance-data']['rf-temp-avg'];
+ } else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) {
+ list[0].rfTempMinb = entry._source['performance-data']['rf-temp-min'];
+ list[0].rfTempMaxb = entry._source['performance-data']['rf-temp-max'];
+ list[0].rfTempAvgb = entry._source['performance-data']['rf-temp-avg'];
+ } else {
+ list.push({
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ rfTempMinb: entry._source['performance-data']['rf-temp-min'],
+ rfTempAvgb: entry._source['performance-data']['rf-temp-avg'],
+ rfTempMaxb: entry._source['performance-data']['rf-temp-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+ });
+ }
+ }
+ });
+
+ $scope.temperature = list;
+ $scope.gridOptionsTemperature.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+
+ break;
+
+ case "snir":
+
+ var list = [];
+ var lookupMap = new Map();
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index);
+ var item = {
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ snirMina: entry._source['performance-data']['snir-min'],
+ snirAvga: entry._source['performance-data']['snir-avg'],
+ snirMaxa: entry._source['performance-data']['snir-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+ };
+
+ list.push(item);
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp);
+ if (index !== undefined) {
+ list[index].snirMinb = entry._source['performance-data']['snir-min'];
+ list[index].snirMaxb = entry._source['performance-data']['snir-max'];
+ list[index].snirAvgb = entry._source['performance-data']['snir-max'];
+ }
+ else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) {
+ list[0].snirMinb = entry._source['performance-data']['snir-min'];
+ list[0].snirMaxb = entry._source['performance-data']['snir-max'];
+ list[0].snirAvgb = entry._source['performance-data']['snir-max'];
+ } else {
+ list.push({
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ snirMinb: entry._source['performance-data']['snir-min'],
+ snirAvgb: entry._source['performance-data']['snir-avg'],
+ snirMaxb: entry._source['performance-data']['snir-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+ });
+ }
+ }
+ });
+ $scope.snir = list;
+ $scope.gridOptionsSnir.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+
+ break;
+
+ case "crossPolarDiscrimination":
+ var list = [];
+
+ var lookupMap = new Map();
+
+ dataA.data.hits.hits.map(function (entry, index) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ lookupMap.set(timeStamp, index);
+ var item = {
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ xpdMina: entry._source['performance-data']['xpd-min'],
+ xpdAvga: entry._source['performance-data']['xpd-avg'],
+ xpdMaxa: entry._source['performance-data']['xpd-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+
+ };
+
+ list.push(item);
+
+ });
+
+ dataB.data.hits.hits.map(function (entry) {
+ var timeStamp = formatTimeStamp(entry._source['time-stamp']);
+ var index = lookupMap.get(timeStamp);
+ if (index !== undefined) {
+ list[index].xpdMinb = entry._source['performance-data']['xpd-min'];
+ list[index].xpdMaxb = entry._source['performance-data']['xpd-max'];
+ list[index].xpdAvgb = entry._source['performance-data']['xpd-avg'];
+ }
+ else {
+ if (list[0].timestamp === $mwtnPerformanceLink.formatTimeStamp(timeStamp)) {
+
+ list[0].xpdMinb = entry._source['performance-data']['xpd-min'];
+ list[0].xpdMaxb = entry._source['performance-data']['xpd-max'];
+ list[0].xpdAvgb = entry._source['performance-data']['xpd-avg'];
+
+ } else {
+ list.push({
+ 'timestamp': $mwtnPerformanceLink.formatTimeStamp(timeStamp),
+ id: entry._source['uuid-interface'],
+ layerProtocol: entry._source['layer-protocol-name'],
+ suspectInterval: entry._source['suspect-interval-flag'],
+ scannerId: entry._source['scanner-id'],
+ xpdMinb: entry._source['performance-data']['xpd-min'],
+ xpdAvgb: entry._source['performance-data']['xpd-avg'],
+ xpdMaxb: entry._source['performance-data']['xpd-max'],
+ 'radiosignal': entry._source['radio-signal-id']
+
+ });
+ }
+
+ }
+ });
+
+ $scope.crossPolarDiscrimination = list;
+ $scope.gridOptionsCrossPolarDiscrimination.totalItems = getMaxItems(dataA.data.hits.total, dataB.data.hits.total);
+
+ break;
+ }
+ };
+
+
+ var getMaxItems = function (a, b) {
+ if ($scope.networkElementA === $scope.networkElementB && $scope.selectedLtpIdA === $scope.selectedLtpIdB) {
+ //assume same network element and intefaces selected, return only 1 length
+ return a;
+ } else {
+ return a + b;
+ }
+ }
+
+ //get data for pm link interafces / ne's from db
+ var getDataFromNEs = function (networkElementA, selectedLtpIdA, networkElementB, selectedLtpIdB, grid) {
+ var pagesize;
+ var pagenr;
+
+ switch (grid) { //get pagesize / nr according to current grid (else everything gets messy => wana get next page in grid a, get next page for grid b too)
+ case 'receiveLevel':
+ pagesize = $scope.gridOptionsReceiveLevel.paginationPageSize;
+ pagenr = $scope.gridOptionsReceiveLevel.paginationCurrentPage;
+ break;
+
+ case 'transmissionLevel':
+ pagesize = $scope.gridOptionsTransmissionLevel.paginationPageSize;
+ pagenr = $scope.gridOptionsTransmissionLevel.paginationCurrentPage;
+ break;
+
+ case 'modulation':
+ pagesize = $scope.gridOptionsModulation.paginationPageSize;
+ pagenr = $scope.gridOptionsModulation.paginationCurrentPage;
+ break;
+
+ case 'temperature':
+ pagesize = $scope.gridOptionsTemperature.paginationPageSize;
+ pagenr = $scope.gridOptionsTemperature.paginationCurrentPage;
+ break;
+
+ case 'snir':
+ pagesize = $scope.gridOptionsSnir.paginationPageSize;
+ pagenr = $scope.gridOptionsSnir.paginationCurrentPage;
+ break;
+
+ case 'crossPolarDiscrimination':
+ pagesize = $scope.gridOptionsCrossPolarDiscrimination.paginationPageSize;
+ pagenr = $scope.gridOptionsCrossPolarDiscrimination.paginationCurrentPage;
+
+ break;
+ }
+
+ var dataA;
+ var dataB;
+ getData((pagenr - 1) * pagesize, pagesize, networkElementA, selectedLtpIdA).then(function (response) {
+ dataA = response;
+ getData((pagenr - 1) * pagesize, pagesize, networkElementB, selectedLtpIdB).then(function (response) {
+ dataB = response;
+ drawLineChart(dataA, dataB, grid);
+ processResponseForGrid(dataA, dataB, grid);
+ });
+ });
+ };
+
+ //override points on graphs
+ var overridePoints = function (series, overrideArray) {
+
+
+ let patternArray = ['rect', 'triangle', 'point', 'rectRot'];
+ let patternCounter = 0;
+
+
+ for (let i = 0; i < series.length; i++) {
+
+ overrideArray[i].pointStyle = patternArray[patternCounter];
+ patternCounter++;
+
+ if (patternCounter === 4) patternCounter = 0;
+ overrideArray[i].pointRadius = 10;
+ }
+
+ };
+
+ var drawLineChart = function (dataA, dataB, grid) {
+
+ //create a sorted lookup array
+
+ var tempSet = new Set(); //remove duplicate timestamps
+
+ dataA.data.hits.hits.map(function (item) {
+ tempSet.add($mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']));
+ });
+
+ dataB.data.hits.hits.map(function (item) {
+ tempSet.add($mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']));
+ });
+
+ // console.log(tempSet);
+ var tempArr = Array.from(tempSet); //create an array from unique timestamps
+
+ tempArr.sort(function (a, b) { //sort it
+ if (a > b) { return 1; }
+ else if (a < b) { return -1; }
+ else {
+ return 0;
+ }
+ });
+
+ //process data according to grid
+ switch (grid) {
+ case 'receiveLevel': {
+
+ //chart specific data
+ $scope.receiveData = [];
+ $scope.receiveSeries = [];
+ $scope.receiveLabels = [];
+ $scope.receiveDatasetOverride = [];
+
+ $scope.receiveOptions = {
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.toolTipMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ var timestamp = $scope.toolTipMap.get($scope.toolTipMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+
+
+
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+ var vaue = $scope.toolTipMap.get(tooltipItem[0].xLabel); //changes int label to timestamp
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+ };
+
+ $scope.testMap = new Map();
+ $scope.toolTipMap = new Map();
+
+ tempArr.map(function (item, index) {
+ $scope.testMap.set(item, index);
+ $scope.toolTipMap.set(index, item);
+ });
+
+ //process a side
+
+ var maxListA = [];
+ var minListA = [];
+ var avgListA = [];
+
+ //add data to array
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.testMap.get(timestamp);
+ if (test) {
+ maxListA.push({ x: test, y: item._source['performance-data']['rx-level-max'] });
+ minListA.push({ x: test, y: item._source['performance-data']['rx-level-min'] });
+ avgListA.push({ x: test, y: item._source['performance-data']['rx-level-avg'] });
+ } else {
+ maxListA.push({ x: 0, y: item._source['performance-data']['rx-level-max'] }); //for some odd reason first is not found, although available within map
+ minListA.push({ x: 0, y: item._source['performance-data']['rx-level-min'] });
+ avgListA.push({ x: 0, y: item._source['performance-data']['rx-level-avg'] });
+ }
+ });
+
+ //add series names and data
+ $scope.receiveSeries.push('Rx max A', 'Rx min A', 'Rx avg A');
+
+
+ $scope.receiveData.push(maxListA);
+ $scope.receiveData.push(minListA);
+ $scope.receiveData.push(avgListA);
+
+ //add y axis override
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+
+ //process b side
+
+ var maxListB = [];
+ var minListB = [];
+ var avgListB = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.testMap.get(timestamp);
+ if (test) {
+ maxListB.push({ x: test, y: item._source['performance-data']['rx-level-max'] });
+ minListB.push({ x: test, y: item._source['performance-data']['rx-level-min'] });
+ avgListB.push({ x: test, y: item._source['performance-data']['rx-level-avg'] });
+ } else {
+ maxListB.push({ x: 0, y: item._source['performance-data']['rx-level-max'] });
+ minListB.push({ x: 0, y: item._source['performance-data']['rx-level-min'] });
+ avgListB.push({ x: 0, y: item._source['performance-data']['rx-level-avg'] });
+ console.log("timestamp" + timestamp + "at first position in map" + $scope.testMap.get(timestamp) + "wasnt found.");
+ }
+ });
+
+ //add series names and data
+ $scope.receiveSeries.push('Rx max B', 'Rx min B', 'Rx avg B');
+
+ $scope.receiveData.push(maxListB);
+ $scope.receiveData.push(minListB);
+ $scope.receiveData.push(avgListB);
+
+ //add y axis override id
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.receiveDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+ overridePoints($scope.receiveSeries, $scope.receiveDatasetOverride);
+
+
+ }
+
+ break;
+
+ case 'transmissionLevel': {
+
+ $scope.transmissionData = [];
+ $scope.transmissionSeries = [];
+ $scope.transmissionDatasetOverride = [];
+
+ $scope.transmissionOptions = {
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.transmissiontoolTipMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ let timestamp = $scope.transmissiontoolTipMap.get($scope.transmissiontoolTipMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+ var vaue = $scope.transmissiontoolTipMap.get(tooltipItem[0].xLabel);
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+ };
+
+
+ $scope.transmissiontestMap = new Map();
+ $scope.transmissiontoolTipMap = new Map();
+
+ tempArr.map(function (item, index) {
+ $scope.transmissiontestMap.set(item, index);
+ $scope.transmissiontoolTipMap.set(index, item);
+ });
+
+ var maxListA = [];
+ var minListA = [];
+ var avgListA = [];
+
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.transmissiontestMap.get(timestamp);
+ if (test) {
+ maxListA.push({ x: test, y: item._source['performance-data']['tx-level-max'] });
+ minListA.push({ x: test, y: item._source['performance-data']['tx-level-min'] });
+ avgListA.push({ x: test, y: item._source['performance-data']['tx-level-avg'] });
+ } else {
+
+ maxListA.push({ x: 0, y: item._source['performance-data']['tx-level-max'] });
+ minListA.push({ x: 0, y: item._source['performance-data']['tx-level-min'] });
+ avgListA.push({ x: 0, y: item._source['performance-data']['tx-level-avg'] });
+ }
+ });
+
+ $scope.transmissionSeries.push('Tx max A', 'Tx min A', 'Tx avg A');
+
+
+ $scope.transmissionData.push(maxListA);
+ $scope.transmissionData.push(minListA);
+ $scope.transmissionData.push(avgListA);
+
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+ var maxListB = [];
+ var minListB = [];
+ var avgListB = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+ var test = $scope.transmissiontestMap.get(timestamp);
+ if (test) {
+ maxListB.push({ x: test, y: item._source['performance-data']['tx-level-max'] });
+ minListB.push({ x: test, y: item._source['performance-data']['tx-level-min'] });
+ avgListB.push({ x: test, y: item._source['performance-data']['tx-level-avg'] });
+ } else {
+
+ maxListB.push({ x: 0, y: item._source['performance-data']['tx-level-max'] });
+ minListB.push({ x: 0, y: item._source['performance-data']['tx-level-min'] });
+ avgListB.push({ x: 0, y: item._source['performance-data']['tx-level-avg'] });
+ }
+ });
+
+ $scope.transmissionSeries.push('Tx max B', 'Tx min B', 'Tx avg B');
+
+ $scope.transmissionData.push(maxListB);
+ $scope.transmissionData.push(minListB);
+ $scope.transmissionData.push(avgListB);
+
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.transmissionDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+ overridePoints($scope.transmissionSeries, $scope.transmissionDatasetOverride);
+ }
+
+ break;
+
+ case 'modulation': {
+
+ $scope.modulationData = [];
+ $scope.modultaionSeries = [];
+ $scope.modulationDatasetOverride = [];
+
+ $scope.modulationOptions = {
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.modLabelMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ var timestamp = $scope.modLabelMap.get($scope.modLabelMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+
+ var vaue = $scope.modtestMap.get(tooltipItem[0].xLabel);
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+
+ };
+
+ $scope.modtestMap = new Map();
+ $scope.modLabelMap = new Map();
+
+ tempArr.map(function (item, index) {
+ $scope.modtestMap.set(item, index);
+ $scope.modLabelMap.set(index, item);
+ });
+
+ var time2S = [];
+ var time2 = [];
+ var time2L = [];
+ var time4S = [];
+ var time4 = [];
+ var time4L = [];
+ var time16S = [];
+ var time16 = [];
+ var time16L = [];
+ var time32S = [];
+ var time32 = [];
+ var time32L = [];
+ var time64S = [];
+ var time64 = [];
+ var time64L = [];
+ var time128S = [];
+ var time128 = [];
+ var time128L = [];
+ var time256S = [];
+ var time256 = [];
+ var time256L = [];
+ var time512S = [];
+ var time512 = [];
+ var time512L = [];
+ var time1024S = [];
+ var time1024 = [];
+ var time1024L = [];
+ var time2048S = [];
+ var time2048 = [];
+ var time2048L = [];
+ var time4096S = [];
+ var time4096 = [];
+ var time4096L = [];
+ var time8192S = [];
+ var time8192 = [];
+ var time8192L = [];
+
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.modtestMap.get(timestamp);
+ if (test) {
+
+ //check if data is not undefined, if yes: add
+ let t2s = checkData(item._source['performance-data']['time2-states-s']);
+ if (t2s != undefined)
+ time2S.push({ x: test, y: t2s });
+
+ let t2 = checkData(item._source['performance-data']['time2-states']);
+ if (t2 != undefined)
+ time2.push({ x: test, y: t2 });
+
+ let t2L = checkData(item._source['performance-data']['time2-states-l']);
+ if (t2L != undefined)
+ time2L.push({ x: test, y: t2L });
+
+ let t4s = checkData(item._source['performance-data']['time4-states-s']);
+ if (t4s != undefined)
+ time4S.push({ x: test, y: t4s });
+
+ let t4 = checkData(item._source['performance-data']['time4-states']);
+ if (t4 != undefined)
+ time4.push({ x: test, y: t4 });
+
+ let t4L = checkData(item._source['performance-data']['time4-states-l']);
+ if (t4L != undefined)
+ time4L.push({ x: test, y: t4L });
+
+ let t16s = checkData(item._source['performance-data']['time16-states-s']);
+ if (t16s != undefined)
+ time16S.push({ x: test, y: t16s });
+
+
+ let t16 = checkData(item._source['performance-data']['time16-states']);
+ if (t16 != undefined)
+ time16.push({ x: test, y: t16 });
+
+
+ let t16L = checkData(item._source['performance-data']['time16-states-l']);
+ if (t16L != undefined)
+ time16L.push({ x: test, y: t16L });
+
+ let t32s = checkData(item._source['performance-data']['time32-states-s']);
+ if (t32s != undefined)
+ time32S.push({ x: test, y: t32s });
+
+ let t32 = checkData(item._source['performance-data']['time32-states']);
+ if (t32 != undefined)
+ time32.push({ x: test, y: t32 });
+
+
+ let t32L = checkData(item._source['performance-data']['time32-states-l']);
+ if (t32L != undefined)
+ time32L.push({ x: test, y: t32L });
+
+
+
+ let t64s = checkData(item._source['performance-data']['time64-states-s']);
+ if (t64s != undefined)
+ time64S.push({ x: test, y: t64s });
+
+ let t64 = checkData(item._source['performance-data']['time64-states']);
+ if (t64 != undefined)
+ time64.push({ x: test, y: t64 });
+
+ let t64L = checkData(item._source['performance-data']['time64-states-l']);
+ if (t64L != undefined)
+ time64L.push({ x: test, y: t64L });
+
+
+ let t128s = checkData(item._source['performance-data']['time128-states-s']);
+ if (t128s != undefined)
+ time128S.push({ x: test, y: t128s });
+
+ let t128 = checkData(item._source['performance-data']['time128-states']);
+ if (t128 != undefined)
+ time128.push({ x: test, y: t128 });
+
+ let t128L = checkData(item._source['performance-data']['time128-states-l']);
+ if (t128L != undefined)
+ time128L.push({ x: test, y: t128L });
+
+
+ let t256s = checkData(item._source['performance-data']['time256-states-s']);
+ if (t256s != undefined)
+ time256S.push({ x: test, y: t256s });
+
+ let t256 = checkData(item._source['performance-data']['time256-states']);
+ if (t256 != undefined)
+ time256.push({ x: test, y: t256 });
+
+ let t256L = checkData(item._source['performance-data']['time256-states-l']);
+ if (t256L != undefined)
+ time256L.push({ x: test, y: t256L });
+
+ let t512s = checkData(item._source['performance-data']['time512-states-s']);
+ if (t512s != undefined)
+ time512S.push({ x: test, y: t512s });
+
+ let t512 = checkData(item._source['performance-data']['time512-states']);
+ if (t512 != undefined)
+ time512.push({ x: test, y: t512 });
+
+ let t512L = checkData(item._source['performance-data']['time512-states-l']);
+ if (t512L != undefined)
+ time512L.push({ x: test, y: t512L });
+
+ let t1024s = checkData(item._source['performance-data']['time1024-states-s']);
+ if (t1024s != undefined)
+ time1024S.push({ x: test, y: t1024s });
+
+ let t1024 = checkData(item._source['performance-data']['time1024-states']);
+ if (t1024 != undefined)
+ time1024.push({ x: test, y: t1024 });
+
+ let t1024L = checkData(item._source['performance-data']['time1024-states-l']);
+ if (t1024L != undefined)
+ time1024L.push({ x: test, y: t1024L });
+
+ let t2048s = checkData(item._source['performance-data']['time2048-states-s']);
+ if (t2048s != undefined)
+ time2048S.push({ x: test, y: t2048s });
+
+ let t2048 = checkData(item._source['performance-data']['time2048-states']);
+ if (t2048 != undefined)
+ time2048.push({ x: test, y: t2048 });
+
+ let t2048L = checkData(item._source['performance-data']['time2048-states-l']);
+ if (t2048L != undefined)
+ time2048L.push({ x: test, y: t2048L });
+
+ let t4096s = checkData(item._source['performance-data']['time4096-states-s']);
+ if (t4096s != undefined)
+ time4096S.push({ x: test, y: t4096s });
+
+ let t4096 = checkData(item._source['performance-data']['time4096-states']);
+ if (t4096 != undefined)
+ time4096.push({ x: test, y: t4096 });
+
+ let t4096L = checkData(item._source['performance-data']['time4096-states-l']);
+ if (t4096L != undefined)
+ time4096L.push({ x: test, y: t4096L });
+
+ let t8192s = checkData(item._source['performance-data']['time8192-states-s']);
+ if (t8192s != undefined)
+ time8192S.push({ x: test, y: t8192s });
+
+ let t8192 = checkData(item._source['performance-data']['time8192-states']);
+ if (t8192 != undefined)
+ time8192.push({ x: test, y: t8192 });
+
+ let t8192L = checkData(item._source['performance-data']['time8192-states-l']);
+ if (t8192L != undefined)
+ time8192L.push({ x: test, y: t8192L });
+
+ } else {
+
+ let t2s = checkData(item._source['performance-data']['time2-states-s']);
+ if (t2s != undefined)
+ time2S.push({ x: 0, y: t2s });
+
+ let t2 = checkData(item._source['performance-data']['time2-states']);
+ if (t2 != undefined)
+ time2.push({ x: 0, y: t2 });
+
+ let t2L = checkData(item._source['performance-data']['time2-states-l']);
+ if (t2L != undefined)
+ time2L.push({ x: 0, y: t2L });
+
+ let t4s = checkData(item._source['performance-data']['time4-states-s']);
+ if (t4s != undefined)
+ time4S.push({ x: 0, y: t4s });
+
+ let t4 = checkData(item._source['performance-data']['time4-states']);
+ if (t4 != undefined)
+ time4.push({ x: 0, y: t4 });
+
+ let t4L = checkData(item._source['performance-data']['time4-states-l']);
+ if (t4L != undefined)
+ time4L.push({ x: 0, y: t4L });
+
+ let t16s = checkData(item._source['performance-data']['time16-states-s']);
+ if (t16s != undefined)
+ time16S.push({ x: 0, y: t16s });
+
+
+ let t16 = checkData(item._source['performance-data']['time16-states']);
+ if (t16 != undefined)
+ time16.push({ x: 0, y: t16 });
+
+
+ let t16L = checkData(item._source['performance-data']['time16-states-l']);
+ if (t16L != undefined)
+ time16L.push({ x: 0, y: t16L });
+
+ let t32s = checkData(item._source['performance-data']['time32-states-s']);
+ if (t32s != undefined)
+ time32S.push({ x: 0, y: t32s });
+
+ let t32 = checkData(item._source['performance-data']['time32-states']);
+ if (t32 != undefined)
+ time32.push({ x: 0, y: t32 });
+
+
+ let t32L = checkData(item._source['performance-data']['time32-states-l']);
+ if (t32L != undefined)
+ time32L.push({ x: 0, y: t32L });
+
+ let t64s = checkData(item._source['performance-data']['time64-states-s']);
+ if (t64s != undefined)
+ time64S.push({ x: 0, y: t64s });
+
+ let t64 = checkData(item._source['performance-data']['time64-states']);
+ if (t64 != undefined)
+ time64.push({ x: 0, y: t64 });
+
+ let t64L = checkData(item._source['performance-data']['time64-states-l']);
+ if (t64L != undefined)
+ time64L.push({ x: 0, y: t64L });
+
+
+ let t128s = checkData(item._source['performance-data']['time128-states-s']);
+ if (t128s != undefined)
+ time128S.push({ x: 0, y: t128s });
+
+ let t128 = checkData(item._source['performance-data']['time128-states']);
+ if (t128 != undefined)
+ time128.push({ x: 0, y: t128 });
+
+ let t128L = checkData(item._source['performance-data']['time128-states-l']);
+ if (t128L != undefined)
+ time128L.push({ x: 0, y: t128L });
+
+
+ let t256s = checkData(item._source['performance-data']['time256-states-s']);
+ if (t256s != undefined)
+ time256S.push({ x: 0, y: t256s });
+
+ let t256 = checkData(item._source['performance-data']['time256-states']);
+ if (t256 != undefined)
+ time256.push({ x: 0, y: t256 });
+
+ let t256L = checkData(item._source['performance-data']['time256-states-l']);
+ if (t256L != undefined)
+ time256L.push({ x: 0, y: t256L });
+
+ let t512s = checkData(item._source['performance-data']['time512-states-s']);
+ if (t512s != undefined)
+ time512S.push({ x: 0, y: t512s });
+
+ let t512 = checkData(item._source['performance-data']['time512-states']);
+ if (t512 != undefined)
+ time512.push({ x: 0, y: t512 });
+
+ let t512L = checkData(item._source['performance-data']['time512-states-l']);
+ if (t512L != undefined)
+ time512L.push({ x: 0, y: t512L });
+
+ let t1024s = checkData(item._source['performance-data']['time1024-states-s']);
+ if (t1024s != undefined)
+ time1024S.push({ x: 0, y: t1024s });
+
+ let t1024 = checkData(item._source['performance-data']['time1024-states']);
+ if (t1024 != undefined)
+ time1024.push({ x: 0, y: t1024 });
+
+ let t1024L = checkData(item._source['performance-data']['time1024-states-l']);
+ if (t1024L != undefined)
+ time1024L.push({ x: 0, y: t1024L });
+
+ let t2048s = checkData(item._source['performance-data']['time2048-states-s']);
+ if (t2048s != undefined)
+ time2048S.push({ x: 0, y: t2048s });
+
+ let t2048 = checkData(item._source['performance-data']['time2048-states']);
+ if (t2048 != undefined)
+ time2048.push({ x: 0, y: t2048 });
+
+ let t2048L = checkData(item._source['performance-data']['time2048-states-l']);
+ if (t2048L != undefined)
+ time2048L.push({ x: 0, y: t2048L });
+
+ let t4096s = checkData(item._source['performance-data']['time4096-states-s']);
+ if (t4096s != undefined)
+ time4096S.push({ x: 0, y: t4096s });
+
+ let t4096 = checkData(item._source['performance-data']['time4096-states']);
+ if (t4096 != undefined)
+ time4096.push({ x: 0, y: t4096 });
+
+ let t4096L = checkData(item._source['performance-data']['time4096-states-l']);
+ if (t4096L != undefined)
+ time4096L.push({ x: 0, y: t4096L });
+
+ let t8192s = checkData(item._source['performance-data']['time8192-states-s']);
+ if (t8192s != undefined)
+ time8192S.push({ x: 0, y: t8192s });
+
+ let t8192 = checkData(item._source['performance-data']['time8192-states']);
+ if (t8192 != undefined)
+ time8192.push({ x: 0, y: t8192 });
+
+ let t8192L = checkData(item._source['performance-data']['time8192-states-l']);
+ if (t8192L != undefined)
+ time8192L.push({ x: 0, y: t8192L });
+
+ }
+ });
+
+ //check, if array has items, if yes: add series and data to chart
+ //reduces amount of labels shown in chart => shows only series' with data
+ if (time2S.length > 0) {
+ $scope.modultaionSeries.push('QAM2S A');
+ $scope.modulationData.push(time2S);
+ }
+
+ if (time2.length > 0) {
+ $scope.modultaionSeries.push('QAM2 A');
+ $scope.modulationData.push(time2);
+ }
+
+ if (time2L.length > 0) {
+ $scope.modultaionSeries.push('QAM2L A');
+ $scope.modulationData.push(time2L);
+ }
+
+ if (time4S.length > 0) {
+ $scope.modultaionSeries.push('QAM4S A');
+ $scope.modulationData.push(time4S);
+ }
+
+ if (time4.length > 0) {
+ $scope.modultaionSeries.push('QAM4 A');
+ $scope.modulationData.push(time4);
+ }
+
+ if (time4L.length > 0) {
+ $scope.modultaionSeries.push('QAM4L A');
+ $scope.modulationData.push(time4L);
+ }
+
+ if (time16S.length > 0) {
+ $scope.modultaionSeries.push('QAM16S A');
+ $scope.modulationData.push(time16S);
+ }
+
+
+ if (time16.length > 0) {
+ $scope.modultaionSeries.push('QAM16 A');
+ $scope.modulationData.push(time16);
+ }
+
+ if (time16L.length > 0) {
+ $scope.modultaionSeries.push('QAM16L A');
+ $scope.modulationData.push(time16L);
+ }
+
+ if (time32S.length > 0) {
+ $scope.modulationData.push(time32S);
+ $scope.modultaionSeries.push('QAM32S A');
+ }
+
+ if (time32.length > 0) {
+ $scope.modulationData.push(time32);
+ $scope.modultaionSeries.push('QAM32 A');
+ }
+
+ if (time32L.length > 0) {
+ $scope.modulationData.push(time32L);
+ $scope.modultaionSeries.push('QAM32L A');
+ }
+
+
+ if (time64S.length > 0) {
+ $scope.modulationData.push(time64S);
+ $scope.modultaionSeries.push('QAM64S A');
+ }
+
+
+ if (time64.length > 0) {
+ $scope.modulationData.push(time64);
+ $scope.modultaionSeries.push('QAM64 A');
+ }
+
+ if (time64L.length > 0) {
+ $scope.modulationData.push(time64L);
+ $scope.modultaionSeries.push('QAM64L A');
+ }
+
+
+ if (time128S.length > 0) {
+ $scope.modultaionSeries.push('QAM128S A');
+ $scope.modulationData.push(time128S);
+ }
+
+ if (time128.length > 0) {
+ $scope.modultaionSeries.push('QAM128 A');
+ $scope.modulationData.push(time128);
+ }
+
+ if (time128L.length > 0) {
+ $scope.modultaionSeries.push('QAM128L A');
+ $scope.modulationData.push(time128L);
+ }
+
+ if (time256S.length > 0) {
+ $scope.modulationData.push(time256S);
+ $scope.modultaionSeries.push('QAM256S A');
+ }
+
+ if (time256.length > 0) {
+ $scope.modulationData.push(time256);
+ $scope.modultaionSeries.push('QAM256 A');
+ }
+
+ if (time256L.length > 0) {
+ $scope.modulationData.push(time256L);
+ $scope.modultaionSeries.push('QAM256L A');
+ }
+
+ if (time512S.length > 0) {
+ $scope.modultaionSeries.push('QAM512S A');
+ $scope.modulationData.push(time512S);
+ }
+
+ if (time512.length > 0) {
+ $scope.modultaionSeries.push('QAM512 A');
+ $scope.modulationData.push(time512);
+ }
+
+ if (time512S.length > 0) {
+ $scope.modultaionSeries.push('QAM512S A');
+ $scope.modulationData.push(time512S);
+ }
+
+ if (time512.length > 0) {
+ $scope.modultaionSeries.push('QAM512 A');
+ $scope.modulationData.push(time512);
+ }
+
+ if (time512L.length > 0) {
+ $scope.modultaionSeries.push('QAM512L A');
+ $scope.modulationData.push(time512L);
+
+ }
+
+ if (time1024S.length > 0) {
+ $scope.modultaionSeries.push('QAM1024S A');
+ $scope.modulationData.push(time1024S);
+ }
+
+ if (time1024.length > 0) {
+ $scope.modultaionSeries.push('QAM1024 A');
+ $scope.modulationData.push(time1024);
+ }
+
+
+ if (time1024L.length > 0) {
+ $scope.modultaionSeries.push('QAM1024L A');
+ $scope.modulationData.push(time1024L);
+ }
+
+
+ if (time2048S.length > 0) {
+ $scope.modultaionSeries.push('QAM2048S A');
+ $scope.modulationData.push(time2048S);
+ }
+
+ if (time2048.length > 0) {
+ $scope.modultaionSeries.push('QAM2048 A');
+ $scope.modulationData.push(time2048);
+ }
+
+ if (time2048L.length > 0) {
+ $scope.modultaionSeries.push('QAM2048L A');
+ $scope.modulationData.push(time2048L);
+
+ }
+
+ if (time4096S.length > 0) {
+ $scope.modultaionSeries.push('QAM4096S A');
+ $scope.modulationData.push(time4096S);
+ }
+
+ if (time4096.length > 0) {
+ $scope.modultaionSeries.push('QAM4096 A');
+ $scope.modulationData.push(time4096);
+ }
+
+
+ if (time4096L.length > 0) {
+ $scope.modultaionSeries.push('QAM4096L A');
+ $scope.modulationData.push(time4096L);
+ }
+
+ if (time8192S.length > 0) {
+ $scope.modultaionSeries.push('QAM8192S A');
+ $scope.modulationData.push(time8192S);
+ }
+
+
+ if (time8192.length > 0) {
+ $scope.modultaionSeries.push('QAM8192 A');
+ $scope.modulationData.push(time8192);
+ }
+
+ if (time8192L.length > 0) {
+ $scope.modultaionSeries.push('QAM8192L A');
+ $scope.modulationData.push(time8192L);
+ }
+
+ //process data for b side
+
+ time2S = [];
+ time2 = [];
+ time2L = [];
+ time4S = [];
+ time4 = [];
+ time4L = [];
+ time16S = [];
+ time16 = [];
+ time16L = [];
+ time32S = [];
+ time32 = [];
+ time32L = [];
+ time64S = [];
+ time64 = [];
+ time64L = [];
+ time128S = [];
+ time128 = [];
+ time128L = [];
+ time256S = [];
+ time256 = [];
+ time256L = [];
+ time512S = [];
+ time512 = [];
+ time512L = [];
+ time1024S = [];
+ time1024 = [];
+ time1024L = [];
+ time2048S = [];
+ time2048 = [];
+ time2048L = [];
+ time4096S = [];
+ time4096 = [];
+ time4096L = [];
+ time8192S = [];
+ time8192 = [];
+ time8192L = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+ var test = $scope.modtestMap.get(timestamp);
+ if (test) {
+ let t2s = checkData(item._source['performance-data']['time2-states-s']);
+ if (t2s != undefined)
+ time2S.push({ x: test, y: t2s });
+
+ let t2 = checkData(item._source['performance-data']['time2-states']);
+ if (t2 != undefined)
+ time2.push({ x: test, y: t2 });
+
+ let t2L = checkData(item._source['performance-data']['time2-states-l']);
+ if (t2L != undefined)
+ time2L.push({ x: test, y: t2L });
+
+ let t4s = checkData(item._source['performance-data']['time4-states-s']);
+ if (t4s != undefined)
+ time4S.push({ x: test, y: t4s });
+
+ let t4 = checkData(item._source['performance-data']['time4-states']);
+ if (t4 != undefined)
+ time4.push({ x: test, y: t4 });
+
+ let t4L = checkData(item._source['performance-data']['time4-states-l']);
+ if (t4L != undefined)
+ time4L.push({ x: test, y: t4L });
+
+ let t16s = checkData(item._source['performance-data']['time16-states-s']);
+ if (t16s != undefined)
+ time16S.push({ x: test, y: t16s });
+
+
+ let t16 = checkData(item._source['performance-data']['time16-states']);
+ if (t16 != undefined)
+ time16.push({ x: test, y: t16 });
+
+
+ let t16L = checkData(item._source['performance-data']['time16-states-l']);
+ if (t16L != undefined)
+ time16L.push({ x: test, y: t16L });
+
+ let t32s = checkData(item._source['performance-data']['time32-states-s']);
+ if (t32s != undefined)
+ time32S.push({ x: test, y: t32s });
+
+ let t32 = checkData(item._source['performance-data']['time32-states']);
+ if (t32 != undefined)
+ time32.push({ x: test, y: t32 });
+
+
+ let t32L = checkData(item._source['performance-data']['time32-states-l']);
+ if (t32L != undefined)
+ time32L.push({ x: test, y: t32L });
+
+
+
+ let t64s = checkData(item._source['performance-data']['time64-states-s']);
+ if (t64s != undefined)
+ time64S.push({ x: test, y: t64s });
+
+ let t64 = checkData(item._source['performance-data']['time64-states']);
+ if (t64 != undefined)
+ time64.push({ x: test, y: t64 });
+
+ let t64L = checkData(item._source['performance-data']['time64-states-l']);
+ if (t64L != undefined)
+ time64L.push({ x: test, y: t64L });
+
+
+ let t128s = checkData(item._source['performance-data']['time128-states-s']);
+ if (t128s != undefined)
+ time128S.push({ x: test, y: t128s });
+
+ let t128 = checkData(item._source['performance-data']['time128-states']);
+ if (t128 != undefined)
+ time128.push({ x: test, y: t128 });
+
+ let t128L = checkData(item._source['performance-data']['time128-states-l']);
+ if (t128L != undefined)
+ time128L.push({ x: test, y: t128L });
+
+
+ let t256s = checkData(item._source['performance-data']['time256-states-s']);
+ if (t256s != undefined)
+ time256S.push({ x: test, y: t256s });
+
+ let t256 = checkData(item._source['performance-data']['time256-states']);
+ if (t256 != undefined)
+ time256.push({ x: test, y: t256 });
+
+ let t256L = checkData(item._source['performance-data']['time256-states-l']);
+ if (t256L != undefined)
+ time256L.push({ x: test, y: t256L });
+
+ let t512s = checkData(item._source['performance-data']['time512-states-s']);
+ if (t512s != undefined)
+ time512S.push({ x: test, y: t512s });
+
+ let t512 = checkData(item._source['performance-data']['time512-states']);
+ if (t512 != undefined)
+ time512.push({ x: test, y: t512 });
+
+ let t512L = checkData(item._source['performance-data']['time512-states-l']);
+ if (t512L != undefined)
+ time512L.push({ x: test, y: t512L });
+
+ let t1024s = checkData(item._source['performance-data']['time1024-states-s']);
+ if (t1024s != undefined)
+ time1024S.push({ x: test, y: t1024s });
+
+ let t1024 = checkData(item._source['performance-data']['time1024-states']);
+ if (t1024 != undefined)
+ time1024.push({ x: test, y: t1024 });
+
+ let t1024L = checkData(item._source['performance-data']['time1024-states-l']);
+ if (t1024L != undefined)
+ time1024L.push({ x: test, y: t1024L });
+
+ let t2048s = checkData(item._source['performance-data']['time2048-states-s']);
+ if (t2048s != undefined)
+ time2048S.push({ x: test, y: t2048s });
+
+ let t2048 = checkData(item._source['performance-data']['time2048-states']);
+ if (t2048 != undefined)
+ time2048.push({ x: test, y: t2048 });
+
+ let t2048L = checkData(item._source['performance-data']['time2048-states-l']);
+ if (t2048L != undefined)
+ time2048L.push({ x: test, y: t2048L });
+
+ let t4096s = checkData(item._source['performance-data']['time4096-states-s']);
+ if (t4096s != undefined)
+ time4096S.push({ x: test, y: t4096s });
+
+ let t4096 = checkData(item._source['performance-data']['time4096-states']);
+ if (t4096 != undefined)
+ time4096.push({ x: test, y: t4096 });
+
+ let t4096L = checkData(item._source['performance-data']['time4096-states-l']);
+ if (t4096L != undefined)
+ time4096L.push({ x: test, y: t4096L });
+
+ let t8192s = checkData(item._source['performance-data']['time8192-states-s']);
+ if (t8192s != undefined)
+ time8192S.push({ x: test, y: t8192s });
+
+ let t8192 = checkData(item._source['performance-data']['time8192-states']);
+ if (t8192 != undefined)
+ time8192.push({ x: test, y: t8192 });
+
+ let t8192L = checkData(item._source['performance-data']['time8192-states-l']);
+ if (t8192L != undefined)
+ time8192L.push({ x: test, y: t8192L });
+
+ } else {
+
+ let t2s = checkData(item._source['performance-data']['time2-states-s']);
+ if (t2s != undefined)
+ time2S.push({ x: 0, y: t2s });
+
+ let t2 = checkData(item._source['performance-data']['time2-states']);
+ if (t2 != undefined)
+ time2.push({ x: 0, y: t2 });
+
+ let t2L = checkData(item._source['performance-data']['time2-states-l']);
+ if (t2L != undefined)
+ time2L.push({ x: 0, y: t2L });
+
+ let t4s = checkData(item._source['performance-data']['time4-states-s']);
+ if (t4s != undefined)
+ time4S.push({ x: 0, y: t4s });
+
+ let t4 = checkData(item._source['performance-data']['time4-states']);
+ if (t4 != undefined)
+ time4.push({ x: 0, y: t4 });
+
+ let t4L = checkData(item._source['performance-data']['time4-states-l']);
+ if (t4L != undefined)
+ time4L.push({ x: 0, y: t4L });
+
+ let t16s = checkData(item._source['performance-data']['time16-states-s']);
+ if (t16s != undefined)
+ time16S.push({ x: 0, y: t16s });
+
+
+ let t16 = checkData(item._source['performance-data']['time16-states']);
+ if (t16 != undefined)
+ time16.push({ x: 0, y: t16 });
+
+
+ let t16L = checkData(item._source['performance-data']['time16-states-l']);
+ if (t16L != undefined)
+ time16L.push({ x: 0, y: t16L });
+
+ let t32s = checkData(item._source['performance-data']['time32-states-s']);
+ if (t32s != undefined)
+ time32S.push({ x: 0, y: t32s });
+
+ let t32 = checkData(item._source['performance-data']['time32-states']);
+ if (t32 != undefined)
+ time32.push({ x: 0, y: t32 });
+
+
+ let t32L = checkData(item._source['performance-data']['time32-states-l']);
+ if (t32L != undefined)
+ time32L.push({ x: 0, y: t32L });
+
+ let t64s = checkData(item._source['performance-data']['time64-states-s']);
+ if (t64s != undefined)
+ time64S.push({ x: 0, y: t64s });
+
+ let t64 = checkData(item._source['performance-data']['time64-states']);
+ if (t64 != undefined)
+ time64.push({ x: 0, y: t64 });
+
+ let t64L = checkData(item._source['performance-data']['time64-states-l']);
+ if (t64L != undefined)
+ time64L.push({ x: 0, y: t64L });
+
+
+ let t128s = checkData(item._source['performance-data']['time128-states-s']);
+ if (t128s != undefined)
+ time128S.push({ x: 0, y: t128s });
+
+ let t128 = checkData(item._source['performance-data']['time128-states']);
+ if (t128 != undefined)
+ time128.push({ x: 0, y: t128 });
+
+ let t128L = checkData(item._source['performance-data']['time128-states-l']);
+ if (t128L != undefined)
+ time128L.push({ x: 0, y: t128L });
+
+
+ let t256s = checkData(item._source['performance-data']['time256-states-s']);
+ if (t256s != undefined)
+ time256S.push({ x: 0, y: t256s });
+
+ let t256 = checkData(item._source['performance-data']['time256-states']);
+ if (t256 != undefined)
+ time256.push({ x: 0, y: t256 });
+
+ let t256L = checkData(item._source['performance-data']['time256-states-l']);
+ if (t256L != undefined)
+ time256L.push({ x: 0, y: t256L });
+
+ let t512s = checkData(item._source['performance-data']['time512-states-s']);
+ if (t512s != undefined)
+ time512S.push({ x: 0, y: t512s });
+
+ let t512 = checkData(item._source['performance-data']['time512-states']);
+ if (t512 != undefined)
+ time512.push({ x: 0, y: t512 });
+
+ let t512L = checkData(item._source['performance-data']['time512-states-l']);
+ if (t512L != undefined)
+ time512L.push({ x: 0, y: t512L });
+
+ let t1024s = checkData(item._source['performance-data']['time1024-states-s']);
+ if (t1024s != undefined)
+ time1024S.push({ x: 0, y: t1024s });
+
+ let t1024 = checkData(item._source['performance-data']['time1024-states']);
+ if (t1024 != undefined)
+ time1024.push({ x: 0, y: t1024 });
+
+ let t1024L = checkData(item._source['performance-data']['time1024-states-l']);
+ if (t1024L != undefined)
+ time1024L.push({ x: 0, y: t1024L });
+
+ let t2048s = checkData(item._source['performance-data']['time2048-states-s']);
+ if (t2048s != undefined)
+ time2048S.push({ x: 0, y: t2048s });
+
+ let t2048 = checkData(item._source['performance-data']['time2048-states']);
+ if (t2048 != undefined)
+ time2048.push({ x: 0, y: t2048 });
+
+ let t2048L = checkData(item._source['performance-data']['time2048-states-l']);
+ if (t2048L != undefined)
+ time2048L.push({ x: 0, y: t2048L });
+
+ let t4096s = checkData(item._source['performance-data']['time4096-states-s']);
+ if (t4096s != undefined)
+ time4096S.push({ x: 0, y: t4096s });
+
+ let t4096 = checkData(item._source['performance-data']['time4096-states']);
+ if (t4096 != undefined)
+ time4096.push({ x: 0, y: t4096 });
+
+ let t4096L = checkData(item._source['performance-data']['time4096-states-l']);
+ if (t4096L != undefined)
+ time4096L.push({ x: 0, y: t4096L });
+
+ let t8192s = checkData(item._source['performance-data']['time8192-states-s']);
+ if (t8192s != undefined)
+ time8192S.push({ x: 0, y: t8192s });
+
+ let t8192 = checkData(item._source['performance-data']['time8192-states']);
+ if (t8192 != undefined)
+ time8192.push({ x: 0, y: t8192 });
+
+ let t8192L = checkData(item._source['performance-data']['time8192-states-l']);
+ if (t8192L != undefined)
+ time8192L.push({ x: 0, y: t8192L });
+
+ }
+ });
+
+ if (time2S.length > 0) {
+ $scope.modultaionSeries.push('QAM2S B');
+ $scope.modulationData.push(time2S);
+ }
+
+ if (time2.length > 0) {
+ $scope.modultaionSeries.push('QAM2 B');
+ $scope.modulationData.push(time2);
+ }
+
+ if (time2L.length > 0) {
+ $scope.modultaionSeries.push('QAM2L B');
+ $scope.modulationData.push(time2L);
+ }
+
+ if (time4S.length > 0) {
+ $scope.modultaionSeries.push('QAM4S B');
+ $scope.modulationData.push(time4S);
+ }
+
+ if (time4.length > 0) {
+ $scope.modultaionSeries.push('QAM4 B');
+ $scope.modulationData.push(time4);
+ }
+
+ if (time4L.length > 0) {
+ $scope.modultaionSeries.push('QAM4L B');
+ $scope.modulationData.push(time4L);
+ }
+
+ if (time16S.length > 0) {
+ $scope.modultaionSeries.push('QAM16S B');
+ $scope.modulationData.push(time16S);
+ }
+
+
+ if (time16.length > 0) {
+ $scope.modultaionSeries.push('QAM16 B');
+ $scope.modulationData.push(time16);
+ }
+
+
+ if (time16L.length > 0) {
+ $scope.modultaionSeries.push('QAM16L B');
+ $scope.modulationData.push(time16L);
+ }
+
+ if (time32S.length > 0) {
+ $scope.modulationData.push(time32S);
+ $scope.modultaionSeries.push('QAM32S B');
+ }
+
+ if (time32.length > 0) {
+ $scope.modulationData.push(time32);
+ $scope.modultaionSeries.push('QAM32 B');
+ }
+
+ if (time32L.length > 0) {
+ $scope.modulationData.push(time32L);
+ $scope.modultaionSeries.push('QAM32L B');
+ }
+
+
+ if (time64S.length > 0) {
+ $scope.modulationData.push(time64S);
+ $scope.modultaionSeries.push('QAM64S B');
+ }
+
+
+ if (time64.length > 0) {
+ $scope.modulationData.push(time64);
+ $scope.modultaionSeries.push('QAM64 B');
+ }
+
+ if (time64L.length > 0) {
+ $scope.modulationData.push(time64L);
+ $scope.modultaionSeries.push('QAM64L B');
+ }
+
+
+ if (time128S.length > 0) {
+ $scope.modultaionSeries.push('QAM128S B');
+ $scope.modulationData.push(time128S);
+ }
+
+ if (time128.length > 0) {
+ $scope.modultaionSeries.push('QAM128 B');
+ $scope.modulationData.push(time128);
+ }
+
+ if (time128L.length > 0) {
+ $scope.modultaionSeries.push('QAM128L B');
+ $scope.modulationData.push(time128L);
+ }
+
+ if (time256S.length > 0) {
+ $scope.modulationData.push(time256S);
+ $scope.modultaionSeries.push('QAM256S B');
+ }
+
+ if (time256.length > 0) {
+ $scope.modulationData.push(time256);
+ $scope.modultaionSeries.push('QAM256 B');
+ }
+
+ if (time256L.length > 0) {
+ $scope.modulationData.push(time256L);
+ $scope.modultaionSeries.push('QAM256L B');
+ }
+
+ if (time512S.length > 0) {
+ $scope.modultaionSeries.push('QAM512S B');
+ $scope.modulationData.push(time512S);
+
+ }
+
+ if (time512.length > 0) {
+ $scope.modultaionSeries.push('QAM512 B');
+ $scope.modulationData.push(time512);
+
+ }
+
+ if (time512S.length > 0) {
+ $scope.modultaionSeries.push('QAM512S B');
+ $scope.modulationData.push(time512S);
+ }
+
+ if (time512.length > 0) {
+ $scope.modultaionSeries.push('QAM512 B');
+ $scope.modulationData.push(time512);
+ }
+
+ if (time512L.length > 0) {
+ $scope.modultaionSeries.push('QAM512L B');
+ $scope.modulationData.push(time512L);
+ }
+
+ if (time1024S.length > 0) {
+ $scope.modultaionSeries.push('QAM1024S B');
+ $scope.modulationData.push(time1024S);
+
+ }
+
+ if (time1024.length > 0) {
+ $scope.modultaionSeries.push('QAM1024 B');
+ $scope.modulationData.push(time1024);
+ }
+
+
+ if (time1024L.length > 0) {
+ $scope.modultaionSeries.push('QAM1024L B');
+ $scope.modulationData.push(time1024L);
+
+ }
+
+
+ if (time2048S.length > 0) {
+ $scope.modultaionSeries.push('QAM2048S B');
+ $scope.modulationData.push(time2048S);
+
+ }
+
+ if (time2048.length > 0) {
+ $scope.modultaionSeries.push('QAM2048 B');
+ $scope.modulationData.push(time2048);
+ }
+
+ if (time2048L.length > 0) {
+ $scope.modultaionSeries.push('QAM2048L B');
+ $scope.modulationData.push(time2048L);
+ }
+
+ if (time4096S.length > 0) {
+ $scope.modultaionSeries.push('QAM4096S B');
+ $scope.modulationData.push(time4096S);
+ }
+
+ if (time4096.length > 0) {
+ $scope.modultaionSeries.push('QAM4096 B');
+ $scope.modulationData.push(time4096);
+ }
+
+
+ if (time4096L.length > 0) {
+ $scope.modultaionSeries.push('QAM4096L B');
+ $scope.modulationData.push(time4096L);
+
+ }
+
+ if (time8192S.length > 0) {
+ $scope.modultaionSeries.push('QAM8192S B');
+ $scope.modulationData.push(time8192S);
+
+ }
+
+
+ if (time8192.length > 0) {
+ $scope.modultaionSeries.push('QAM8192 B');
+ $scope.modulationData.push(time8192);
+
+ }
+
+ if (time8192L.length > 0) {
+ $scope.modultaionSeries.push('QAM8192L B');
+ $scope.modulationData.push(time8192L);
+
+ }
+
+ let patternArray = ['rect', 'triangle', 'point', 'cross'];
+ let patternCounter = 0;
+
+ //add y axis override and remove color below graph for all items in chart series
+ for (let i = 0; i < $scope.modultaionSeries.length; i++) {
+ $scope.modulationDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.modulationDatasetOverride[i].fill = false;
+
+ //override points in graph
+ $scope.modulationDatasetOverride[i].pointStyle = patternArray[patternCounter];
+ patternCounter++;
+ if (patternCounter === 4) patternCounter = 0;
+ $scope.modulationDatasetOverride[i].pointRadius = 10;
+
+ }
+ }
+
+ break;
+
+ case 'temperature': {
+
+ $scope.tempData = [];
+ $scope.tempSeries = [];
+ $scope.tempDatasetOverride = [];
+
+ $scope.tempOptions = {
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.tempLabelMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ var timestamp = $scope.tempLabelMap.get($scope.tempLabelMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+
+ var vaue = $scope.tempLabelMap.get(tooltipItem[0].xLabel);
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+ };
+
+ $scope.temptestMap = new Map();
+ $scope.tempLabelMap = new Map();
+
+
+ tempArr.map(function (item, index) {
+ $scope.temptestMap.set(item, index);
+ $scope.tempLabelMap.set(index, item);
+ });
+
+ //process data for a side
+ var maxListA = [];
+ var minListA = [];
+ var avgListA = [];
+
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.temptestMap.get(timestamp);
+ if (test) {
+ maxListA.push({ x: test, y: item._source['performance-data']['rf-temp-max'] });
+ minListA.push({ x: test, y: item._source['performance-data']['rf-temp-min'] });
+ avgListA.push({ x: test, y: item._source['performance-data']['rf-temp-avg'] });
+ } else {
+
+ maxListA.push({ x: 0, y: item._source['performance-data']['rf-temp-max'] });
+ minListA.push({ x: 0, y: item._source['performance-data']['rf-temp-min'] });
+ avgListA.push({ x: 0, y: item._source['performance-data']['rf-temp-avg'] });
+ }
+ });
+
+ $scope.tempSeries.push('Rf temp max A', 'Rf temp min A', 'Rf temp avg A');
+
+
+ $scope.tempData.push(maxListA);
+ $scope.tempData.push(minListA);
+ $scope.tempData.push(avgListA);
+
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+ //process data fro side b
+
+ var maxListB = [];
+ var minListB = [];
+ var avgListB = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+ var test = $scope.temptestMap.get(timestamp);
+ if (test) {
+ maxListB.push({ x: test, y: item._source['performance-data']['rf-temp-max'] });
+ minListB.push({ x: test, y: item._source['performance-data']['rf-temp-min'] });
+ avgListB.push({ x: test, y: item._source['performance-data']['rf-temp-avg'] });
+ } else {
+
+ maxListB.push({ x: 0, y: item._source['performance-data']['rf-temp-max'] });
+ minListB.push({ x: 0, y: item._source['performance-data']['rf-temp-min'] });
+ avgListB.push({ x: 0, y: item._source['performance-data']['rf-temp-avg'] });
+ }
+ });
+
+ $scope.tempSeries.push('Rf temp max B', 'Rf temp min B', 'Rf temp avg B');
+
+
+
+ $scope.tempData.push(maxListB);
+ $scope.tempData.push(minListB);
+ $scope.tempData.push(avgListB);
+
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.tempDatasetOverride.push({ yAxisID: 'y-axis-1' });
+
+ overridePoints($scope.tempSeries, $scope.tempDatasetOverride);
+ }
+ break;
+
+ case 'snir': {
+
+ $scope.snirChartData = [];
+ $scope.snirSeries = [];
+ $scope.snirsetOverride = [];
+
+ $scope.snirOptions = {
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.snirLabelMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ var timestamp = $scope.snirLabelMap.get($scope.snirLabelMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+
+ var vaue = $scope.snirLabelMap.get(tooltipItem[0].xLabel);
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+ };
+
+ $scope.snirtestMap = new Map();
+ $scope.snirLabelMap = new Map();
+
+ tempArr.map(function (item, index) {
+ $scope.snirtestMap.set(item, index);
+ $scope.snirLabelMap.set(index, item);
+ });
+
+ var maxListA = [];
+ var minListA = [];
+ var avgListA = [];
+
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.snirtestMap.get(timestamp);
+ if (test) {
+ maxListA.push({ x: test, y: item._source['performance-data']['rf-temp-max'] });
+ minListA.push({ x: test, y: item._source['performance-data']['rf-temp-min'] });
+ avgListA.push({ x: test, y: item._source['performance-data']['rf-temp-avg'] });
+ } else {
+ maxListA.push({ x: 0, y: item._source['performance-data']['rf-temp-max'] });
+ minListA.push({ x: 0, y: item._source['performance-data']['rf-temp-min'] });
+ avgListA.push({ x: 0, y: item._source['performance-data']['rf-temp-avg'] });
+ }
+ });
+
+ $scope.snirSeries.push('Snir max A', 'Snir min A', 'Snir avg A');
+
+
+ $scope.snirChartData.push(maxListA);
+ $scope.snirChartData.push(minListA);
+ $scope.snirChartData.push(avgListA);
+
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+
+ var maxListB = [];
+ var minListB = [];
+ var avgListB = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+ var test = $scope.snirtestMap.get(timestamp);
+ if (test) {
+ maxListB.push({ x: test, y: item._source['performance-data']['rf-temp-max'] });
+ minListB.push({ x: test, y: item._source['performance-data']['rf-temp-min'] });
+ avgListB.push({ x: test, y: item._source['performance-data']['rf-temp-avg'] });
+ } else {
+ maxListB.push({ x: 0, y: item._source['performance-data']['rf-temp-max'] });
+ minListB.push({ x: 0, y: item._source['performance-data']['rf-temp-min'] });
+ avgListB.push({ x: 0, y: item._source['performance-data']['rf-temp-avg'] });
+ }
+ });
+
+ $scope.snirSeries.push('Snir max B', 'Snir min B', 'Snir avg B');
+
+
+
+ $scope.snirChartData.push(maxListB);
+ $scope.snirChartData.push(minListB);
+ $scope.snirChartData.push(avgListB);
+
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.snirsetOverride.push({ yAxisID: 'y-axis-1' });
+
+ overridePoints($scope.snirSeries, $scope.snirsetOverride);
+ }
+ break;
+
+ case 'crossPolarDiscrimination': {
+
+ $scope.xpdChartData = [];
+ $scope.xpdSeries = [];
+ $scope.crossPolarDiscriminationsetOverride = [];
+
+ $scope.xpdOptions = {
+ scales: {
+ xAxes: [{
+
+ type: 'linear',
+ position: 'bottom',
+ afterTickToLabelConversion: function (data) { //adds our custom timestamp labels
+
+ var xLabels = data.ticks;
+ xLabels.forEach(function (labels, i) {
+ var timestamp = $scope.xpdLabelMap.get(parseInt(labels));
+ if (parseInt(labels) == labels)
+ xLabels[i] = timestamp;
+ else
+ xLabels[i] = '';
+
+ });
+
+ //calculate last timestamp if label is missing
+ if (xLabels[xLabels.length - 1] === undefined) {
+ var timestamp = $scope.xpdLabelMap.get($scope.xpdLabelMap.size - 1);
+ let stopper = true;
+ let counter = 0;
+ let labelLength = xLabels.length - 1;
+ while (stopper) {
+ if (labelLength % 10 == 0) {
+ stopper = false;
+ } else {
+ labelLength++;
+ counter++;
+ }
+ }
+
+ xLabels[xLabels.length - 1] = calculateMissingTimestamp(timestamp, counter);
+ }
+ }
+ }],
+ yAxes: [
+ {
+ id: 'y-axis-1',
+ type: 'linear',
+ display: true,
+ position: 'left'
+ }
+ ]
+ },
+ tooltips: {
+ enabled: true,
+ mode: 'point',
+ callbacks: {
+ title: function (tooltipItem, data) { //picks right tool tip
+
+ var vaue = $scope.xpdLabelMap.get(tooltipItem[0].xLabel);
+ return vaue;
+ }
+ }
+ },
+ legend: {
+ display: true,
+ position: "bottom"
+ }
+ };
+
+ $scope.xpdtestMap = new Map();
+ $scope.xpdLabelMap = new Map();
+
+ tempArr.map(function (item, index) {
+ $scope.xpdtestMap.set(item, index);
+ $scope.xpdLabelMap.set(index, item);
+ });
+
+ var maxListA = [];
+ var minListA = [];
+ var avgListA = [];
+
+ dataA.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+
+ var test = $scope.xpdtestMap.get(timestamp);
+ if (test) {
+ maxListA.push({ x: test, y: item._source['performance-data']['xpd-max'] });
+ minListA.push({ x: test, y: item._source['performance-data']['xpd-min'] });
+ avgListA.push({ x: test, y: item._source['performance-data']['xpd-avg'] });
+ } else {
+ maxListA.push({ x: 0, y: item._source['performance-data']['xpd-max'] });
+ minListA.push({ x: 0, y: item._source['performance-data']['xpd-min'] });
+ avgListA.push({ x: 0, y: item._source['performance-data']['xpd-avg'] });
+ }
+ });
+
+ $scope.xpdSeries.push('CPD max A', 'CPD min A', 'CPD avg A');
+
+
+ $scope.xpdChartData.push(maxListA);
+ $scope.xpdChartData.push(minListA);
+ $scope.xpdChartData.push(avgListA);
+
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+
+ var maxListB = [];
+ var minListB = [];
+ var avgListB = [];
+
+ dataB.data.hits.hits.map(function (item, index) {
+ var timestamp = $mwtnPerformanceLink.formatTimeStamp(item._source['time-stamp']);
+ var test = $scope.xpdtestMap.get(timestamp);
+ if (test) {
+ maxListB.push({ x: test, y: item._source['performance-data']['xpd-max'] });
+ minListB.push({ x: test, y: item._source['performance-data']['xpd-min'] });
+ avgListB.push({ x: test, y: item._source['performance-data']['xpd-avg'] });
+ } else {
+ maxListB.push({ x: 0, y: item._source['performance-data']['xpd-max'] });
+ minListB.push({ x: 0, y: item._source['performance-data']['xpd-min'] });
+ avgListB.push({ x: 0, y: item._source['performance-data']['xpd-avg'] });
+ }
+ });
+
+ $scope.xpdSeries.push('CPD max B', 'CPD min B', 'CPD avg B');
+
+ $scope.xpdChartData.push(maxListB);
+ $scope.xpdChartData.push(minListB);
+ $scope.xpdChartData.push(avgListB);
+
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+ $scope.crossPolarDiscriminationsetOverride.push({ yAxisID: 'y-axis-1' });
+
+ overridePoints($scope.xpdSeries, $scope.crossPolarDiscriminationsetOverride);
+
+ }
+ break;
+
+ }
+ };
+
+ var getColor = function (hexcolorCode) {
+ var color = {
+ backgroundColor: hexcolorCode, pointBackgroundColor: hexcolorCode,
+ pointHoverBackgroundColor: hexcolorCode,
+ borderColor: hexcolorCode,
+ pointBorderColor: hexcolorCode,
+ pointHoverBorderColor: hexcolorCode,
+ fill: false
+ };
+ return color;
+ };
+
+ var getData = function (from, size, networkElement, selectedLtpId) {
+
+ var sort = [{ "time-stamp": { order: 'desc' } }];
+
+ var query = { "query": { "bool": { "must": [{ prefix: { "node-name": networkElement } }] } } };
+
+
+ //add layer protocol selector to filter query
+ query.query.bool.must.push({ prefix: { "layer-protocol-name": "MWPS" } });
+
+ //add interface selector to filter query
+ if (selectedLtpId && selectedLtpId !== 'Select LTP') {
+ query.query.bool.must.push({ prefix: { "uuid-interface": selectedLtpId } });
+ }
+
+ var selected15minPeriod = true;
+ if ($scope.timePeriod !== $scope.timePeriods[0]) selected15minPeriod = false;
+
+ return $mwtnPerformanceLink.getFilteredSortedData(from, size, sort, query, selected15minPeriod);
+ };
+
+ $scope.status = { ne: false };
+ $scope.spinner = { ne: false };
+
+ // events
+ $scope.$watch('linkId', function (newValue, oldValue) {
+ if (newValue && oldValue !== "" && newValue !== oldValue) {
+
+ var functionId = 'sdnperformance';
+ var docType = 'historicalperformance15min';
+ if ($scope.timePeriod !== $scope.timePeriods[0]) {
+ docType = 'historicalperformance24h';
+ }
+ var aggregations = {
+ "size":0,
+ "query": {
+ "match": {
+ "radio-signal-id": newValue
+ }
+ },
+ "aggregations": {
+ "node-name": {
+ "terms": {
+ "field": "node-name"
+ }
+ },
+ "ltp": {
+ "terms": {
+ "field": "uuid-interface"
+ }
+ }
+ }
+ };
+ $mwtnPerformanceLink.getAggregations(functionId, docType, aggregations).then(function (success) {
+ console.log(JSON.stringify(success));
+ var nodes = success.data.aggregations['node-name'].buckets.map(function(bucket){
+ return bucket.key;
+ });
+ console.warn(nodes);
+ if (nodes.length = 0) {
+ $scope.networkElementA = '';
+ $scope.networkElementB = '';
+ } else if (nodes.length = 1) {
+ $scope.networkElementA = nodes[0];
+ $scope.networkElementB = '';
+ } else if (nodes.length = 2) {
+ $scope.networkElementA = nodes[0];
+ $scope.networkElementB = nodes[1]
+ } else {
+ $scope.networkElementA = nodes[0];
+ $scope.networkElementB = nodes[1]
+ console.warn('Check nodes for radio signal id: ' + newValue + ' ' + JSON.stringify(nodes));
+ }
+ var ltps = success.data.aggregations['ltp'].buckets.map(function(bucket){
+ return bucket.key;
+ });
+ if (ltps.length = 0) {
+ $scope.selectedLtpIdA = '';
+ $scope.selectedLtpIdB = '';
+ } else if (ltps.length = 1) {
+ $scope.selectedLtpIdA = ltps[0];
+ $scope.selectedLtpIdB = ltps[0];
+ } else if (ltps.length = 2) {
+ // TODO Who belongs to whom - just guessing ;/
+ $scope.selectedLtpIdA = ltps[0];
+ $scope.selectedLtpIdB = ltps[1]
+ } else {
+ $scope.selectedLtpIdA = ltps[0];
+ $scope.selectedLtpIdB = ltps[1]
+ console.warn('Check ltps for radio signal id: ' + newValue + ' ' + JSON.stringify(nodes));
+ }
+ }, function (error) {
+ console.log(error);
+ $scope.networkElementA = '';
+ $scope.networkElementB = '';
+ $scope.selectedLtpIdA = '';
+ $scope.selectedLtpIdB = '';
+ });
+ }
+ });
+
+ $scope.$watch('selectedLtpIdA', function (newValue, oldValue) {
+ if (newValue && oldValue !== "" && newValue !== oldValue) {
+ //TODO: get data based on open grids
+ Object.keys($scope.status).map(function (key) {
+ if ($scope.status[key]) {
+ $scope.defaultColors = [];
+ $scope.defaultColors.push(getColor('#0062ff'));
+ $scope.defaultColors.push(getColor('#b9341b'));
+ $scope.defaultColors.push(getColor('#f0141f'));
+ $scope.defaultColors.push(getColor('#4c7759'));
+ $scope.defaultColors.push(getColor('#55b64e'));
+ $scope.defaultColors.push(getColor("#6c8995"));
+
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, key)
+ $window.dispatchEvent(new Event("resize"));
+ }
+ });
+ }
+
+ }, true);
+
+ $scope.$watch('selectedLtpIdB', function (newValue, oldValue) {
+ if (newValue && oldValue !== "" && newValue !== oldValue && newValue != 'Select LTP') {
+ Object.keys($scope.status).map(function (key) {
+ if ($scope.status[key]) {
+ $scope.defaultColors = [];
+ $scope.defaultColors.push(getColor('#0062ff'));
+ $scope.defaultColors.push(getColor('#b9341b'));
+ $scope.defaultColors.push(getColor('#f0141f'));
+ $scope.defaultColors.push(getColor('#4c7759'));
+ $scope.defaultColors.push(getColor('#55b64e'));
+ $scope.defaultColors.push(getColor("#6c8995"));
+
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, key)
+ $window.dispatchEvent(new Event("resize"));
+ }
+ });
+ }
+
+ }, true);
+
+ $scope.$watch('status', function (status, oldValue) {
+ Object.keys(status).map(function (key) {
+ if ($scope.networkElementIdA && $scope.networkElementIdB && status[key] && status[key] !== oldValue[key]) {
+
+
+ //add a set of default colors for line graphs with 6 values
+ $scope.defaultColors = [];
+ $scope.defaultColors.push(getColor('#0062ff'));
+ $scope.defaultColors.push(getColor('#b9341b'));
+ $scope.defaultColors.push(getColor('#f0141f'));
+ $scope.defaultColors.push(getColor('#4c7759'));
+ $scope.defaultColors.push(getColor('#55b64e'));
+ $scope.defaultColors.push(getColor("#6c8995"));
+
+ getDataFromNEs($scope.networkElementIdA, $scope.selectedLtpIdA, $scope.networkElementIdB, $scope.selectedLtpIdB, key)
+ $window.dispatchEvent(new Event("resize"));
+
+ }
+
+ });
+ }, true);
+
+ $scope.$watch('timePeriod', function (newValue, oldValue) {
+
+ if (newValue && oldValue !== "" && newValue !== oldValue) {
+
+ //change page sizes and tell gridapi to update
+
+ $scope.gridOptionsReceiveLevel.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsReceiveLevel.paginationPageSize = $scope.gridOptionsReceiveLevel.paginationPageSizes[0];
+ $scope.recvGridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+ $scope.gridOptionsTransmissionLevel.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsTransmissionLevel.paginationPageSize = $scope.gridOptionsTransmissionLevel.paginationPageSizes[0];
+ $scope.transmissionGridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+
+ $scope.gridOptionsModulation.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsModulation.paginationPageSize = $scope.gridOptionsModulation.paginationPageSizes[0];
+ $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+ $scope.gridOptionsTemperature.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsTemperature.paginationPageSize = $scope.gridOptionsTemperature.paginationPageSizes[0];
+ $scope.gridTemperatureApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+ $scope.gridOptionsSnir.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsSnir.paginationPageSize = $scope.gridOptionsSnir.paginationPageSizes[0];
+ $scope.gridSNIRApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+ $scope.gridOptionsCrossPolarDiscrimination.paginationPageSizes = $scope.pageSizes();
+ $scope.gridOptionsCrossPolarDiscrimination.paginationPageSize = $scope.gridOptionsCrossPolarDiscrimination.paginationPageSizes[0];
+ $scope.gridXpdApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
+
+ //get new interface data
+ getInterfaces($scope.networkElementIdA, $scope.availableLtpIdsA);
+ getInterfaces($scope.networkElementIdB, $scope.availableLtpIdsB);
+ }
+
+ }, true);
+
+ $scope.collapseAll = function () {
+ // close all groups
+ Object.keys($scope.status).map(function (group) {
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function (group) {
+ $scope.spinner[group] = false;
+ });
+ };
+
+ //get data on ne selection
+
+ $scope.$watch('networkElementA', function (neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+ var revision;
+ $scope.networkElements.map(function (ne) {
+ if (ne.id === neId) revision = ne.revision;
+ });
+ $scope.networkElementIdA = neId;
+ $scope.revisionA = revision;
+
+ getInterfaces(neId, $scope.availableLtpIdsA);
+ $scope.collapseAll();
+
+ }
+ });
+
+ $scope.$watch('networkElementB', function (neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+ var revision;
+ $scope.networkElements.map(function (ne) {
+ if (ne.id === neId) revision = ne.revision;
+ });
+ $scope.networkElementIdB = neId;
+ $scope.revisionB = revision;
+
+ getInterfaces(neId, $scope.availableLtpIdsB);
+ $scope.collapseAll();
+
+ }
+ });
+
+ var getInterfaces = function (networkElement, networkList) {
+
+ //clear interface array
+ var length = networkList.length;
+ networkList.splice(1, length);
+
+ //request to get interfaces
+ var aggr = {
+ "size": 0,
+ "aggregations": {
+ "neinterfaces": {
+ "filter": {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "node-name": networkElement
+ }
+ },
+ {
+ "term": {
+ "layer-protocol-name": "MWPS"
+ }
+ }
+ ]
+ }
+ },
+ "aggregations": {
+ "interfaces": {
+ "terms": {
+ "field": "uuid-interface"
+ }
+ }
+ }
+ }
+ }
+ };
+
+
+ var selected15minPeriod = true;
+ if ($scope.timePeriod !== $scope.timePeriods[0]) selected15minPeriod = false;
+
+ $mwtnPerformanceLink.getInterfaces(aggr, selected15minPeriod).then(function (response) {
+
+ if (response.data.aggregations.neinterfaces.interfaces.buckets.length >= 0) {
+ response.data.aggregations.neinterfaces.interfaces.buckets.map(function (item) {
+ networkList.push(item.key);
+ });
+ }
+
+
+ });
+ };
+
+
+ }]);
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.module.js
new file mode 100644
index 00000000..34a0d583
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.module.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnPerformanceLinkApp = angular.module('app.mwtnPerformanceLink', ['ui.grid','chart.js', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'ui.router.state','ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.pagination']);
+
+ mwtnPerformanceLinkApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnPerformanceLinkApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnPerformanceLink/mwtnPerformanceLink.controller');
+ NavHelperProvider.addToMenu('mwtnPerformanceLink', {
+ "link" : "#/pnfPerformanceLink",
+ "active" : "main.mwtnPerformanceLink",
+ "title" : "pnf PM Link",
+ "icon" : "fa fa-bar-chart", // Add navigation icon css class here
+ "page" : {
+ "title" : "pnf PM Link",
+ "description" : "mwtnLinkPerformance"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnPerformanceLink', {
+ url: 'pnfPerformanceLink',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnPerformanceLink/mwtnPerformanceLink.tpl.html',
+ controller: 'mwtnPerformanceLinkCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnPerformanceLinkApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.services.js
new file mode 100644
index 00000000..eb18b629
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.services.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 HCL Inc. 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/mwtnPerformanceLink/mwtnPerformanceLink.module'], function (mwtnPerformanceLinkApp) {
+
+ mwtnPerformanceLinkApp.register.factory('$mwtnPerformanceLink', function ($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnPerformanceLink';
+ $mwtnLog.info({ component: COMPONENT, message: '$mwtnPerformanceLink started!' });
+
+ var service = {};
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.getAggregations = $mwtnDatabase.getAggregations;
+
+
+ service.TimeStampToONFFormat = function (timestamp) {
+ timestamp = timestamp.split('-').join('');
+ timestamp = timestamp.split(':').join('');
+ timestamp = timestamp.split(' ').join('');
+ timestamp = timestamp.replace('UTC', 'Z');
+ return timestamp;
+ };
+
+ service.getFilteredSortedData = function (from, size, sort, query, selected15minPeriod) {
+
+ var functionId = 'sdnperformance';
+ var docType = 'historicalperformance15min';
+ if (selected15minPeriod === false) {
+ docType = 'historicalperformance24h';
+ }
+
+ var deferred = $q.defer();
+ $mwtnDatabase.getFilteredSortedData(functionId, docType, from, size, sort, query).then(function (success) {
+ deferred.resolve(success);
+ }, function (error) {
+ $mwtnLog.error({ component: '$mwtnPerformanceLink.getFilteredSortedData', message: JSON.stringify(error.data) });
+ deferred.reject(error)
+ });
+ return deferred.promise;
+ };
+
+ service.getInterfaces = function (aggregation, selected15minPeriod) {
+
+ var functionId = 'sdnperformance';
+ var docType = 'historicalperformance15min';
+ if (selected15minPeriod === false) {
+ docType = 'historicalperformance24h';
+ }
+
+ var deferred = $q.defer();
+ $mwtnDatabase.getAggregatedData(functionId, docType, aggregation).then(function (success) {
+ deferred.resolve(success);
+ }, function (error) {
+ $mwtnLog.error({ component: '$mwtnPerformanceLink.getFilteredSortedData', message: JSON.stringify(error.data) });
+ deferred.reject(error)
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.tpl.html
new file mode 100644
index 00000000..a65d5cf2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/mwtnPerformanceLink-module/src/main/resources/mwtnPerformanceLink/mwtnPerformanceLink.tpl.html
@@ -0,0 +1,487 @@
+<ht-header help-link='sdnr/pnfPerformance/0.4.0/README.md'></ht-header>
+<div class="owl container">
+
+<!-- input for link id
+ <div class="row">
+ <div class="col-md-2 text-right radio">
+ <span>{{'MWTN_LINK_IDENTIFIER' | translate }}</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <input list="linkIds" class="form-control" ng-model="linkId">
+ <datalist id="linkIds">
+ <option ng-repeat="linkId in linkIds" value="{{linkId}}" >{{linkId}}</option>
+ </datalist>
+ </div>
+ </div>
+ </div> -->
+
+ <div class="row">
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'MWTN_NETWORKELEMENT' | translate}} A</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <input list="networkElementsA" class="form-control" ng-model="networkElementA" placeholder="Select network element">
+ <datalist id="networkElementsA">
+ <option ng-repeat="ne in networkElements" value="{{ne.id}}">{{ne.id}}</option>
+ </datalist>
+ </div>
+ </div>
+
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'MWTN_NETWORKELEMENT' | translate}} B</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <input list="networkElementsB" class="form-control" ng-model="networkElementB" placeholder="Select network element">
+ <datalist id="networkElementsB">
+ <option ng-repeat="ne in networkElements" value="{{ne.id}}">{{ne.id}}</option>
+ </datalist>
+ </div>
+ </div>
+
+ </div>
+ <div class="row">
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'MWTN_AIR_INTERFACE' | translate }} A</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <select class="form-control" ng-model="selectedLtpIdA">
+ <option ng-repeat="protocol in availableLtpIdsA">{{protocol}}</option>
+ </select>
+ </div>
+ </div>
+
+
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'MWTN_AIR_INTERFACE' | translate }} B</span>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <select class="form-control" ng-model="selectedLtpIdB">
+ <option ng-repeat="protocol in availableLtpIdsB">{{protocol}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-2 text-right radio">
+ <span class="white">{{'MWTN_TIME_PERIOD' | translate}}</span>
+ </div>
+ <div class="col-md-2">
+ <div class="form-group">
+ <select class="form-control" ng-model="timePeriod">
+ <option ng-repeat="time in timePeriods">{{time}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <div class="row" ng-if="networkElementA && networkElementB && selectedLtpIdA !== 'Select LTP' && selectedLtpIdB !== 'Select LTP' ">
+ <uib-accordion close-others="true">
+ <div uib-accordion-group class="panel-primary" is-open="status.receiveLevel">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.receiveLevel, 'fa-chevron-right': !status.receiveLevel}"></i>
+ <span>Receive Level</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.receiveLevel"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="receiveData"
+ chart-series="receiveSeries"
+ chart-options="receiveOptions"
+ chart-dataset-override="receiveDatasetOverride"
+ chart-colors="defaultColors">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+
+ <div
+ ui-grid="gridOptionsReceiveLevel"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnLinkGrid">
+ </div>
+
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsReceiveLevel.paginationCurrentPage === 1"
+ ng-click="recvGridApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsReceiveLevel.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsReceiveLevel.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsReceiveLevel.paginationCurrentPage === 1}"
+ ng-click="recvGridApi.pagination.previousPage()"
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsReceiveLevel.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsReceiveLevel.paginationCurrentPage,'receiveLevel')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ recvGridApi.pagination.getTotalPages() }}</span>
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsReceiveLevel.paginationCurrentPage === recvGridApi.pagination.getTotalPages()"
+ ng-click="recvGridApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsReceiveLevel.paginationCurrentPage === recvGridApi.pagination.getTotalPages()"
+ ng-click="recvGridApi.pagination.seek(recvGridApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect" id="repeatSelect"
+ ng-init="gridOptionsReceiveLevel.paginationPageSize = gridOptionsReceiveLevel.paginationPageSizes[0]"
+ ng-model="gridOptionsReceiveLevel.paginationPageSize"
+ ng-options="option for option in gridOptionsReceiveLevel.paginationPageSizes"></select>
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('receiveLevel') }}</span>
+ </div>
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.transmissionLevel">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.transmissionLevel, 'fa-chevron-right': !status.transmissionLevel}"></i>
+ <span>Transmission Power</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.transmissionLevel"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="transmissionData"
+ chart-series="transmissionSeries"
+ chart-options="transmissionOptions"
+ chart-dataset-override="transmissionDatasetOverride"
+ chart-colors="defaultColors">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+ <div
+ ui-grid="gridOptionsTransmissionLevel"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnLinkGrid">
+ </div>
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsTransmissionLevel.paginationCurrentPage === 1"
+ ng-click="transmissionGridApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsTransmissionLevel.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsTransmissionLevel.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsTransmissionLevel.paginationCurrentPage === 1}"
+ ng-click="transmissionGridApi.pagination.previousPage()"
+
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsTransmissionLevel.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsTransmissionLevel.paginationCurrentPage,'transmissionLevel')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ transmissionGridApi.pagination.getTotalPages() }}</span>
+
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsTransmissionLevel.paginationCurrentPage === transmissionGridApi.pagination.getTotalPages()"
+ ng-click="transmissionGridApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsTransmissionLevel.paginationCurrentPage === transmissionGridApi.pagination.getTotalPages()"
+ ng-click="transmissionGridApi.pagination.seek(transmissionGridApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect"
+ ng-init="gridOptionsTransmissionLevel.paginationPageSize = gridOptionsTransmissionLevel.paginationPageSizes[0]"
+ ng-model="gridOptionsTransmissionLevel.paginationPageSize"
+ ng-options="option for option in gridOptionsTransmissionLevel.paginationPageSizes"></select>
+
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('transmissionLevel') }}</span>
+ </div>
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.modulation">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.modulation, 'fa-chevron-right': !status.modulation}"></i>
+ <span>Adaptive Modulation</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.modulation"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="modulationData"
+ chart-series="modultaionSeries"
+ chart-options="modulationOptions"
+ chart-dataset-override="modulationDatasetOverride">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+ <div
+ ui-grid="gridOptionsModulation"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns class="mwtnLinkGrid">
+ </div>
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsModulation.paginationCurrentPage === 1"
+ ng-click="gridApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsModulation.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsModulation.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsModulation.paginationCurrentPage === 1}"
+ ng-click="gridApi.pagination.previousPage()"
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsModulation.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsModulation.paginationCurrentPage,'modulation')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridApi.pagination.getTotalPages() }}</span>
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsModulation.paginationCurrentPage === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsModulation.paginationCurrentPage === gridApi.pagination.getTotalPages()"
+ ng-click="gridApi.pagination.seek(gridApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect"
+ ng-init="gridOptionsModulation.paginationPageSize = gridOptionsModulation.paginationPageSizes[0]"
+ ng-model="gridOptionsModulation.paginationPageSize"
+ ng-options="option for option in gridOptionsModulation.paginationPageSizes"></select>
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('modulation') }}</span>
+ </div>
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.temperature">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.temperature, 'fa-chevron-right': !status.temperature}"></i>
+ <span>Temperature</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.temperature"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="tempData"
+ chart-series="tempSeries"
+ chart-options="tempOptions"
+ chart-dataset-override="tempDatasetOverride"
+ chart-colors="defaultColors">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+ <div
+ ui-grid="gridOptionsTemperature"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns
+ class="mwtnLinkGrid">
+ </div>
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsTemperature.paginationCurrentPage === 1"
+ ng-click="gridTemperatureApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsTemperature.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsTemperature.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsTemperature.paginationCurrentPage === 1}"
+ ng-click="gridTemperatureApi.pagination.previousPage()"
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsTemperature.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsTemperature.paginationCurrentPage,'temperature')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridTemperatureApi.pagination.getTotalPages() }}</span>
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsTemperature.paginationCurrentPage === gridTemperatureApi.pagination.getTotalPages()"
+ ng-click="gridTemperatureApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsTemperature.paginationCurrentPage === gridTemperatureApi.pagination.getTotalPages()"
+ ng-click="gridTemperatureApi.pagination.seek(gridTemperatureApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect"
+ ng-init="gridOptionsTemperature.paginationPageSize = gridOptionsTemperature.paginationPageSizes[0]"
+ ng-model="gridOptionsTemperature.paginationPageSize"
+ ng-options="option for option in gridOptionsTemperature.paginationPageSizes"></select>
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('temperature') }}</span>
+ </div>
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.snir">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.snir, 'fa-chevron-right': !status.snir}"></i>
+ <span>{{'MWTN_SINR' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.snir"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="snirChartData"
+ chart-series="snirSeries"
+ chart-options="snirOptions"
+ chart-dataset-override="snirsetOverride"
+ chart-colors="defaultColors">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+ <div
+ ui-grid="gridOptionsSnir"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns
+ class="mwtnLinkGrid">
+ </div>
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsSnir.paginationCurrentPage === 1"
+ ng-click="gridSNIRApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsSnir.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsSnir.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsSnir.paginationCurrentPage === 1}"
+ ng-click="gridSNIRApi.pagination.previousPage()"
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsSnir.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsSnir.paginationCurrentPage,'snir')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridSNIRApi.pagination.getTotalPages() }}</span>
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsSnir.paginationCurrentPage === gridSNIRApi.pagination.getTotalPages()"
+ ng-click="gridSNIRApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsSnir.paginationCurrentPage === gridSNIRApi.pagination.getTotalPages()"
+ ng-click="gridSNIRApi.pagination.seek(gridSNIRApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect"
+ ng-init="gridOptionsSnir.paginationPageSize = gridOptionsSnir.paginationPageSizes[0]"
+ ng-model="gridOptionsSnir.paginationPageSize"
+ ng-options="option for option in gridOptionsSnir.paginationPageSizes"></select>
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('snir') }}</span>
+ </div>
+ </div>
+
+ <div uib-accordion-group class="panel-primary" is-open="status.crossPolarDiscrimination">
+ <uib-accordion-heading> <i class="pull-left fa"
+ ng-class="{'fa-chevron-down': status.crossPolarDiscrimination, 'fa-chevron-right': !status.crossPolarDiscrimination}"></i>
+ <span>Cross Polar Discrimination</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.crossPolarDiscrimination"></i>
+ </uib-accordion-heading>
+ <canvas id="line"
+ class="chart chart-line"
+ chart-data="xpdChartData"
+ chart-series="xpdSeries"
+ chart-options="xpdOptions"
+ chart-dataset-override="crossPolarDiscriminationsetOverride"
+ chart-colors="defaultColors">
+ </canvas
+ </div> <!-- canvas bugs with div, please keep in!-->
+ <div
+ ui-grid="gridOptionsCrossPolarDiscrimination"
+ ui-grid-pagination
+ ui-grid-exporter
+ ui-grid-selection
+ ui-grid-pinning
+ ui-grid-resize-columns
+ ui-grid-move-columns
+ class="mwtnLinkGrid">
+ </div>
+ <!-- pagniation controll for grid-->
+ <div class="ht-pagination">
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsCrossPolarDiscrimination.paginationCurrentPage === 1"
+ ng-click="gridXpdApi.pagination.seek(1)"
+ ng-class="{'cancelCursor':gridOptionsCrossPolarDiscrimination.paginationCurrentPage === 1}"
+ role="menuitem" type="button" title="Page to first" aria-label="Page to first">
+ <i class="fa fa-step-backward "></i>
+ </button>
+ <button class="btn btn-default"
+ ng-disabled="gridOptionsCrossPolarDiscrimination.paginationCurrentPage === 1"
+ ng-class="{'cancelCursor':gridOptionsCrossPolarDiscrimination.paginationCurrentPage === 1}"
+ ng-click="gridXpdApi.pagination.previousPage()"
+ role="menuitem" type="button" title="Previous Page" aria-label="Previous Page">
+ <i class="fa fa-play fa-rotate-180 "></i>
+ </button>
+ <input class="btn btn-default" style="text-align:right;" border="1"
+ ng-model="gridOptionsCrossPolarDiscrimination.paginationCurrentPage"
+ ng-change="seekPage(gridOptionsCrossPolarDiscrimination.paginationCurrentPage,'crossPolarDiscrimination')"
+ type="number" style="width:20px;"/>
+ <span class="dark">&nbsp;/ {{ gridXpdApi.pagination.getTotalPages() }}</span>
+ <button class="btn btn-default" role="menuitem" type="button" title="Next Page" aria-label="Next Page"
+ ng-disabled="gridOptionsCrossPolarDiscrimination.paginationCurrentPage === gridXpdApi.pagination.getTotalPages()"
+ ng-click="gridXpdApi.pagination.nextPage()">
+ <i class="fa fa-play "></i>
+ </button>
+ <button class="btn btn-default" ng-disabled="gridOptionsCrossPolarDiscrimination.paginationCurrentPage === gridXpdApi.pagination.getTotalPages()"
+ ng-click="gridXpdApi.pagination.seek(gridXpdApi.pagination.getTotalPages())"
+ role="menuitem" type="button" title="Page to last" aria-label="Page to last">
+ <i class="fa fa-step-forward "></i>
+ </button>
+ <select
+ class="btn btn-default" name="repeatSelect"
+ ng-init="gridOptionsCrossPolarDiscrimination.paginationPageSize = gridOptionsCrossPolarDiscrimination.paginationPageSizes[0]"
+ ng-model="gridOptionsCrossPolarDiscrimination.paginationPageSize"
+ ng-options="option for option in gridOptionsCrossPolarDiscrimination.paginationPageSizes"></select>
+ <span class="dark"> {{ itemsMessage() }}</span>
+ <span class="pull-right dark">{{ paginationStatusMessage('crossPolarDiscrimination') }}</span>
+ </div>
+ </div>
+ </uib-accordion>
+ </div>
+</div>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/pom.xml
new file mode 100644
index 00000000..840b923f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnPerformanceLink/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnPerformanceLink</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnPerformanceLink-module</module>
+ <module>mwtnPerformanceLink-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/pom.xml
new file mode 100644
index 00000000..7a50612c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnSpectrum</artifactId>
+ <groupId>cn.com.zte.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>mwtnSpectrum-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>cn.com.zte.odl.dlux</groupId>
+ <artifactId>mwtnSpectrum-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>cn.com.zte.odl.dlux</groupId>
+ <includeArtifactIds>mwtnSpectrum-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..51ddc024
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnSpectrum"/>
+ <property name="url" value="/src/app/mwtnSpectrum"/>
+ <property name="directory" value="/mwtnSpectrum"/>
+ <property name="requireJs" value="app/mwtnSpectrum/mwtnSpectrum.module"/>
+ <property name="angularJs" value="app.mwtnSpectrum"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnSpectrum/mwtnSpectrum-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/pom.xml
new file mode 100644
index 00000000..ca8ef939
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnSpectrum</artifactId>
+ <groupId>cn.com.zte.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>mwtnSpectrum-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/bluelight.gif b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/bluelight.gif
new file mode 100644
index 00000000..33de2178
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/bluelight.gif
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/mwtnSpectrum.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/mwtnSpectrum.png
new file mode 100755
index 00000000..23956335
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/images/mwtnSpectrum.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum-custom.css
new file mode 100644
index 00000000..df461795
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum-custom.css
@@ -0,0 +1,45 @@
+/**
+ * Add your application related css here
+ */
+
+.alarm div {
+ height: 160px;
+ vertical-align: middle;
+}
+
+.cleared {
+ color: lightgreen;
+}
+.cleared span {
+ color: lightgreen;
+}
+
+.raised {
+ color: red;
+}
+.raised span {
+ color: red;
+}
+
+.mwtnSpectrumGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.mwtnSpectrumGrid span {
+ color: #393939;
+}
+
+.mwtnSpectrumGrid span.mismatch {
+ font-weight: bold;
+ color: #428bca;
+}
+
+.mwtnSpectrumGrid .green {
+ color: darkgreen;
+}
+.mwtnSpectrumGrid .green span {
+ color: darkgreen;
+}
+
+ \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.controller.js
new file mode 100644
index 00000000..f2433853
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.controller.js
@@ -0,0 +1,135 @@
+/*
+ * 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/mwtnSpectrum/mwtnSpectrum.module',
+ 'app/mwtnSpectrum/mwtnSpectrum.services',
+ 'app/mwtnCommons/mwtnCommons.services'], function(mwtnSpectrumApp) {
+
+ mwtnSpectrumApp.register.controller('mwtnSpectrumCtrl', ['$scope', '$rootScope', 'uiGridConstants','$mwtnSpectrum', '$mwtnLog', 'OnfNetworkElement', 'MicrowavePhysicalSection',
+ function($scope, $rootScope, uiGridConstants, $mwtnSpectrum, $mwtnLog, OnfNetworkElement, MicrowavePhysicalSection) {
+
+ var COMPONENT = 'mwtnSpectrumCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnSpectrumCtrl started!'});
+
+ $rootScope.section_logo = 'src/app/mwtnSpectrum/images/mwtnSpectrum.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.interference = {
+ alarmStatus: 'cleared'
+ };
+
+ $scope.execute = function() {
+ $scope.interference.alarmStatus = 'raised';
+ $mwtnSpectrum.execute().then(function(success) {
+ $scope.interference.alarmStatus = 'cleared';
+ }, function(error) {
+ $scope.interference.alarmStatus = 'cleared';
+ });
+ };
+ $scope.clear = function() {
+ console.log("Cleared");
+ $scope.interference.alarmStatus = 'cleared';
+ };
+
+ var updateAirInterface = function(spec, data) {
+ if (data) {
+ var radioSignalID = data.airInterfaceConfiguration.radioSignalID;
+ $scope.gridOptions.data.map(function(row){
+ if (row.name === spec.nodeId && row.radioSignalID === radioSignalID) {
+ row.actualTxFrequency = data.airInterfaceConfiguration.txFrequency;
+ row.actualRxFrequency = data.airInterfaceConfiguration.rxFrequency;
+ }
+ });
+ } else {
+ $scope.gridOptions.data.map(function(row){
+ if (row.nodeId === spec.nodeId) {
+ row.actualTxFrequency = '?';
+ row.actualRxFrequency = '?';
+ }
+ });
+ }
+ };
+
+ $scope.processing = false;
+ $scope.refresh = function() {
+ $scope.processing = true;
+ $scope.interference.alarmStatus = 'cleared';
+ $mwtnSpectrum.refresh().then(function(success){
+ $scope.processing = false;
+ $scope.gridOptions.data = success.airInterfaces;
+ success.actualNodes.map(function(actualNode){
+ if (actualNode.connectionStatus !== 'connected') {
+ return;
+ }
+ var revision = '2016-09-01';
+ $mwtnSpectrum.getActualNetworkElement(actualNode.id, revision).then(function(onfNe){
+ var aOnfNe = new OnfNetworkElement(onfNe.NetworkElement);
+ aOnfNe.getLTPMwpsList().map(function(ltp){
+ var spec = {
+ nodeId: actualNode.id,
+ revision: revision,
+ pacId: 'airinterface',
+ layerProtocolId: ltp._lpList[0].uuid,
+ partId: 'Configuration'
+ };
+ $mwtnSpectrum.getPacParts(spec).then(function(success){
+ updateAirInterface(spec, success);
+ }, function(error){
+ updateAirInterface(spec, error);
+ });
+ });
+ }, function(error){
+ // do nothing
+ });
+ });
+ }, function(error){
+ $scope.processing = false;
+ $scope.gridOptions.data = [];
+ });
+ };
+
+ $scope.highlightFilteredHeader = $mwtnSpectrum.highlightFilteredHeader;
+
+ var requiredNesConnectionStatusCellTemplate = [
+ '<div class="ui-grid-cell-contents" ng-class="{ \'green\': grid.getCellValue(row, col) === \'connected\'}"}>',
+ ' <i ng-show="grid.getCellValue(row, col) === \'connected\'" class="fa fa-link" aria-hidden="true"></i>',
+ ' <span>{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ var actualTxFrequencyCellTemplate = [
+ '<div class="ui-grid-cell-contents" ng-class="{ \'green\': grid.getCellValue(row, col) === \'connected\'}"}>',
+ ' <span ng-class="{\'mismatch\': {{row.entity.plannedTxFrequency}} !== grid.getCellValue(row, col) }">{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ var actualRxFrequencyCellTemplate = [
+ '<div class="ui-grid-cell-contents" ng-class="{ \'green\': grid.getCellValue(row, col) === \'connected\'}"}>',
+ ' <span ng-class="{\'mismatch\': {{row.entity.plannedRxFrequency}} !== grid.getCellValue(row, col) }">{{grid.getCellValue(row, col)}}</span>',
+ '</div>'].join('');
+
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnSpectrum.gridOptions));
+ $scope.gridOptions.columnDefs = [
+ { field: 'id', type: 'number', displayName: 'Id', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true , sort: {
+ direction: uiGridConstants.ASC,
+ ignoreSort: false,
+ priority: 0
+ }},
+ { field: 'name', type: 'string', displayName: 'Name', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'connectionStatus', type: 'string', displayName: 'Connection status', headerCellClass: $scope.highlightFilteredHeader, width : 150, cellTemplate: requiredNesConnectionStatusCellTemplate },
+ { field: 'airInterfaceName', type: 'string', displayName: 'Airinterface name', headerCellClass: $scope.highlightFilteredHeader, width : 140 },
+ { field: 'radioSignalID', type: 'string', displayName: 'Radio signal id', headerCellClass: $scope.highlightFilteredHeader, width : 130 },
+ { field: 'plannedTxFrequency', type: 'number', displayName: 'TX (plan)', headerCellClass: $scope.highlightFilteredHeader, width : 110, cellClass: 'number' },
+ { field: 'actualTxFrequency', type: 'number', displayName: 'TX (actual)', headerCellClass: $scope.highlightFilteredHeader, width : 110, cellClass: 'number', cellTemplate: actualTxFrequencyCellTemplate},
+ { field: 'plannedRxFrequency', type: 'number', displayName: 'RX (plan)', headerCellClass: $scope.highlightFilteredHeader, width : 110, cellClass: 'number' },
+ { field: 'actualRxFrequency', type: 'number', displayName: 'RX (actual)', headerCellClass: $scope.highlightFilteredHeader, width : 110, cellClass: 'number', cellTemplate: actualRxFrequencyCellTemplate}
+ ];
+
+ $scope.refresh();
+
+ }]);
+
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.module.js
new file mode 100644
index 00000000..238f3ad3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.module.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var mwtnSpectrumApp = angular.module('app.mwtnSpectrum', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state','config']);
+
+ mwtnSpectrumApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnSpectrumApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/mwtnSpectrum/mwtnSpectrum.controller');
+ NavHelperProvider.addToMenu('mwtnSpectrum', {
+ "link" : "#/mwtnSpectrum",
+ "active" : "main.mwtnSpectrum",
+ "title" : "MWTN Spectrum",
+ "icon" : "fa fa-bar-chart", // Add navigation icon css class here
+ "page" : {
+ "title" : "MWTN Spectrum",
+ "description" : "mwtnSpectrum"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnSpectrum', {
+ url: 'mwtnSpectrum',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/mwtnSpectrum/mwtnSpectrum.tpl.html',
+ controller: 'mwtnSpectrumCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnSpectrumApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.services.js
new file mode 100644
index 00000000..df822a9b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.services.js
@@ -0,0 +1,90 @@
+/*
+ * 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/mwtnSpectrum/mwtnSpectrum.module'],function(mwtnSpectrumApp) {
+
+
+ mwtnSpectrumApp.register.factory('$mwtnSpectrum', function($q, $mwtnCommons, $mwtnLog) {
+ var service = {};
+
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+ service.getActualNetworkElement = $mwtnCommons.getActualNetworkElement;
+ service.getPacParts = $mwtnCommons.getPacParts;
+
+
+ service.execute = function() {
+ var request = {
+ method: 'POST',
+ url: 'operations/scheduler:next'
+ };
+ var deferred = $q.defer();
+ $mwtnCommons.genericRequest(request).then(function(success) {
+ deferred.resolve(success);
+ }, function(error) {
+ deferred.reject(error);
+ });
+ return deferred.promise;
+ };
+
+ service.refresh = function() {
+ var deferred = $q.defer();
+ $mwtnCommons.getRequiredNetworkElements(true).then(function(pNes){
+ var neIds = pNes.map(function(pNe){
+ pNe._source.connectionStatus = 'disconnected';
+ return pNe._id;
+ });
+ $mwtnCommons.getMountPoints(). then(function(mountpoints){
+ var actualNodes = mountpoints.map(function(mountpoint){
+ var pIndex = neIds.indexOf(mountpoint['node-id']);
+ if (pIndex > -1) {
+ pNes[pIndex]._source.connectionStatus = mountpoint['netconf-node-topology:connection-status'];
+ }
+ return {
+ id: mountpoint['node-id'],
+ connectionStatus: mountpoint['netconf-node-topology:connection-status']
+ };
+ });
+ var airInterfaces = [];
+ pNes.map(function(hit){
+ hit._source.MW_AirInterface_Pac.filter(function(airinterface){
+ return airinterface.airInterfaceConfiguration;
+ }).map(function(airinterface){
+ airInterfaces.push({
+ id: $mwtnCommons.getNodeIntIdFromNodeId(hit._source.nodeId),
+ name: hit._source.nodeId,
+ connectionStatus: hit._source.connectionStatus,
+ airInterfaceName: airinterface.airInterfaceConfiguration.airInterfaceName,
+ radioSignalID: airinterface.airInterfaceConfiguration.radioSignalID,
+ plannedTxFrequency: airinterface.airInterfaceConfiguration.txFrequency,
+ actualTxFrequency: '?',
+ plannedRxFrequency: airinterface.airInterfaceConfiguration.rxFrequency,
+ actualRxFrequency: '?'
+ });
+ });
+ });
+
+ airInterfaces.sort(function(a, b){
+ if(a.radioSignalID < b.radioSignalID) return -1;
+ if(a.radioSignalID > b.radioSignalID) return 1;
+ return 0;
+ });
+ deferred.resolve({airInterfaces: airInterfaces, actualNodes: actualNodes});
+ }, function(error){
+ deferred.reject([]);
+ });
+
+ }, function(error){
+ deferred.reject([]);
+ });
+ return deferred.promise;
+ };
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.tpl.html
new file mode 100644
index 00000000..ae9543dd
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/mwtnSpectrum-module/src/main/resources/mwtnSpectrum/mwtnSpectrum.tpl.html
@@ -0,0 +1,64 @@
+<ht-header help-link='sdnr/mwtnSpectrum/0.4.0/README.md'></ht-header>
+<div class="owl container">
+ <div class="row">
+ <div clase="col-md-12 text-left radio"
+ ng-class="{'raised':interference.alarmStatus !== 'cleared', 'cleared':interference.alarmStatus === 'cleared' }">
+ <span>{{'MWTN_INTERFERENCE_ALARM_STATUS' | translate}}: </span>
+ <i class="fa fa-bell" aria-hidden="true" ng-show="interference.alarmStatus !== 'cleared'"></i>
+ <span>{{interference.alarmStatus}}</span>
+ </div>
+ </div>
+ <div class="row">
+ <div clase="col-md-12">
+ <hr/>
+ <button class="btn btn-lg btn-block" ng-click="execute()" ng-class="{'btn-danger':interference.alarmStatus !== 'cleared', 'btn-success':interference.alarmStatus === 'cleared' }">
+ <div class="container" >
+ <div class="row alarm">
+ <div class="col-md-2 text-left">
+ <img ng-show="interference.alarmStatus !== 'cleared'" src="src/app/mwtnSpectrum/images/bluelight.gif" ></img>
+ </div>
+ <div class="col-md-8">
+ </br></br>
+ <i class="fa" ng-class="{'fa-exclamation-triangle':interference.alarmStatus !== 'cleared', 'fa-question-circle-o':interference.alarmStatus === 'cleared' }" aria-hidden="true"></i>
+ <span ng-show="interference.alarmStatus !== 'cleared'">{{'MWTN_INTERFERENCE_ALARM!' | translate}}</span>
+ <span ng-show="interference.alarmStatus === 'cleared'">{{'MWTN_INTERFERENCE_ALARM?' | translate}}</span>
+ </div>
+ <div class="col-md-2">
+ <img ng-show="interference.alarmStatus !== 'cleared'" src="src/app/mwtnSpectrum/images/bluelight.gif" ></img>
+ </div>
+ </div>
+ </div>
+ </button>
+ <hr/>
+ </div>
+ </div>
+<!-- <div class="row">
+ <div clase="col-md-12">
+ <button class="btn btn-success" ng-click="clear()">
+ <i class="fa fa-magic" aria-hidden="true"></i>
+ <span>{{'MWTN_CLEAR' | translate}}</span>
+ </button>
+ </div>
+ </div> -->
+ <div class="row">
+ <div clase="col-md-12 text-right">
+ <button class="btn btn-primary pull-right" ng-click="refresh()">
+ <i class="fa fa-refresh" ng-class="{'fa-spin':processing == true}" aria-hidden="true"></i>
+ <span>{{'MWTN_REFRESH' | translate}}</span>
+ </button>
+ </div>
+ </div>
+ <div class="row">
+ <div clase="col-md-12">
+ <div><span class="white">All frequencies in kHz</span></div>
+ <div id="mwtnSpectrumGrid" ui-grid="gridOptions" ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns
+ class="mwtnSpectrumGrid">
+ </div>
+ </div>
+ </div>
+
+</div>
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/pom.xml
new file mode 100644
index 00000000..06cc878a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnSpectrum/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>cn.com.zte.odl.dlux</groupId>
+ <artifactId>mwtnSpectrum</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnSpectrum-module</module>
+ <module>mwtnSpectrum-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/pom.xml
new file mode 100644
index 00000000..11d9cec3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTdm</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTdm-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTdm-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnTdm-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..02eb833c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnTdm"/>
+ <property name="url" value="/src/app/mwtnTdm"/>
+ <property name="directory" value="/mwtnTdm"/>
+ <property name="requireJs" value="app/mwtnTdm/mwtnTdm.module"/>
+ <property name="angularJs" value="app.mwtnTdm"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnTdm/mwtnTdm-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/pom.xml
new file mode 100644
index 00000000..9c8c8716
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTdm</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTdm-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/images/mwtnTdm.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/images/mwtnTdm.png
new file mode 100755
index 00000000..2da5f584
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/images/mwtnTdm.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm-custom.css
new file mode 100644
index 00000000..d396932f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm-custom.css
@@ -0,0 +1,11 @@
+/**
+ * Add your application related css here
+ */
+
+.owl .bbg b {
+ color: white;
+}
+
+.owl .bbg i {
+ color: white;
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.controller.js
new file mode 100644
index 00000000..e4e488bc
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.controller.js
@@ -0,0 +1,159 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnTdm/mwtnTdm.module',
+ 'app/mwtnTdm/mwtnTdm.services'],
+ function (mwtnTdmApp) {
+
+ mwtnTdmApp.register.controller('mwtnTdmCtrl', ['$scope', '$rootScope', '$timeout', '$mwtnLog', '$mwtnTdm', '$translate', 'OnfNetworkElement', 'uiGridConstants',
+ function ($scope, $rootScope, $timeout, $mwtnLog, $mwtnTdm, $translate, OnfNetworkElement, uiGridConstants) {
+
+ var COMPONENT = 'mwtnTdmCtrl';
+ $rootScope.section_logo = 'src/app/mwtnTdm/images/mwtnTdm.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $mwtnTdm.highlightFilteredHeader;
+ $scope.gridOptions = JSON.parse(JSON.stringify($mwtnTdm.gridOptions));
+ $scope.gridOptions.onRegisterApi = function (gridApi) {
+ $scope.gridApi = gridApi;
+ };
+ $scope.gridOptions.columnDefs = [
+ // { field: 'id', type: 'number', displayName: 'No.', headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
+ { field: 'nodeId', type: 'string', displayName: 'Node', headerCellClass: $scope.highlightFilteredHeader, width: 200 },
+ { field: 'layer', type: 'string', displayName: 'Layer', headerCellClass: $scope.highlightFilteredHeader, width: 100 },
+ { field: 'ltpRef', type: 'string', displayName: 'Logical termiantion point', headerCellClass: $scope.highlightFilteredHeader, width: 300 },
+ { field: 'reserved', type: 'number', displayName: 'Reserved E1', headerCellClass: $scope.highlightFilteredHeader, width: 150, cellClass: 'number' },
+ { field: 'configured', type: 'number', displayName: 'Configured E1', headerCellClass: $scope.highlightFilteredHeader, width: 150, cellClass: 'number' },
+ { field: 'utilization', type: 'number', displayName: 'Utilization [%]', headerCellClass: $scope.highlightFilteredHeader, width: 150, cellClass: 'number', sort: {
+ direction: uiGridConstants.ASC,
+ priority: 1
+ } }
+ ];
+
+ $scope.gridOptions.data = [];
+
+ var getUtilization = function(row) {
+ if (row.reserved === '?' || row.configured === '?' || row.reserved < 1) {
+ return '?';
+ }
+ return (( row.configured / row.reserved ) * 100).toFixed(2);
+ };
+
+ var cleanProgess = function() {
+ $scope.progress = {
+ show: false,
+ max: 0,
+ value: 0
+ };
+ };
+ cleanProgess();
+
+ var cleanMessage = function() {
+ $scope.message = {
+ error: undefined,
+ show: true,
+ startTime: undefined,
+ endTime: undefined,
+ duration: undefined
+ };
+ };
+
+ var finish = function() {
+ $scope.message.endTime = new Date().toISOString();
+ $scope.message.duration = ((new Date($scope.message.endTime) - new Date($scope.message.startTime))/1000).toFixed(1) + 's';
+ $scope.gridOptions.columnDefs.filter(function(column){
+ return column.field === 'utilization';
+ }).map(function(column){
+ column.sort.direction = uiGridConstants.ASC;
+ $scope.gridApi.core.refresh();
+ });
+ $timeout(cleanProgess, 1000);
+ };
+ $scope.scan = function() {
+ cleanMessage();
+ $scope.progress.show = true;
+ $scope.message.startTime = new Date().toISOString();
+
+ $mwtnTdm.getMountPoints().then(function (mountpoints) {
+ $scope.gridOptions.data = [];
+ if (mountpoints.length === 0) {
+ $timeout(cleanProgess, 1000);
+ }
+ mountpoints.filter(function (mountpoint) {
+ return mountpoint['netconf-node-topology:connection-status'] === 'connected';
+ }).map(function (mountpoint) {
+ $mwtnTdm.getActualNetworkElement(mountpoint['node-id'], '2017-03-24').then(function (success) {
+ var onfNetworkElement = new OnfNetworkElement(success['network-element']);
+ var tdmLtps = onfNetworkElement.getLTPMwsList().filter(function (ltp) {
+ return ltp.getConditionalPackages()[0].contains('hybrid');
+ }).map(function (ltp) {
+ $scope.progress.max = $scope.progress.max + 1;
+ var row = {
+ ltpId: [ltp.getId(), onfNetworkElement.getId()].join('@'),
+ nodeId: onfNetworkElement.getName(),
+ layer: 'MWS',
+ ltpRef: ltp.getLabel(),
+ reserved: '?',
+ configured: '?',
+ utilization: '?'
+ };
+
+ var specConfig = {
+ nodeId: mountpoint['node-id'],
+ revision: '2017-03-24',
+ pacId: 'microwave-model:mw-hybrid-mw-structure-pac',
+ layerProtocolId: ltp.getLayerProtocols()[0].getId(),
+ partId: 'hybrid-mw-structure-configuration'
+ };
+ $mwtnTdm.getPacParts(specConfig).then(function(success){
+ success = $mwtnTdm.yangifyObject(success);
+ row.reserved = success['hybrid-mw-structure-configuration']['number-of-tdm-segments-to-be-reserved'];
+ row.utilization = getUtilization(row);
+ }, function(error){
+ // ignore
+ });
+
+ var specStatus = {
+ nodeId: mountpoint['node-id'],
+ revision: '2017-03-24',
+ pacId: 'microwave-model:mw-hybrid-mw-structure-pac',
+ layerProtocolId: ltp.getLayerProtocols()[0].getId(),
+ partId: 'hybrid-mw-structure-status'
+ };
+ $mwtnTdm.getPacParts(specStatus).then(function(success){
+ success = $mwtnTdm.yangifyObject(success);
+ row.configured = success['hybrid-mw-structure-status']['segment-status-list'].filter(function(item){
+ return item['segment-is-reserved-for-tdm'] === true;
+ }).length;
+ row.utilization = getUtilization(row);
+ $scope.progress.value = $scope.progress.value + 1;
+ if ($scope.progress.max === $scope.progress.value) {
+ finish();
+ }
+ }, function(error){
+ // ignore
+ });
+
+ $scope.gridOptions.data.push(row);
+ });
+ console.warn(JSON.stringify(tdmLtps));
+ if (tdmLtps.length === 0 && $scope.progress.max === $scope.progress.value) {
+ finish();
+ }
+ });
+ }, function (error) {
+ $scope.gridOptions.data = [];
+ });
+
+ });
+ };
+ $scope.scan();
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.module.js
new file mode 100644
index 00000000..b136b535
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.module.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module',
+ 'app/mwtnCommons/bower_components/angular-clipboard/angular-clipboard'], function(ng) {
+ var mwtnTdmApp = angular.module('app.mwtnTdm', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'angular-clipboard']);
+
+ mwtnTdmApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnTdmApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnTdm/mwtnTdm.controller');
+ NavHelperProvider.addToMenu('mwtnTdm', {
+ "link" : "#/mwtnTdm",
+ "active" : "main.mwtnTdm",
+ "title" : "MWTN TDM",
+ "icon" : "fa fa-cogs", // Add navigation icon css class here
+ "page" : {
+ "title" : "MWTN TDM",
+ "description" : "mwtnTdm"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnTdm', {
+ url: 'mwtnTdm',
+ access: access.admin,
+ views : {
+ content : {
+ templateUrl: 'src/app/mwtnTdm/templates/frame.tpl.html',
+ controller: 'mwtnTdmCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnTdmApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.services.js
new file mode 100644
index 00000000..824fd26b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/mwtnTdm.services.js
@@ -0,0 +1,31 @@
+/*
+ * @copyright 2017 highstreet technologies 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/mwtnTdm/mwtnTdm.module'],function(mwtnTdmApp) {
+
+ mwtnTdmApp.register.factory('$mwtnTdm', function($mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.getActualNetworkElement = $mwtnCommons.getActualNetworkElement;
+ service.getMountPoints = $mwtnCommons.getMountPoints;
+ service.getPacParts = $mwtnCommons.getPacParts;
+
+ service.parts = $mwtnCommons.parts;
+ service.separator = $mwtnCommons.separator;
+ service.yangify = $mwtnCommons.yangify;
+ service.yangifyObject = $mwtnCommons.yangifyObject;
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/templates/frame.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/templates/frame.tpl.html
new file mode 100644
index 00000000..c253807c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/mwtnTdm-module/src/main/resources/mwtnTdm/templates/frame.tpl.html
@@ -0,0 +1,52 @@
+<ht-header help-link='sdnr/mwtnTdm/0.4.0/README.md'></ht-header>
+
+<div class="owl container" style="width: 100%;">
+
+ <div class="row bbg">
+ <div class="col-md-2">
+ <button type="button" id="scan" class="btn btn-primary" ng-click="scan()">
+ <i class="fa fa-spinner fa-pulse" aria-hidden="true" ng-if="progress.show"></i>
+ <span>{{'MWTN_SCAN_NETWORK' | translate}}</span>
+ </button>
+ </div>
+ <div class="col-md-3" ng-if="message.startTime !== undefined">
+ <span>{{'MWTN_START_TIME' | translate}}</span>
+ <b>{{message.startTime.toHumanReadableTimeFormat()}}</b>
+ </div>
+ <div class="col-md-3" ng-if="message.endTime !== undefined">
+ <span>{{'MWTN_END_TIME' | translate}}</span>
+ <b>{{message.endTime.toHumanReadableTimeFormat()}}</b>
+ </div>
+ <div class="col-md-2" ng-if="message.duration !== undefined">
+ <span>{{'MWTN_DURATION' | translate}}</span>
+ <b>{{message.duration}}</b>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class=" col-md-12">
+ <hr/>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class=" col-md-12">
+ <div id="mwtnTdmGrid" ui-grid="gridOptions" ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns
+ class="mwtnLogGrid"></div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class=" col-md-12">
+ <uib-progressbar ng-if="progress.show" class="progress-striped col-md-12" type="primary" max="progress.max" value="progress.value">
+ <i class="owl-dark">{{progress.value}} / {{progress.max}}</i>
+ </uib-progressbar>
+ </div>
+ </div>
+
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/pom.xml
new file mode 100644
index 00000000..8abbeca5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTdm/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTdm</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnTdm-module</module>
+ <module>mwtnTdm-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/pom.xml
new file mode 100644
index 00000000..984511b7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTest</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTest-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTest-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnTest-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..512631f5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnTest"/>
+ <property name="url" value="/src/app/mwtnTest"/>
+ <property name="directory" value="/mwtnTest"/>
+ <property name="requireJs" value="app/mwtnTest/mwtnTest.module"/>
+ <property name="angularJs" value="app.mwtnTest"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnTest/mwtnTest-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/pom.xml
new file mode 100644
index 00000000..400eada1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTest</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTest-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/images/mwtnTest.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/images/mwtnTest.png
new file mode 100755
index 00000000..bd00ceda
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/images/mwtnTest.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest-custom.css
new file mode 100644
index 00000000..15c398c1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest-custom.css
@@ -0,0 +1,24 @@
+/**
+ * Add your application related css here
+ */
+
+.json-formatter-row .constructor-name {
+ cursor: pointer;
+ color: #333333;
+}
+
+.json-formatter-row .toggler:after {
+ color: darkgreen;
+ font-weight: bold;
+ display: inline-block;
+ transition: transform .1s ease-in;
+ content: ">"
+}
+
+.owl span.key-text {
+ color: #333333;
+}
+
+.owl span.colon {
+ color: #333333;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.controller.js
new file mode 100644
index 00000000..e873f19c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.controller.js
@@ -0,0 +1,477 @@
+/*
+ * @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 http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/mwtnTest/mwtnTest.module',
+ 'app/mwtnTest/mwtnTest.services'],
+ function(mwtnTestApp) {
+
+ mwtnTestApp.register.controller('mwtnTestCtrl', ['$scope', '$rootScope', '$mwtnLog', '$mwtnTest', '$translate', 'OnfNetworkElement', 'LogicalTerminationPoint',
+ function($scope, $rootScope, $mwtnLog, $mwtnTest, $translate, OnfNetworkElement, LogicalTerminationPoint) {
+
+ var COMPONENT = 'mwtnTestCtrl';
+ $mwtnLog.info({component: COMPONENT, message: 'mwtnTestCtrl started!'});
+ $rootScope.section_logo = 'src/app/mwtnTest/images/mwtnTest.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ var pacTemplate = {
+ 'layer-protocol': 'unknown'
+ };
+
+ // get important infromation from yang modules
+ $mwtnTest.getModules().then(function(success){
+
+ var pacOrder = {
+ 'onf-otn-odu-conditional-packages:otn-odu-connection-pac' : 2,
+ 'onf-otn-odu-conditional-packages:otn-odu-termination-pac' : 1,
+ 'onf-ethernet-conditional-packages:ethernet-pac' : 1,
+ 'microwave-model:mw-air-interface-diversity-pac' : 1,
+ 'microwave-model:mw-air-interface-hsb-end-point-pac' : 1,
+ 'microwave-model:mw-air-interface-hsb-fc-switch-pac' : 2,
+ 'onf-core-model-conditional-packages:holder-pac' : 3,
+ 'onf-core-model-conditional-packages:connector-pac' : 4,
+ 'onf-core-model-conditional-packages:equipment-pac' : 5,
+ 'microwave-model:mw-ethernet-container-pac' : 6,
+ 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_Pac' : 7,
+ 'microwave-model:mw-ethernet-container-pac' : 8,
+ 'microwave-model:mw-tdm-container-pac': 9,
+ 'microwave-model:mw-pure-ethernet-structure-pac': 10,
+ 'microwave-model:mw-hybrid-mw-structure-pac': 11,
+ 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac' : 12,
+ 'microwave-model:mw-air-interface-pac' : 13,
+ 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac' : 14
+ };
+
+ $scope.modules = success;
+ $scope.orderedPacs = [];
+ $scope.parts = [];
+ Object.keys(success).map(function(module){
+ Object.keys(success[module]).filter(function(key){
+ return key.endsWith('-pac') || key.endsWith('_Pac');
+ }).map(function(pacName){
+ $scope.orderedPacs.push([module, pacName].join(':'));
+ // sort
+ $scope.orderedPacs.sort(function(a, b) {
+ if (!pacOrder[a]) console.warn(a);
+ if (!pacOrder[b]) console.warn(b);
+ if(pacOrder[a] > pacOrder[b]) return 1;
+ if(pacOrder[a] < pacOrder[b]) return -1;
+ return 0;
+ })
+
+ if (pacName === 'mw-air-interface-pac') {
+ $scope.parts = Object.keys(success[module][pacName]).filter(function(conditionalPackage){
+ return success[module][pacName][conditionalPackage]['local-name'];
+ }).map(function(conditionalPackage){
+ return success[module][pacName][conditionalPackage]['local-name'];
+ });
+ }
+ });
+ });
+ }, function(error){
+ $scope.modules = undefined;
+ $scope.orderedPacs = undefined;
+ $scope.parts = undefined;
+ });
+
+ /**
+ * @function updateNe
+ * A function, which updates onfNetworkElement by new data.
+ * @param {*} data New data recieved from OpenDaylight via RestConf
+ */
+ var updateNe = function(data) {
+ if (!data) return;
+ // update onfNetworkElement
+ switch ($scope.revision) {
+ case '2016-03-23':
+ $scope.onfNetworkElement = JSON.parse(JSON.stringify(data['network-element'][0]));
+ $scope.onfLtps = data['network-element'][0].ltp;
+ $scope.onfNetworkElement.ltp = undefined;
+ break;
+ case '2016-08-09':
+ case '2016-08-11':
+ case '2017-02-17':
+ case '2017-03-20':
+ // console.log(JSON.stringify(data));
+ $scope.onfNetworkElement = new OnfNetworkElement(data['network-element']);
+ $scope.onfLtps = $scope.onfNetworkElement.getLogicalTerminationPoints();
+ // $scope.onfNetworkElement.ltp = undefined;
+ break;
+ default:
+ $mwtnLog.info({component: COMPONENT, message: ['The ONF CoreModel revision', $scope.mountpoint.onfCoreModelRevision, ' is not supported (yet)!'].join(' ')});
+ $scope.onfNetworkElement = {};
+ $scope.onfLtps = {};
+ }
+
+ var order = $mwtnTest.layerProtocolNameOrder;
+ // update onfLTPs
+ $scope.onfLtps.sort(function(a, b){
+ if(order[a.getLayer()] < order[b.getLayer()]) return -1;
+ if(order[a.getLayer()] > order[b.getLayer()]) return 1;
+ if(a.getId() < b.getId()) return -1;
+ if(a.getId() > b.getId()) return 1;
+ return 0;
+ });
+
+ // calculate conditional packages
+ $scope.pacs = {};
+ $scope.onfLtps.map(function(ltp) {
+ ltp.getLayerProtocols().map(
+ /**
+ * A function processing a layer-protocol object
+ * @param {LayerProtocol} lp A layer-protocol object
+ */
+ function(lp) {
+ var template = JSON.parse(JSON.stringify(pacTemplate));
+ template['layer-protocol'] = lp.getId();
+ var conditionalPackage = lp.getConditionalPackage(true);
+ // console.log(conditionalPackage);
+ if (conditionalPackage !== '') {
+ if ($scope.pacs[conditionalPackage] === undefined) {
+ // create missing pac array
+ $scope.pacs[conditionalPackage] = [];
+ }
+ $scope.pacs[conditionalPackage].push(template);
+ } else {
+ $mwtnLog.info({component: COMPONENT, message: 'No conditional package for ' + ltp.getLabel() });
+ }
+ });
+ });
+
+ // sort the conditional packages
+ if ($scope.orderedPacs) {
+ $scope.orderedPacs.filter(function(item){
+ return $scope.pacs[item] !== undefined;
+ }).map(function(item){
+ $scope.pacs[item].sort(function(a, b){
+ if(a['layer-protocol'] < b['layer-protocol']) return -1;
+ if(a['layer-protocol'] > b['layer-protocol']) return 1;
+ return 0;
+ });
+ });
+ }
+ data.revision = undefined;
+ };
+
+ var updateNetworkElementCurrentProblems = function(data) {
+ if (!data) return;
+ $scope.neCurrentProblems = data;
+ };
+
+ var updateLtp = function(data) {
+ $scope.onfLtps.map(function(ltp){
+ if (ltp.getData().uuid === data.data.ltp[0].uuid) {
+ ltp = new LogicalTerminationPoint(data.data.ltp[0]);
+ }
+ });
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateAirInterface = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.airinterfaces.map(function(airinterface){
+ // console.log(JSON.stringify(airinterface));
+ if (airinterface['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].startsWith('air-interface')) {
+ airinterface[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ airinterface[part] = data['mw-air-interface-pac'][0]['air-interface-capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ airinterface[part] = data['mw-air-interface-pac'][0]['air-interface-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateStructure = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.structures.map(function(structure){
+ // console.log(JSON.stringify(structure));
+ if (structure['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].contains('tructure')) {
+ structure[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ structure[part] = data['mw-structure-pac'][0]['structure.capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ structure[part] = data['mw-structure-pac'][0]['structure-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * @deprecated since all conditaional packages are handle the same way even for
+ * 3rd and 4th PoC model - 2nd PoC model not supported any more.
+ * @param {*} lpId
+ * @param {*} part
+ * @param {*} data
+ */
+ var updateContainer = function(lpId, part, data) {
+ // console.log(JSON.stringify(data), lpId);
+ $scope.containers.map(function(container){
+ // console.log(JSON.stringify(container));
+ if (container['layer-protocol'] === lpId) {
+ if (Object.keys(data)[0].contains('ontainer') ) {
+ container[part] = data;
+ } else if (part === 'Capability') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ container[part] = data['mw-container-pac'][0]['container-capability-list'];
+ } else if (part === 'CurrentProblems') {
+ // 2. PoC
+ // console.log(part, JSON.stringify(data));
+ container[part] = data['mw-container-pac'][0]['container-current-problem-list'];
+ }
+ }
+ });
+ data.revision = undefined;
+ };
+
+ /**
+ * Creates a template of a conditional packages with its subclasses
+ * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass
+ */
+ var initPac = function(spec) {
+ $scope.pacs[spec.pacId].filter(function(conditionalPackage){
+ return conditionalPackage['layer-protocol'] === spec.layerProtocolId;
+ }).map(function(pac){
+ $scope.parts.map(function(localName){
+ pac[localName] = {id:$mwtnTest.getPartGlobalId(spec, localName),localName: localName, data:'No data available'}
+ });
+ });
+ };
+
+ /**
+ * Updates an existing template of a conditional packages with its subclasses
+ * @param {{pacId: string, layerProtocolId: string, partId:string}} spec - Specification object of a conditional package subclass
+ */
+ var updateSubClassData = function(spec, data) {
+ $scope.pacs[spec.pacId].filter(function(conditionalPackage){
+ return conditionalPackage['layer-protocol'] === spec.layerProtocolId;
+ }).map(function(conditionalPackage){
+ conditionalPackage[$mwtnTest.getPartLocalId(spec)].data = data[$mwtnTest.yangify(spec.partId)];
+ });
+ };
+
+ var updatePart = function(spec, data) {
+ switch (spec.pacId) {
+ case 'ne':
+ updateNe(data);
+ break;
+ case 'neCurrentProblems':
+ updateNetworkElementCurrentProblems(data);
+ case 'clock':
+ // console.warn('yea clock', JSON.stringify(data));
+ $scope.clock = data;
+ break;
+ case 'ltp':
+ updateLtp(data);
+ break;
+ case 'airinterface':
+ console.log(JSON.stringify(spec, JSON.stringify(data)));
+ updateAirInterface(spec.layerProtocolId, spec.partId, data);
+ break;
+ case 'structure':
+ console.log(JSON.stringify(data));
+ updateStructure(spec.layerProtocolId, spec.partId, data);
+ break;
+ case 'container':
+ console.log(JSON.stringify(data));
+ updateContainer(spec.layerProtocolId, spec.partId, data);
+ break;
+ // 3rd Poc
+ case 'MicrowaveModel-ObjectClasses-AirInterface:MW_AirInterface_Pac':
+ case 'MicrowaveModel-ObjectClasses-PureEthernetStructure:MW_PureEthernetStructure_Pac':
+ case 'MicrowaveModel-ObjectClasses-EthernetContainer:MW_EthernetContainer_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) {
+ initPac(spec);
+ } else {
+ updateSubClassData(spec, data);
+ }
+ break;
+ }
+ };
+
+ // events
+ $scope.status = {ne:false};
+ $scope.spinner = {ne:false};
+ $scope.separator = $mwtnTest.separator; //'&nbsp;'
+
+ $scope.myClipboard = {
+ data : {'key': 'value'},
+ 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});
+ }
+ };
+
+ $scope.$watch('status', function(status, oldValue) {
+ Object.keys(status).filter(function(key){
+ return $scope.networkElementId && status[key] && status[key] !== oldValue[key];
+ }).map(function(key){
+ $scope.spinner[key] = true;
+ var info = key.split($scope.separator);
+ var spec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: info[0],
+ layerProtocolId: info[1],
+ partId: info[2]
+ };
+ $mwtnTest.getPacParts(spec).then(function(success){
+ success = $mwtnTest.yangifyObject(success)
+ $scope.myClipboard.data = success;
+ updatePart(spec, success);
+ $scope.spinner[key] = false;
+ }, function(error){
+ $scope.myClipboard.data = 'Opps!';
+ updatePart(spec, error);
+ $scope.spinner[key] = false;
+ });
+ $scope.mountpoint = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === $scope.networkElementId;
+ })[0];
+ if (key === 'mountpoint') {
+ $scope.spinner['mountpoint'] = false;
+ $scope.myClipboard.data = $scope.mountpoint;
+ }
+ });
+ }, true);
+
+ // var spec = {
+ // nodeId: $scope.networkElementId,
+ // revision: $scope.revision,
+ // pacId: 'clock'
+ // };
+ // $mwtnTest.getPacParts(spec).then(function(success){
+ // $scope.collapseAll();
+ // updatePart(spec, $mwtnTest.yangifyObject(success));
+ // }, function(error){
+ // $scope.collapseAll();
+ // updatePart(spec, error);
+ // });
+
+
+ $scope.collapseAll = function() {
+ // close all groups
+ Object.keys($scope.status).map(function(group){
+ $scope.status[group] = false;
+ });
+ Object.keys($scope.spinner).map(function(group){
+ $scope.spinner[group] = false;
+ });
+ };
+
+ $scope.$watch('networkElement', function(neId, oldValue) {
+ if (neId && neId !== '' && neId !== oldValue) {
+
+ // clear old data
+ $scope.airinterfaces = [];
+ $scope.structures = [];
+ $scope.containers = [];
+ $scope.onfLtps = [];
+ $scope.clock = undefined;
+
+ $scope.networkElementId = neId;
+ $scope.revision = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ return mountpoint.onfCoreModelRevision;
+ })[0];
+
+ // network element alarms
+ var neAlarms = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ return mountpoint.onfCapabilities.filter(function(cap){
+ return cap.module === 'MicrowaveModel-NetworkElement-CurrentProblemList' || cap.module === 'onf-core-model-conditional-packages';
+ });
+ });
+ if (neAlarms.length === 1 && neAlarms[0].length === 1 ) {
+ $translate('MWTN_LOADING').then(function (translation) {
+ $scope.neCurrentProblems = translation;
+ });
+ } else {
+ $scope.neCurrentProblems = undefined;
+ }
+
+ var spec = {
+ nodeId: $scope.networkElementId,
+ revision: $scope.revision,
+ pacId: 'ne'
+ };
+ $mwtnTest.getPacParts(spec).then(function(success){
+ $scope.collapseAll();
+ updatePart(spec, $mwtnTest.yangifyObject(success));
+ }, function(error){
+ $scope.collapseAll();
+ updatePart(spec, error);
+ });
+
+ // ptp-clock
+ var ptpClock = $scope.mountPoints.filter(function(mountpoint){
+ return mountpoint['node-id'] === neId;
+ }).map(function(mountpoint){
+ return mountpoint.onfCapabilities.filter(function(cap){
+ return cap.module === 'onf-ptp-dataset';
+ });
+ });
+ if (ptpClock.length === 1 && ptpClock[0].length === 1 ) {
+ $translate('MWTN_LOADING').then(function (translation) {
+ $scope.clock = translation;
+ });
+ } else {
+ $scope.clock = undefined;
+ }
+
+ }
+ });
+
+ }]);
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.module.js
new file mode 100644
index 00000000..b2f0a8fd
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.module.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module',
+ 'app/mwtnCommons/bower_components/angular-clipboard/angular-clipboard'], function(ng) {
+ var mwtnTestApp = angular.module('app.mwtnTest', ['ui.grid', 'ui.bootstrap', 'app.core', 'ui.router.state', 'config', 'angular-clipboard']);
+
+ mwtnTestApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ mwtnTestApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+ NavHelperProvider.addControllerUrl('app/mwtnTest/mwtnTest.controller');
+ NavHelperProvider.addToMenu('mwtnTest', {
+ "link" : "#/mwtnTest/",
+ "active" : "main.mwtnTest",
+ "title" : "LTE RAN Test",
+ "icon" : "fa fa-check-square-o", // Add navigation icon css class here
+ "page" : {
+ "title" : "LTE RAN Test",
+ "description" : "mwtnTest"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnTest', {
+ url: 'mwtnTest/:nodeId',
+ access: access.admin,
+ views : {
+ content : {
+ templateUrl: 'src/app/mwtnTest/templates/frame.tpl.html',
+ controller: 'mwtnTestCtrl'
+ }
+ }
+ });
+
+ });
+
+ return mwtnTestApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.services.js
new file mode 100644
index 00000000..b61ca531
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/mwtnTest.services.js
@@ -0,0 +1,32 @@
+/*
+ * @copyright 2017 highstreet technologies 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/mwtnTest/mwtnTest.module'],function(mwtnTestApp) {
+
+ mwtnTestApp.register.factory('$mwtnTest', function($mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var COMPONENT = '$mwtnTest';
+ $mwtnLog.info({component: COMPONENT, message: '$mwtnTest started!'});
+
+ var service = {};
+
+ service.parts = $mwtnCommons.parts;
+ service.getPacParts = $mwtnCommons.getPacParts;
+ service.getModules = $mwtnDatabase.getModules;
+ service.getPartGlobalId = $mwtnCommons.getPartGlobalId;
+ service.getPartLocalId = $mwtnCommons.getPartLocalId;
+ service.layerProtocolNameOrder = $mwtnCommons.layerProtocolNameOrder;
+
+ service.separator = $mwtnCommons.separator;
+ service.yangify = $mwtnCommons.yangify;
+ service.yangifyObject = $mwtnCommons.yangifyObject;
+
+ return service;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/templates/frame.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/templates/frame.tpl.html
new file mode 100644
index 00000000..6a341d20
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/mwtnTest-module/src/main/resources/mwtnTest/templates/frame.tpl.html
@@ -0,0 +1,172 @@
+<ht-header help-link='sdnr/mwtnTest/0.4.0/README.md'></ht-header>
+<mwtn-select-network-element></mwtn-select-network-element>
+
+
+<div class="owl container" ng-show="networkElements.lenght !== 0">
+ <div class="row">
+
+ <uib-accordion close-others="oneAtATime">
+
+ <div uib-accordion-group class="panel-primary"
+ is-open="status.ne">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.ne, 'fa-chevron-right': !status.ne}"></i>
+ <span>{{'MWTN_NETWORKELEMENT' | translate}} '{{onfNetworkElement.getName()}}'</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.ne"></i>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <json-formatter json="onfNetworkElement.data" open="1"></json-formatter>
+ </div>
+
+ <div uib-accordion-group class="panel-default"
+ is-open="status.mountpoint">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.mountpoint, 'fa-chevron-right': !status.mountpoint}"></i>
+ <span>{{'MWTN_MOUNTPOINT' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.mountpoint"></i>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <json-formatter json="mountpoint" open="1"></json-formatter>
+ </div>
+
+ <div uib-accordion-group class="panel-default"
+ is-open="status.clock" ng-show="clock">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.clock, 'fa-chevron-right': !status.clock}"></i>
+ <span>{{'MWTN_CLOCK' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.clock"></i>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <json-formatter json="clock" open="1"></json-formatter>
+ </div>
+
+ <div uib-accordion-group class="panel-default"
+ is-open="status.neCurrentProblems" ng-show="neCurrentProblems">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status.neCurrentProblems, 'fa-chevron-right': !status.neCurrentProblems}"></i>
+ <span>{{'MWTN_CURRENT_PROBLEM_LIST' | translate}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner.neCurrentProblems"></i>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <json-formatter json="neCurrentProblems" open="1"></json-formatter>
+ </div>
+
+ <div ng-repeat="ltp in onfLtps"
+ uib-accordion-group
+ class="panel-default"
+ is-open="status['ltp' + separator + ltp.getData().uuid]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status['ltp' + separator + ltp.getData().uuid], 'fa-chevron-right': !status['ltp' + separator + ltp.getData().uuid]}"></i>
+ <span>{{'MWTN_LTP' | translate}}(</span>
+ <b>{{ltp.getLayerProtocols()[0].getItuLabel().toUpperCase()}}</b>
+ <span>): {{ltp.getId()}}</span>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <span>{{'MWTN_ID' | translate}}</span> <b>{{ltp.getId()}}</b><br/>
+ <span>{{'MWTN_DIRECTIONALITY' | translate}}</span> <b>{{ltp.getDirectionality()}}</b><br/>
+ <span>{{'MWTN_SERVER_LTPS' | translate}}</span> <b>{{ltp.getServerLtps()}}</b><br/>
+ <span>{{'MWTN_CLIENT_LTPS' | translate}}</span> <b>{{ltp.getClientLtps()}}</b><br/><br/>
+
+ <div ng-repeat="lp in ltp.getLayerProtocols()">
+ <b>{{'MWTN_LAYER_PROTOCOL' | translate}}</b><br/>
+ <span>{{'MWTN_ID' | translate}}</span> <b>{{lp.getId()}}</b><br/>
+ <span>{{'MWTN_LAYER' | translate}}</span> <b>{{lp.getLayer()}}</b><br/>
+ <span>{{'MWTN_TERMINATION_STATE' | translate}}</span> <b>{{lp.getTerminationState()}}</b><br/>
+ <span>{{'MWTN_LABEL' | translate}}</span> <b>{{lp.getItuLabel().toUpperCase()}}</b><br/>
+ <span>{{'MWTN_CAPABILITY' | translate}}</span> <b>{{lp.getCapability()}}</b><br/>
+ <span>{{'MWTN_REVISON' | translate}}</span> <b>{{lp.getRevision()}}</b><br/>
+ <span>{{'MWTN_CONDITIONAL_PACKAGE' | translate}}</span> <b>{{lp.getConditionalPackage()}}</b><br/><br/>
+ <!-- <pre>{{lp.getData() | json}}</pre> -->
+ </div>
+ <json-formatter json="ltp.getData()" open="1"></json-formatter>
+ </div>
+
+ </uib-accordion>
+ </div>
+
+ <div ng-repeat="orderedPac in orderedPacs" class="row" style="margin-top: 5px" ng-show="pacs[orderedPac]">
+ <uib-accordion close-others="oneAtATime">
+ <div ng-repeat="pac in pacs[orderedPac]"
+ uib-accordion-group
+ class="panel-primary"
+ is-open="status[ [orderedPac, pac['layer-protocol']].join(separator) ]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status[ [orderedPac, pac['layer-protocol']].join(separator) ], 'fa-chevron-right': !status[ [orderedPac, pac['layer-protocol']].join(separator) ]}"></i>
+ <span>{{ 'MWTN_' + orderedPac.toUpperCase().replaceAll('-', '_') | translate }} '{{pac['layer-protocol']}}'</span>
+ </uib-accordion-heading>
+
+ <div ng-repeat="part in parts"
+ uib-accordion-group
+ class="panel-default"
+ is-open="status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]">
+ <uib-accordion-heading>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ], 'fa-chevron-right': !status[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]}"></i>
+ <span>{{part}}</span>
+ <i class="pull-right fa fa-spinner fa-pulse" ng-show="spinner[ [orderedPac, pac['layer-protocol'], pac[part].id].join(separator) ]"></i>
+ </uib-accordion-heading>
+
+ <button class="pull-right 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>
+
+ <json-formatter json="pac[part].data" open="1"></json-formatter>
+ </div>
+ </div>
+
+ </uib-accordion>
+ </div>
+</div>
+<hr />
+<div class="owl">
+ <span>ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/pom.xml
new file mode 100644
index 00000000..b0436ffb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTest/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTest</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnTest-module</module>
+ <module>mwtnTest-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/pom.xml
new file mode 100644
index 00000000..c1639dcb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTopology</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTopology-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTopology-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>mwtnTopology-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..a5cfcfc2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="mwtnTopology"/>
+ <property name="url" value="/src/app/mwtnTopology"/>
+ <property name="directory" value="/mwtnTopology"/>
+ <property name="requireJs" value="app/mwtnTopology/mwtnTopology.module"/>
+ <property name="angularJs" value="app.mwtnTopology"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/mwtnTopology/mwtnTopology-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/pom.xml
new file mode 100644
index 00000000..1eb8126c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtnTopology</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>mwtnTopology-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.builinfo.md b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.builinfo.md
new file mode 100755
index 00000000..594b8e26
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.builinfo.md
@@ -0,0 +1,39 @@
+# Buildinfo
+
+Ausgehend vom Verzeichnis:
+SDN-Projects-Boron/code/ux
+
+ll => pom.xml muss vorhanden sein.
+
+## manuelles Builden
+
+Die Schritte 1, 5 und 6 sind während des Buildens notwendig, die anderen Schritte sind zu Kontrollzwecken und zum starten / Stoppen vom Karaf Server
+
+1. Für den Compilevorgang der eigenen Komponenten:
+ - `cd ~/SDN-Projects-Boron/code`
+ - `mvn clean install -DskipTests`
+ - `cp -R ~/.m2/repository/com/highstreet $ODL_KARAF_HOME/system/com`
+2. Zum beenden von Karaf:
+ - ctrl+d in der Shell, auf der Karaf läuft.
+ - `sudo $ODL_KARAF_HOME/bin/client -u karaf "shutdown --force"`, wenn man nicht in der passenden Shell ist
+3. Starten von Karaf:
+ - `cd $ODL_KARAF_HOME`
+ - `./bin/karaf`
+4. Zum gucken, welche Module installiert sind (von highstreet, grep):
+ - `bundle:list | grep mwtn`
+5. Bundles deinstallieren (Funktioniert nur innerhalb der Karaf Shell)
+ - `bundle:uninstall "ONF :: Wireless :: mwtnCommons-bundle" "ONF :: Wireless :: mwtnTopology-bundle"`
+6. (geänderte) Bundles installieren (Funktioniert nur innerhalb der Karaf Shell)
+ - `bundle:install -s mvn:com.highstreet.technologies.odl.dlux/mwtnCommons-bundle/0.4.0-SNAPSHOT mvn:com.highstreet.technologies.odl.dlux/mwtnTopology-bundle/0.4.0-SNAPSHOT`
+
+## GIT:
+
+Abrufen:
+- `cd ~/SDN-Projects-Boron/code/ux/mwtnTopology/mwtnTopology-module/src/main/resources`
+- `git pull`
+
+Einchecken:
+- `git add doc/*.md`
+- `git status` (Kontrolle der einzucheckenden Dateien)
+- `git commit` (Ist der eincheckvorgang an sich (lokaler GitServer))
+- `git push` (Übertragen aller Commits zum zentralen Server)
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.fs.md b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.fs.md
new file mode 100755
index 00000000..861306c2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/doc/mwtnTopology.fs.md
@@ -0,0 +1,78 @@
+# mwtnTopology - Functional Specification
+
+## Beschreibung
+
+Das mwtnTopology Control zeichnet eine Karte mit Hilfe eines austauschbaren Kartendienstes
+Dabei wird die Satellitendarstellung verwendet (wenn möglich), sonst wird die Kartendarstellung gewählt.
+Über dem Kartenlayer soll ein Vectorlayer mit Informationen zu Mobilfunkmasten und zugehörigen Richtfunkstrecken dargestellt werden.
+Die Karte soll mittels Mausbedienung Scroll und Zoombar sein, Klicks auf einen Mast oder eine Richtfunkstrecke stellen weitere Informationen in einem Popup zur Verfügung.
+
+## Anforderungen
+
+* Die Webseite / der Webserver hat *keinen* Zugriff auf das öffentliche Internet. Online-Kartendienste wie Google, Bing oder OpenStreetMap sind damit nicht erreichbar.
+* Der Server stellt eine API bereit, an welcher die Kartenkacheln als Bitmaps (png/jpeg) bereitgestellt werden.
+* Der darzustellende Bereich wird angegeben durch
+ - Ein Latitude/Longitude Koordinatenpaar (Mittelpunkt) und eine Zoomstufe in % wobei 0% der "Weltraumansicht" und 100% der "Sandkrümel auf der Straße" entspricht.
+ Die benötigten Kacheln werden anhand der Zoomstufe und der Größe des Kartenausschnitts in Bildschirmpixel berechnet.
+ - Zwei Latitude/Longitude Koordinatenpaare, welche die obere rechte Ecke und die untere linke Ecke des darzustellenden Kartenausschnitts darstellen.
+ Die benötigte Zoomstufe wird anhand der Koordinatenpaare und der Größe des Kartenausschnitts in Bildschirmpixel berechnet.
+ + 2 Mögliche SubModi: "Fill" und "Cut"
+* Die Zoomstufen als %-Angaben werden auf die vom Kartenprovider verwendeten ganzzahligen Zoomstufen gemappt.
+ - Nicht jeder Kartenprovider kann für alle Zoomstufen Bitmaps liefern. Gibt es eine Möglichkeit die maximale Provider-Zoomstufe für eine Koordinate abzufragen?
+* Der Client cached die Bildkacheln, um die Serverlast zu reduzieren.
+ - Localstorage?
+
+## Offene Fragen
+
+* Soll die Karte immer eingenordet sein oder ist eine Kartenrotation erforderlich?
+* Welche Karten-UI-Steuerelemente müssen angezeigt werden
+ - +/- Button / Zoom-Slider
+ - 2D-Rotations-Gizmo / Kompass
+ - Geokoordinate Zentrieren
+ - Kartenscale (20m|---------------|)
+ - Copyright-Angaben der verwendeten Kartendaten
+ - Ein/Ausblenden des Vector-Overlays
+* Kann ein eigener Tile Render Server (wie z.B. Maperitive) verwendet werden?
+* Transparente, vorberechnete Kacheln des VectorLayers verfügbar? (Kacheln erlauben keine Hover-Informationen einzelner Richtfunktstrecken)
+
+## Berechnungsformeln
+
+- [OSM: Slippy map tilenames](http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames)
+
+The first part of the URL specifies the tile server, and perhaps other parameters which might influence the style.
+
+Generally several subdomains (server names) are provided to get around browser limitations on the number of simultaneous HTTP connections to each host.
+Browser-based applications can thus request multiple tiles from multiple subdomains faster than from one subdomain.
+For example, OSM, OpenCycleMap and CloudMade servers have three subdomains (a.tile, b.tile, c.tile), MapQuest has four (otile1, otile2, otile3, otile4),
+all pointing to the same CDN. That all comes before the /zoom/x/y.png tail.
+
+Example:
+http://[abc].tile.openstreetmap.org/zoom/x/y.png
+
+```js
+function long2tile(lon,zoom) { return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
+function lat2tile(lat,zoom) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
+
+var zoom = 9;
+var top_tile = lat2tile(north_edge, zoom); // eg.lat2tile(34.422, 9);
+var left_tile = lon2tile(west_edge, zoom);
+var bottom_tile = lat2tile(south_edge, zoom);
+var right_tile = lon2tile(east_edge, zoom);
+var width = Math.abs(left_tile - right_tile) + 1;
+var height = Math.abs(top_tile - bottom_tile) + 1;
+
+// total tiles
+var total_tiles = width * height; // -> eg. 377
+```
+
+## Links
+
+- [OpenStreetMap DE:Tile usage policy](http://wiki.openstreetmap.org/wiki/DE:Tile_usage_policy)
+- [OpenStreetMap DE:Karte in Webseite einbinden](http://wiki.openstreetmap.org/wiki/DE:Karte_in_Webseite_einbinden)
+- [OpenStreetMap DE:Maperitive](http://wiki.openstreetmap.org/wiki/DE:Maperitive)
+- [Maperitive, EN:Hauptwebseite](http://maperitive.net/)
+- [Google Maps Javascript API + Key anfordern](https://developers.google.com/maps/documentation/javascript/?hl=de)
+- [Google Maps Javascript Erste Schritte](https://developers.google.com/maps/documentation/javascript/tutorial?hl=de)
+- [Google Developer Console](https://console.developers.google.com/)
+- [GoogleMap AngularJS Directive](https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/docs/index.html)
+- [Sample asnyc script load into head element](http://just-run.it/#/ByvA_ClTe/0)
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/images/mwtnTopology.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/images/mwtnTopology.png
new file mode 100755
index 00000000..7ddbeb2e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/images/mwtnTopology.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology-custom.css
new file mode 100755
index 00000000..d04a7645
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology-custom.css
@@ -0,0 +1,102 @@
+/**
+ * Add your application related css here
+ */
+
+.owl p span {
+ color: #393939;
+}
+
+.angular-google-map-container {
+ height: 1200px;
+}
+
+.mwtnTopologyGrid {
+ height: 412px;
+ background-color: white;
+}
+
+.mwtnTopologyGrid span {
+ color: #393939;
+}
+
+#mwtnTopology .nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+#mwtnTopology .nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+#mwtnTopology .nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+#mwtnTopology .nav-tabs > li > a:hover {
+ color: #fff;
+ cursor: default;
+ background-color: #428bca;
+ border: 1px solid #428bca;
+ border-color: #eee #eee #ddd;
+ border-bottom-color: transparent;
+
+}
+#mwtnTopology .nav-tabs > li.active > a,
+#mwtnTopology .nav-tabs > li.active > a:hover,
+#mwtnTopology .nav-tabs > li.active > a:focus {
+ color: #fff;
+ cursor: default;
+ background-color: #428bca;
+ border: 1px solid #428bca;
+ border-bottom-color: transparent;
+}
+#mwtnTopology .nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+#mwtnTopology .nav-tabs.nav-justified > li {
+ float: none;
+}
+#mwtnTopology .nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+#mwtnTopology .nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ #mwtnTopology .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ #mwtnTopology .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+#mwtnTopology .nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+#mwtnTopology .nav-tabs.nav-justified > .active > a,
+#mwtnTopology .nav-tabs.nav-justified > .active > a:hover,
+#mwtnTopology .nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ #mwtnTopology .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ #mwtnTopology .nav-tabs.nav-justified > .active > a,
+ #mwtnTopology .nav-tabs.nav-justified > .active > a:hover,
+ #mwtnTopology .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.controller.js
new file mode 100755
index 00000000..f8aa303a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.controller.js
@@ -0,0 +1,4877 @@
+/*
+ * 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
+ */
+if (typeof (Number.prototype.toRad) === "undefined") {
+ Number.prototype.toRadians = function () {
+ return this * Math.PI / 180;
+ }
+}
+
+if (Number.prototype.toDegrees === undefined) {
+ Number.prototype.toDegrees = function () {
+ return this * 180 / Math.PI;
+ };
+}
+
+// If array is empty, undefined is returned. If not empty, the first element
+// that evaluates to false is returned. If no elements evaluate to false, the
+// last element in the array is returned.
+Array.prototype.and = function (defaultValue) {
+ for (var i = 0, len = this.length - 1; i < len && this[i]; i++);
+ return this.length ? this[i] : defaultValue;
+};
+
+// If array is empty, undefined is returned. If not empty, the first element
+// that evaluates to true is returned. If no elements evaluate to true, the
+// last element in the array is returned.
+Array.prototype.or = function () {
+ for (var i = 0, len = this.length - 1; i < len && !this[i]; i++);
+ return this[i];
+};
+
+var eventsFabric = function () {
+ var topics = {};
+ var hOP = topics.hasOwnProperty;
+
+ return {
+ subscribe: function (topic, listener) {
+ // Create the topic's object if not yet created
+ if (!hOP.call(topics, topic)) topics[topic] = [];
+
+ // Add the listener to queue
+ var index = topics[topic].push(listener) - 1;
+
+ // Provide handle back for removal of topic
+ return {
+ remove: function () {
+ delete topics[topic][index];
+ }
+ };
+ },
+ publish: function (topic, info) {
+ // If the topic doesn't exist, or there's no listeners in queue, just leave
+ if (!hOP.call(topics, topic)) return;
+
+ // Cycle through topics queue, fire!
+ topics[topic].forEach(function (item) {
+ item(info != undefined ? info : {});
+ });
+ }
+ };
+};
+
+var lastOpenedInfoWindow = null;
+
+/*********************************************************************************************/
+
+/** @typedef {{ id: string, siteA: string, siteZ: string, siteNameA: string, siteNameZ: string, airInterfaceLinks: {id: string, siteLink: string, radio: string, polarization: string }[]}} SiteLinkDetails */
+
+define(['app/mwtnCommons/bower_components/lodash/dist/lodash',
+ 'app/mwtnCommons/bower_components/cytoscape/dist/cytoscape',
+ 'app/mwtnTopology/mwtnTopology.module',
+ 'app/mwtnTopology/mwtnTopology.services',
+ 'app/mwtnCommons/mwtnCommons.services'
+], function (_, cytoscape, mwtnTopologyApp) {
+
+ // module.exports = function () {
+ // const mwtnTopologyApp = require('app/mwtnTopology/mwtnTopology.module');
+ // const mwtnTopologyService = require('app/mwtnTopology/mwtnTopology.services');
+ // const cytoscape = require('cytoscape');
+
+ // remove '_' from global scope but use it here as '_'.
+ _.noConflict();
+
+ /********************************************* Sites *************************/
+
+ mwtnTopologyApp.directive('mwtnTopologyMap', ["$timeout", "$q", "$mwtnTopology", function ($timeout, $q, $mwtnTopology) {
+ return {
+ restrict: 'E',
+ replace: true,
+ template: '<div style="position:realtive;width:100%;height:700px" ng-transclude=""></div>',
+ controller: function () {
+
+ },
+ transclude: true,
+ scope: {
+ manualMapBounds: "=?",
+ onBoundsChanged: "&?"
+ },
+ link: function (scope, element, attrs, ctrl) {
+
+ var mapApiReadyDefer = $q.defer();
+ var disbaleNotifications = true;
+ //var includeCenter = false;
+
+ var initialMapOptions = {
+ center: new google.maps.LatLng(0, 0),
+ mapTypeId: google.maps.MapTypeId.HYBRID,
+ panControl: false,
+ rotateControl: false,
+ streetViewControl: false,
+ tilt: 0,
+ zoom: 2,
+ minZoom: 2
+ };
+
+ // Wait at least one digest cycle before init the google map.
+ $timeout(function () {
+ ctrl.map = new google.maps.Map(element[0], initialMapOptions);
+
+ // Wait until google maps is fully intialized to attach nessessary event handler.
+ waitUntilGoogleMapsIsReady();
+ });
+
+ element.on("$destroy", function () {
+ if (scope.waitUntilGoogleMapsIsReadyTimeoutId) {
+ $timeout.cancel(scope.waitUntilGoogleMapsIsReadyTimeoutId);
+ }
+ if (scope.onDragEndListener) {
+ google.maps.event.removeListener(scope.onDragEndListener);
+ delete (scope.onDragEndListener);
+ }
+ if (scope.onZoomChangedListener) {
+ google.maps.event.removeListener(scope.onZoomChangedListener);
+ delete (scope.onZoomChangedListener);
+ }
+
+ // window.removeEventListener('resize', onBoundsChanged);
+
+ });
+
+ scope.$watch("manualMapBounds", function (newBounds, oldBounds) {
+ mapApiReadyDefer.promise.then(function () {
+
+ // if this was an uri change from an not user originated action just return;
+ if (newBounds.internal) return;
+
+ // values must exist and at least one must be different or initial load (new === old)
+ if (newBounds.bottom != null && newBounds.left != null && newBounds.top != null && newBounds.right != null) {
+ fitBounds(ctrl.map, new google.maps.LatLngBounds(
+ new google.maps.LatLng(newBounds.bottom, newBounds.left),
+ new google.maps.LatLng(newBounds.top, newBounds.right)));
+ } else if (newBounds.lat != null && newBounds.lng != null && newBounds.zoom != null && (newBounds.lat != oldBounds.lat || newBounds.lng != oldBounds.lng || newBounds.zoom != oldBounds.zoom || newBounds === oldBounds)) {
+ disbaleNotifications = true;
+ google.maps.event.addListenerOnce(ctrl.map, 'bounds_changed', function (event) {
+ disbaleNotifications = false;
+ onBoundsChanged(false);
+
+ });
+ ctrl.map.setCenter({ lat: newBounds.lat, lng: newBounds.lng });
+ ctrl.map.setZoom(newBounds.zoom);
+
+ }
+ console.log("manualMapBounds", newBounds);
+ });
+ });
+
+ /**
+ * An asynchronous function that is called continuously every 100 milliseconds until the google maps control has finished its first complete draw.
+ * Then it sets up all event handlers and reports its bounds.
+ */
+ function waitUntilGoogleMapsIsReady() {
+ var getBoundsApi = ctrl.map.getBounds();
+ if (getBoundsApi) {
+ delete (scope.waitUntilGoogleMapsIsReadyTimeoutId);
+ // Change to dragend https://developers.google.com/maps/documentation/javascript/events?hl=de
+ scope.onDragEndListener = ctrl.map.addListener('dragend', function () {
+ onBoundsChanged(true);
+ });
+ scope.onZoomChangedListener = ctrl.map.addListener('zoom_changed', function () {
+ onBoundsChanged(true);
+ });
+ // window.addEventListener('resize', function () {
+ // onBoundsChanged(false);
+ // });
+
+ disbaleNotifications = false;
+ mapApiReadyDefer.resolve();
+ } else {
+ scope.waitUntilGoogleMapsIsReadyTimeoutId = $timeout(waitUntilGoogleMapsIsReady, 100);
+ }
+ }
+
+ /**
+ * Gets the current bound and zoom level of the map control and reports it to its parent component.
+ * Hint: do not call directly use fitBounds helper function since there is a google bug in the fit bounds function.
+ */
+ function onBoundsChanged(userOriginated) {
+ if (!disbaleNotifications && scope.onBoundsChanged && angular.isFunction(scope.onBoundsChanged)) {
+
+ var getBoundsApi = ctrl.map.getBounds();
+ var northEastApi = getBoundsApi.getNorthEast();
+ var southWestApi = getBoundsApi.getSouthWest();
+ var center = ctrl.map.getCenter();
+
+ var data = {
+ top: northEastApi.lat(),
+ right: northEastApi.lng(),
+ bottom: southWestApi.lat(),
+ left: southWestApi.lng(),
+ lat: center.lat(),
+ lng: center.lng(),
+ zoom: ctrl.map.getZoom()
+ };
+
+ console.log("onBoundsChanged", data);
+
+ scope.onBoundsChanged({
+ data: data,
+ userOriginated: userOriginated === true
+ });
+ }
+ }
+
+ // bug: the original google code will fit bounds will add some extra space, this function will fix it
+ function fitBounds(map, bounds) {
+ var oldBounds = map.getBounds();
+
+ // ensure there is any change
+ if (oldBounds.toUrlValue() == bounds.toUrlValue()) {
+ return;
+ }
+
+ disbaleNotifications = true;
+ google.maps.event.addListenerOnce(map, 'bounds_changed', function (event) {
+ // bugfix: this is a fix for the https://issuetracker.google.com/issues/35820423
+ // the map does sometime zoom out if it gets its one bounds
+
+ // var newSpan = map.getBounds().toSpan(); // the span of the map set by Google fitBounds (always larger by what we ask)
+ // var askedSpan = bounds.toSpan(); // the span of what we asked for
+ // var latRatio = (newSpan.lat() / askedSpan.lat()) - 1; // the % of increase on the latitude
+ // var lngRatio = (newSpan.lng() / askedSpan.lng()) - 1; // the % of increase on the longitude
+ // // if the % of increase is too big (> to a threshold) we zoom in
+ // if (Math.min(latRatio, lngRatio) > 0.46) {
+ // // 0.46 is the threshold value for zoming in. It has been established empirically by trying different values.
+ // this.setZoom(this.getZoom() + 1);
+ // }
+ disbaleNotifications = false;
+ onBoundsChanged(false);
+
+ });
+ map.fitBounds(bounds); // does the job asynchronously
+ }
+ }
+ };
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyMapSites', ['$compile', '$rootScope', function ($compile, $rootScope) {
+
+ return {
+ restrict: 'E',
+ require: '^mwtnTopologyMap',
+ scope: {
+ sites: "=",
+ selectedSite: "=",
+ api: "="
+ },
+ link: function (scope, element, attrs, mwtnTopologyMapController) {
+ // todo: shouild come from a service
+ var normalIcon = {
+ path: google.maps.SymbolPath.CIRCLE,
+ scale: 10,
+ strokeColor: '#00ccff',
+ strokeOpacity: 0.8,
+ strokeWeight: 2,
+ fillColor: '#00ccff',
+ fillOpacity: 0.35,
+ zIndex: 2
+ };
+
+ var highlightIcon = {
+ path: google.maps.SymbolPath.CIRCLE,
+ scale: 10,
+ strokeColor: '#eaae3c',
+ strokeOpacity: 0.8,
+ strokeWeight: 3,
+ fillColor: '#eaae3c',
+ fillOpacity: 0.65,
+ zIndex: 2
+ };
+
+ var selectedIcon = {
+ path: google.maps.SymbolPath.CIRCLE,
+ scale: 10,
+ strokeColor: '#00FD30',
+ strokeOpacity: 0.8,
+ strokeWeight: 2,
+ fillColor: '#00FD30',
+ fillOpacity: 0.35,
+ zIndex: 2
+ };
+
+ scope.displayedSites = {};
+ scope.knownSites = {};
+
+ scope.$watch("selectedSite", function (newSiteId, oldSiteId) {
+
+ if (oldSiteId && scope.displayedSites[oldSiteId]) {
+ scope.displayedSites[oldSiteId].setOptions({
+ icon: normalIcon
+ });
+ }
+
+ if (newSiteId && scope.displayedSites[newSiteId]) {
+ scope.displayedSites[newSiteId].setOptions({
+ icon: selectedIcon
+ });
+ }
+
+ });
+
+ if (!scope.api) return;
+
+ /**
+ * Updates the google map markers
+ * @param addedSiteIds {string[]} The ids of the sites which are added to the scope.displayedSites dictionary.
+ * @param removedFromVisibleIds {string[]} The ids of sites which are removed from the visible bounding rectangle.
+ * @param movedFromVisibleToKnownIds {string[]} The ids of sites which are moved from the visible bounding rectangle to the extended bounding rectangle.
+ * @param removedFromKnownIds {string[]} The ids of sites which are removed from the extended bounding rectangle.
+ * @param movedFromKnownToVisibleIds {string[]} The ids of sites which are moved from the extended bounding rectangle to the visible bounding rectangle.
+ */
+ scope.api.updateSites = function (addedSiteIds, removedFromVisibleIds, movedFromVisibleToKnownIds, removedFromKnownIds, movedFromKnownToVisibleIds) {
+ if (!addedSiteIds) addedSiteIds = [];
+ if (!removedFromVisibleIds) removedFromVisibleIds = [];
+ if (!movedFromVisibleToKnownIds) movedFromVisibleToKnownIds = [];
+ if (!removedFromKnownIds) removedFromKnownIds = [];
+ if (!movedFromKnownToVisibleIds) movedFromKnownToVisibleIds = [];
+
+ removedFromVisibleIds.forEach(function (siteId) {
+ var marker = scope.displayedSites[siteId];
+ if (marker) {
+ marker.setMap(null);
+ //delete marker;
+ delete scope.displayedSites[siteId];
+ }
+ });
+
+ removedFromKnownIds.forEach(function (siteId) {
+ var marker = scope.knownSites[siteId];
+ if (marker) {
+ marker.setMap(null);
+ //delete marker;
+ delete scope.knownSites[siteId];
+ }
+ });
+
+ movedFromVisibleToKnownIds.forEach(function (siteId) {
+ var marker = scope.displayedSites[siteId];
+ if (marker) {
+ marker.setVisible(false);
+ scope.knownSites[siteId] = marker;
+ delete scope.displayedSites[siteId];
+ }
+ });
+
+ movedFromKnownToVisibleIds.forEach(function (siteId) {
+ var marker = scope.knownSites[siteId];
+ if (marker) {
+ marker.setVisible(true);
+ scope.displayedSites[siteId] = marker;
+ delete scope.knownSites[siteId];
+ }
+ });
+
+ addedSiteIds.forEach(function (newSiteId) {
+ var newSite = scope.sites[newSiteId];
+ var newSiteNormalIcon = Object.assign({}, normalIcon, {
+ fillColor: (newSite.type === 'data-center') ? "#ffff00": "#00ccff",
+ strokeColor: (newSite.type === 'data-center') ? "#ffff00" : "#00ccff"
+ });
+ var newSiteHighlightIcon = Object.assign({}, highlightIcon, {
+ fillColor: (newSite.type === 'data-center') ? "#ffff00": "#00ccff",
+ strokeColor: (newSite.type === 'data-center') ? "#ffff00" : "#00ccff"
+ });
+ if (newSite && !scope.displayedSites[newSiteId]) {
+
+ // create the marker
+ var marker = new google.maps.Marker({
+ map: mwtnTopologyMapController.map,
+ position: newSite.location,
+ title: newSite.name,
+ icon: newSiteNormalIcon
+ });
+
+ // add event listeners to the marker
+ marker.addListener('click', function () {
+ // cloase all already opened windows
+ if (lastOpenedInfoWindow) {
+ lastOpenedInfoWindow.close();
+ lastOpenedInfoWindow = null;
+ }
+
+ // compile the content
+ var infoWindowTemplate = '<mwtn-topology-site-details site-id="siteId" />';
+ var infoWindowScope = $rootScope.$new();
+ infoWindowScope['siteId'] = newSiteId;
+ var infoWindowContent = $compile(infoWindowTemplate)(infoWindowScope)[0];
+
+ // create the info window
+ var infowindow = new google.maps.InfoWindow({
+ content: infoWindowContent,
+ disableAutoPan: true
+ });
+
+ // open the window and keek a refenrece to close it if new window opens
+ infowindow.open(mwtnTopologyMapController.map, marker);
+ lastOpenedInfoWindow = infowindow;
+
+ // remove the reference if the windows is closed
+ infowindow.addListener('closeclick', function () {
+ lastOpenedInfoWindow = null;
+ });
+ });
+
+ marker.addListener('mouseover', function () {
+ marker.setOptions({ icon: newSiteHighlightIcon });
+ });
+
+ marker.addListener('mouseout', function () {
+ marker.setOptions({ icon: newSiteNormalIcon });
+ });
+
+ // store marker
+ scope.displayedSites[newSiteId] = marker;
+ }
+ });
+ };
+
+ }
+ }
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyMapSiteLinks', ['$compile', '$rootScope', function ($compile, $rootScope) {
+ return {
+ restrict: 'E',
+ require: '^mwtnTopologyMap',
+ scope: {
+ selectedSiteLink: "=",
+ siteLinks: "=",
+ api: "="
+ },
+ link: function (scope, element, attrs, mwtnTopologyMapController) {
+
+ var normalColor = "#FF0000";
+ var selectedColor = "#00FD30";
+
+ scope.$watch("selectedSiteLink", function (newSiteLinkId, oldSiteLinkId) {
+
+ if (oldSiteLinkId && scope.displayedSiteLinks[oldSiteLinkId]) {
+ scope.displayedSiteLinks[oldSiteLinkId].setOptions({
+ strokeColor: normalColor,
+ });
+ }
+
+ if (newSiteLinkId && scope.displayedSiteLinks[newSiteLinkId]) {
+ scope.displayedSiteLinks[newSiteLinkId].setOptions({
+ strokeColor: selectedColor,
+ });
+ }
+
+ });
+
+ scope.displayedSiteLinks = {};
+
+ /**
+ * Updates the google map Polylines
+ * @param addedSiteLinkIds {string[]} The ids of sites links which are added to the scope.displayedSiteLinks dictionary and the google map.
+ * @param removedSiteLinkIds {string[]} The ids of sites links which are removed from the visible bounding rectangle within the google map.
+ */
+ scope.api.updateSiteLinks = function (addedSiteLinkIds, removedSiteLinkIds) {
+ if (!addedSiteLinkIds) addedSiteLinkIds = [];
+ if (!removedSiteLinkIds) removedSiteLinkIds = [];
+
+ removedSiteLinkIds.forEach(function (siteLinkId) {
+ var polyline = scope.displayedSiteLinks[siteLinkId];
+ if (polyline) {
+ polyline.setMap(null);
+ //delete polyline;
+ delete scope.displayedSiteLinks[siteLinkId];
+ }
+ });
+
+ addedSiteLinkIds.forEach(function (siteLinkId) {
+ var siteLink = scope.siteLinks[siteLinkId];
+ console.log(siteLink);
+
+ if (siteLink && !scope.displayedSiteLinks[siteLinkId]) {
+
+ // create the poly line
+ var polyline = new google.maps.Polyline({
+ map: mwtnTopologyMapController.map,
+ path: [siteLink.siteA.location, siteLink.siteZ.location],
+ strokeColor: siteLink.type === 'traffic' ? '#00ccff': '#ffff00',
+ strokeOpacity: 0.8,
+ strokeWeight: siteLink.type === 'traffic' ? 4 : 2,
+ zIndex: 1,
+ geodesic: true
+ });
+ console.log(siteLink.type, polyline.strokeColor);
+
+ // add event listeners to the polyline
+ polyline.addListener('click', function (event) {
+ // cloase all already opened windows
+ if (lastOpenedInfoWindow) {
+ lastOpenedInfoWindow.close();
+ lastOpenedInfoWindow = null;
+ }
+
+ // compile the content
+ var infoWindowTemplate = '<mwtn-topology-link-details link-id="linkId"></mwtn-topology-link-details>';
+ var infoWindowScope = $rootScope.$new();
+ infoWindowScope['linkId'] = siteLinkId;
+ var infoWindowContent = $compile(infoWindowTemplate)(infoWindowScope)[0];
+
+ // create the info window
+ var infowindow = new google.maps.InfoWindow({
+ content: infoWindowContent,
+ disableAutoPan: true
+ });
+
+ // open the window and keek a refenrece to close it if new window opens
+ // adjust and show the info window
+ infowindow.setPosition(event.latLng);
+ infowindow.open(mwtnTopologyMapController.map);
+ lastOpenedInfoWindow = infowindow;
+
+ // remove the reference if the windows is closed
+ infowindow.addListener('closeclick', function () {
+ lastOpenedInfoWindow = null;
+ });
+
+ });
+
+ polyline.addListener('mouseover', function () {
+ polyline.setOptions({ strokeWeight: 6 });
+ });
+
+ polyline.addListener('mouseout', function () {
+ polyline.setOptions({ strokeWeight: 3 });
+ });
+
+ // store the ployline
+ scope.displayedSiteLinks[siteLinkId] = polyline;
+ }
+ });
+ };
+
+ }
+ };
+ }]);
+
+ mwtnTopologyApp.controller('mwtnTopologySiteDetailsController', ['$scope', '$timeout', '$mwtnTopology', function ($scope, $timeout, $mwtnTopology) {
+ var vm = this;
+ vm.site = null;
+
+ $scope.$watch(function () { return vm.siteId }, function (newSiteId, oldSiteId) {
+ if (!newSiteId) return;
+
+ vm.status = {
+ message: 'Searching...',
+ type: 'warning',
+ isWorking: true
+ };
+
+ $mwtnTopology.getSiteDetailsBySiteId(newSiteId).then(function (siteDetails) {
+ vm.site = siteDetails;
+
+ vm.status = {
+ message: undefined,
+ type: 'success',
+ isWorking: false
+ };
+ }, function (err) {
+ vm.status = {
+ message: err,
+ type: 'error',
+ isWorking: false
+ };
+ });
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologySiteDetails', function () {
+ return {
+ scope: { siteId: "=" },
+ restrict: 'E',
+ controller: 'mwtnTopologySiteDetailsController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/siteDetails.tpl.html'
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologyLinkDetailsController', ['$scope', '$timeout', '$mwtnTopology', function ($scope, $timeout, $mwtnTopology) {
+ /** @type {{ link: SiteLinkDetails } & {[key: string]: any}} */
+ var vm = this;
+ vm.site = null;
+ vm.link = null;
+
+ $scope.$watch(function () { return vm.linkId }, function (newLinkId, oldLinkId) {
+ if (!newLinkId) return;
+
+ vm.status = {
+ message: 'Searching...',
+ type: 'warning',
+ isWorking: true
+ };
+
+ // getLinkDetailsByLinkId
+ $mwtnTopology.getLinkDetailsByLinkId(newLinkId).then(
+ /** @param {SiteLinkDetails} linkDetails*/
+ function (linkDetails) {
+ vm.link = linkDetails;
+
+ vm.status = {
+ message: undefined,
+ type: 'success',
+ isWorking: false
+ };
+ }, function (err) {
+ vm.status = {
+ message: err,
+ type: 'error',
+ isWorking: false
+ };
+ });
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyLinkDetails', function () {
+ return {
+ scope: { linkId: "=" },
+ restrict: 'E',
+ controller: 'mwtnTopologyLinkDetailsController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/linkDetails.tpl.html'
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologyFrameController', ['$scope', '$rootScope', '$timeout', '$state', '$window', '$mwtnTopology', function ($scope, $rootScope, $timeout, $state, $window, $mwtnTopology) {
+ var vm = this;
+
+ $rootScope.section_logo = 'src/app/mwtnTopology/images/mwtnTopology.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ /** @type {{ [tabName: string] : { [parameterName : string] : any } }} */
+ var tabParameters = {};
+
+ var tabs;
+ (function (tabs) {
+ tabs[tabs["site"] = 0] = "site";
+ tabs[tabs["physical"] = 1] = "physical";
+ tabs[tabs["ethernet"] = 2] = "ethernet";
+ tabs[tabs["ieee1588"] = 3] = "ieee1588";
+ })(tabs || (tabs = {}));
+
+ $scope.$watch(function () { return vm.activeTab; }, function (newVal, oldVal, scope) {
+ if (newVal == null) return;
+
+ var newName = tabs[newVal];
+
+ if (oldVal != null && tabs[oldVal]) {
+ var oldName = tabs[oldVal];
+ tabParameters[oldName] = $state.params;
+ }
+
+ var newParameters = Object.keys($state.params).reduce(function (acc, cur, ind, arr) { acc[cur] = null; return acc; }, {});
+ Object.assign(newParameters, tabParameters[newName] || {}, { tab: newName, internal: false });
+
+ $state.go('main.mwtnTopology', newParameters, { notify: false });
+ console.log("activeTab: ", newName);
+ });
+
+ $scope.$watch(function () { return $state.params.tab; }, function (newVal, oldVal, scope) {
+ if (newVal == oldVal) return;
+ if (newVal && !$state.params.internal) {
+ vm.activeTab = tabs[newVal || "site"];
+ console.log("navigationTab: ", vm.activeTab);
+ }
+ });
+
+ // hide all tabs until the google api is fully loaded.
+ // initialize with true is the promise is resolved === 1
+ vm.googleIsReady = $mwtnTopology.googleMapsApiPromise.$$state.status === 1;
+
+ if (!vm.googleIsReady) $mwtnTopology.googleMapsApiPromise.then(function () {
+ $timeout(function () {
+ vm.googleIsReady = true;
+ });
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyFrame', function () {
+ return {
+ restrict: 'E',
+ controller: 'mwtnTopologyFrameController',
+ controllerAs: 'vm',
+ templateUrl: 'src/app/mwtnTopology/templates/frame.tpl.html'
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologySiteViewController', ['$scope', '$q', '$timeout', '$state', '$window', '$mwtnTopology', function ($scope, $q, $timeout, $state, $window, $mwtnTopology) {
+ var vm = this;
+ // Determines if a database request loop should be canceld.
+ var cancelRequested = false;
+ // Represents a defer which is resolved, if a cancel was requested and fulfilled.
+ var cancelDefer = $q.defer();
+ // Represents the new bounding rectangle who was set with the last user action to change the map bounds.
+ // The value is saved until the cancel operation is fulfilled.
+ /** @type {{top: number, right: number, bottom: number, left: number, zoom: number}} */
+ var waitForCancelMapBoundAndZoom;
+ // While getting all sites collect all site link ids which are available through visible and known sites.
+ // This dictionary will be cleared each time a new map bound is changed and a new database request loop is started.
+ var collectedSiteLinkIds = {};
+
+ vm.status = {
+ // Determines the bounds of the map which is manually set by the code. These are the initial values.
+ manualMapBounds: {
+ top: !Number.isNaN(+$state.params.top) ? +$state.params.top : undefined,
+ bottom: !Number.isNaN(+$state.params.bottom) ? +$state.params.bottom : undefined,
+ left: !Number.isNaN(+$state.params.left) ? +$state.params.left : undefined,
+ right: !Number.isNaN(+$state.params.right) ? +$state.params.right : undefined,
+ zoom: !Number.isNaN(+$state.params.zoom) ? +$state.params.zoom : undefined,
+ lat: !Number.isNaN(+$state.params.lat) ? +$state.params.lat : undefined,
+ lng: !Number.isNaN(+$state.params.lng) ? +$state.params.lng : undefined
+ },
+
+ // Determines if the accordeon group element for SiteMap, SiteGrid or SiteLinkGrid is open.
+ siteMapIsOpen: true,
+ siteGridIsOpen: true,
+ siteLinkGridIsOpen: true,
+ sitePathGridIsOpen: false,
+
+ // Determines if a processing is running.
+ processing: false,
+ totalSitesInBoundingBox: 0,
+ loadedSitesInBoundingBox: 0,
+ maximumCountOfVisibleSites: 300,
+
+ // selectet Elements
+ site: null,
+ siteLink: null,
+ sitePath: null
+ };
+
+ // Contains the known and visible sites as well as known site links as dictionaries.
+ vm.knownSites = {};
+ vm.visibleSites = {};
+ vm.knownSiteLinks = {};
+
+ // Api-Object that will be filled with update methods from the mwtnTopologyMapSites Component.
+ vm.mapSitesComponentApi = {};
+ // Api-Object that will be filled with update methods from the mwtnTopologyMapSiteLinks Component.
+ vm.mapSiteLinksComponentApi = {};
+
+ //addedSiteLinkIds, removedSiteLinkIds
+
+ initializeMapBounds();
+
+ function initializeMapBounds() {
+
+ vm.status.manualMapBounds = {
+ top: !Number.isNaN(+$state.params.top) ? +$state.params.top : undefined,
+ bottom: !Number.isNaN(+$state.params.bottom) ? +$state.params.bottom : undefined,
+ left: !Number.isNaN(+$state.params.left) ? +$state.params.left : undefined,
+ right: !Number.isNaN(+$state.params.right) ? +$state.params.right : undefined,
+ zoom: !Number.isNaN(+$state.params.zoom) ? +$state.params.zoom : undefined,
+ lat: !Number.isNaN(+$state.params.lat) ? +$state.params.lat : undefined,
+ lng: !Number.isNaN(+$state.params.lng) ? +$state.params.lng : undefined
+ };
+
+ // Calculate the initial map control bound, if we have no initial bounds
+ if ((vm.status.manualMapBounds.top == null && vm.status.manualMapBounds.bottom == null && vm.status.manualMapBounds.right == null && vm.status.manualMapBounds.left == null && vm.status.manualMapBounds.lat == null && vm.status.manualMapBounds.lng == null && $state.params.site == null && $state.params.siteLink == null && $state.params.sitePath == null)) {
+ $mwtnTopology.getOuterBoundingRectangleForSites().then(function (bounds) {
+ // Ensures that the new value is set within a digest cycle.
+ vm.status.manualMapBounds = bounds;
+ });
+ }
+ }
+
+ $scope.$watch(function () { return $state.params.site; }, function (newVal, oldVal, scope) {
+ if (newVal) {
+ $mwtnTopology.getSiteDetailsBySiteId(newVal).then(function (siteDetails) {
+ if (siteDetails) {
+ // just update the location of the browser if the location has changed
+ $state.go('main.mwtnTopology', {
+ tab: "site",
+ lat: siteDetails.location.lat,
+ lng: siteDetails.location.lng,
+ zoom: 19,
+ top: null,
+ bottom: null,
+ right: null,
+ left: null,
+ site: $state.params.site,
+ siteLink: null,
+ sitePath: null,
+ internal: false
+ }, {
+ notify: false
+ });
+ };
+ }, function (err) {
+
+ });
+ }
+ });
+
+ $scope.$watch(function () { return $state.params.siteLink; }, function (newVal, oldVal, scope) {
+ if (newVal) {
+ $mwtnTopology.getLinkDetailsByLinkId(newVal).then(function (link) {
+ if (link) {
+
+ var top = link.siteA.location.lat >= link.siteZ.location.lat ? link.siteA.location.lat : link.siteZ.location.lat;
+ var bottom = link.siteA.location.lat >= link.siteZ.location.lat ? link.siteZ.location.lat : link.siteA.location.lat;
+
+ // todo: this code is not able to handle links which overlap the -100|180 ° borderline
+ var left = link.siteA.location.lng <= link.siteZ.location.lng ? link.siteA.location.lng : link.siteZ.location.lng;
+ var right = link.siteA.location.lng <= link.siteZ.location.lng ? link.siteZ.location.lng : link.siteA.location.lng;
+ // just update the location of the browser if the location has changed
+ $state.go('main.mwtnTopology', {
+ tab: "site",
+ lat: null,
+ lng: null,
+ zoom: $state.params.zoom,
+ top: top,
+ bottom: bottom,
+ right: right,
+ left: left,
+ site: null,
+ siteLink: $state.params.siteLink,
+ sitePath: null,
+ internal: false
+ }, {
+ notify: false
+ });
+ };
+ }, function (err) {
+
+ });
+ }
+ });
+
+ $scope.$watchCollection(function () { return [vm.status.siteMapIsOpen, vm.status.siteGridIsOpen, vm.status.siteLinkGridIsOpen, vm.status.sitePathGridIsOpen] }, function (newVal, oldVal) {
+ if (newVal[1] || newVal[2] || newVal[3]) {
+ $timeout(function () {
+ $window.dispatchEvent(new Event("resize"));
+ });
+ }
+ });
+
+ $scope.$watchCollection(function () { return [+$state.params.top, +$state.params.bottom, +$state.params.left, +$state.params.right, +$state.params.lat, +$state.params.lng, +$state.params.zoom]; }, function (newVal, oldVal, scope) {
+
+ if (oldVal == null || oldVal === newVal) return; // ignore initial value
+
+ if (!vm.status.siteMapIsOpen) {
+ console.log("open Site Map")
+ vm.status.siteMapIsOpen = true;
+ return;
+ }
+
+ vm.status.manualMapBounds = {
+ top: !Number.isNaN(newVal[0]) ? newVal[0] : undefined,
+ bottom: !Number.isNaN(newVal[1]) ? newVal[1] : undefined,
+ left: !Number.isNaN(newVal[2]) ? newVal[2] : undefined,
+ right: !Number.isNaN(newVal[3]) ? newVal[3] : undefined,
+ zoom: !Number.isNaN(newVal[6]) ? newVal[6] : undefined,
+ internal: !!$state.params.internal
+ };
+
+ if (!Number.isNaN(newVal[4]) && !Number.isNaN(newVal[5])) {
+ vm.status.manualMapBounds.lat = newVal[4];
+ vm.status.manualMapBounds.lng = newVal[5];
+ } else {
+ vm.status.manualMapBounds.lat = undefined;
+ vm.status.manualMapBounds.lng = undefined;
+ }
+
+ if (!!$state.params.internal) $state.params.internal = false;
+
+ });
+
+ $scope.$watchCollection(function () { return vm.status.siteMapIsOpen }, function (newVal, oldVal, scope) {
+ if (oldVal == newVal) return; // ignore initial value
+ if (newVal) {
+ // Map (re)-opend
+ initializeMapBounds();
+ } else {
+ // Map closed
+ vm.status.loadedSitesInBoundingBox = 0;
+ vm.status.totalSitesInBoundingBox = 0;
+ vm.status.manualMapBounds = {};
+ vm.knownSites = {};
+ vm.visibleSites = {};
+ vm.knownSiteLinks = {};
+ };
+ // tell all sub components the visuability of the map view
+ $scope.$broadcast('mapViewVisuability', newVal);
+ });
+
+ /* callback and helper methods */
+ /**
+ * A callback function which is called by the map control of the user changed the bounds of the map.
+ * @param mapBoundsAndZoom {{top: number, right: number, bottom: number, left: number, zoom: number}} The new bounds and the new zoom level of the map control.
+ */
+ vm.mapBoundsChanged = function (mapBoundsAndZoom, userOriginated) {
+
+ // just update the location of the browser if the location has changed
+ $state.go('main.mwtnTopology', {
+ tab: "site",
+ lat: mapBoundsAndZoom.lat,
+ lng: mapBoundsAndZoom.lng,
+ zoom: mapBoundsAndZoom.zoom,
+ top: null,
+ bottom: null,
+ right: null,
+ left: null,
+ site: !userOriginated ? $state.params.site : null,
+ siteLink: !userOriginated ? $state.params.siteLink : null,
+ sitePath: !userOriginated ? $state.params.sitePath : null,
+ internal: true
+ }, {
+ notify: false
+ });
+ console.log("handleBoundsChanged", mapBoundsAndZoom);
+
+ if (vm.status.siteMapIsOpen) refreshAllSites(mapBoundsAndZoom);
+ };
+
+ /**
+ * Refreshes all visible elements in the given view port
+ * @param mapBoundsAndZoom {{top: number, right: number, bottom: number, left: number, zoom: number}} The new bounds and the new zoom level of the map control.
+ */
+ function refreshAllSites(mapBoundsAndZoom) {
+
+ // Datenbankabfragen werden werden in kleine Chunks zerlegt.
+ // Jeder Chunk enthält maximal ${chunkSize} (100) Sites und die Anzahl aller Sites für die spezifische Abfrage in der Antwort.
+ // Sind noch nicht alle Chunks von der Datenbank angefordert worden, wird zuerst der nächste Chunk angefordert.
+ // Der aktuell zurückgegebene Chunk wird aber erst verarbeitet, bevor in einer weiteren Callback-Situation der nächste Datenbank-Chunk abgeholt wird.
+ // Dadurch werden kontinuierlich alle Sites auch auf der Map ergänzt, sobald sie verarbeitet wurden und es kommt zu keiner Verzögerung im Benutzerinterface.
+ // Im Maximum werden aber ${vm.status.maximumCountOfVisibleSites} (2500) Sites abgerufen, um die Google Map nicht zu überlasten.
+
+ // Fallunterscheidung: gibt es bereits eine aktive Datenbankabfrage zu den Sites?
+ // => Nein: Starte eine neue Datenbankabfrage
+ // => Ja: Breche die aktuelle Verarbeitung ab, aktualisiere den Status und starte dann eine neue Datenbankabfrage.
+ if (vm.status.processing) {
+ waitForCancelMapBoundAndZoom = mapBoundsAndZoom;
+
+ if (cancelRequested) {
+ console.log("Cancel is already requested.");
+ return;
+ }
+
+ // Request a database loop cancel.
+ cancelRequested = true;
+ console.log("New Cancel requested.")
+
+ // Wait until the current database loos was canceled.
+ cancelDefer.promise.then(function () {
+ // The database loop is canceled. Create a new defer for the next possible cancel request.
+ console.log("Cancel fulfilled.");
+ cancelDefer = $q.defer();
+ // Restart the database loop with the new bounding rectangle.
+ beginProcessing(waitForCancelMapBoundAndZoom);
+ });
+
+ // Do not start a database loop here - so leave the method.
+ return;
+ }
+
+ // Start a new database loop here.
+ beginProcessing(mapBoundsAndZoom);
+
+ /**
+ * The private function which begins a new database processing loop.
+ * @param mapBoundsAndZoom {{top: number, right: number, bottom: number, left: number, zoom: number}} The new bounds and the new zoom level of the map control.
+ */
+ function beginProcessing(mapBoundsAndZoom) {
+ // Set the processing flag to true.
+ vm.status.processing = true;
+
+ var chunkSize = 100;
+ var chunkSiteStartIndex = 0;
+
+ // If a site link cannot convert its siteA or siteZ (id) Parameter to a real site object these ids will collected.
+ // After a subsequent database call to get these sites the queued site links will be converted.
+ var additionalSiteIds = [];
+ var queuedSiteLinksToConvert = [];
+
+ // Entferne Sites, welche aufgrund des neuen Bounds leicht außer Sicht sind von den sichtbaren Sites.
+ // Hinzufügen von Sites aus den leicht außer Sicht Bereich zum sichtbaren Bereich.
+ var movedOrRemovedSites = refreshOutOfSightSites(mapBoundsAndZoom);
+ var removedFromVisibleIds = movedOrRemovedSites.removedFromVisibleIds;
+ var movedFromVisibleToKnownIds = movedOrRemovedSites.movedFromVisibleToKnownIds;
+ var removedFromKnownIds = movedOrRemovedSites.removedFromKnownIds;
+ var movedFromKnownToVisibleIds = movedOrRemovedSites.movedFromKnownToVisibleIds;
+ var removedSiteLinkIds = movedOrRemovedSites.removedSiteLinkIds;
+
+ // While getting all sites collect all site link ids which are available through visible and known sites.
+ collectedSiteLinkIds = {};
+
+ doSiteRequestLoop();
+
+ /* internal function within beginProcessing */
+ /**
+ * Starts a new database request loop to get all sites.
+ */
+ function doSiteRequestLoop() {
+ requestNextSiteChunk(mapBoundsAndZoom, chunkSize, chunkSiteStartIndex).then(
+ /**
+ * @param result {{addedSiteIds: string[], total: number}} An array with the ids of the sites which are added to the vm.visibleSites dictionary.
+ */
+ function (result) {
+ // update the frontend before continue with the next database request.
+ vm.mapSitesComponentApi.updateSites && vm.mapSitesComponentApi.updateSites(result.addedSiteIds, removedFromVisibleIds, movedFromVisibleToKnownIds, removedFromKnownIds, movedFromKnownToVisibleIds);
+ removedSiteLinkIds && removedSiteLinkIds.length && vm.mapSiteLinksComponentApi.updateSiteLinks && vm.mapSiteLinksComponentApi.updateSiteLinks([], removedSiteLinkIds);
+ // to not re-remove and re-move already removed and moved sites clear the arrays for any subsequent database requests.
+ removedFromVisibleIds = [];
+ movedFromVisibleToKnownIds = [];
+ removedFromKnownIds = [];
+ movedFromKnownToVisibleIds = [];
+ removedSiteLinkIds = [];
+
+ if (cancelRequested) {
+ // reset the cancelRequested flag and resolve the cancel request.
+ cancelRequested = false;
+ cancelDefer.resolve();
+ return;
+ }
+
+ // Enforce angular to process a new digest cycle.
+ $timeout(function () {
+ vm.status.totalSitesInBoundingBox = result.total;
+ vm.status.loadedSitesInBoundingBox = Math.min(chunkSiteStartIndex + chunkSize, result.total);
+ if (chunkSiteStartIndex + chunkSize >= result.total || chunkSiteStartIndex + chunkSize >= vm.status.maximumCountOfVisibleSites) {
+ // This was the last database request to get sites.
+ // Remove all known site link ids from the collectedSiteLinkIds dictionary.
+ var knownSiteLinkIds = Object.keys(vm.knownSiteLinks);
+ knownSiteLinkIds.forEach(function (knownSiteLinkId) {
+ if (collectedSiteLinkIds[knownSiteLinkId]) {
+ delete collectedSiteLinkIds[knownSiteLinkId];
+ }
+ });
+
+ // Start the request loop for site links now.
+ doSiteLinkRequestLoop(Object.keys(collectedSiteLinkIds));
+ } else {
+ // There are more data, request the database again.
+ chunkSiteStartIndex += chunkSize;
+
+ doSiteRequestLoop();
+ }
+ });
+
+ }, processError);
+ }
+
+ function endProcessing() {
+ vm.status.processing = false;
+
+ $timeout(function () {
+ vm.status.site = $state.params.site;
+ vm.status.siteLink = $state.params.siteLink;
+ });
+ }
+
+ /**
+ * Starts a new database request loop to get all site links.
+ */
+ function doSiteLinkRequestLoop(siteLinkIds) {
+ var requestedSiteLinkIds = siteLinkIds.splice(0, chunkSize);
+
+ $mwtnTopology.getSiteLinksByIds(requestedSiteLinkIds).then(
+ /**
+ * Processes the database result.
+ * The returned site links doesn't contain site objects but site ids.
+ * In a subsequent step these ids will be converted into real site objects.
+ * @param result {{id: string, siteA: string, siteZ: string}[]} The database result.
+ */
+ function (result) {
+ // Subsequent convert.
+ // All site links which siteA and siteZ site ids are known could be added to vm.knownSiteLinks.
+ // The rest has to saved until all requests are finished.
+ // Another database call will get the additional sites to convert these site links.
+ var addedSiteLinkIds = result.reduce(function (accumulator, currentSiteLink) {
+ var siteA = vm.visibleSites[currentSiteLink.siteA] || vm.knownSites[currentSiteLink.siteA];
+ var siteZ = vm.visibleSites[currentSiteLink.siteZ] || vm.knownSites[currentSiteLink.siteZ];
+ if (siteA && siteZ) {
+ vm.knownSiteLinks[currentSiteLink.id] = {
+ id: currentSiteLink.id,
+ siteA: siteA,
+ siteZ: siteZ,
+ type: currentSiteLink.type
+ };
+ accumulator.push(currentSiteLink.id);
+ } else {
+ // Theoretically, only siteA or siteZ can be unknown. I still check both separately.
+ var isPushed = false;
+ if (!siteA) {
+ additionalSiteIds.push(currentSiteLink.siteA);
+ queuedSiteLinksToConvert.push(currentSiteLink);
+ isPushed = true;
+ }
+ if (!siteZ) {
+ additionalSiteIds.push(currentSiteLink.siteZ);
+ isPushed || queuedSiteLinksToConvert.push(currentSiteLink);
+ }
+ }
+ return accumulator;
+ }, []);
+
+ // update the frontend before continue with the next database request.
+ vm.mapSiteLinksComponentApi.updateSiteLinks && vm.mapSiteLinksComponentApi.updateSiteLinks(addedSiteLinkIds);
+
+ if (cancelRequested) {
+ // reset the cancelRequested flag and resolve the cancel request.
+ cancelRequested = false;
+ cancelDefer.resolve();
+ return;
+ }
+
+ // Enforce angular to process a new digest cycle. (And to let angular time to redraw the map.)
+ $timeout(function () {
+ if (siteLinkIds.length === 0) {
+ if (additionalSiteIds.length === 0) {
+ endProcessing();
+ return;
+ }
+
+ // Only get a maximum of chunkSize additional sites.
+ // Site links more than that will not be drawed in the map due to performance reasons.
+ // If the user zooms in the additional site links will be requested again.
+ $mwtnTopology.getSitesByIds(additionalSiteIds.splice(0, chunkSize)).then(
+ /**
+ * Processes the database result to gain new sites within the bounding box of the database request.
+ * @param result {{total: number, sites: {id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}}[]}} The database result.
+ */
+ function (result) {
+ var addedSiteLinkIds = queuedSiteLinksToConvert.reduce(function (accumulator, currentSiteLink) {
+ var siteA = vm.visibleSites[currentSiteLink.siteA] || vm.knownSites[currentSiteLink.siteA] || result.sites.find(
+ function (site) {
+ return site.id === currentSiteLink.siteA
+ });
+ var siteZ = vm.visibleSites[currentSiteLink.siteZ] || vm.knownSites[currentSiteLink.siteZ] || result.sites.find(
+ function (site) {
+ return site.id === currentSiteLink.siteZ
+ });
+ if (siteA && siteZ) {
+ vm.knownSiteLinks[currentSiteLink.id] = {
+ id: currentSiteLink.id,
+ siteA: siteA,
+ siteZ: siteZ,
+ type: currentSiteLink.type
+ };
+ accumulator.push(currentSiteLink.id);
+ }
+ return accumulator;
+ }, []);
+ // update the frontend the last time until the user changed the map position.
+ vm.mapSiteLinksComponentApi.updateSiteLinks && vm.mapSiteLinksComponentApi.updateSiteLinks(addedSiteLinkIds);
+
+ // all done - puh.
+ endProcessing();
+ }, processError);
+
+ } else {
+ // There are more data, request the database again.
+ doSiteLinkRequestLoop(siteLinkIds);
+ }
+ });
+
+ }, processError);
+ }
+
+ }
+ };
+
+ /**
+ * Recalculates the targets site container for Sites within knownSites and visibleSites.
+ * @param mapBoundsAndZoom {{top: number, right: number, bottom: number, left: number, zoom: number}} The new bounds and the new zoom level of the map control.
+ */
+ function refreshOutOfSightSites(mapBoundsAndZoom) {
+ var additionalWidth = (mapBoundsAndZoom.right - mapBoundsAndZoom.left) / 4;
+ var additionalHeight = (mapBoundsAndZoom.top - mapBoundsAndZoom.bottom) / 4;
+ var slightlyTop = mapBoundsAndZoom.top + additionalHeight;
+ var slightlyRight = mapBoundsAndZoom.right + additionalWidth;
+ var slightlyBottom = mapBoundsAndZoom.bottom - additionalHeight;
+ var slightlyLeft = mapBoundsAndZoom.left - additionalWidth;
+
+ var removedFromVisibleIds = [];
+ var movedFromVisibleToKnownIds = [];
+ var removedFromKnownIds = [];
+ var movedFromKnownToVisibleIds = [];
+ var removedSiteLinkIds = [];
+
+ var visibleSiteKeys = Object.keys(vm.visibleSites);
+ var knownSiteKeys = Object.keys(vm.knownSites);
+ var knownSiteLinkKeys = Object.keys(vm.knownSiteLinks);
+
+ visibleSiteKeys.forEach(function (siteId) {
+ /** @var {{id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}} site */
+ var site = vm.visibleSites[siteId];
+
+ if (site.location.lat > slightlyTop || site.location.lng > slightlyRight || site.location.lat < slightlyBottom || site.location.lng < slightlyLeft) {
+ // This site is completly out of sight - so remove it and add the id to the removedFromVisibleIds list.
+ delete vm.visibleSites[siteId];
+ removedFromVisibleIds.push(siteId);
+ return;
+ }
+
+ if (site.location.lat > mapBoundsAndZoom.top || site.location.lng > mapBoundsAndZoom.right || site.location.lat < mapBoundsAndZoom.bottom || site.location.lng < mapBoundsAndZoom.left) {
+ // This site is moved from the visible map bounds to the extended map bounds and will only hide but stay in the google object.
+ vm.knownSites[siteId] = site;
+ delete vm.visibleSites[siteId];
+ movedFromVisibleToKnownIds.push(siteId);
+ return;
+ }
+ });
+
+ knownSiteKeys.forEach(function (siteId) {
+ /** @type {{id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}} site */
+ var site = vm.knownSites[siteId];
+
+ if (site.location.lat > slightlyTop || site.location.lng > slightlyRight || site.location.lat < slightlyBottom || site.location.lng < slightlyLeft) {
+ // This site is completly out of sight - so remove it and add the id to the removedFromKnownIds list.
+ delete vm.knownSites[siteId];
+ removedFromKnownIds.push(siteId);
+ return;
+ }
+
+ if (site.location.lat <= mapBoundsAndZoom.top && site.location.lng <= mapBoundsAndZoom.right && site.location.lat >= mapBoundsAndZoom.bottom && site.location.lng >= mapBoundsAndZoom.left) {
+ // This site is moved from the extended map bounds to the visible map bounds. Therefore the hidden google maps object should set visible again.
+ vm.visibleSites[siteId] = site;
+ delete vm.knownSites[siteId];
+ movedFromKnownToVisibleIds.push(siteId);
+ return;
+ }
+ });
+
+ knownSiteLinkKeys.forEach(function (siteLinkId) {
+ /** @type {{id: string, siteA: {id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}}, siteZ: {id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}}}} siteLink */
+ var siteLink = vm.knownSiteLinks[siteLinkId];
+ var siteA = siteLink.siteA;
+ var siteZ = siteLink.siteZ;
+
+ if ((siteA.location.lat > slightlyTop || siteA.location.lng > slightlyRight || siteA.location.lat < slightlyBottom || siteA.location.lng < slightlyLeft) &&
+ (siteZ.location.lat > slightlyTop || siteZ.location.lng > slightlyRight || siteZ.location.lat < slightlyBottom || siteZ.location.lng < slightlyLeft)) {
+ // This site link is completly out of sight - so remove it and add the id to the removedSiteLinkIds list.
+ delete vm.knownSiteLinks[siteLinkId];
+ removedSiteLinkIds.push(siteLinkId);
+ }
+ });
+
+ return {
+ removedFromVisibleIds: removedFromVisibleIds,
+ movedFromVisibleToKnownIds: movedFromVisibleToKnownIds,
+ removedFromKnownIds: removedFromKnownIds,
+ movedFromKnownToVisibleIds: movedFromKnownToVisibleIds,
+ removedSiteLinkIds: removedSiteLinkIds
+ };
+ }
+
+ /**
+ * Requests a chunk of sites from the database.
+ * @param mapBoundsAndZoom {{top: number, right: number, bottom: number, left: number, zoom: number}} The bounds and the zoom level of the map control to request the next chunk for.
+ * @param chunkSize {number} The chunk size of a single database request. To big values will block the user interface, to small values will lead in to many database requests.
+ * @param chunkSiteStartIndex {number} The index of the first site returned by the database.
+ */
+ function requestNextSiteChunk(mapBoundsAndZoom, chunkSize, chunkSiteStartIndex) {
+ var requestNextSiteChunkDefer = $q.defer();
+ var addedSiteIds = [];
+
+ // Request the next chunk.
+ $mwtnTopology.getSitesInBoundingBox(mapBoundsAndZoom, chunkSize, chunkSiteStartIndex).then(
+ /**
+ * Processes the database result to gain new sites within the bounding box of the database request.
+ * @param result {{chunkSize: number, chunkSiteStartIndex: number, total: number, sites: {id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]}}[]}} The database result.
+ */
+ function (result) {
+ result.sites.forEach(function (site) {
+ // The map bounds may have changed since the start of the database request.
+ // Therefore check if the site is within the bounding rectangle.
+
+ if (!$mwtnTopology.isInBounds(mapBoundsAndZoom, site.location)) {
+ return;
+ }
+
+ // add all site link ids to the selectedSiteLinkIds dictionary.
+ site.references.siteLinks.forEach(function (siteLinkId) {
+ collectedSiteLinkIds[siteLinkId] = true;
+ });
+
+ // check, if the site is within the knownSites dictionary.
+ if (vm.knownSites[site.id]) {
+ delete vm.knownSites[site.id];
+ }
+
+ // check if the site is within the visibleSites dictionary.
+ if (vm.visibleSites[site.id]) {
+ // Override the site (refresh)
+ vm.visibleSites[site.id] = site;
+ } else {
+ // Add the site to the dictionary and remember the siteId.
+ vm.visibleSites[site.id] = site;
+ addedSiteIds.push(site.id);
+ }
+ });
+
+ requestNextSiteChunkDefer.resolve({
+ addedSiteIds: addedSiteIds,
+ total: result.total
+ });
+ }, requestNextSiteChunkDefer.reject);
+
+ return requestNextSiteChunkDefer.promise;
+ }
+
+ /**
+ * Handles error messages by writing the information to the javascript console.
+ * Resets the processing flag.
+ * @param error Information about the error.
+ */
+ function processError(error) {
+ // Reset the processing flag.
+ vm.status.processing = false;
+ // Write the error information to the console.
+ console.error(error);
+ }
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologySiteView', function () {
+ return {
+ restrict: 'E',
+ controller: 'mwtnTopologySiteViewController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/siteView.tpl.html',
+ scope: {
+ initialMapBounds: "="
+ }
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologySiteGridController', ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+ var sitesAtCurrentPageCache = {};
+
+ vm.showAllSites = false;
+
+ vm.onNavigateToSite = function (row) {
+ var site = sitesAtCurrentPageCache[row.entity.id];
+ $state.go("main.mwtnTopology", {
+ tab: "site",
+ lat: site.location.lat,
+ lng: site.location.lng,
+ zoom: 19,
+ site: site.id,
+ internal: false
+ }, { notify: false });
+ };
+
+ // see http://ui-grid.info/docs/#/tutorial/317_custom_templates
+ var buttonCellTemplate = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i ng-click="grid.appScope.vm.onNavigateToSite(row)" ng-class="{\'fa\':true, \'fa-map-marker\': true, \'{{COL_FIELD}}\':true}" aria-hidden="true"></i></div>';
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "name",
+ type: "string",
+ displayName: "Name"
+ },
+ {
+ field: "location",
+ type: "string",
+ displayName: "Location"
+ },
+ {
+ field: "amslGround",
+ type: "string",
+ displayName: "AmslGround"
+ },
+ {
+ field: "countLinks",
+ type: "number",
+ displayName: "Count (Links)"
+ },
+ {
+ field: "countNetworkElements",
+ type: "number",
+ displayName: "Count (Network elements)"
+ },
+ {
+ field: "buttons",
+ type: "string",
+ displayName: "",
+ width: 40,
+ enableFiltering: false,
+ enableSorting: false,
+ cellTemplate: buttonCellTemplate,
+ pinnedRight: true
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0)
+ ? null
+ : sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({ field: col.field, term: col.filters[0].term });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ $scope.$on("mapViewVisuability", function (event, data) {
+ vm.showAllSites = !data;
+ });
+
+ $scope.$watch("visibleSites", function (newVisibleSites, oldVisibleSites) {
+ console.log("watch: visibleSites");
+ if (!vm.showAllSites) loadPage();
+ }, true); // deep watch, maybe find a better solution; e.g. with an api object like the site in the map.
+
+ $scope.$watch(function () { return vm.showAllSites; }, loadPage);
+
+ function loadPage() {
+ if (vm.showAllSites) {
+ loadRemotePage();
+ } else {
+ loadLocalPage();
+ }
+ }
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadLocalPage() {
+ var siteIds = Object.keys($scope.visibleSites);
+
+ var tempData = siteIds.filter(function (siteId, ind, arr) {
+ var site = $scope.visibleSites[siteId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case "countLinks":
+ return (site.references.siteLinks ? site.references.siteLinks.length : 0) == +filter.term;
+ default:
+ return site[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (siteId) {
+ var site = $scope.visibleSites[siteId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: siteId
+ }
+ }
+
+ switch (sortColumn.field) {
+ case "countLinks":
+ orderBy = site.references.siteLinks ? site.references.siteLinks.length : 0;
+ break;
+ case "countNetworkElements":
+ orderBy = site.references.networkElements ? site.references.networkElements.length : 0;
+ break;
+ case "buttons":
+ orderBy = siteId;
+ break;
+ default:
+ orderBy = site[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: siteId,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedSitesAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ sitesAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedSitesAtCurrentPage.forEach(function (orderedSite) {
+ var site = $scope.visibleSites[orderedSite.id];
+ sitesAtCurrentPageCache[site.id] = site;
+ orderedData.push({
+ id: orderedSite.id,
+ name: site.name,
+ location: site.location.lat.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }) + ", " + site.location.lng.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ amslGround: site.amslGround,
+ countLinks: site.references.siteLinks ? site.references.siteLinks.length : 0,
+ countNetworkElements: site.references.networkElements ? site.references.networkElements.length : 0
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ /**
+ * Loads the page content for the grid and sets the values to the gridOprions.data object.
+ */
+ function loadRemotePage() {
+
+ $mwtnTopology.getSites((sortColumn && sortColumn.field), sortColumn && ((sortColumn.sort.direction && sortColumn.sort.direction === uiGridConstants.ASC) ? 'asc' : 'desc'), gridFilters, paginationPageSize, (paginationPage - 1) * paginationPageSize).then(function (result) {
+ sitesAtCurrentPageCache = result.sites.reduce(function (acc, cur, ind, arr) {
+ acc[cur.id] = cur;
+ return acc;
+ }, {});
+ vm.gridOptions.data = result.sites.map(function (site) {
+ return {
+ id: site.id,
+ name: site.name,
+ location: site.location.lat.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }) + ", " + site.location.lng.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ amslGround: site.amslGround,
+ countLinks: site.references.siteLinks ? site.references.siteLinks.length : 0,
+ countNetworkElements: site.references.networkElements ? site.references.networkElements.length : 0
+ }
+ });
+ vm.gridOptions.totalItems = result.total;
+ });
+ }
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologySiteGrid', function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologySiteGridController',
+ controllerAs: 'vm',
+ scope: {
+ visibleSites: "="
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/siteGrid.tpl.html'
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologySiteLinkGridController', ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+
+ var linksAtCurrentPageCache = {};
+
+ vm.showAllLinks = false;
+
+ vm.onNavigateToLink = function (row) {
+ var link = linksAtCurrentPageCache[row.entity.id];
+
+ var top = link.siteA.location.lat >= link.siteZ.location.lat ? link.siteA.location.lat : link.siteZ.location.lat;
+ var bottom = link.siteA.location.lat >= link.siteZ.location.lat ? link.siteZ.location.lat : link.siteA.location.lat;
+
+ // todo: this code is not able to handle links which overlap the -100|180 ° borderline
+ var left = link.siteA.location.lng <= link.siteZ.location.lng ? link.siteA.location.lng : link.siteZ.location.lng;
+ var right = link.siteA.location.lng <= link.siteZ.location.lng ? link.siteZ.location.lng : link.siteA.location.lng;
+
+ $state.go("main.mwtnTopology", {
+ tab: "site",
+ top: top,
+ bottom: bottom,
+ left: left,
+ right: right,
+ siteLink: link.id,
+ internal: false
+ }, { notify: false });
+ console.log(link);
+ };
+
+ // see http://ui-grid.info/docs/#/tutorial/317_custom_templates
+ var buttonCellTemplate = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i ng-click="grid.appScope.vm.onNavigateToLink(row)" ng-class="{\'fa\':true, \'fa-map-marker\': true, \'{{COL_FIELD}}\':true}" aria-hidden="true"></i></div>';
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ // enableFiltering: false,
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "name",
+ type: "string",
+ displayName: "Name"
+ },
+ {
+ field: "siteIdA",
+ type: "string",
+ displayName: "SiteA"
+ },
+ {
+ field: "siteIdZ",
+ type: "string",
+ displayName: "SiteZ"
+ },
+ {
+ field: "buttons",
+ type: "string",
+ displayName: "",
+ width: 40,
+ enableFiltering: false,
+ enableSorting: false,
+ cellTemplate: buttonCellTemplate,
+ pinnedRight: true
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({ field: col.field, term: col.filters[0].term });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ $scope.$on("mapViewVisuability", function (event, data) {
+ vm.showAllLinks = !data;
+ });
+
+ $scope.$watch("knownSiteLinks", function (newKnownSiteLinks, oldKnownSiteLinks) {
+ console.log("watch: knownSiteLinks");
+ loadPage();
+ }, true); // deep watch, maybe find a better solution; e.g. with an api object like the site in the map.
+
+ $scope.$watch(function () { return vm.showAllLinks; }, loadPage);
+
+ function loadPage() {
+ if (vm.showAllLinks) {
+ loadRemotePage();
+ } else {
+ loadLocalPage();
+ }
+ }
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadLocalPage() {
+ var linkIds = Object.keys($scope.knownSiteLinks);
+
+ var tempData = linkIds.filter(function (linkId, ind, arr) {
+ var link = $scope.knownSiteLinks[linkId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case 'siteIdA':
+ return link.siteA.id.contains(filter.term);
+ case 'siteIdZ':
+ return link.siteZ.id.contains(filter.term);
+ default:
+ return link[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (linkId) {
+ var link = $scope.knownSiteLinks[linkId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: linkId
+ }
+ }
+
+ switch (sortColumn.field) {
+ case 'siteIdA':
+ orderBy = link.siteA.id;
+ break;
+ case 'siteIdZ':
+ orderBy = link.siteZ.id;
+ break;
+ default:
+ orderBy = link[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: linkId,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedSitesAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ linksAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedSitesAtCurrentPage.forEach(function (orderdLink) {
+ var link = $scope.knownSiteLinks[orderdLink.id];
+ linksAtCurrentPageCache[link.id] = link;
+ orderedData.push({
+ id: link.id,
+ name: link.name,
+ siteIdA: link.siteA.id,
+ siteIdZ: link.siteZ.id,
+ type: link.type
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ /**
+ * Loads the page content for the grid and sets the values to the gridOprions.data object.
+ */
+ function loadRemotePage() {
+ linksAtCurrentPageCache = {};
+
+ // the links for one page
+ $mwtnTopology.getLinks((sortColumn && sortColumn.field), sortColumn && ((sortColumn.sort.direction && sortColumn.sort.direction === uiGridConstants.ASC) ? 'asc' : 'desc'), gridFilters, paginationPageSize, (paginationPage - 1) * paginationPageSize).then(function (result) {
+ // get all site id s
+ var siteIds = {};
+ result.links.forEach(function (link) {
+ siteIds[link.siteA] = link.siteA;
+ siteIds[link.siteZ] = link.siteZ;
+ });
+
+ // load all sites
+ $mwtnTopology.getSitesByIds(Object.keys(siteIds)).then(function (sitesResult) {
+ var sites = sitesResult.sites.reduce(function (acc, cur, ind, arr) {
+ acc[cur.id] = cur;
+ return acc;
+ }, {});
+ result.links.forEach(function (link) {
+ linksAtCurrentPageCache[link.id] = {
+ id: link.id,
+ name: link.name,
+ siteA: sites[link.siteA],
+ siteZ: sites[link.siteZ],
+ type: link.type
+ };
+ });
+ vm.gridOptions.data = result.links.map(function (link) {
+ return {
+ id: link.id,
+ name: link.name,
+ siteIdA: link.siteA,
+ siteIdZ: link.siteZ,
+ type: link.type
+ }
+ });
+ vm.gridOptions.totalItems = result.total;
+
+ });
+ });
+ }
+
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologySiteLinkGrid', function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologySiteLinkGridController',
+ controllerAs: 'vm',
+ templateUrl: 'src/app/mwtnTopology/templates/siteLinkGrid.tpl.html',
+ scope: {
+ knownSiteLinks: "="
+ },
+ };
+ });
+
+ mwtnTopologyApp.controller('mwtnTopologySitePathGridController', ['$scope', function ($scope) {
+ var vm = this;
+
+ vm.showAllPaths = false;
+
+ $scope.$on("mapViewVisuability", function (event, data) {
+ vm.showAllPaths = !data;
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologySitePathGrid', function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologySitePathGridController',
+ controllerAs: 'vm',
+ templateUrl: 'src/app/mwtnTopology/templates/sitePathGrid.tpl.html'
+ };
+ });
+
+ /********************************************* Physical ***********************************/
+
+ mwtnTopologyApp.controller('mwtnTopologyPhysicalViewController', ['$scope', '$q', '$timeout', '$state', '$window', '$mwtnTopology', function ($scope, $q, $timeout, $state, $window, $mwtnTopology) {
+ var vm = this;
+ vm.status = {
+ graphIsOpen: false,
+ networkElementsIsOpen: false,
+ LinksIsOpen: false
+ };
+
+ $scope.$watchCollection(function () { return [vm.status.graphIsOpen, vm.status.networkElementsIsOpen, vm.status.LinksIsOpen] }, function (newVal, oldVal) {
+ if (newVal[1] || newVal[2]) {
+ $timeout(function () {
+ $window.dispatchEvent(new Event("resize"));
+ });
+ }
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyPhysicalView', function () {
+ return {
+ restrict: 'E',
+ controller: 'mwtnTopologyPhysicalViewController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/physicalView.tpl.html',
+ scope: {
+
+ }
+ };
+ });
+
+ /**
+ * Typedefinitions for the mwtnTopologyPhysicalPathData service.
+ * @typedef { { 'site' | 'device' | 'port' } } NodeLayerType
+ * @typedef { { x: number, y: number } } PositionType
+ * @typedef { { id: string, label: string, parent: string, grentparent: string, active: string, latitude: number, longitude: number } } NodeDataVo
+ * @typedef { { data: NodeDataVo, position: PositionType } } NodeVo
+ * @typedef { { id: string, label: string, parent: string, type: string, layer: NodeLayerType, active: boolean, latitude?: number, longitude?: number } } NodeData
+ * @typedef { { data: NodeData, position: PositionType } } Node
+ * @typedef { { id: string, source: string, target: string, label: string , lentgh: string, azimuthAZ: string , azimuthZA: string , layer: string , active: string } } EdgeData
+ * @typedef { { data: EdgeData } Edge
+ */
+ mwtnTopologyApp.factory("mwtnTopologyPhysicalPathData", ['$q','$mwtnTopology',
+ /** @param $q { ng.IQService } */
+ function ($q, $mwtnTopology) {
+ var colors = {
+ root: '#f54',
+ port: '#377',
+ device: '#252',
+ site: '#525',
+ edge: '#49a',
+ white: '#eed',
+ grey: '#555',
+ selected: '#ff0'
+ };
+
+ var styles = [
+ {
+ selector: 'node',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#666666',
+ 'border-color': '#000000',
+ 'border-width': '1px',
+ 'color': '#ffffff'
+ }
+ },
+ {
+ selector: 'node[layer = "MWPS"]',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#316ac5',
+ 'border-color': '#000000',
+ 'border-width': '1px',
+ 'color': '#ffffff'
+ }
+ },
+ {
+ selector: '$node > node',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'top',
+ 'text-halign': 'center',
+ 'background-color': '#eeeeee',
+ 'color': '#444444',
+ 'border-color': '#888888'
+ }
+ },
+ {
+ selector: 'node[type = "site"]',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#fefefe',
+ 'color': '#444444',
+ 'border-color': '#888888',
+ 'font-weight': 'bold'
+ }
+ },
+ {
+ selector: 'node[type = "device"][active = "true"]',
+ css: {
+ 'background-color': '#316ac5',
+ 'background-opacity': '0.3',
+ 'border-color': '#316ac5',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[type = "port"][active = "true"]',
+ css: {
+ 'background-opacity': '1.0',
+ }
+ },
+ {
+ selector: 'node[active = "false"]',
+ css: {
+ 'background-opacity': '0.3',
+ 'border-opacity': '0.5'
+ }
+ },
+
+ {
+ selector: 'edge',
+ css: {
+ 'content': 'data(id)',
+ 'target-arrow-shape': 'triangle',
+ 'line-color': '#666666',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'edge[active = "false"]',
+ css: {
+ 'line-color': '#cccccc',
+ 'text-opacity': '0.9'
+ }
+ },
+ {
+ selector: 'edge[layer = "MWPS"]',
+ css: {
+ 'content': 'data(id)',
+ 'target-arrow-shape': 'triangle',
+ 'width': '5px',
+ 'line-color': '#316ac5',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'edge[layer = "MWPS"][active = "false"]',
+ css: {
+ 'line-color': '#C0D1EC',
+ 'text-opacity': '0.9'
+ }
+ },
+ {
+ selector: ':selected',
+ css: {
+ 'background-color': 'black',
+ 'line-color': 'black',
+ 'target-arrow-color': 'black',
+ 'source-arrow-color': 'black'
+ }
+ }
+ ];
+
+ var events = eventsFabric();
+
+ /** Heplerfunction to retrive all elements from the database and convert to the structure needed */
+ function getElements() {
+ var res = $q.defer();
+
+ $q.all([
+ $mwtnTopology.getAllNodes(),
+ $mwtnTopology.getAllEdges()
+ ]).then(function (results) {
+ res.resolve({ nodes: results[0], edges: results[1] });
+ });
+
+ return res.promise;
+ }
+
+ var result = {
+ colors: colors,
+ getElements: getElements,
+ styles: styles,
+ events: events
+ };
+
+ var someMethodChangingTheElements = function () {
+ // @Martin: hier kannst Du die Elements ändern, anschließend mußt Du das Ereignis veröffentlichen
+ // das Ereigniss wird in der Directive aufgefangen und die Grig wird neu gezeichnet
+
+ // Hinweis: Die Reihenfolge muss so bleiben und du kannst NUR result.elements ändern.
+
+ events.publish("elementsChanged", {
+ elements: result.elements
+ });
+ };
+
+ return result;
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyPhysicalPathGraph", ["mwtnTopologyPhysicalPathData", "$mwtnTopology", "$mwtnCommons", function (pathGraphData, $mwtnTopology, $mwtnCommons) {
+
+ return {
+ restrict: 'E',
+ replace: true,
+ template: '<div style="height:750px; width: 100%;"></div>',
+ controller: function () {
+
+ },
+ scope: {
+
+ },
+ link: function (scope, element, attrs, ctrl) {
+
+ var cy = cytoscape({
+ container: element[0],
+
+ boxSelectionEnabled: false,
+ autounselectify: true,
+
+ style: pathGraphData.styles,
+ elements: [],
+ layout: {
+ name: 'preset',
+ padding: 5
+ }
+ });
+
+ cy.viewport({
+ zoom: 0.50,
+ pan: { x: 100, y: 50 }
+ });
+
+ pathGraphData.getElements().then(function (elements) {
+ cy.json({
+ elements: elements
+ });
+
+ // disable drag & drop
+ cy.nodes().ungrabify();
+ });
+
+ var filterActiveMountPoints = function (mountpoints) {
+ return mountpoints.filter(function (mountpoint) {
+ if (!mountpoint) return false;
+ // console.warn(mountpoint['node-id'], mountpoint['netconf-node-topology:connection-status']);
+ return mountpoint['netconf-node-topology:connection-status'] === 'connected';
+ }).map(function (mountpoint) {
+ return mountpoint['node-id'];
+ });
+ };
+
+ var setDevicesActive = function (nodeIds) {
+ // console.warn(nodeIds);
+ cy.nodes().filter(function (node) {
+ node.data('active', 'false');
+ return node.data('type') === 'device' && nodeIds.contains(node.data('id'));
+ }).map(function (node) {
+ node.data('active', 'true');
+ });
+ };
+
+ var setAllDevicesInactive = function () {
+ cy.nodes().map(function (node) {
+ node.data('active', 'false');
+ });
+ };
+
+ var setPortAndEdgedActive = function () {
+ cy.edges().map(function (edge) {
+ var active = 'true';
+ edge.connectedNodes().map(function (port) {
+ // console.log(' node', JSON.stringify(edge.data()));
+ var parent = cy.getElementById(port.data('parent'));
+ if (parent.data('active') === 'false') {
+ port.data('active', 'false');
+ edge.data('active', 'false');
+ } else {
+ port.data('active', 'true');
+ }
+ });
+ });
+ };
+
+ var setCss = function () {
+ var width = 5 / cy.zoom();
+ var stroke = 1 / cy.zoom();
+ cy.edges().css('width', width);
+ cy.nodes().css('border-width', stroke);
+ };
+
+ var init = function () {
+ $mwtnCommons.getMountPoints().then(function (mountpoints) {
+ var filtered = filterActiveMountPoints(mountpoints);
+ setDevicesActive(filtered);
+ setPortAndEdgedActive();
+ }, function (error) {
+ setAllDevicesInactive();
+ setPortAndEdgedActive();
+ });
+ };
+
+ init();
+ setCss();
+
+ var orderLtps = function () {
+ var done = [];
+ var x = 0;
+ var y = 0;
+ var row = 0;
+ var offset = 100;
+ var selector = "[type = 'device']";
+ var devices = cy.nodes(selector).sort(function (a, b) {
+ if (a.children().length > b.children().length) return -1;
+ if (a.children().length < b.children().length) return 1;
+ return 0;
+ }).map(function (device) {
+ device.children().filter(function (ltp) {
+ return done.indexOf(ltp.id()) === -1;
+ }).map(function (ltp) {
+ ltp.position({ x: x, y: y });
+ y = y + offset;
+ var remeberX = x;
+ ltp.connectedEdges().map(function (edge) {
+ edge.connectedNodes().sort(function (a, b) {
+ if (a.data("parent") === device.id()) return -1;
+ return 1;
+ }).map(function (node) {
+ // x = remeberX + 0 * offset;
+ node.position({ x: x, y: y });
+ x = x + 3 * offset;
+ y = y + offset;
+ done.push(node.id());
+ });
+ y = y - 2 * offset;
+
+ });
+ x = remeberX;
+ done.push(ltp.id());
+ });
+ y = row * 6 * offset;
+ x = x + 6 * offset;
+
+ if (x > 4000) {
+ row = row + 1;
+ x = 0;
+ y = row * 6 * offset;
+ }
+ return device;
+ });
+ };
+
+ var dragedNodes = [];
+ // add an event handler for 'tabdrag' for all ports
+ cy.on('drag', 'node[type = "port"]', function (event) {
+ var id = event.target.data().id;
+ dragedNodes.indexOf(id) <= -1 && dragedNodes.push(id);
+ });
+
+ cy.on('tap', function (event) {
+ if (event.target !== cy) {
+ console.info('click', JSON.stringify(event.target.data()));
+ } else {
+ orderLtps();
+ // cy.zoom(0.1);
+ cy.fit();
+ cy.center();
+ }
+ });
+
+ cy.on('zoom', function (event) {
+ setCss();
+ });
+
+ // global keyboard event handler
+ function handleKey(e) {
+ if (!e.ctrlKey && !e.commandKey) return;
+ switch (e.which) {
+ case 69:
+ dragedNodes = [];
+ cy.nodes().grabify();
+ e.preventDefault();
+ return false;
+ break;
+ case 83:
+ cy.nodes().ungrabify();
+ e.preventDefault();
+ var modifiedNodes = dragedNodes.map(id => ({ id: id, position: cy.nodes().getElementById(id).position() }));
+ $mwtnTopology.saveChangedNodes(modifiedNodes);
+ console.log("dragedNodes", modifiedNodes);
+ return false;
+ break;
+ // default:
+ // console.log(e.which);
+ // e.preventDefault();
+ // return false;
+ // break;
+ }
+ }
+
+ // register global keyboard event handler
+ window.addEventListener('keydown', handleKey, false);
+
+ scope.$on('$destroy', function () {
+ // un-register global keyboard event handler
+ window.removeEventListener('keydown', handleKey, false);
+ });
+
+ }
+ }
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyNetworkElementsGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyPhysicalPathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyPhysicalPathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "layer",
+ type: "string",
+ displayName: "Layer",
+ width: 100,
+ },
+ {
+ field: "active",
+ type: "string",
+ displayName: "Active",
+ width: 100,
+ },
+ {
+ field: "latitude",
+ type: "string",
+ displayName: "Latitude",
+ visible: false
+ },
+ {
+ field: "longitude",
+ type: "string",
+ displayName: "Longitude",
+ visible: false
+ },
+ {
+ field: "installed", // capacity in Mbit/s
+ type: "number",
+ displayName: "Installed [Mbit/s]",
+ className: "number",
+ width: 150
+ },
+ {
+ field: "configured", // capacity in Mbit/s
+ type: "number",
+ displayName: "Configured [Mbit/s]",
+ className: "number",
+ width: 150
+ },
+ {
+ field: "effective", // capacity in Mbit/s
+ type: "number",
+ displayName: "Effective [Mbit/s]",
+ className: "number",
+ width: 150
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+
+ // extract all ports
+ var ports = mwtnTopologyPhysicalPathData.elements.nodes.filter(function (node, ind, arr) {
+ return node && node.data && node.data.type === 'port';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) acc[cur.data.id] = cur.data;
+ return acc;
+ }, {});
+
+ // get all port ids
+ var portIds = Object.keys(ports);
+
+ // apply the grid filters
+ var tempData = portIds.filter(function (portId, ind, arr) {
+ var port = ports[portId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case "active":
+ return port[filter.field].toString().contains(filter.term);
+ default:
+ return port[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (portId) {
+ var port = ports[portId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: port.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ case "active":
+ orderBy = port[sortColumn.field] ? 1 : 0;
+ break;
+ default:
+ orderBy = port[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: port.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedPortsAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ portsAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedPortsAtCurrentPage.forEach(function (orderedPort) {
+ var port = ports[orderedPort.id];
+ portsAtCurrentPageCache[port.id] = port;
+ orderedData.push({
+ id: orderedPort.id,
+ layer: port.layer,
+ active: port.active,
+ latitude: port.latitude.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ longitude: port.longitude.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ installed: 0,
+ configured: 0,
+ effective: 0
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ mwtnTopologyPhysicalPathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyNetworkElementsGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyNetworkElementsGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/networkElementsGrid.tpl.html'
+ };
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyLinksGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyPhysicalPathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyPhysicalPathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "source",
+ type: "string",
+ displayName: "PortA"
+ },
+ {
+ field: "target",
+ type: "string",
+ displayName: "PortZ"
+ },
+ {
+ field: "layer",
+ type: "string",
+ displayName: "Layer"
+ },
+ {
+ field: "length",
+ type: "string",
+ displayName: "Length"
+ },
+ {
+ field: "azimuthAZ",
+ type: "string",
+ displayName: "azimuthAZ"
+ },
+ {
+ field: "azimuthZA",
+ type: "string",
+ displayName: "azimuthZA"
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+ // extract all ports
+ var ports = mwtnTopologyPhysicalPathData.elements.nodes.filter(function (node, ind, arr) {
+ return node && node.data && node.data.type === 'port';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) acc[cur.data.id] = cur.data;
+ return acc;
+ }, {});
+
+ // extract all links
+ var links = mwtnTopologyPhysicalPathData.elements.edges.filter(function (node, ind, arr) {
+ return true; // node && node.data && node.data.type === 'port';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) {
+
+ if (cur.data.layer === 'MWPS') {
+ var portA = ports[cur.data.source];
+ var portZ = ports[cur.data.target];
+
+ // calculate length
+ cur.data.length = (portA && portZ) ? $mwtnTopology.getDistance(portA.latitude, portA.longitude, portZ.latitude, portZ.longitude) : 0;
+ cur.data.azimuthAZ = (portA && portZ) ? $mwtnTopology.bearing(portA.latitude, portA.longitude, portZ.latitude, portZ.longitude) : 0;
+ cur.data.azimuthZA = (portA && portZ) ? $mwtnTopology.bearing(portZ.latitude, portZ.longitude, portA.latitude, portA.longitude) : 0;
+
+ } else {
+ cur.data.length = 0;
+ cur.data.azimuthAZ = 0;
+ cur.data.azimuthZA = 0;
+ }
+ acc[cur.data.id] = cur.data;
+ }
+ return acc;
+ }, {});
+
+ // get all link ids
+ var linkIds = Object.keys(links);
+
+ // apply the grid filters
+ var tempData = linkIds.filter(function (linkId, ind, arr) {
+ var link = links[linkId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case "length":
+ case "azimuthAZ":
+ case "azimuthZA":
+ return true;
+ default:
+ return link[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (linkId) {
+ var link = links[linkId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: link.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ default:
+ orderBy = link[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: link.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedLinksAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ linksAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedLinksAtCurrentPage.forEach(function (orderedLink) {
+ var link = links[orderedLink.id];
+ linksAtCurrentPageCache[link.id] = link;
+ orderedData.push({
+ id: orderedLink.id,
+ source: link.source,
+ target: link.target,
+ layer: link.layer,
+ length: link.length,
+ azimuthAZ: link.azimuthAZ.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ azimuthZA: link.azimuthZA.toLocaleString("en-US", {
+ minimumFractionDigits: 4
+ }),
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ var subscription = mwtnTopologyPhysicalPathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ // to unsubscribe call subscription.remove();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyLinksGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyLinksGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/linksGrid.tpl.html'
+ };
+ }]);
+
+ /********************************************* Ethernet ***********************************/
+
+ mwtnTopologyApp.controller('mwtnTopologyEthernetViewController', ['$scope', '$q', '$timeout', '$state', '$window', '$mwtnTopology', function ($scope, $q, $timeout, $state, $window, $mwtnTopology) {
+ var vm = this;
+ vm.status = {
+ topologyIsOpen: false,
+ portsOpen: false,
+ ethConnectionsIsOpen: false
+ }
+
+ $scope.$watchCollection(function () { return [vm.status.topologyIsOpen, vm.status.portsOpen, vm.status.ethConnectionsIsOpen] }, function (newVal, oldVal) {
+ if (newVal[1] || newVal[2]) {
+ $timeout(function () {
+ $window.dispatchEvent(new Event("resize"));
+ });
+ }
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyEthernetView', function () {
+ return {
+ restrict: 'E',
+ controller: 'mwtnTopologyEthernetViewController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/ethernetView.tpl.html',
+ scope: {
+
+ }
+ };
+ });
+
+ mwtnTopologyApp.factory("mwtnTopologyEthernetPathData", function () {
+ var colors = {
+ root: '#f54',
+ port: '#377',
+ device: '#252',
+ site: '#525',
+ edge: '#49a',
+ white: '#eed',
+ grey: '#555',
+ selected: '#ff0'
+ };
+
+ var styles = [
+ {
+ selector: 'node',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#eeeeee',
+ 'border-color': '#000000',
+ 'border-width': '1px',
+ 'color': '#000000'
+ }
+ },
+ {
+ selector: 'node[type = "label"]',
+ css: {
+ 'content': 'data(label)',
+ 'border-width': '0px',
+ 'background-color': '#ffffff',
+ 'font-size': '50px',
+ 'text-valign': 'bottom',
+ 'text-halign': 'right',
+
+ }
+ },
+
+ {
+ selector: 'node[layer = "MWPS"]',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#316ac5',
+ 'border-color': '#000000',
+ 'border-width': '1px',
+ 'color': '#ffffff'
+ }
+ },
+ {
+ selector: 'node[layer = "ETH-TTP"]',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#008800',
+ 'border-color': '#004400',
+ 'border-width': '1px',
+ 'color': '#ffffff'
+ }
+ },
+ {
+ selector: '$node > node',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'top',
+ 'text-halign': 'center',
+ 'background-color': '#eeeeee',
+ 'color': '#444444',
+ 'border-color': '#888888'
+ }
+ },
+ {
+ selector: 'node[type = "site"]',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#fefefe',
+ 'color': '#444444',
+ 'border-color': '#888888',
+ 'font-weight': 'bold'
+ }
+ },
+ {
+ selector: 'node[type = "device"]',
+ css: {
+ 'background-color': '#eeeeee',
+ 'background-opacity': '0.1',
+ 'border-color': '#888888',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[type = "device"][active = "true"]',
+ css: {
+ 'background-color': '#316ac5',
+ 'background-opacity': '0.1',
+ 'border-color': '#316ac5',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[type = "port"][active = "true"]',
+ css: {
+ 'background-opacity': '1.0',
+ }
+ },
+ {
+ selector: 'node[path = "working"]',
+ css: {
+ 'background-color': '#FFA500',
+ 'border-color': '#FFA500',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[path = "protection"]',
+ css: {
+ 'background-color': '#ffffff',
+ 'border-color': '#FFA500',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: '$node > node[path = "working"]',
+ css: {
+ 'background-color': '#FFA500',
+ 'border-color': '#FFA500',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: '$node > node[path = "protection"]',
+ css: {
+ 'border-color': '#FFA500',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[active = "false"]',
+ css: {
+ 'background-opacity': '0.3',
+ 'border-opacity': '0.5'
+ }
+ },
+ {
+ selector: 'edge',
+ css: {
+ 'content': 'data(id)',
+ 'target-arrow-shape': 'triangle',
+ 'line-color': '#666666',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'edge[active = "false"]',
+ css: {
+ 'line-color': '#cccccc',
+ 'text-opacity': '0.9'
+ }
+ },
+ {
+ selector: 'edge[layer = "ETC"]',
+ css: {
+ 'content': 'data(id)',
+ 'target-arrow-shape': 'triangle',
+ 'width': '3px',
+ 'line-color': '#316ac5',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'edge[layer = "ETH"]',
+ css: {
+ 'content': '',
+ 'target-arrow-shape': 'triangle',
+ 'width': '2px',
+ 'line-color': '#FFA500',
+ 'color': '#000000'
+ }
+ }, {
+ selector: 'edge[layer = "ETC"][active = "false"]',
+ css: {
+ 'line-color': '#C0D1EC',
+ 'text-opacity': '0.9'
+ }
+ },
+
+ {
+ selector: 'edge[layer = "ETH"][path = "false"]',
+ css: {
+ 'opacity': '0.0'
+ }
+ },
+ {
+ selector: 'edge[path = "working"]',
+ css: {
+ 'line-color': '#FFA500',
+ 'width': '5px',
+ 'opacity': '1.0'
+ }
+ },
+ {
+ selector: 'edge[path = "protection"]',
+ css: {
+ 'line-color': '#FFA500',
+ 'line-style': 'dashed',
+ 'width': '3px',
+ 'opacity': '1.0'
+ }
+ },
+ {
+ selector: ':selected',
+ css: {
+ 'background-color': 'black',
+ 'line-color': 'black',
+ 'target-arrow-color': 'black',
+ 'source-arrow-color': 'black'
+ }
+ }
+ ];
+
+ var elements = {
+ nodes: [
+ { data: { id: 'label', label : '' , type: 'label' }, position: { x: -259, y: -167 } },
+
+ { data: { id: 'north', label : 'north' , type: 'site', latitude: 50.734916, longitude: 7.137636 } },
+ { data: { id: 'north-east', label : 'north-east' , type: 'site', latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'north-west', label : 'north-west' , type: 'site', latitude: 50.730230, longitude: 7.126017 } },
+ { data: { id: 'east', label : 'east' , type: 'site', latitude: 50.725672, longitude: 7.158488 } },
+ { data: { id: 'west', label : 'west' , type: 'site', latitude: 50.721914, longitude: 7.120521 } },
+ { data: { id: 'south-east', label : 'south-east' , type: 'site', latitude: 50.717158, longitude: 7.155506 } },
+ { data: { id: 'south-west', label : 'south-west' , type: 'site', latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'south', label : 'south' , type: 'site', latitude: 50.712472, longitude: 7.143887 } },
+
+ { data: { id: 'ADVA-Y', label : 'ADVA-Y' , parent : 'north-east', type: 'device', active: 'true' , latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'ADVA-Z', label : 'ADVA-Z' , parent : 'south', type: 'device', active: 'true' , latitude: 50.712472, longitude: 7.143887 } },
+ { data: { id: 'Aviat-A', label : 'Aviat-A' , parent : 'north-east', type: 'device', active: 'true' , latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'Aviat-Z', label : 'Aviat-Z' , parent : 'east', type: 'device', active: 'true' , latitude: 50.725672, longitude: 7.158488 } },
+ { data: { id: 'Ceragon-A', label : 'Ceragon-A' , parent : 'north-west', type: 'device', active: 'true' , latitude: 50.730230, longitude: 7.126017 } },
+ { data: { id: 'Ceragon-Z', label : 'Ceragon-Z' , parent : 'west', type: 'device', active: 'true' , latitude: 50.721914, longitude: 7.120521 } },
+ { data: { id: 'DragonWave-A', label : 'DragonWave-A' , parent : 'south-west', type: 'device', active: 'true' , latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'DragonWave-Z', label : 'DragonWave-Z' , parent : 'south', type: 'device', active: 'true' , latitude: 50.712472, longitude: 7.143887 } },
+ { data: { id: 'ELVA-1-A', label : 'ELVA-1-A' , parent : 'north', type: 'device', active: 'true' , latitude: 50.734916, longitude: 7.137636 } },
+ { data: { id: 'ELVA-1-Z', label : 'ELVA-1-Z' , parent : 'south-west', type: 'device', active: 'true' , latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'Ericsson-A', label : 'Ericsson-A' , parent : 'north-east', type: 'device', active: 'true' , latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'Ericsson-Z', label : 'Ericsson-Z' , parent : 'east', type: 'device', active: 'true' , latitude: 50.725672, longitude: 7.158488 } },
+ { data: { id: 'Fujitsu-A', label : 'Fujitsu-A' , parent : 'east', type: 'device', active: 'true' , latitude: 50.725672, longitude: 7.158488 } },
+ { data: { id: 'Fujitsu-Z', label : 'Fujitsu-Z' , parent : 'south-east', type: 'device', active: 'true' , latitude: 50.717158, longitude: 7.155506 } },
+ { data: { id: 'Huawei-A', label : 'Huawei-A' , parent : 'south-west', type: 'device', active: 'true' , latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'Huawei-Z', label : 'Huawei-Z' , parent : 'south', type: 'device', active: 'true' , latitude: 50.712472, longitude: 7.143887 } },
+ { data: { id: 'Intracom-A', label : 'Intracom-A' , parent : 'south', type: 'device', active: 'true' , latitude: 50.712472, longitude: 7.143887 } },
+ { data: { id: 'Intracom-Z', label : 'Intracom-Z' , parent : 'south-east', type: 'device', active: 'true' , latitude: 50.717158, longitude: 7.155506 } },
+ { data: { id: 'NEC-A', label : 'NEC-A' , parent : 'north', type: 'device', active: 'true' , latitude: 50.734916, longitude: 7.137636 } },
+ { data: { id: 'NEC-Z', label : 'NEC-Z' , parent : 'north-east', type: 'device', active: 'true' , latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'Nokia-A', label : 'Nokia-A' , parent : 'west', type: 'device', active: 'fasel' , latitude: 50.721914, longitude: 7.120521 } },
+ { data: { id: 'Nokia-Z', label : 'Nokia-Z' , parent : 'south-west', type: 'device', active: 'true' , latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'SIAE-A', label : 'SIAE-A' , parent : 'south', type: 'device', active: 'true' , latitude: 50.712472, longitude: 7.143887 } },
+ { data: { id: 'SIAE-Z', label : 'SIAE-Z' , parent : 'south-east', type: 'device', active: 'true' , latitude: 50.717158, longitude: 7.155506 } },
+ { data: { id: 'ZTE-A', label : 'ZTE-A' , parent : 'north-west', type: 'device', active: 'true' , latitude: 50.730230, longitude: 7.126017 } },
+ { data: { id: 'ZTE-Z', label : 'ZTE-Z' , parent : 'north', type: 'device', active: 'true' , latitude: 50.734916, longitude: 7.137636 } },
+
+ { data: { id: 'Aviat-Z#5', label : '#5' , parent : 'Aviat-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1984, y: 390 } },
+ { data: { id: 'Aviat-Z#6', label : '#6' , parent : 'Aviat-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1984, y: 321 } },
+ { data: { id: 'Ericsson-Z#5', label : '#5' , parent : 'Ericsson-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1777, y: 393 } },
+ { data: { id: 'Ericsson-Z#6', label : '#6' , parent : 'Ericsson-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1765, y: 325 } },
+ { data: { id: 'Fujitsu-A#5', label : '#5' , parent : 'Fujitsu-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1859, y: 567 } },
+ { data: { id: 'Fujitsu-A#6', label : '#6' , parent : 'Fujitsu-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1859, y: 647 } },
+ { data: { id: 'ELVA-1-A#2', label : '#2' , parent : 'ELVA-1-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 895, y: 150 } },
+ { data: { id: 'ELVA-1-A#6', label : '#6' , parent : 'ELVA-1-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 815, y: 150 } },
+ { data: { id: 'NEC-A#3', label : '#3' , parent : 'NEC-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 955, y: -52 } },
+ { data: { id: 'NEC-A#6', label : '#6' , parent : 'NEC-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 1035, y: -52 } },
+ { data: { id: 'ZTE-Z#4', label : '#4' , parent : 'ZTE-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 707, y: -67 } },
+ { data: { id: 'ZTE-Z#5', label : '#5' , parent : 'ZTE-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 747, y: -27 } },
+ { data: { id: 'ZTE-Z#6', label : '#6' , parent : 'ZTE-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.734916, longitude: 7.137636 }, position: { x: 667, y: -27 } },
+ // { data: { id: 'ADVA-Y#1', label : '#1' , parent : 'ADVA-Y' , type:'port', layer:'ETY', active:'true', latitude:50.733028, longitude:7.151086}, position: { x: 1392, y: 229 } },
+ { data: { id: 'ADVA-Y#2', label : '#2' , parent : 'ADVA-Y' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: 172 } },
+ { data: { id: 'ADVA-Y#3', label : '#3' , parent : 'ADVA-Y' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1392, y: 172 } },
+ { data: { id: 'ADVA-Y#4', label : '#4' , parent : 'ADVA-Y' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: 229 } },
+ { data: { id: 'Aviat-A#5', label : '#5' , parent : 'Aviat-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1654, y: -47 } },
+ { data: { id: 'Aviat-A#6', label : '#6' , parent : 'Aviat-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1654, y: 22 } },
+ { data: { id: 'Ericsson-A#4', label : '#4' , parent : 'Ericsson-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1605, y: 229 } },
+ { data: { id: 'Ericsson-A#5', label : '#5' , parent : 'Ericsson-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1605, y: 172 } },
+ { data: { id: 'Ericsson-A#6', label : '#6' , parent : 'Ericsson-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1664, y: 226 } },
+ // { data: { id: 'NEC-Z#3', label : '#3' , parent : 'NEC-Z' , type:'port', layer:'ETY', active:'true', latitude:50.733028, longitude:7.151086}, position: { x: 1392, y: 16 } },
+ { data: { id: 'NEC-Z#4', label : '#4' , parent : 'NEC-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: 16 } },
+ { data: { id: 'NEC-Z#2', label : '#2' , parent : 'NEC-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: -41 } },
+ { data: { id: 'NEC-Z#6', label : '#6' , parent : 'NEC-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1382, y: -23 } },
+ { data: { id: 'Ceragon-A#5', label : '#5' , parent : 'Ceragon-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.730230, longitude: 7.126017 }, position: { x: 195, y: 312 } },
+ { data: { id: 'Ceragon-A#6', label : '#6' , parent : 'Ceragon-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.730230, longitude: 7.126017 }, position: { x: 136, y: 366 } },
+ { data: { id: 'ZTE-A#5', label : '#5' , parent : 'ZTE-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.730230, longitude: 7.126017 }, position: { x: 345, y: 108 } },
+ { data: { id: 'ZTE-A#6', label : '#6' , parent : 'ZTE-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.730230, longitude: 7.126017 }, position: { x: 408, y: 99 } },
+ { data: { id: 'ADVA-Z#1', label : '#1' , parent : 'ADVA-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1139, y: 1001 } },
+ // { data: { id: 'ADVA-Z#2', label : '#2' , parent : 'ADVA-Z' , type:'port', layer:'ETY', active:'true', latitude:50.712472, longitude:7.143887}, position: { x: 1196, y: 944 } },
+ // { data: { id: 'ADVA-Z#3', label : '#3' , parent : 'ADVA-Z' , type:'port', layer:'ETY', active:'true', latitude:50.712472, longitude:7.143887}, position: { x: 1139, y: 944 } },
+ { data: { id: 'ADVA-Z#4', label : '#4' , parent : 'ADVA-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1196, y: 1001 } },
+ { data: { id: 'DragonWave-Z#2', label : '#2' , parent : 'DragonWave-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1133, y: 1252 } },
+ { data: { id: 'DragonWave-Z#6', label : '#6' , parent : 'DragonWave-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1053, y: 1252 } },
+ { data: { id: 'Huawei-Z#3', label : '#3' , parent : 'Huawei-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1046, y: 1094 } },
+ // { data: { id: 'Huawei-Z#4', label : '#4' , parent : 'Huawei-Z' , type:'port', layer:'ETY', active:'true', latitude:50.712472, longitude:7.143887}, position: { x: 989, y: 1094 } },
+ { data: { id: 'Huawei-Z#5', label : '#5' , parent : 'Huawei-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1058, y: 1123 } },
+ { data: { id: 'Huawei-Z#6', label : '#6' , parent : 'Huawei-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 978, y: 1123 } },
+ { data: { id: 'Intracom-A#2', label : '#2' , parent : 'Intracom-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1203, y: 1252 } },
+ { data: { id: 'Intracom-A#6', label : '#6' , parent : 'Intracom-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1283, y: 1252 } },
+ { data: { id: 'SIAE-A#4', label : '#4' , parent : 'SIAE-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1289, y: 1094 } },
+ { data: { id: 'SIAE-A#5', label : '#5' , parent : 'SIAE-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1278, y: 1123 } },
+ { data: { id: 'SIAE-A#6', label : '#6' , parent : 'SIAE-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1346, y: 1094 } },
+ { data: { id: 'Fujitsu-Z#5', label : '#5' , parent : 'Fujitsu-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1855, y: 821 } },
+ { data: { id: 'Fujitsu-Z#6', label : '#6' , parent : 'Fujitsu-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1855, y: 741 } },
+ { data: { id: 'Intracom-Z#5', label : '#5' , parent : 'Intracom-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1755, y: 998 } },
+ { data: { id: 'Intracom-Z#6', label : '#6' , parent : 'Intracom-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1714, y: 1018 } },
+ { data: { id: 'SIAE-Z#4', label : '#4' , parent : 'SIAE-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1590, y: 784 } },
+ { data: { id: 'SIAE-Z#5', label : '#5' , parent : 'SIAE-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1647, y: 784 } },
+ { data: { id: 'SIAE-Z#6', label : '#6' , parent : 'SIAE-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1588, y: 838 } },
+ { data: { id: 'DragonWave-A#2', label : '#2' , parent : 'DragonWave-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 455, y: 1178 } },
+ { data: { id: 'DragonWave-A#6', label : '#6' , parent : 'DragonWave-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 535, y: 1178 } },
+ { data: { id: 'ELVA-1-Z#2', label : '#2' , parent : 'ELVA-1-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 455, y: 878 } },
+ { data: { id: 'ELVA-1-Z#6', label : '#6' , parent : 'ELVA-1-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 535, y: 878 } },
+ { data: { id: 'Huawei-A#5', label : '#5' , parent : 'Huawei-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 605, y: 1028 } },
+ { data: { id: 'Huawei-A#6', label : '#6' , parent : 'Huawei-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 685, y: 1028 } },
+ { data: { id: 'Nokia-Z33', label : '33' , parent : 'Nokia-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 385, y: 1028 } },
+ { data: { id: 'Nokia-Z#6', label : '#6' , parent : 'Nokia-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.714359, longitude: 7.130437 }, position: { x: 305, y: 1028 } },
+ { data: { id: 'Ceragon-Z#4', label : '#4' , parent : 'Ceragon-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.721914, longitude: 7.120521 }, position: { x: -159, y: 547 } },
+ { data: { id: 'Ceragon-Z#5', label : '#5' , parent : 'Ceragon-Z' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.721914, longitude: 7.120521 }, position: { x: -159, y: 604 } },
+ { data: { id: 'Ceragon-Z#6', label : '#6' , parent : 'Ceragon-Z' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.721914, longitude: 7.120521 }, position: { x: -130, y: 536 } },
+ // { data: { id: 'Nokia-A13', label : '13' , parent : 'Nokia-A' , type:'port', layer:'ETY', active:'true', latitude:50.721914, longitude:7.120521}, position: { x: 40, y: 801 } },
+ // { data: { id: 'Nokia-A34', label : '34' , parent : 'Nokia-A' , type:'port', layer:'ETY', active:'true', latitude:50.721914, longitude:7.120521}, position: { x: 28, y: 772 } },
+ { data: { id: 'Nokia-A11', label : '11' , parent : 'Nokia-A' , type: 'port', layer: 'ETY', active: 'true', latitude: 50.721914, longitude: 7.120521 }, position: { x: -29, y: 772 } },
+ { data: { id: 'Nokia-A#6', label : '#6' , parent : 'Nokia-A' , type: 'port', layer: 'ETC', active: 'true', latitude: 50.721914, longitude: 7.120521 }, position: { x: 28, y: 829 } },
+
+ { data: { id: 'Spirent#1', label : '#1' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service13' }, position: { x: 707, y: -167 } },
+ { data: { id: 'Spirent#2', label : '#2' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service24' }, position: { x: -259, y: 547 } },
+ { data: { id: 'Spirent#3', label : '#3' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service13' }, position: { x: 1292, y: 172 } },
+ { data: { id: 'Spirent#4', label : '#4' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service24' }, position: { x: 1490, y: 784 } },
+ { data: { id: 'Spirent#5', label : '#5' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service56' }, position: { x: 1754, y: -47 } },
+ { data: { id: 'Spirent#6', label : '#6' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service56' }, position: { x: 455, y: 1278 } },
+ { data: { id: 'Spirent#7', label : '#7' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service78' }, position: { x: 895, y: 250 } },
+ { data: { id: 'Spirent#8', label : '#8' , parent : 'Spirent' , type: 'host', layer: 'ETH-TTP', active: 'true', service: 'service78' }, position: { x: 455, y: 778 } },
+
+ ],
+ edges: [
+
+ { data: { id: '21', source: 'Aviat-A#6', target: 'Aviat-Z#6', label: '21', layer: 'ETC' , active: 'true' } },
+ { data: { id: '31', source: 'Ceragon-A#6', target: 'Ceragon-Z#6', label: '31', layer: 'ETC' , active: 'true' } },
+ { data: { id: '41', source: 'DragonWave-A#6', target: 'DragonWave-Z#6', label: '41', layer: 'ETC' , active: 'true' } },
+ { data: { id: '121', source: 'ELVA-1-A#6', target: 'ELVA-1-Z#6', label: '121' , layer: 'ETC' , active: 'true' } },
+ { data: { id: 'ERI1', source: 'Ericsson-A#6', target: 'Ericsson-Z#6', label: 'ERI1', layer: 'ETC' , active: 'true' } },
+ { data: { id: '61', source: 'Fujitsu-A#6', target: 'Fujitsu-Z#6', label: '61', layer: 'ETC' , active: 'true' } },
+ { data: { id: '71', source: 'Huawei-A#6', target: 'Huawei-Z#6', label: '71', layer: 'ETC' , active: 'true' } },
+ { data: { id: '131', source: 'Intracom-A#6', target: 'Intracom-Z#6', label: '131', layer: 'ETC' , active: 'true' } },
+ { data: { id: '81', source: 'NEC-A#6', target: 'NEC-Z#6', label: '81', layer: 'ETC' , active: 'true' } },
+ { data: { id: '91', source: 'Nokia-A#6', target: 'Nokia-Z#6', label: '91', layer: 'ETC' , active: 'true' } },
+ { data: { id: '101', source: 'SIAE-A#6', target: 'SIAE-Z#6', label: '101', layer: 'ETC' , active: 'true' } },
+ { data: { id: '111', source: 'ZTE-A#6', target: 'ZTE-Z#6', label: '111', layer: 'ETC' , active: 'true' } },
+
+ // { data: { id: 'ETY01', source: 'ADVA-A#1', target: 'Nokia-A34', label: 'ADVA-A#1-Nokia-A34' , layer: 'ETY' , active: 'true' } },
+ // { data: { id: 'ETY02', source: 'ADVA-A#2', target: 'ZTE-A#4', label: 'ADVA-A#2-ZTE-A#4' , layer: 'ETY' , active: 'false' } },
+ // { data: { id: 'ETY03', source: 'ADVA-B#1', target: 'Nokia-A13', label: 'ADVA-B#1-Nokia-A13' , layer: 'ETY' , active: 'true' } },
+ // { data: { id: 'ETY04', source: 'ADVA-B#2', target: 'ZTE-A#3', label: 'ADVA-B#2-ZTE-A#3' , layer: 'ETY' , active: 'true' } },
+ // { data: { id: 'ETY05', source: 'ADVA-Y#1', target: 'Huawei-Z#4', label: 'ADVA-Y#1-Huawei-Z#4' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY06', source: 'ADVA-Y#2', target: 'NEC-Z#4', label: 'ADVA-Y#2-NEC-Z#4' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY07', source: 'ADVA-Y#3', target: 'Spirent#3', label: 'ADVA-Y#3-Spirent#3' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY08', source: 'ADVA-Y#4', target: 'Ericsson-A#4', label: 'ADVA-Y#4-Ericsson-A#4' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY09', source: 'ADVA-Z#1', target: 'Huawei-Z#3', label: 'ADVA-Z#1-Huawei-Z#3' , layer: 'ETY' , active: 'true' } },
+ // { data: { id: 'ETY10', source: 'ADVA-Z#2', target: 'NEC-Z#3', label: 'ADVA-Z#2-NEC-Z#3' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY11', source: 'ADVA-Z#4', target: 'SIAE-A#4', label: 'ADVA-Z#4-SIAE-A#4' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY12', source: 'Aviat-A#5', target: 'Spirent#5', label: 'Aviat-A#5-Spirent#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY13', source: 'Aviat-Z#5', target: 'Fujitsu-A#5', label: 'Aviat-Z#5-Fujitsu-A#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY14', source: 'Ceragon-A#5', target: 'ZTE-A#5', label: 'Ceragon-A#5-ZTE-A#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY15', source: 'Ceragon-Z#4', target: 'Spirent#2', label: 'Ceragon-Z#4-Spirent#2' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY16', source: 'Ceragon-Z#5', target: 'Nokia-A11', label: 'Ceragon-Z#5-Nokia-A11' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY17', source: 'DragonWave-A#2', target: 'Spirent#6', label: 'DragonWave-A#2-Spirent#6' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY18', source: 'DragonWave-Z#2', target: 'Intracom-A#2', label: 'DragonWave-Z#2-Intracom-A#2' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY19', source: 'ELVA-1-A#2', target: 'Spirent#7', label: 'ELVA-1-A#2-Spirent#7' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY20', source: 'ELVA-1-Z#2', target: 'Spirent#8', label: 'ELVA-1-Z#2-Spirent#8' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY21', source: 'Ericsson-A#5', target: 'NEC-Z#2', label: 'Ericsson-A#5-NEC-Z#2' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY22', source: 'Ericsson-Z#5', target: 'SIAE-Z#5', label: 'Ericsson-Z#5-SIAE-Z#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY23', source: 'Fujitsu-Z#5', target: 'Intracom-Z#5', label: 'Fujitsu-Z#5-Intracom-Z#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY24', source: 'Huawei-A#5', target: 'Nokia-Z33', label: 'Huawei-A#5-Nokia-Z33' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY25', source: 'Huawei-Z#5', target: 'SIAE-A#5', label: 'Huawei-Z#5-SIAE-A#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY26', source: 'NEC-A#3', target: 'ZTE-Z#5', label: 'NEC-A#3-ZTE-Z#5' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY27', source: 'SIAE-Z#4', target: 'Spirent#4', label: 'SIAE-Z#4-Spirent#4' , layer: 'ETY' , active: 'true' } },
+ { data: { id: 'ETY28', source: 'ZTE-Z#4', target: 'Spirent#1', label: 'Spirent#1-ZTE-Z#4' , layer: 'ETY' , active: 'true' } },
+
+ {  data:  {  id:  'ADVA-Y#2-ETH-13<->ADVA-Y#3-ETH-13',  source:  'ADVA-Y#2',  target:  'ADVA-Y#3',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'ADVA-Y#2-ETH-24<->ADVA-Y#4-ETH-24',  source:  'ADVA-Y#2',  target:  'ADVA-Y#4',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'ADVA-Y#3-ETH-13<->ADVA-Y#4-ETH-13',  source:  'ADVA-Y#3',  target:  'ADVA-Y#4',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Aviat-A#5-ETH-56<->Aviat-A#6-ETH-56',  source:  'Aviat-A#5',  target:  'Aviat-A#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Aviat-Z#5-ETH-56<->Aviat-Z#6-ETH-56',  source:  'Aviat-Z#5',  target:  'Aviat-Z#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ceragon-A#5-ETH-13<->Ceragon-A#6-ETH-13',  source:  'Ceragon-A#5',  target:  'Ceragon-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ceragon-A#5-ETH-24<->Ceragon-A#6-ETH-24',  source:  'Ceragon-A#5',  target:  'Ceragon-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'Ceragon-Z#4-ETH-24<->Ceragon-Z#5-ETH-24',  source:  'Ceragon-Z#4',  target:  'Ceragon-Z#5',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ceragon-Z#4-ETH-24<->Ceragon-Z#6-ETH-24',  source:  'Ceragon-Z#4',  target:  'Ceragon-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'Ceragon-Z#5-ETH-13<->Ceragon-Z#6-ETH-13',  source:  'Ceragon-Z#5',  target:  'Ceragon-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'DragonWave-A#2-ETH-56<->DragonWave-A#6-ETH-56',  source:  'DragonWave-A#2',  target:  'DragonWave-A#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'DragonWave-Z#2-ETH-56<->DragonWave-Z#6-ETH-56',  source:  'DragonWave-Z#2',  target:  'DragonWave-Z#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'ELVA-1-A#2-ETH-78<->ELVA-1-A#6-ETH-78',  source:  'ELVA-1-A#2',  target:  'ELVA-1-A#6',  label:  'service78' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service78' ,  rule:  'working'  }  },
+ {  data:  {  id:  'ELVA-1-Z#2-ETH-78<->ELVA-1-Z#6-ETH-78',  source:  'ELVA-1-Z#2',  target:  'ELVA-1-Z#6',  label:  'service78' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service78' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ericsson-A#4-ETH-13<->Ericsson-A#6-ETH-13',  source:  'Ericsson-A#4',  target:  'Ericsson-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ericsson-A#4-ETH-24<->Ericsson-A#6-ETH-24',  source:  'Ericsson-A#4',  target:  'Ericsson-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'Ericsson-Z#5-ETH-13<->Ericsson-Z#6-ETH-13',  source:  'Ericsson-Z#5',  target:  'Ericsson-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Ericsson-Z#5-ETH-24<->Ericsson-Z#6-ETH-24',  source:  'Ericsson-Z#5',  target:  'Ericsson-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'Fujitsu-A#5-ETH-56<->Fujitsu-A#6-ETH-56',  source:  'Fujitsu-A#5',  target:  'Fujitsu-A#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Fujitsu-Z#5-ETH-56<->Fujitsu-Z#6-ETH-56',  source:  'Fujitsu-Z#5',  target:  'Fujitsu-Z#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Huawei-A#5-ETH-13<->Huawei-A#6-ETH-13',  source:  'Huawei-A#5',  target:  'Huawei-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Huawei-A#5-ETH-24<->Huawei-A#6-ETH-24',  source:  'Huawei-A#5',  target:  'Huawei-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Huawei-Z#5-ETH-13<->Huawei-Z#6-ETH-13',  source:  'Huawei-Z#5',  target:  'Huawei-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Huawei-Z#5-ETH-24<->Huawei-Z#6-ETH-24',  source:  'Huawei-Z#5',  target:  'Huawei-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Intracom-A#2-ETH-56<->Intracom-A#6-ETH-56',  source:  'Intracom-A#2',  target:  'Intracom-A#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Intracom-Z#5-ETH-56<->Intracom-Z#6-ETH-56',  source:  'Intracom-Z#5',  target:  'Intracom-Z#6',  label:  'service56' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service56' ,  rule:  'working'  }  },
+ {  data:  {  id:  'NEC-A#3-ETH-13<->NEC-A#6-ETH-13',  source:  'NEC-A#3',  target:  'NEC-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'NEC-A#3-ETH-24<->NEC-A#6-ETH-24',  source:  'NEC-A#3',  target:  'NEC-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'NEC-Z#4-ETH-13<->NEC-Z#6-ETH-13',  source:  'NEC-Z#4',  target:  'NEC-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'NEC-Z#4-ETH-24<->NEC-Z#6-ETH-24',  source:  'NEC-Z#4',  target:  'NEC-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'Nokia-A11-ETH-13<->Nokia-A#6-ETH-13',  source:  'Nokia-A11',  target:  'Nokia-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Nokia-A11-ETH-24<->Nokia-A#6-ETH-24',  source:  'Nokia-A11',  target:  'Nokia-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Nokia-Z33-ETH-13<->Nokia-Z#6-ETH-13',  source:  'Nokia-Z33',  target:  'Nokia-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'Nokia-Z33-ETH-24<->Nokia-Z#6-ETH-24',  source:  'Nokia-Z33',  target:  'Nokia-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'SIAE-A#5-ETH-13<->SIAE-A#6-ETH-13',  source:  'SIAE-A#5',  target:  'SIAE-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'SIAE-A#5-ETH-24<->SIAE-A#6-ETH-24',  source:  'SIAE-A#5',  target:  'SIAE-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'SIAE-Z#4-ETH-24<->SIAE-Z#6-ETH-24',  source:  'SIAE-Z#4',  target:  'SIAE-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'working'  }  },
+ {  data:  {  id:  'SIAE-Z#4-ETH-24<->SIAE-Z#5-ETH-24',  source:  'SIAE-Z#4',  target:  'SIAE-Z#5',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'SIAE-Z#5-ETH-13<->SIAE-Z#6-ETH-13',  source:  'SIAE-Z#5',  target:  'SIAE-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'ZTE-A#5-ETH-13<->ZTE-A#6-ETH-13',  source:  'ZTE-A#5',  target:  'ZTE-A#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'ZTE-A#5-ETH-24<->ZTE-A#6-ETH-24',  source:  'ZTE-A#5',  target:  'ZTE-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'ZTE-A#5-ETH-24<->ZTE-A#6-ETH-24',  source:  'ZTE-A#5',  target:  'ZTE-A#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'ZTE-Z#4-ETH-13<->ZTE-Z#6-ETH-13',  source:  'ZTE-Z#4',  target:  'ZTE-Z#6',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'working'  }  },
+ {  data:  {  id:  'ZTE-Z#4-ETH-13<->ZTE-Z#5-ETH-13',  source:  'ZTE-Z#4',  target:  'ZTE-Z#5',  label:  'service13' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service13' ,  rule:  'protection'  }  },
+ {  data:  {  id:  'ZTE-Z#5-ETH-24<->ZTE-Z#6-ETH-24',  source:  'ZTE-Z#5',  target:  'ZTE-Z#6',  label:  'service24' ,  layer:  'ETH' ,  active:  'true' ,  path:  'false'  ,  service:  'service24' ,  rule:  'protection'  }  },
+ ]
+ };
+
+ var events = eventsFabric();
+
+ var result = {
+ colors: colors,
+ elements: elements,
+ styles: styles,
+ events: events
+ };
+
+ var someMethodChangingTheElements = function () {
+ // @Martin: hier kannst Du die Elements ändern, anschließend mußt Du das Ereignis veröffentlichen
+ // das Ereigniss wird in der Directive aufgefangen und die Grig wird neu gezeichnet
+
+ // Hinweis: Die Reihenfolge muss so bleiben und du kannst NUR result.elements ändern.
+
+ events.publish("elementsChanged", {
+ elements: result.elements
+ });
+ };
+
+ return result;
+ });
+
+ mwtnTopologyApp.directive("mwtnTopologyEthernetPathGraph", ["mwtnTopologyEthernetPathData", '$mwtnCommons', function (mwtnTopologyEthernetPathData, $mwtnCommons) {
+
+ return {
+ restrict: 'E',
+ replace: true,
+ template: '<div id="cy" style="height: 750px; width: 100%;"></div>',
+ controller: function () {
+
+ },
+ scope: {
+
+ },
+ link: function (scope, element, attrs, ctrl) {
+
+ var cy = cytoscape({
+ container: element[0],
+
+ boxSelectionEnabled: false,
+ autounselectify: true,
+
+ style: mwtnTopologyEthernetPathData.styles,
+ elements: mwtnTopologyEthernetPathData.elements,
+ layout: {
+ name: 'preset',
+ padding: 5
+ }
+ });
+
+ // @ Martin: Hier wird das Ereignis aus dem Service aboniert.
+ // Es ist möglich mehrere Ereignisse zu definieren.
+ mwtnTopologyEthernetPathData.events.subscribe("elementsChanged", function (data) {
+
+ // @Martin: cy aktualisiert sich mit Hilfe der Referenz auf die Elemente aus dem Service
+ cy.json({
+ elements: mwtnTopologyEthernetPathData.elements // oder data.elements
+ });
+
+ });
+
+ // pathGraphData.events.subscribe("styleChanged", function () {
+ // cy.json({
+ // style: mwtnTopologyEthernetPathData.styles
+ // });
+ // });
+
+ cy.viewport({
+ zoom: 0.5,
+ pan: { x: 150, y: 100 }
+ });
+
+ var clearService = function () {
+ var lable = cy.getElementById('label');
+ lable.data('label', '');
+
+ var pathState = ['working', 'protection', 'hidden'];
+ pathState.map(function (state) {
+ var selector = "[path = '" + state + "']";
+ cy.elements(selector).map(function (element) {
+ element.data('path', 'false');
+ });
+ });
+ };
+
+ var highlightService = function (service) {
+ var lable = cy.getElementById('label');
+ lable.data('label', service);
+
+ var selector = "[service = '" + service + "']";
+ // start and end service node (host, traffic analyser)
+ cy.nodes(selector).map(function (node) {
+ // console.log(node.id());
+ node.data('path', 'working');
+ });
+
+ ['protection', 'working'].map(function (state) {
+ selector = "[service = '" + service + "'][rule = '" + state + "']";
+ cy.edges(selector).map(function (edge) {
+ edge.connectedNodes().map(function (node) {
+ node.data('path', edge.data('rule'));
+ });
+ });
+ return state;
+ }).reverse().map(function (state) {
+ selector = "[path = '" + state + "']";
+ cy.nodes(selector).connectedEdges().filter(function (edge) {
+ return edge.data('service') === service || edge.data('layer') !== "ETH";
+ }).map(function (edge) {
+ edge.data('path', state);
+ });
+ });
+ };
+ var filterActiveMountPoints = function (mountpoints) {
+ return mountpoints.filter(function (mountpoint) {
+ if (!mountpoint) return false;
+ // console.warn(mountpoint['node-id'], mountpoint['netconf-node-topology:connection-status']);
+ return mountpoint['netconf-node-topology:connection-status'] === 'connected';
+ }).map(function (mountpoint) {
+ return mountpoint['node-id'];
+ });
+ };
+
+ var setDevicesActive = function (nodeIds) {
+ // console.warn(nodeIds);
+ cy.nodes().filter(function (node) {
+ node.data('active', 'false');
+ return node.data('type') === 'device' && nodeIds.contains(node.data('id'));
+ }).map(function (node) {
+ node.data('active', 'true');
+ });
+ };
+
+ var setAllDevicesInactive = function () {
+ cy.nodes().map(function (node) {
+ node.data('active', 'false');
+ });
+ };
+
+ var setPortAndEdgedActive = function () {
+ cy.edges().map(function (edge) {
+ var active = 'true';
+ edge.connectedNodes().map(function (port) {
+ // console.log(' node', JSON.stringify(edge.data()));
+ var parent = cy.getElementById(port.data('parent'));
+ if (parent.data('active') === 'false') {
+ port.data('active', 'false');
+ edge.data('active', 'false');
+ } else {
+ port.data('active', 'true');
+ }
+ });
+ });
+ };
+
+ var init = function () {
+ var timerName = 'init ethernet';
+ console.time(timerName);
+ $mwtnCommons.getMountPoints().then(function (mountpoints) {
+ var filtered = filterActiveMountPoints(mountpoints);
+ setDevicesActive(filtered);
+ setPortAndEdgedActive();
+ console.timeEnd(timerName);
+ }, function (error) {
+ setAllDevicesInactive();
+ setPortAndEdgedActive();
+ console.timeEnd(timerName);
+ });
+
+ };
+ init();
+
+ cy.on('tap', function (event) {
+ clearService();
+ if (event.target !== cy) {
+ if (event.target.data('service')) {
+ highlightService(event.target.data('service'));
+ }
+ } else {
+ init();
+ }
+ });
+ }
+ }
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyPortsGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyEthernetPathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyEthernetPathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "layer",
+ type: "string",
+ displayName: "Layer"
+ },
+ {
+ field: "active",
+ type: "string",
+ displayName: "Active"
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+
+ // extract all ports
+ var ports = mwtnTopologyEthernetPathData.elements.nodes.filter(function (node, ind, arr) {
+ return node && node.data && node.data.type === 'port';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) acc[cur.data.id] = cur.data;
+ return acc;
+ }, {});
+
+ // get all port ids
+ var portIds = Object.keys(ports);
+
+ // apply the grid filters
+ var tempData = portIds.filter(function (portId, ind, arr) {
+ var port = ports[portId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case "active":
+ return port[filter.field].toString().contains(filter.term);
+ default:
+ return port[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (portId) {
+ var port = ports[portId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: port.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ case "active":
+ orderBy = port[sortColumn.field] ? 1 : 0;
+ break;
+ default:
+ orderBy = port[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: port.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedPortsAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ portsAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedPortsAtCurrentPage.forEach(function (orderedPort) {
+ var port = ports[orderedPort.id];
+ portsAtCurrentPageCache[port.id] = port;
+ orderedData.push({
+ id: orderedPort.id,
+ layer: port.layer,
+ active: port.active
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ mwtnTopologyEthernetPathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyPortsGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyPortsGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/portsGrid.tpl.html'
+ };
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyEthConnectionsGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyEthernetPathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyEthernetPathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id",
+ width: 400
+ },
+ {
+ field: "source",
+ type: "string",
+ displayName: "PortA",
+ width: 200
+ },
+ {
+ field: "target",
+ type: "string",
+ displayName: "PortZ",
+ width: 200
+ },
+ {
+ field: "layer",
+ type: "string",
+ displayName: "Layer",
+ width: 80
+ },
+ {
+ field: "service",
+ type: "string",
+ displayName: "Service",
+ width: 150
+ },
+ {
+ field: "rule",
+ type: "string",
+ displayName: "Rule",
+ width: 150
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+
+ // extract all links
+ var links = mwtnTopologyEthernetPathData.elements.edges.filter(function (link, ind, arr) {
+ // return true; // node && node.data && node.data.type === 'port';
+ return link.data.layer === 'ETH';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) {
+ acc[cur.data.id] = cur.data;
+ }
+ return acc;
+ }, {});
+
+ // get all relevant link ids
+ var linkIds = Object.keys(links);
+
+ // apply the grid filters
+ var tempData = linkIds.filter(function (linkId, ind, arr) {
+ var link = links[linkId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ default:
+ return link[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (linkId) {
+ var link = links[linkId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: link.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ default:
+ orderBy = link[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: link.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedLinksAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ linksAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedLinksAtCurrentPage.forEach(function (orderedLink) {
+ var link = links[orderedLink.id];
+ linksAtCurrentPageCache[link.id] = link;
+ orderedData.push({
+ id: orderedLink.id,
+ source: link.source,
+ target: link.target,
+ layer: link.layer,
+ service: link.service,
+ rule: link.rule
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ var subscription = mwtnTopologyEthernetPathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ // to unsubscribe call subscription.remove();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyEthConnectionsGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyEthConnectionsGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/ethConnectionsGrid.tpl.html'
+ };
+ }]);
+
+ /********************************************* IEEE 1588v2 (PTP) **************************/
+
+ mwtnTopologyApp.controller('mwtnTopologyIeee1588ViewController', ['$scope', '$q', '$timeout', '$state', '$window', '$mwtnTopology', function ($scope, $q, $timeout, $state, $window, $mwtnTopology) {
+ var vm = this;
+ vm.status = {
+ topologyIsOpen: false,
+ portsOpen: false,
+ ethConnectionsIsOpen: false
+ }
+
+ $scope.$watchCollection(function () { return [vm.status.topologyIsOpen, vm.status.portsOpen, vm.status.ethConnectionsIsOpen] }, function (newVal, oldVal) {
+ if (newVal[1] || newVal[2]) {
+ $timeout(function () {
+ $window.dispatchEvent(new Event("resize"));
+ });
+ }
+ });
+ }]);
+
+ mwtnTopologyApp.directive('mwtnTopologyIeee1588View', function () {
+ return {
+ restrict: 'E',
+ controller: 'mwtnTopologyIeee1588ViewController',
+ controllerAs: 'vm',
+ bindToController: true,
+ templateUrl: 'src/app/mwtnTopology/templates/ieee1588View.tpl.html',
+ scope: {
+
+ }
+ };
+ });
+
+ mwtnTopologyApp.factory("mwtnTopologyIeee1588PathData", function () {
+ var colors = {
+ root: '#f54',
+ port: '#377',
+ device: '#252',
+ site: '#525',
+ edge: '#49a',
+ white: '#eed',
+ grey: '#555',
+ selected: '#ff0'
+ };
+
+ var styles = [
+ {
+ selector: 'node',
+ css: {
+ 'content': 'data(label)',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#aaaaaa',
+ 'border-color': '#000000',
+ 'border-width': '1px',
+ 'color': '#ffffff'
+ }
+ },
+ {
+ selector: '$node > node',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'top',
+ 'text-halign': 'center',
+ 'background-color': '#eeeeee',
+ 'color': '#444444',
+ 'border-color': '#888888'
+ }
+ },
+ {
+ selector: 'node[type = "site"]',
+ css: {
+ 'shape': 'roundrectangle',
+ 'padding-top': '10px',
+ 'padding-left': '10px',
+ 'padding-bottom': '10px',
+ 'padding-right': '10px',
+ 'text-valign': 'center',
+ 'text-halign': 'center',
+ 'background-color': '#fefefe',
+ 'color': '#444444',
+ 'border-color': '#888888',
+ 'font-weight': 'bold'
+ }
+ },
+ {
+ selector: 'node[type = "ptp-clock"][active = "true"]',
+ css: {
+ 'background-color': '#316ac5',
+ 'background-opacity': '0.2',
+ 'border-color': '#316ac5',
+ 'border-opacity': '0.8',
+ 'border-width': '2px',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'node[type = "port"][active = "true"]',
+ css: {
+ 'background-opacity': '1.0',
+ }
+ },
+ {
+ selector: 'node[active = "false"]',
+ css: {
+ 'background-opacity': '0.3',
+ 'border-opacity': '0.5'
+ }
+ },
+ {
+ selector: 'node[path = "true"]',
+ css: {
+ 'background-color': '#ff00ff',
+ 'background-opacity': '0.9',
+ 'border-color': '#880088',
+ }
+ },
+ {
+ selector: '$node > node[path = "true"]',
+ css: {
+ 'background-color': '#ff00ff',
+ 'background-opacity': '0.3',
+ 'border-color': '#ff00ff',
+ 'border-opacity': '1.0',
+ 'border-width': '2px',
+ }
+ },
+ {
+ selector: 'edge',
+ css: {
+ 'content': 'data(id)',
+ 'target-arrow-shape': 'triangle',
+ 'line-color': '#666666',
+ 'color': '#444444'
+ }
+ },
+ {
+ selector: 'edge[active = "false"]',
+ css: {
+ 'line-color': '#cccccc',
+ 'text-opacity': '0.9'
+ }
+ },
+ {
+ selector: 'edge[path = "true"]',
+ css: {
+ 'line-color': '#ff00ff',
+ 'width': '5px'
+ }
+ },
+ {
+ selector: ':selected',
+ css: {
+ 'background-color': 'black',
+ 'line-color': 'black',
+ 'target-arrow-color': 'black',
+ 'source-arrow-color': 'black'
+ }
+ }];
+
+ var elements = {
+ nodes: [
+ { data: { id: 'north', label: 'north', type: 'site', latitude: 50.734916, longitude: 7.137636 } },
+ { data: { id: 'north-east', label: 'north-east', type: 'site', latitude: 50.733028, longitude: 7.151086 } },
+ { data: { id: 'north-west', label: 'north-west', type: 'site', latitude: 50.730230, longitude: 7.126017 } },
+ { data: { id: 'east', label: 'east', type: 'site', latitude: 50.725672, longitude: 7.158488 } },
+ { data: { id: 'west', label: 'west', type: 'site', latitude: 50.721914, longitude: 7.120521 } },
+ { data: { id: 'south-east', label: 'south-east', type: 'site', latitude: 50.717158, longitude: 7.155506 } },
+ { data: { id: 'south-west', label: 'south-west', type: 'site', latitude: 50.714359, longitude: 7.130437 } },
+ { data: { id: 'south', label: 'south', type: 'site', latitude: 50.712472, longitude: 7.143887 } },
+
+ {  data:  {  id:  'ADVA-A',  label :  'ADVA-A' ,  parent :  'west', type: 'ptp-clock', base64: 'AIDq//6MFzA=', hex: '0x47 0x4D 0x30 0x30 0x30 0x30 0x30 0x31', active: 'true' , latitude: 50.721914, longitude: 7.120521, parentDs: '', path: 'false' }   },
+ {  data:  {  id:  'ADVA-B',  label :  'ADVA-B' ,  parent :  'north-west', type: 'ptp-clock', base64: 'AIDq//6MGDA=', hex: '0x47 0x4D 0x30 0x30 0x30 0x30 0x30 0x32', active: 'true' , latitude: 50.730230, longitude: 7.126017, parentDs: '', path: 'false' }   },
+ {  data:  {  id:  'ADVA-Y',  label :  'ADVA-Y' ,  parent :  'north-east', type: 'ptp-clock', base64: 'AIDqb0hQAAE=', hex: '0x53 0x4C 0x41 0x56 0x45 0x30 0x30 0x31', active: 'true' , latitude: 50.733028, longitude: 7.151086, parentDs: 'NEC-Z#4', path: 'false' }   },
+ {  data:  {  id:  'ADVA-Z',  label :  'ADVA-Z' ,  parent :  'south', type: 'ptp-clock', base64: 'AIDqb0mAAAA=', hex: '0x53 0x4C 0x41 0x56 0x45 0x30 0x30 0x32', active: 'true' , latitude: 50.712472, longitude: 7.143887, parentDs: 'Huawei-Z#3', path: 'false' }   },
+ {  data:  {  id:  'Ericsson-A',  label :  'Ericsson-A' ,  parent :  'north-east', type: 'ptp-clock', base64: 'BE4G//4jsio=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x31', active: 'true' , latitude: 50.733028, longitude: 7.151086, parentDs: 'NEC-Z#2', path: 'false' }   },
+ {  data:  {  id:  'Ericsson-Z',  label :  'Ericsson-Z' ,  parent :  'east', type: 'ptp-clock', base64: 'BE4G//4jtBA=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x32', active: 'true' , latitude: 50.725672, longitude: 7.158488, parentDs: 'Ericsson-A#6', path: 'false' }   },
+ {  data:  {  id:  'Huawei-A',  label :  'Huawei-A' ,  parent :  'south-west', type: 'ptp-clock', base64: 'ACWeIQAJq6A=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x33', active: 'true' , latitude: 50.714359, longitude: 7.130437, parentDs: 'Nokia-Z33', path: 'false' }   },
+ {  data:  {  id:  'Huawei-Z',  label :  'Huawei-Z' ,  parent :  'south', type: 'ptp-clock', base64: 'ACWeIQAJAm8=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x34', active: 'true' , latitude: 50.712472, longitude: 7.143887, parentDs: 'Huawei-A#6', path: 'false' }   },
+ {  data:  {  id:  'NEC-A',  label :  'NEC-A' ,  parent :  'north', type: 'ptp-clock', base64: 'jN+d//5XDuA=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x35', active: 'true' , latitude: 50.734916, longitude: 7.137636, parentDs: 'ZTE-Z#5', path: 'false' }   },
+ {  data:  {  id:  'NEC-Z',  label :  'NEC-Z' ,  parent :  'north-east', type: 'ptp-clock', base64: 'jN+d//5XDwA=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x36', active: 'true' , latitude: 50.733028, longitude: 7.151086, parentDs: 'NEC-A#6', path: 'false' }   },
+ {  data:  {  id:  'Nokia-A',  label :  'Nokia-A' ,  parent :  'west', type: 'ptp-clock', base64: 'ACGu//4Crac=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x37', active: 'true' , latitude: 50.721914, longitude: 7.120521, parentDs: 'ADVA-A#1', path: 'false' }   },
+ {  data:  {  id:  'Nokia-Z',  label :  'Nokia-Z' ,  parent :  'south-west', type: 'ptp-clock', base64: 'ACGu//4CrZY=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x38', active: 'true' , latitude: 50.714359, longitude: 7.130437, parentDs: 'Nokia-A#6', path: 'false' }   },
+ {  data:  {  id:  'SIAE-A',  label :  'SIAE-A' ,  parent :  'south', type: 'ptp-clock', base64: 'ALCs//4R6K8=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x30 0x39', active: 'true' , latitude: 50.712472, longitude: 7.143887, parentDs: 'Huawei-Z#5', path: 'false' }   },
+ {  data:  {  id:  'SIAE-Z',  label :  'SIAE-Z' ,  parent :  'south-east', type: 'ptp-clock', base64: 'ALCs//4RucQ=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x31 0x30', active: 'true' , latitude: 50.717158, longitude: 7.155506, parentDs: 'SIAE-A#6', path: 'false' }   },
+ {  data:  {  id:  'ZTE-A',  label :  'ZTE-A' ,  parent :  'north-west', type: 'ptp-clock', base64: 'DBJi//7Zdpo=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x31 0x31', active: 'true' , latitude: 50.730230, longitude: 7.126017, parentDs: 'ADVA-B#2', path: 'false' }   },
+ {  data:  {  id:  'ZTE-Z',  label :  'ZTE-Z' ,  parent :  'north', type: 'ptp-clock', base64: 'DBJi//7ZdqQ=', hex: '0x42 0x43 0x30 0x30 0x30 0x30 0x31 0x32', active: 'true' , latitude: 50.734916, longitude: 7.137636, parentDs: 'ZTE-A#6', path: 'false' }   },
+
+ { data: { id: 'ADVA-A#1', label: '#1', parent: 'ADVA-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.721914, longitude: 7.120521 }, position: { x: 124, y: 564 } },
+ { data: { id: 'ADVA-A#2', label: '#2', parent: 'ADVA-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.721914, longitude: 7.120521 }, position: { x: 124, y: 507 } },
+ { data: { id: 'ADVA-B#1', label: '#1', parent: 'ADVA-B', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.730230, longitude: 7.126017 }, position: { x: 380, y: 381 } },
+ { data: { id: 'ADVA-B#2', label: '#2', parent: 'ADVA-B', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.730230, longitude: 7.126017 }, position: { x: 380, y: 301 } },
+ { data: { id: 'ADVA-Y#1', label: '#1', parent: 'ADVA-Y', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1392, y: 229 } },
+ { data: { id: 'ADVA-Y#2', label: '#2', parent: 'ADVA-Y', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: 172 } },
+ { data: { id: 'ADVA-Z#1', label: '#1', parent: 'ADVA-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1139, y: 1001 } },
+ { data: { id: 'ADVA-Z#2', label: '#2', parent: 'ADVA-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1196, y: 944 } },
+ { data: { id: 'Ericsson-A#5', label: '#5', parent: 'Ericsson-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1605, y: 172 } },
+ { data: { id: 'Ericsson-A#6', label: '#6', parent: 'Ericsson-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1664, y: 226 } },
+ { data: { id: 'Ericsson-Z#6', label: '#6', parent: 'Ericsson-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.725672, longitude: 7.158488 }, position: { x: 1765, y: 325 } },
+ { data: { id: 'Huawei-A#5', label: '#5', parent: 'Huawei-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.714359, longitude: 7.130437 }, position: { x: 605, y: 1028 } },
+ { data: { id: 'Huawei-A#6', label: '#6', parent: 'Huawei-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.714359, longitude: 7.130437 }, position: { x: 685, y: 1028 } },
+ { data: { id: 'Huawei-Z#3', label: '#3', parent: 'Huawei-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1046, y: 1094 } },
+ { data: { id: 'Huawei-Z#4', label: '#4', parent: 'Huawei-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 989, y: 1094 } },
+ { data: { id: 'Huawei-Z#5', label: '#5', parent: 'Huawei-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1058, y: 1123 } },
+ { data: { id: 'Huawei-Z#6', label: '#6', parent: 'Huawei-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 978, y: 1123 } },
+ { data: { id: 'NEC-A#3', label: '#3', parent: 'NEC-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.734916, longitude: 7.137636 }, position: { x: 955, y: -52 } },
+ { data: { id: 'NEC-A#6', label: '#6', parent: 'NEC-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.734916, longitude: 7.137636 }, position: { x: 1035, y: -52 } },
+ { data: { id: 'NEC-Z#2', label: '#2', parent: 'NEC-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: -41 } },
+ { data: { id: 'NEC-Z#3', label: '#3', parent: 'NEC-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1392, y: 16 } },
+ { data: { id: 'NEC-Z#4', label: '#4', parent: 'NEC-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1449, y: 16 } },
+ { data: { id: 'NEC-Z#6', label: '#6', parent: 'NEC-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.733028, longitude: 7.151086 }, position: { x: 1382, y: -23 } },
+ { data: { id: 'Nokia-A13', label: '13', parent: 'Nokia-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.721914, longitude: 7.120521 }, position: { x: 40, y: 801 } },
+ { data: { id: 'Nokia-A34', label: '34', parent: 'Nokia-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.721914, longitude: 7.120521 }, position: { x: 28, y: 772 } },
+ { data: { id: 'Nokia-A#6', label: '#6', parent: 'Nokia-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.721914, longitude: 7.120521 }, position: { x: 28, y: 829 } },
+ { data: { id: 'Nokia-Z33', label: '33', parent: 'Nokia-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.714359, longitude: 7.130437 }, position: { x: 385, y: 1028 } },
+ { data: { id: 'Nokia-Z#6', label: '#6', parent: 'Nokia-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.714359, longitude: 7.130437 }, position: { x: 305, y: 1028 } },
+ { data: { id: 'SIAE-A#5', label: '#5', parent: 'SIAE-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1278, y: 1123 } },
+ { data: { id: 'SIAE-A#6', label: '#6', parent: 'SIAE-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.712472, longitude: 7.143887 }, position: { x: 1346, y: 1094 } },
+ { data: { id: 'SIAE-Z#6', label: '#6', parent: 'SIAE-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.717158, longitude: 7.155506 }, position: { x: 1588, y: 838 } },
+ { data: { id: 'ZTE-A#3', label: '#3', parent: 'ZTE-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.730230, longitude: 7.126017 }, position: { x: 380, y: 168 } },
+ { data: { id: 'ZTE-A#4', label: '#4', parent: 'ZTE-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.730230, longitude: 7.126017 }, position: { x: 345, y: 148 } },
+ { data: { id: 'ZTE-A#6', label: '#6', parent: 'ZTE-A', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.730230, longitude: 7.126017 }, position: { x: 408, y: 99 } },
+ { data: { id: 'ZTE-Z#5', label: '#5', parent: 'ZTE-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.734916, longitude: 7.137636 }, position: { x: 747, y: -27 } },
+ { data: { id: 'ZTE-Z#6', label: '#6', parent: 'ZTE-Z', type: 'port', layer: 'PTP', active: 'true', path: 'false', latitude: 50.734916, longitude: 7.137636 }, position: { x: 667, y: -27 } },
+
+ ],
+ edges: [
+ { data: { id: 'ERI1', source: 'Ericsson-A#6', target: 'Ericsson-Z#6', label: 'ERI1', layer: 'PTP', active: 'true' } },
+ { data: { id: '71', source: 'Huawei-A#6', target: 'Huawei-Z#6', label: '71', layer: 'PTP', active: 'true' } },
+ { data: { id: '81', source: 'NEC-A#6', target: 'NEC-Z#6', label: '81', layer: 'PTP', active: 'true' } },
+ { data: { id: '91', source: 'Nokia-A#6', target: 'Nokia-Z#6', label: '91', layer: 'PTP', active: 'true' } },
+ { data: { id: '101', source: 'SIAE-A#6', target: 'SIAE-Z#6', label: '101', layer: 'PTP', active: 'true' } },
+ { data: { id: '111', source: 'ZTE-A#6', target: 'ZTE-Z#6', label: '111', layer: 'PTP', active: 'true' } },
+
+ { data: { id: 'ETY01', source: 'ADVA-A#1', target: 'Nokia-A34', label: 'ADVA-A#1-Nokia-A34', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY02', source: 'ADVA-A#2', target: 'ZTE-A#4', label: 'ADVA-A#2-ZTE-A#4', layer: 'PTP', active: 'false' } },
+ { data: { id: 'ETY03', source: 'ADVA-B#1', target: 'Nokia-A13', label: 'ADVA-B#1-Nokia-A13', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY04', source: 'ADVA-B#2', target: 'ZTE-A#3', label: 'ADVA-B#2-ZTE-A#3', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY05', source: 'ADVA-Y#1', target: 'Huawei-Z#4', label: 'ADVA-Y#1-Huawei-Z#4', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY06', source: 'ADVA-Y#2', target: 'NEC-Z#4', label: 'ADVA-Y#2-NEC-Z#4', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY09', source: 'ADVA-Z#1', target: 'Huawei-Z#3', label: 'ADVA-Z#1-Huawei-Z#3', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY10', source: 'ADVA-Z#2', target: 'NEC-Z#3', label: 'ADVA-Z#2-NEC-Z#3', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY21', source: 'Ericsson-A#5', target: 'NEC-Z#2', label: 'Ericsson-A#5-NEC-Z#2', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY24', source: 'Huawei-A#5', target: 'Nokia-Z33', label: 'Huawei-A#5-Nokia-Z33', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY25', source: 'Huawei-Z#5', target: 'SIAE-A#5', label: 'Huawei-Z#5-SIAE-A#5', layer: 'PTP', active: 'true' } },
+ { data: { id: 'ETY26', source: 'NEC-A#3', target: 'ZTE-Z#5', label: 'NEC-A#3-ZTE-Z#5', layer: 'PTP', active: 'true' } },
+
+ ]
+ };
+
+ var events = eventsFabric();
+
+ var result = {
+ colors: colors,
+ elements: elements,
+ styles: styles,
+ events: events
+ };
+
+ var someMethodChangingTheElements = function () {
+ // @Martin: hier kannst Du die Elements ändern, anschließend mußt Du das Ereignis veröffentlichen
+ // das Ereigniss wird in der Directive aufgefangen und die Grig wird neu gezeichnet
+
+ // Hinweis: Die Reihenfolge muss so bleiben und du kannst NUR result.elements ändern.
+
+ events.publish("elementsChanged", {
+ elements: result.elements
+ });
+ };
+
+ return result;
+ });
+
+ mwtnTopologyApp.directive("mwtnTopologyIeee1588PathGraph", ["mwtnTopologyIeee1588PathData", "$mwtnPtp", function (mwtnTopologyIeee1588PathData, $mwtnPtp) {
+
+ return {
+ restrict: 'E',
+ replace: true,
+ template: '<div style="height: 750px; width: 100%;"></div>',
+ controller: function () {
+
+ },
+ scope: {
+
+ },
+ link: function (scope, element, attrs, ctrl) {
+
+ var cy = cytoscape({
+ container: element[0],
+
+ boxSelectionEnabled: false,
+ autounselectify: true,
+
+ style: mwtnTopologyIeee1588PathData.styles,
+ elements: mwtnTopologyIeee1588PathData.elements,
+ layout: {
+ name: 'preset',
+ padding: 5
+ }
+ });
+
+ // @ Martin: Hier wird das Ereignis aus dem Service aboniert.
+ // Es ist möglich mehrere Ereignisse zu definieren.
+ mwtnTopologyIeee1588PathData.events.subscribe("elementsChanged", function (data) {
+
+ // @Martin: cy aktualisiert sich mit Hilfe der Referenz auf die Elemente aus dem Service
+ cy.json({
+ elements: mwtnTopologyIeee1588PathData.elements // oder data.elements
+ });
+ });
+
+ // pathGraphData.events.subscribe("styleChanged", function () {
+ // cy.json({
+ // style: mwtnTopologyIeee1588PathData.styles
+ // });
+ // });
+
+ cy.viewport({
+ zoom: 0.5,
+ pan: { x: 150, y: 100 }
+ });
+
+ var clearPtpPath = function () {
+ var selector = "[path = 'true']";
+ cy.elements(selector).map(function (element) {
+ element.data('path', 'false');
+ });
+ };
+
+ var highlightPtpMaster = function (id) {
+ var selector = "[id = '" + id + "']";
+ cy.nodes(selector).map(function (node) {
+ if (node.data('parentDs') && node.data('parentDs') != '') {
+ // console.warn('parentDs', node.data('parentDs'));
+ var parentNode = node.data('parentDs').slice(0, -2);
+ if (parentNode !== id) {
+ highlightPtpMaster(parentNode);
+
+ // highlight edge
+ selector = "[id = '" + node.data('parentDs') + "']";
+ cy.nodes(selector).connectedEdges().map(function (edge) {
+ edge.data('path', 'true');
+ edge.connectedNodes().map(function (node) {
+ node.data('path', 'true');
+ });
+ });
+ }
+ }
+ });
+ };
+
+ var setAllDevicesInactive = function () {
+ cy.nodes().map(function (node) {
+ node.data('active', 'false');
+ });
+ };
+
+ var setPortAndEdgedActive = function () {
+ cy.edges().map(function (edge) {
+ var active = 'true';
+ edge.connectedNodes().map(function (port) {
+ // console.log(' node', JSON.stringify(edge.data()));
+ var parent = cy.getElementById(port.data('parent'));
+ if (parent.data('active') === 'false') {
+ port.data('active', 'false');
+ edge.data('active', 'false');
+ } else {
+ port.data('active', 'true');
+ }
+ });
+ });
+ };
+
+ var init = function () {
+ setAllDevicesInactive();
+ $mwtnPtp.getPtpClocks().then(function (clocks) {
+ // setDevicesActive(Object.keys(clocks));
+ var hex = true;
+ // update clock ids first
+ Object.keys(clocks).map(function (key) {
+ var clock = clocks[key];
+ var graphClock = cy.getElementById(key);
+ graphClock.data('active', 'true')
+ graphClock.data('base64', clock.getIdentity());
+ graphClock.data('hex', clock.getIdentity(hex));
+ });
+ // update rest
+ Object.keys(clocks).map(function (key) {
+ var clock = clocks[key];
+ var graphClock = cy.getElementById(key);
+ var graphParentDs = nodeId(clock.getParent().slice(0, -2));
+ graphClock.data('parentDs', graphParentDs + clock.getParent().slice(-2));
+ graphClock.data('grandMaster', nodeId(clock.getGrandMaster()));
+
+ // clock.getPtpPorts().map(function(port){
+ // // console.warn(port.getId(), port.getNumber(), port.getState(), port.isSlave(), port.isMaster(), port.getLogicalTerminationPointReference());
+ // var portKey = [key, port.getNumber() < 10 ? '#' : '', port.getNumber()].join('');
+ // var graphPort = cy.getElementById(portKey);
+ // // console.warn(JSON.stringify(graphPort.data()));
+ // if (graphPort === undefined) {
+ // console.error('PtpPort not found in graph:' , portKey);
+ // } else {
+ // console.info('PtpPort found in graph:' , portKey);
+ // }
+
+ // });
+ });
+ setPortAndEdgedActive();
+ }, function (error) {
+ setPortAndEdgedActive();
+ console.error(JSON.stringify(error));
+ });
+ };
+ // init();
+
+ var getNodeId = function (base64) {
+ if (base64 === undefined || base64 === '') return '';
+
+ var selector = "[type = 'ptp-clock']";
+ var result = cy.nodes(selector).filter(function (graphClock) {
+ // console.error(base64, graphClock.data('base64'), graphClock.data('base64') === base64);
+ return graphClock.data('base64') === base64;
+ });
+ if (result.length === 0) {
+ console.warn('Clock', base64, 'not found!');
+ return '';
+ } else {
+ return result[0].id();
+ }
+ };
+
+ var getParentClock = function (nodeId) {
+ $mwtnPtp.getParent(nodeId).then(function (parentPortIdentity) {
+ var parentNode = getNodeId(parentPortIdentity['clock-identity']);
+ console.log(JSON.stringify(parentPortIdentity), parentNode);
+ if (parentNode) {
+ getParentClock(parentNode);
+ }
+ });
+ };
+
+ cy.on('tap', function (event) {
+ console.log('tap');
+ clearPtpPath();
+ if (event.target !== cy) {
+ if (event.target.data('type') === 'ptp-clock') {
+ getParentClock(event.target.id());
+ // highlightPtpMaster(event.target.id());
+ } else if (event.target.data('type') === 'port') {
+ var parent = cy.getElementById(event.target.data('parent'));
+ // highlightPtpMaster(parent.id());
+ getParentClock(event.target.id());
+ }
+ } else {
+ // init();
+ }
+ });
+
+ }
+ }
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyClocksGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyIeee1588PathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyIeee1588PathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Node id",
+ width: 120
+ },
+ {
+ field: "hex",
+ type: "string",
+ displayName: "Clock identity in hex",
+ width: 300
+ }, {
+ field: "base64",
+ type: "string",
+ displayName: "... in base64",
+ width: 150
+ },
+ {
+ field: "parentDs",
+ type: "string",
+ displayName: "parentDs",
+ width: 150
+ },
+ {
+ field: "grandMaster",
+ type: "string",
+ displayName: "grandmaster",
+ width: 300
+ },
+ {
+ field: "active",
+ type: "string",
+ displayName: "Active",
+ width: 80
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+
+ // extract all ports
+ var ports = mwtnTopologyIeee1588PathData.elements.nodes.filter(function (node, ind, arr) {
+ return node && node.data && node.data.type === 'ptp-clock';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) acc[cur.data.id] = cur.data;
+ return acc;
+ }, {});
+
+ // get all port ids
+ var portIds = Object.keys(ports);
+
+ // apply the grid filters
+ var tempData = portIds.filter(function (portId, ind, arr) {
+ var port = ports[portId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ case "active":
+ return port[filter.field].toString().contains(filter.term);
+ default:
+ return port[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (portId) {
+ var port = ports[portId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: port.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ case "active":
+ orderBy = port[sortColumn.field] ? 1 : 0;
+ break;
+ default:
+ orderBy = port[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: port.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedPortsAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ portsAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedPortsAtCurrentPage.forEach(function (orderedPort) {
+ var port = ports[orderedPort.id]; // TODO [sko] varible port should be renamed to clock
+ portsAtCurrentPageCache[port.id] = port;
+ orderedData.push({
+ id: orderedPort.id,
+ layer: port.layer,
+ active: port.active,
+ hex: port.hex,
+ base64: port.base64,
+ parentDs: port.parentDs,
+ grandMaster: port.grandMaster
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ mwtnTopologyIeee1588PathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyClocksGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyClocksGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/clocksGrid.tpl.html'
+ };
+ }]);
+
+ mwtnTopologyApp.controller("mwtnTopologyPtpLinksGridController", ['$scope', '$timeout', '$state', '$mwtnCommons', '$mwtnTopology', 'uiGridConstants', 'mwtnTopologyIeee1588PathData', function ($scope, $timeout, $state, $mwtnCommons, $mwtnTopology, uiGridConstants, mwtnTopologyIeee1588PathData) {
+ var vm = this;
+
+ // The page number to show in the grid.
+ var paginationPage = 1;
+ // The page size.
+ var paginationPageSize = 100;
+ // The grid column object with current sorting informations.
+ var sortColumn = null;
+ // The grid column object with current sorting informations.
+ var gridFilters = [];
+ // caches all sites at the current grid page
+
+ vm.gridOptions = Object.assign({}, $mwtnCommons.gridOptions, {
+ showGridFooter: false, // disable the grid footer because the pagination component sets its own.
+ paginationPageSizes: [10, 25, 50, 100],
+ paginationPageSize: paginationPageSize,
+ useExternalPagination: true,
+ useExternalFiltering: true,
+ useExternalSorting: true,
+ totalItems: 0,
+ columnDefs: [{
+ field: "id",
+ type: "string",
+ displayName: "Id"
+ },
+ {
+ field: "source",
+ type: "string",
+ displayName: "PortA"
+ },
+ {
+ field: "target",
+ type: "string",
+ displayName: "PortZ"
+ },
+ {
+ field: "active",
+ type: "string",
+ displayName: "active"
+ }
+ ],
+ data: [],
+ onRegisterApi: function (gridApi) {
+ // http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi
+ vm.gridApi = gridApi;
+
+ vm.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
+ // Save the current sort column for later use.
+ sortColumn = (!sortColumns || sortColumns.length === 0) ?
+ null :
+ sortColumns[0];
+ loadPage();
+ });
+
+ vm.gridApi.pagination.on.paginationChanged($scope, function (newPage, newPageSize) {
+ // Save the pagination informations for later use.
+ paginationPage = newPage;
+ paginationPageSize = newPageSize;
+ loadPage();
+ });
+
+ vm.gridApi.core.on.filterChanged($scope, function () {
+ // Save the all filters for later use.
+ var filters = [];
+ this.grid.columns.forEach(function (col, ind) {
+ if (col.filters[0] && col.filters[0].term) {
+ filters.push({
+ field: col.field,
+ term: col.filters[0].term
+ });
+ }
+ });
+ gridFilters = filters;
+ loadPage();
+ });
+
+ loadPage();
+ }
+ });
+
+ /**
+ * Calculates the page content of the grid and sets the values to the gridOprions.data object.
+ */
+ function loadPage() {
+
+ // extract all links
+ var links = mwtnTopologyIeee1588PathData.elements.edges.filter(function (node, ind, arr) {
+ return true; // node && node.data && node.data.type === 'port';
+ }).reduce(function (acc, cur, ind, arr) {
+ if (cur.data) {
+ acc[cur.data.id] = cur.data;
+ }
+ return acc;
+ }, {});
+
+ // get all link ids
+ var linkIds = Object.keys(links);
+
+ // apply the grid filters
+ var tempData = linkIds.filter(function (linkId, ind, arr) {
+ var link = links[linkId];
+ return gridFilters.map(function (filter) {
+ switch (filter.field) {
+ default:
+ return link[filter.field].contains(filter.term);
+ }
+ }).and(true);
+ }).map(function (linkId) {
+ var link = links[linkId];
+ var orderBy;
+
+ if (!sortColumn || !sortColumn.sort.direction) {
+ return {
+ id: link.id
+ }
+ }
+
+ switch (sortColumn.field) {
+ case "active":
+ orderBy = link[sortColumn.field] ? 1 : 0;
+ default:
+ orderBy = link[sortColumn.field];
+ break;
+ }
+
+ return {
+ id: link.id,
+ orderBy: orderBy
+ };
+ });
+
+ if (sortColumn && sortColumn.sort.direction) {
+ tempData.sort(function (left, right) {
+ if (left === right || left.orderBy === right.orderBy) {
+ return 0;
+ }
+ if (left.orderBy > right.orderBy) {
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? 1 : -1;
+ }
+ return (sortColumn.sort.direction === uiGridConstants.ASC) ? -1 : 1;
+ });
+ }
+
+ var maxPageNumber = Math.max(1, Math.ceil(tempData.length / paginationPageSize));
+ var currentPage = Math.min(maxPageNumber, paginationPage);
+ var orderedLinksAtCurrentPage = tempData.slice((currentPage - 1) * paginationPageSize, currentPage * paginationPageSize);
+
+ linksAtCurrentPageCache = {};
+ var orderedData = [];
+
+ orderedLinksAtCurrentPage.forEach(function (orderedLink) {
+ var link = links[orderedLink.id];
+ linksAtCurrentPageCache[link.id] = link;
+ orderedData.push({
+ id: orderedLink.id,
+ source: link.source,
+ target: link.target,
+ active: link.active
+ });
+ });
+
+ $timeout(function () {
+ vm.gridOptions.data = orderedData;
+ vm.gridOptions.totalItems = tempData.length;
+ });
+ }
+
+ // subscribe to the elementsChanged event to reload the grid page if the data in the service has chenged
+ var subscription = mwtnTopologyIeee1588PathData.events.subscribe("elementsChanged", function (data) {
+ loadPage();
+ // to unsubscribe call subscription.remove();
+ });
+
+ }]);
+
+ mwtnTopologyApp.directive("mwtnTopologyPtpLinksGrid", [function () {
+ return {
+ restrict: 'E',
+ replace: false,
+ controller: 'mwtnTopologyPtpLinksGridController',
+ controllerAs: 'vm',
+ scope: {
+
+ },
+ templateUrl: 'src/app/mwtnTopology/templates/ptpLinksGrid.tpl.html'
+ };
+ }]);
+
+ mwtnTopologyApp.filter('coordinateFilter', coordinateFilter);
+
+ function coordinateFilter($sce) {
+
+ return function (coordinate, conversion, type, places) {
+
+ // The filter will be running as we type values into the input boxes, which returns undefined
+ // and brings up an error in the console. Here wait until the coordinate is defined
+ if (coordinate != undefined) {
+
+ // Check for user input that is a positive or negative number with the option
+ // that it is a float. Match only the numbers and not the white space or other characters
+ var pattern = /[-+]?[0-9]*\.?[0-9]+/g
+ var match = String(coordinate).match(pattern);
+
+ if (conversion === "toDD" && match && coordinateIsValid(match, type)) {
+ // If the match array only has one item, the user has provided decimal degrees
+ // and we can just return what the user typed in
+ if (match.length === 1) {
+ return parseFloat(match);
+ }
+
+ // If the match array has a length of three then we know degrees, minutes, and seconds
+ // were provided so we can convert it to decimal degrees
+ if (match.length === 3) {
+ return toDecimalDegrees(match);
+ }
+ }
+
+ else if (conversion === 'toDMS' && match && coordinateIsValid(match, type)) {
+ // When converting from decimal degrees to degrees, minutes and seconds, if
+ // the match array has one item we know the user has input decimal degrees
+ // so we can convert it to degrees, minutes and seconds
+ if (match.length === 1) {
+ return toDegreesMinutesSeconds(match, type);
+ }
+
+ // To properly format the converted coordinates we will need to add in HTML entities
+ // which means we'll need to bind the returned string as HTML and thus we need
+ // to use $sce (Strict Contextual Escaping) to say that we trust what is being bound as HTML
+ if (match.length === 3) {
+ return $sce.trustAsHtml(match[0] + '&deg; ' + match[1] + '&prime; ' + match[2] + '&Prime; ');
+ }
+ }
+
+ // Output a notice that the coordinates are invalid if they are
+ else if (!coordinateIsValid(match, type)) {
+ return "Invalid Coordinate!";
+ }
+
+ function toDecimalDegrees(coord) {
+ // Setup for all parts of the DMS coordinate and the necessary math to convert
+ // from DMS to DD
+ var degrees = parseInt(coord[0]);
+ var minutes = parseInt(coord[1]) / 60;
+ var seconds = parseInt(coord[2]) / 3600;
+
+ // When the degrees value is negative, the math is a bit different
+ // than when the value is positive. This checks whether the value is below zero
+ // and does subtraction instead of addition if it is.
+ if (degrees < 0) {
+ var calculated = degrees - minutes - seconds;
+ return calculated.toFixed(places || 4);
+ }
+ else {
+ var calculated = degrees + minutes + seconds
+ return calculated.toFixed(places || 4);
+ }
+ }
+
+ // This function converts from DD to DMS. Math.abs is used a lot because
+ // for the minutes and seconds, negative values aren't valid
+ function toDegreesMinutesSeconds(decimal_degrees, type) {
+
+ var dd = decimal_degrees[0];
+ var direction = 'E';
+
+ if (type === 'lat') {
+ if (dd < 0) {
+ direction = 'S';
+ } else {
+ direction = 'N'
+ }
+ } else {
+ if (dd < 0) {
+ direction = 'W';
+ } else {
+ direction = 'E'
+ }
+ }
+
+ dd = Math.abs(dd);
+ var degrees = Math.floor(dd);
+ var frac = dd - degrees; // get fractional part
+ var min = Math.floor(frac * 60);
+ var sec = frac * 3600 - min * 60;
+
+ var formated = [degrees, '° ', ("0" + min).slice(-2), '\' ', ("0" + sec.toFixed(4)).slice(-7), '\" ', direction];
+ return formated.join('');
+
+ // var degrees = coordinate[0].split('.')[0];
+ // var minutes = Math.abs(Math.floor(60 * (Math.abs(coordinate[0]) - Math.abs(degrees))));
+ // var seconds = 3600 * (Math.abs(coordinate[0]) - Math.abs(degrees) - Math.abs(minutes) / 60).toFixed(2);
+
+ // return $sce.trustAsHtml(degrees + '° ' + minutes + '\' ' + seconds + '\" ');
+
+ }
+
+ // This function checks whether the coordinate value the user enters is valid or not.
+ // If the coordinate doesn't pass one of these rules, the function will return false
+ // which will then alert the user that the coordinate is invalid.
+ function coordinateIsValid(coordinate, type) {
+ if (coordinate) {
+
+ // The degree values of latitude coordinates have a range between -90 and 90
+ if (coordinate[0] && type === 'lat') {
+ if (!(-90 <= +(coordinate[0]) <= 90)) return false;
+ }
+ // The degree values longitude coordinates have a range between -180 and 180
+ else if (coordinate[0] && type === 'lon') {
+ if (!(-180 <= +(coordinate[0]) <= 180)) return false;
+ }
+ // Minutes and seconds can only be between 0 and 60
+ if (coordinate[1]) {
+ if (!(0 <= +(coordinate[1]) <= 60)) return false;
+ }
+ if (coordinate[2]) {
+ if (!(0 <= +(coordinate[2]) <= 60)) return false;
+ }
+ }
+
+ // If the coordinate made it through all the rules above, the function
+ // returns true because the coordinate is good
+ return true;
+ }
+ }
+ }
+ }
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.module.js
new file mode 100755
index 00000000..db795d22
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.module.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+
+ var mwtnTopologyApp = angular.module('app.mwtnTopology', ['app.core', 'ui.router.state', 'ui.grid', 'ui.grid.pagination', 'ui.grid.selection', 'ui.bootstrap', 'config', 'app.mwtnCommons']);
+
+ mwtnTopologyApp.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ // // AF/MF: Warum? (Remove as soon as possible)
+ // mwtnTopologyApp.register = {
+ // controller: $controllerProvider.register,
+ // directive: $compileProvider.directive,
+ // factory: $provide.factory,
+ // service: $provide.service
+ // };
+
+ NavHelperProvider.addControllerUrl('app/mwtnTopology/mwtnTopology.controller');
+ NavHelperProvider.addToMenu('mwtnTopology', {
+ "link": "#/pnfTopology/site",
+ "active": "main.mwtnTopology",
+ "title": "pnf Topology",
+ "icon": "fa fa-connectdevelop", // Add navigation icon css class here
+ "page": {
+ "title": "pnf Topology",
+ "description": "mwtnTopology"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.mwtnTopology', {
+ url: 'pnfTopology/:tab?&top&bottom&right&left&lat&lng&zoom&site&siteLink&sitePath',
+ reloadOnSearch: false,
+ access: access.admin,
+ params: {
+ internal: false
+ },
+ views: {
+ content: {
+ template: '<mwtn-topology-frame />'
+ }
+ }
+ });
+
+ });
+
+ return mwtnTopologyApp;
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.rest b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.rest
new file mode 100755
index 00000000..323b13ad
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.rest
@@ -0,0 +1,209 @@
+###
+# get outer bounding box for all sites.
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "aggregations": {
+ "top": {
+ "max": {
+ "field": "location.lat"
+ }
+ },
+ "right": {
+ "max": {
+ "field": "location.lon"
+ }
+ },
+ "bottom": {
+ "min": {
+ "field": "location.lat"
+ }
+ },
+ "left": {
+ "min": {
+ "field": "location.lon"
+ }
+ }
+ },
+ "size": 0
+}
+
+###
+# get sites in bounding box
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "geo_bounding_box": {
+ "location": {
+ "top": -10.681254175812176,
+ "right": -48.3738302863769,
+ "bottom": -10.736012963621369,
+ "left": -48.433356043212834
+ }
+ }
+ },
+ "size": 100
+}
+
+###
+# get single site by id
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "id": "vivsp"
+ }
+ }
+ ]
+ }
+ }
+}
+
+###
+# get sites with site links
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "bool": {
+ "must": {
+ "exists": {
+ "field": "references.site-links"
+ }
+ }
+ }
+ },
+ "size": 100
+}
+
+###
+# get the first 3 site links
+POST http://03-wtp-poc:9200/mwtn/site-link/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "match_all": {}
+ },
+ "size": 3
+}
+
+###
+# get site links where siteA or siteZ refers to a list ob site ids.
+POST http://03-wtp-poc:9200/mwtn/site-link/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "bool": {
+ "filter": {
+ "term": {
+ "siteA": "atdrj"
+ }
+ }
+ }
+ }
+}
+
+###
+# get site links where siteLinkId is one of the ids in given List.
+POST http://03-wtp-poc:9200/mwtn/site-link/_search
+content-type: application/json
+
+{
+ "query": {
+ "bool": {
+ "should": [
+ {"term": {"id" : "aaapb:aacal"}},
+ {"term": {"id" : "site-6:site-7"}},
+ {"term": {"id" : "site-7:site-8"}}
+ ]
+ }
+ }
+}
+
+###
+# get the first 3 site links
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "match_all": {}
+ },
+ "sort" : {
+ "name": {
+ "order": "asc"
+ }
+ },
+ "size": 30
+}
+
+###
+# get the first 3 site links
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "match_all": {}
+ },
+ "sort" : {
+ "_script" : {
+ "script" : {
+ "lang": "expression",
+ "inline" : "doc['references'].value['site-links'].length"
+ } ,
+ "type" : "number",
+ "order" : "desc"
+ }
+ },
+ "size": 30
+}
+
+
+###
+# get the first 3 site links
+POST http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "from":0,
+ "size":10,
+ "sort": {
+ "id":{
+ "order":"asc"
+ }
+ },
+ "query":{
+ "regexp":{
+ "name":".*00.*"
+ }
+ }
+}
+
+
+###
+# get the first 3 site links
+GET http://03-wtp-poc:9200/mwtn/site/_search HTTP/1.1
+content-type: application/json
+
+{
+ "query": {
+ "function_score": {
+ "script_score": {
+ "script": "Math.pow(2, 2)",
+ "lang": "groovy"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.services.js
new file mode 100755
index 00000000..195c08f0
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/mwtnTopology.services.js
@@ -0,0 +1,1020 @@
+/*
+ * 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
+ */
+
+/** Type Definitions
+ * @typedef {{id: string, siteLink: string, radio: string, polarization: string }} AirInterfaceLink
+ * @typedef {{id: string, siteA: string, siteZ: string, siteNameA: string, siteNameZ: string, airInterfaceLinks: AirInterfaceLink[] }} DbLink
+ * @typedef {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: DbLink, _type: string}[], max_score: number, total: number}}, status: number}} DbLinkResult */
+
+define(['app/mwtnTopology/mwtnTopology.module'], function (mwtnTopologyApp) {
+// module.exports = function () {
+// const mwtnTopologyApp = require('app/mwtnTopology/mwtnTopology.module');
+// const mwtnTopologyCommons = require('app/mwtnCommons/mwtnCommons.service');
+
+ mwtnTopologyApp.factory('$mwtnTopology', function ($q, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+ var service = {};
+
+ // AF/MF: Obsolete - will removed soon. All data access function
+ service.getRequiredNetworkElements = $mwtnCommons.getRequiredNetworkElements;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.highlightFilteredHeader = $mwtnCommons.highlightFilteredHeader;
+ service.getAllData = $mwtnDatabase.getAllData;
+
+
+ /**
+ * Since not all browsers implement this we have our own utility that will
+ * convert from degrees into radians
+ *
+ * @param deg - The degrees to be converted into radians
+ * @return radians
+ */
+ var _toRad = function (deg) {
+ return deg * Math.PI / 180;
+ };
+
+ /**
+ * Since not all browsers implement this we have our own utility that will
+ * convert from radians into degrees
+ *
+ * @param rad - The radians to be converted into degrees
+ * @return degrees
+ */
+ var _toDeg = function (rad) {
+ return rad * 180 / Math.PI;
+ };
+
+ // public functions
+ /**
+ * Calculate the bearing between two positions as a value from 0-360
+ *
+ * @param lat1 - The latitude of the first position
+ * @param lng1 - The longitude of the first position
+ * @param lat2 - The latitude of the second position
+ * @param lng2 - The longitude of the second position
+ *
+ * @return int - The bearing between 0 and 360
+ */
+ service.bearing = function (lat1, lng1, lat2, lng2) {
+ var dLon = (lng2 - lng1);
+ var y = Math.sin(dLon) * Math.cos(lat2);
+ var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
+ var brng = _toDeg(Math.atan2(y, x));
+ return 360 - ((brng + 360) % 360);
+ },
+
+
+ /**
+ * Gets the geospatial distance between two points
+ * @param lat1 {number} The latitude of the first point.
+ * @param lon1 {number} The longitude of the first point.
+ * @param lat2 {number} The latitude of the second point.
+ * @param lon2 {number} The longitude of the second point.
+ * @returns {number} The distance between the two given points.
+ */
+ service.getDistance = function (lat1, lon1, lat2, lon2) {
+ var R = 6371; // km
+ var φ1 = _toRad(lat1);
+ var φ2 = _toRad(lat2);
+ var Δφ = _toRad(lat2 - lat1);
+ var Δλ = _toRad(lon2 - lon1);
+
+ var a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
+ Math.cos(φ1) * Math.cos(φ2) *
+ Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
+ var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+
+ return (R * c).toFixed(3);
+ };
+
+ /**
+ * Gets a promise which is resolved if the database has been calculated the bounds containing all sites.
+ * @returns {promise} The promise which is resolved if the database has completed its calculation.
+ */
+ service.getOuterBoundingRectangleForSites = function () {
+ var getOuterBoundingRectangleForSitesDefer = $q.defer();
+ var aggregation = {
+ "aggregations": {
+ "top": {
+ "max": {
+ "field": "location.lat"
+ }
+ },
+ "right": {
+ "max": {
+ "field": "location.lon"
+ }
+ },
+ "bottom": {
+ "min": {
+ "field": "location.lat"
+ }
+ },
+ "left": {
+ "min": {
+ "field": "location.lon"
+ }
+ }
+ },
+ "size": 0
+ };
+
+ $mwtnDatabase.getAggregatedData('mwtn', 'site', aggregation).then(function (result) {
+ getOuterBoundingRectangleForSitesDefer.resolve({
+ top: result.data.aggregations.top.value,
+ right: result.data.aggregations.right.value,
+ bottom: result.data.aggregations.bottom.value,
+ left: result.data.aggregations.left.value
+ });
+ }, function (error) {
+ getOuterBoundingRectangleForSitesDefer.reject(error);
+ });
+
+ return getOuterBoundingRectangleForSitesDefer.promise;
+ };
+
+ /**
+ * Gets a promise which resolved with an array of sites within the given bounding box.
+ * @param boundingBox {{top: number, right: number, bottom: number, left: number}} The bounding box to get all sites for.
+ * @param chunkSize {number} The maximum count of sites who should return.
+ * @param chunkSiteStartIndex {number} The index of the first site element to get.
+ */
+ service.getSitesInBoundingBox = function (boundingBox, chunkSize, chunkSiteStartIndex) {
+ var resultDefer = $q.defer();
+
+ var filter = {
+ "geo_bounding_box": {
+ "location": {
+ "top": boundingBox.top,
+ "right": boundingBox.right,
+ "bottom": boundingBox.bottom,
+ "left": boundingBox.left
+ }
+ }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "site", chunkSiteStartIndex, chunkSize, filter)
+ .then(processResult, resultDefer.reject);
+
+ return resultDefer.promise;
+
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, location: {lat: number, lon: number}, "amsl-ground": number, references: {"network-elements": string[], "site-links": string[]}}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function processResult(result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ var total = hits.total;
+ var sites = [];
+
+ for (var hitIndex = 0; hitIndex < hits.hits.length; ++hitIndex) {
+ var site = hits.hits[hitIndex];
+ sites.push({
+ id: site._source.id,
+ name: site._source.name,
+ type: site._source.type,
+ location: {
+ lat: site._source.location.lat,
+ lng: site._source.location.lon
+ },
+ amslGround: site._source["amsl-ground"],
+ references: {
+ siteLinks: site._source.references["site-links"]
+ }
+ });
+ }
+
+ resultDefer.resolve({
+ chunkSize: chunkSize,
+ chunkSiteStartIndex: chunkSiteStartIndex,
+ total: total,
+ sites: sites
+ })
+ }
+ };
+
+ /**
+ * Gets a promise which is resolved with an array of sites filtered by given site ids.
+ * This function does not use chunks!
+ * @param siteIds {string[]} The ids of the sites to return.
+ */
+ service.getSitesByIds = function (siteIds) {
+ var resultDefer = $q.defer();
+
+ if (!siteIds || siteIds.length === 0) {
+ resultDefer.resolve([]);
+ return resultDefer.promise;
+ }
+
+ var query = {
+ bool: {
+ should: siteIds.map(function (siteId) {
+ return { term: { id: siteId } };
+ })
+ }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "site", 0, siteIds.length, query)
+ .then(processResult, resultDefer.reject);
+
+ return resultDefer.promise;
+
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, location: {lat: number, lon: number}, "amsl-ground": number, references: {"network-elements": string[], "site-links": string[]}}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function processResult(result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ var total = hits.total;
+ var sites = [];
+
+ for (var hitIndex = 0; hitIndex < hits.hits.length; ++hitIndex) {
+ var site = hits.hits[hitIndex];
+ sites.push({
+ id: site._source.id,
+ name: site._source.name,
+ type: site._source.type,
+ location: {
+ lat: site._source.location.lat,
+ lng: site._source.location.lon
+ },
+ amslGround: site._source["amsl-ground"],
+ references: {
+ siteLinks: site._source.references["site-links"]
+ }
+ });
+ }
+
+ resultDefer.resolve({
+ total: total,
+ sites: sites
+ })
+ }
+ };
+
+ /**
+ * Gets a promise which is resolved with an array of sites using the given filter expression.
+ */
+ service.getSites = function (sortColumn, sortDirection, filters, chunkSize, chunkSiteStartIndex) {
+ var resultDefer = $q.defer();
+
+ // determine the sort parameter
+ var sort = null;
+ if (sortColumn != null && sortDirection != null) {
+ sort = {};
+ switch (sortColumn) {
+ case 'countNetworkElements':
+ case 'countLinks':
+ sort = null;
+ break;
+ case 'amslGround':
+ sort['amsl-ground'] = {
+ order: sortDirection === 'desc' ? 'desc' : 'asc'
+ }
+ break;
+ default:
+ sort[sortColumn] = {
+ order: sortDirection === 'desc' ? 'desc' : 'asc'
+ }
+ break;
+ }
+ }
+
+ // determine the query parameter
+ var query = {};
+ if (filters == null || filters.length == 0) {
+ query["match_all"] = {};
+ } else {
+ var regexp = {};
+ filters.forEach(function (filter) {
+ if (filter && filter.field) {
+ regexp[filter.field] = '.*'+ filter.term + '.*';
+ }
+ });
+ query["regexp"] = regexp;
+ }
+
+
+ if (sort) {
+ $mwtnDatabase.getFilteredSortedData("mwtn", "site", chunkSiteStartIndex, chunkSize, sort, query).then(processResult, resultDefer.reject);
+ } else {
+ $mwtnDatabase.getFilteredData("mwtn", "site", chunkSiteStartIndex, chunkSize, query).then(processResult, resultDefer.reject);
+ }
+
+ return resultDefer.promise;
+
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, location: {lat: number, lon: number}, "amsl-ground": number, references: {"network-elements": string[], "site-links": string[]}}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function processResult(result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ var total = hits.total;
+ var sites = [];
+
+ for (var hitIndex = 0; hitIndex < hits.hits.length; ++hitIndex) {
+ var site = hits.hits[hitIndex];
+ sites.push({
+ id: site._source.id,
+ name: site._source.name,
+ type: site._source.type,
+ location: {
+ lat: site._source.location.lat,
+ lng: site._source.location.lon
+ },
+ amslGround: site._source["amsl-ground"],
+ references: {
+ siteLinks: site._source.references["site-links"]
+ }
+ });
+ }
+
+ resultDefer.resolve({
+ total: total,
+ sites: sites
+ })
+ }
+ };
+
+ /**
+ * Gets a promise which resolved with an array of site links referenced by given sites.
+ * @param sites {({id: string, name: string, location: {lat: number, lng: number}, amslGround: number, references: {siteLinks: string[]})[]}
+ * @param chunkSize {number} The maximum count of site links who should return.
+ * @param chunkSiteLinkStartIndex {number} The index of the first site link element to get.
+ */
+ service.getSiteLinksForSites = function (sites, chunkSize, chunkSiteLinkStartIndex) {
+ var resultDefer = $q.defer();
+
+ if (!sites || sites.length === 0) {
+ resultDefer.resolve([]);
+ return resultDefer.promise;
+ }
+
+ var siteLinkIds = Object.keys(sites.reduce(function (accumulator, currentSite) {
+ // Add all site link ids referenced by the current site to the accumulator object.
+ currentSite.references.siteLinks.forEach(function (siteLinkId) {
+ // The value "true"" isnt important, i only use the key (siteLinkId) later.
+ // But this way i dont have to check, if the key is already known.
+ accumulator[siteLinkId] = true;
+ });
+ return accumulator;
+ }, {})).map(function (siteLinkId) {
+ return { term: { id: siteLinkId } };
+ });
+
+ var query = {
+ bool: { should: siteLinkIds }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "site-link", chunkSiteLinkStartIndex, chunkSize, query).then(
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, siteA: string, siteZ: string, siteNameA: string, siteNameZ: string, airInterfaceLinks: {id: string, siteLink: string, radio: string, polarization: string }[] }, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function (result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ if (hits.total === 0) {
+ resultDefer.resolve([]);
+ return;
+ }
+
+ // get additional sites that wont be given in the sites array but are referenced by the site links.
+ // get all sites, referenced by the site links.
+ var allReferencedSiteIds = hits.hits.reduce(function (accumulator, currentSiteLink) {
+ accumulator[currentSiteLink._source.siteA] = true;
+ accumulator[currentSiteLink._source.siteZ] = true;
+ return accumulator;
+ }, {});
+ // remove all known sites
+ sites.forEach(function (site) {
+ if (allReferencedSiteIds.hasOwnProperty(site.id)) {
+ delete allReferencedSiteIds[site.id];
+ }
+ });
+
+ var additionalReferencedSiteIds = Object.keys(allReferencedSiteIds).map(function (referencedSiteId) {
+ return { term: { id: referencedSiteId } };
+ });
+
+ if (additionalReferencedSiteIds.length > 0) {
+ query = {
+ bool: { should: additionalReferencedSiteIds }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "site", 0, 400, query).then(
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, location: {lat: number, lon: number}, "amsl-ground": number, references: {"network-elements": string[], "site-links": string[]}}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function (result) {
+ var siteHits = result && result.data && result.data.hits;
+ if (!siteHits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ var additionalSites = siteHits.hits.map(function (site) {
+ return {
+ id: site._source.id,
+ name: site._source.name,
+ type: site._source.type,
+ location: {
+ lat: site._source.location.lat,
+ lng: site._source.location.lon
+ },
+ amslGround: site._source["amsl-ground"],
+ type: site._source.type,
+ references: {
+ siteLinks: site._source.references["site-links"]
+ }
+ };
+ });
+
+ var siteLinks = hits.hits.map(function (siteLink) {
+ return {
+ id: siteLink._source.id,
+ siteA: sites.find(function (site) { return site.id === siteLink._source.siteA; }) || additionalSites.find(function (site) { return site.id === siteLink._source.siteA; }),
+ siteZ: sites.find(function (site) { return site.id === siteLink._source.siteZ; }) || additionalSites.find(function (site) { return site.id === siteLink._source.siteZ; }),
+ type: siteLink._source.type,
+ length: 5000 // AF/MF: the length will be served from the database in the next version.
+ };
+ });
+
+ resultDefer.resolve(siteLinks);
+ },
+ resultDefer.reject);
+
+ return;
+ }
+
+ var siteLinks = hits.hits.map(function (siteLink) {
+ return {
+ id: siteLink._source.id,
+ siteA: sites.find(function (site) { return site.id === siteLink._source.siteA; }),
+ siteZ: sites.find(function (site) { return site.id === siteLink._source.siteZ; }),
+ type: siteLink._source.type,
+ length: 5000 // AF/MF: the length will be served from the database in the next version.
+ };
+ });
+
+ resultDefer.resolve(siteLinks);
+ },
+ resultDefer.reject);
+
+ return resultDefer.promise;
+ };
+
+ /**
+ * Gets a promise which is resolved with an array of planned filtered by given network element ids.
+ * This function does not use chunks!
+ * @param neIds {string[]} The ids of the site links to return.
+ */
+ service.getPlannedNetworkElementsByIds = function (neIds) {
+ var resultDefer = $q.defer();
+
+ if (!neIds || neIds.length === 0) {
+ resultDefer.resolve([]);
+ return resultDefer.promise;
+ }
+
+ var query = {
+ bool: {
+ should: neIds.map(function (neId) {
+ return { term: { id: neId } };
+ })
+ }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "planned-network-elements", 0, neIds.length, query).then(
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, type: string}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function (result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ if (hits.total === 0) {
+ resultDefer.resolve([]);
+ return;
+ }
+
+ var plannedNetworkElements = hits.hits.map(function (plannedNetworkElement) {
+ return {
+ id: plannedNetworkElement._source.id,
+ name: plannedNetworkElement._source.name,
+ type: plannedNetworkElement._source.radioType
+ };
+ });
+
+ resultDefer.resolve(plannedNetworkElements);
+ }, resultDefer.reject);
+
+ return resultDefer.promise;
+ };
+
+
+ /**
+ * Gets a promise which is resolved with an array of site links filtered by given site link ids.
+ * This function does not use chunks!
+ * @param siteLinkIds {string[]} The ids of the site links to return.
+ */
+ service.getSiteLinksByIds = function (siteLinkIds) {
+ var resultDefer = $q.defer();
+
+ if (!siteLinkIds || siteLinkIds.length === 0) {
+ resultDefer.resolve([]);
+ return resultDefer.promise;
+ }
+
+ var query = {
+ bool: {
+ should: siteLinkIds.map(function (siteLinkId) {
+ return { term: { id: siteLinkId } };
+ })
+ }
+ };
+
+ $mwtnDatabase.getFilteredData("mwtn", "site-link", 0, siteLinkIds.length, query).then(
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, siteA: string, siteZ: string}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function (result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ if (hits.total === 0) {
+ resultDefer.resolve([]);
+ return;
+ }
+
+ var siteLinks = hits.hits.map(function (siteLink) {
+ return {
+ id: siteLink._source.id,
+ siteA: siteLink._source.siteA,
+ siteZ: siteLink._source.siteZ,
+ azimuthAz: siteLink._source.azimuthAZ,
+ azimuthZa: siteLink._source.azimuthZA,
+ length: siteLink._source.length,
+ type: siteLink._source.type
+ };
+ });
+
+ resultDefer.resolve(siteLinks);
+ }, resultDefer.reject);
+
+ return resultDefer.promise;
+ };
+
+ /**
+ * Gets a promise with all details for a given site by its id.
+ * @param siteId {string} The id of the site to request the details for.
+ */
+ service.getSiteDetailsBySiteId = function (siteId) {
+ var resultDefer = $q.defer();
+
+ var siteQuery = {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "id": siteId
+ }
+ }
+ ]
+ }
+ };
+
+ // get all site details
+ $mwtnDatabase.getFilteredData("mwtn", "site", 0, 1, siteQuery).then(
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, name: string, location: {lat: number, lon: number}, "amsl-ground": number, references: {"network-elements": string[], "site-links": string[]}}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function (result) {
+ if (result.data.hits.total != 1) {
+ // todo: handle this error
+ resultDefer.reject("Error loading details for " + siteId + ((result.data.hits.total) ? ' Too many recoeds found.' : ' No record found.'));
+ }
+ var site = result.data.hits.hits[0];
+ var siteDetails = {
+ id: site._source.id,
+ name: site._source.name,
+ type: site._source.type,
+ location: {
+ lat: site._source.location.lat,
+ lng: site._source.location.lon
+ },
+ amslGround: site._source["amsl-ground"],
+ references: {
+ siteLinks: site._source.references["site-links"],
+ networkElements: site._source.references["network-elements"]
+ }
+ };
+
+ service.getSiteLinksByIds(siteDetails.references.siteLinks).then(
+ /** Callback for the database request.
+ * @param result {{id: string, siteA: string, siteZ: string }[]}
+ */
+ function (result) {
+ siteDetails.siteLinks = result;
+ resultDefer.resolve(siteDetails);
+ });
+
+ service.getPlannedNetworkElementsByIds(siteDetails.references.networkElements).then(
+ /** Callback for the database request.
+ * @param result {{id: string, name: string, type: string }[]}
+ */
+ function (result) {
+ siteDetails.plannedNetworkElements = result;
+ resultDefer.resolve(siteDetails);
+ });
+ }
+ );
+ return resultDefer.promise;
+ };
+
+ /**
+ * Gets a promise with all details for a given link by its id.
+ * @param siteId {string} The id of the link to request the details for.
+ */
+ service.getLinkDetailsByLinkId = function (linkId) {
+ var resultDefer = $q.defer();
+
+ var linkQuery = {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "id": linkId
+ }
+ }
+ ]
+ }
+ };
+
+ // get all site details
+ $mwtnDatabase.getFilteredData("mwtn", "site-link", 0, 1, linkQuery).then(
+ /**
+ * Callback for the database request.
+ * @param result { DbLinkResult } The database result.
+ */
+ function (result) {
+ if (result.data.hits.total != 1) {
+ // todo: handle this error
+ resultDefer.reject("Error loading details for " + siteId + ((result.data.hits.total) ? ' Too many recoeds found.' : ' No record found.'));
+ }
+ var link = result.data.hits.hits[0];
+ var linkDetails = {
+ id: link._source.id,
+ siteA: link._source.siteA,
+ siteZ: link._source.siteZ,
+ siteNameA: link._source.siteNameA,
+ siteNameZ: link._source.siteNameZ,
+ length: link._source.length,
+ azimuthA: link._source.azimuthAZ,
+ azimuthB: link._source.azimuthZA,
+ airInterfaceLinks: link._source.airInterfaceLinks,
+ type: link._source.type,
+ airInterfaceLinks: link._source.airInterfaceLinks
+ };
+
+ service.getSitesByIds([link._source.siteA, link._source.siteZ]).then(
+ /** Callback for the database request.
+ * @param result {{ total: number, sites: { id: string, name: string } []}}
+ */
+ function (result) {
+ var siteA = result.sites.find(function (site) { return site.id == linkDetails.siteA });
+ var siteZ = result.sites.find(function (site) { return site.id == linkDetails.siteZ });
+ if (result.total != 2 || !siteA || !siteZ) {
+ resultDefer.reject("Could not load Sites for link "+linkDetails.id);
+ }
+ linkDetails.siteA = siteA;
+ linkDetails.siteZ = siteZ;
+
+ resultDefer.resolve(linkDetails);
+ })
+ }
+ );
+ return resultDefer.promise;
+ }
+
+ /**
+ * Gets a promise which is resolved with an array of links using the given filter expression.
+ */
+ service.getLinks = function (sortColumn, sortDirection, filters, chunkSize, chunkSiteStartIndex) {
+ var resultDefer = $q.defer();
+
+ // determine the sort parameter
+ var sort = null;
+ if (sortColumn != null && sortDirection != null) {
+ sort = {};
+ switch (sortColumn) {
+ case 'siteIdA':
+ sort['siteA'] = {
+ order: sortDirection === 'desc' ? 'desc' : 'asc'
+ }
+ break;
+ case 'siteIdZ':
+ sort['siteZ'] = {
+ order: sortDirection === 'desc' ? 'desc' : 'asc'
+ }
+ break;
+ default:
+ sort[sortColumn] = {
+ order: sortDirection === 'desc' ? 'desc' : 'asc'
+ }
+ break;
+ }
+ }
+
+ // determine the query parameter
+ var query = {};
+ if (filters == null || filters.length == 0) {
+ query["match_all"] = {};
+ } else {
+ var regexp = {};
+ filters.forEach(function (filter) {
+ if (filter && filter.field) {
+ switch (filter.field) {
+ case 'siteIdA':
+ regexp['siteIdA'] = '.*' + filter.term + '.*';
+ break;
+ case 'siteIdZ':
+ regexp['siteZ'] = '.*' + filter.term + '.*';
+ break;
+ default:
+ regexp[filter.field] = '.*' + filter.term + '.*';
+ break;
+ }
+ }
+ });
+ query["regexp"] = regexp;
+ }
+
+
+ if (sort) {
+ $mwtnDatabase.getFilteredSortedData("mwtn", "site-link", chunkSiteStartIndex, chunkSize, sort, query).then(processResult, resultDefer.reject);
+ } else {
+ $mwtnDatabase.getFilteredData("mwtn", "site-link", chunkSiteStartIndex, chunkSize, query).then(processResult, resultDefer.reject);
+ }
+
+ /**
+ * Callback for the database request.
+ * @param result {{data: {hits: {hits: {_id: string, _index: string, _score: number, _source: {id: string, siteA: string, siteZ: string}, _type: string}[], max_score: number, total: number}}, status: number}} The database result.
+ */
+ function processResult (result) {
+ var hits = result && result.data && result.data.hits;
+ if (!hits) {
+ resultDefer.reject("Invalid result.");
+ return;
+ }
+
+ var total = hits.total;
+ var links = [];
+
+ var siteLinks = hits.hits.map(function (siteLink) {
+ return {
+ id: siteLink._source.id,
+ siteA: siteLink._source.siteA,
+ siteZ: siteLink._source.siteZ,
+ type: siteLink._source.type,
+ };
+ });
+
+ resultDefer.resolve({
+ total: total,
+ links: siteLinks
+ });
+ }
+
+ return resultDefer.promise;
+
+
+ };
+
+ /**
+ * Determines if a coordinate is in a bounding box
+ * @param bounds {{ top: number, left: number, right: number, bottom: number}} The bounding box.
+ * @param coordinate {{ lat: number, lng: number }} The coordinate.
+ * @return if the bounding box contains the coordinate
+ */
+ service.isInBounds = function(bounds, coordinate) {
+ var isLongInRange = (bounds.right < bounds.left)
+ ? coordinate.lng >= bounds.left || coordinate.lng <= bounds.right
+ : coordinate.lng >= bounds.left && coordinate.lng <= bounds.right ;
+
+ return coordinate.lat >= bounds.bottom && coordinate.lat <= bounds.top && isLongInRange;
+ }
+
+ service.getAllEdges = function () {
+ var edges = [];
+ return getGenericChunk("edge", edges).then(function () {
+ return edges;
+ });
+ };
+
+ /**
+ * Retrieves all nodes.
+ * @return a Promis containing an array of nodes
+ */
+ service.getAllNodes = function () {
+ var resultDefer = $q.defer();
+ var nodes = [];
+ getGenericChunk("node", nodes).then(function () {
+
+ // recreate the tree structure from the flat list
+ var finalNodes = nodes.reduce(
+ /** @param acc { Node[] } */
+ function (acc, cur, ind, arr) {
+ // the site will be added with the first device, so it can not be missing after the first device is in
+ if (!acc.some(node => node.data.type == "site" && node.data.id == cur.data.grandparent)) {
+ acc.push({
+ data: {
+ type: "site",
+ id: cur.data.grandparent,
+ label: cur.data.grandparent,
+ active: cur.data.active
+ }
+ });
+ }
+ if (!acc.some(node => node.data.type == "device" && node.data.id == cur.data.parent)) {
+ acc.push({
+ data: {
+ _parent: cur.data.grandparent,
+ type: "device",
+ id: cur.data.parent,
+ get parent() { return cur.data.grandparent },
+ set parent(val) { debugger; },
+ label: cur.data.parent,
+ active: cur.data.active
+ }
+ });
+ }
+ acc.push({
+ data: Object.keys(cur.data).reduce(function (obj, key) {
+ if (key == 'grandparent') {
+ obj['type'] = 'port'
+ } else {
+ cur.data.hasOwnProperty(key) && (obj[key] = cur.data[key]);
+ }
+ return obj;
+ }, {}),
+ position: cur.position
+ });
+ return acc;
+ }, []);
+
+ resultDefer.resolve(finalNodes);
+ }, function (err) {
+ console.error(err);
+ resultDefer.reject(err);
+ });
+ return resultDefer.promise;
+ }
+
+ /** @param nodes {{id: string,position:{ x:number, y:number}}}[]} */
+ service.saveChangedNodes = function (nodes) {
+ return $mwtnDatabase.getBase('topology').then(function (base) {
+ var resultDefer = $q.when();
+
+ nodes.forEach(function (node) {
+ resultDefer = resultDefer.then(function () {
+ return $mwtnDatabase.genericRequest({
+ method: 'POST',
+ base: base.base,
+ index: base.index,
+ docType: 'node',
+ command: encodeURI(node.id) +'/_update',
+ data: {
+ "doc": {
+ "position": node.position
+ }
+ }
+ });
+ })
+ });
+ return resultDefer;
+ });
+ }
+
+ // Start to initialize google maps api and save the returned promise.
+ service.googleMapsApiPromise = initializeGoogleMapsApi();
+
+ return service;
+
+ // private helper functions of $mwtnTopology
+
+ function getGenericChunk(docType, target) {
+ var size = 30;
+ return $mwtnDatabase.getAllData('topology', docType, target.length || 0, size, undefined)
+ .then(function (result) {
+ if (result.status === 200 && result.data) {
+ var total = (result.data.hits && result.data.hits.total) || 0;
+ var hits = (total && result.data.hits.hits) || [];
+ hits.forEach(function (hit) {
+ target.push(hit._source || {});
+ });
+ if (total > target.length) {
+ return getGenericChunk(docType, target);
+ }
+ return $q.resolve(true);
+ } else {
+ return $q.reject("Could not load " + docType + ".");
+ }
+ }, function (err) {
+ resultDefer.reject(err);
+ });
+
+ return resultDefer.promise;
+ }
+
+
+ /**
+ * Gets a promise which is resolved if the google maps api initialization is completed.
+ * @returns {promise} The promise which is resolved if the initialization is completed.
+ */
+ function initializeGoogleMapsApi() {
+ var googleMapsApiDefer = $q.defer();
+ window.googleMapsApiLoadedEvent = new Event("googleMapsApiLoaded");
+
+ window.addEventListener("googleMapsApiLoaded", function (event) {
+
+ /**
+ * Calculates the bounds this map would display at a given zoom level.
+ *
+ * @member google.maps.Map
+ * @method boundsAt
+ * @param {Number} zoom Zoom level to use for calculation.
+ * @param {google.maps.LatLng} [center] May be set to specify a different center than the current map center.
+ * @param {google.maps.Projection} [projection] May be set to use a different projection than that returned by this.getProjection().
+ * @param {Element} [div] May be set to specify a different map viewport than this.getDiv() (only used to get dimensions).
+ * @return {google.maps.LatLngBounds} the calculated bounds.
+ *
+ * @example
+ * var bounds = map.boundsAt(5); // same as map.boundsAt(5, map.getCenter(), map.getProjection(), map.getDiv());
+ */
+ google.maps.Map.prototype.boundsAt = function (zoom, center, projection, div) {
+ var p = projection || this.getProjection();
+ if (!p) return undefined;
+ var d = $(div || this.getDiv());
+ var zf = Math.pow(2, zoom) * 2;
+ var dw = d.getStyle('width').toInt() / zf;
+ var dh = d.getStyle('height').toInt() / zf;
+ var cpx = p.fromLatLngToPoint(center || this.getCenter());
+ return new google.maps.LatLngBounds(
+ p.fromPointToLatLng(new google.maps.Point(cpx.x - dw, cpx.y + dh)),
+ p.fromPointToLatLng(new google.maps.Point(cpx.x + dw, cpx.y - dh)));
+ }
+
+ googleMapsApiDefer.resolve();
+ });
+
+ var head = document.getElementsByTagName('head')[0];
+
+ var callbackScript = document.createElement("script");
+ callbackScript.appendChild(document.createTextNode("function googleMapsApiLoadedCallback() { window.dispatchEvent(window.googleMapsApiLoadedEvent); };"));
+
+ var googleScript = document.createElement('script');
+ googleScript.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBWyNNhRUhXxQpvR7i-Roh23PaWqi-kNdQ&callback=googleMapsApiLoadedCallback";
+
+ head.appendChild(callbackScript);
+ head.appendChild(googleScript);
+
+ return googleMapsApiDefer.promise;
+ }
+
+ });
+
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/accordeonHeader.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/accordeonHeader.tpl.html
new file mode 100755
index 00000000..21b2a28c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/accordeonHeader.tpl.html
@@ -0,0 +1,13 @@
+<div role="tab" id="{{::headingId}}" aria-selected="{{isOpen}}" class="panel-heading" ng-keypress="toggleOpen($event)">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" href aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0" class="accordion-toggle"
+ ng-click="toggleOpen()" uib-accordion-transclude="heading" ng-disabled="isDisabled" uib-tabindex-toggle>
+ <i class="pull-left fa" ng-class="{'fa-chevron-down': isOpen, 'fa-chevron-right': !isOpen}"></i>
+ <span uib-accordion-header ng-class="{'text-muted': isDisabled}">{{heading}}</span>
+ </a>
+ </h4>
+</div>
+<div id="{{::panelId}}" aria-labelledby="{{::headingId}}" aria-hidden="{{!isOpen}}" role="tabpanel" class="panel-collapse collapse"
+ uib-collapse="!isOpen">
+ <div class="panel-body" ng-transclude></div>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/clocksGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/clocksGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/clocksGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethConnectionsGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethConnectionsGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethConnectionsGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethernetView.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethernetView.tpl.html
new file mode 100755
index 00000000..7f234477
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ethernetView.tpl.html
@@ -0,0 +1,18 @@
+<uib-accordion close-others="false">
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.topologyIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Topology' | translate }}">
+ <mwtn-topology-ethernet-path-graph ng-if="vm.status.topologyIsOpen" />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.portsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Ports' | translate}}">
+ <mwtn-topology-ports-grid />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.ethConnectionsIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'ETH connections' | translate}}">
+ <mwtn-topology-eth-connections-grid />
+ </div>
+
+</uib-accordion>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/frame.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/frame.tpl.html
new file mode 100755
index 00000000..7e15cfb9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/frame.tpl.html
@@ -0,0 +1,34 @@
+<ht-header help-link='sdnr/mwtnTopology/0.4.0/README.md'></ht-header>
+<div class="owl">
+ <!-- Display a loading indicator as long as google isn't initialized. -->
+ <div class="bbg" ng-if="!vm.googleIsReady">
+ <i class="fa fa-spinner fa-pulse" aria-hidden="true"></i>
+ <span>{{'MWTN_LOADING' | translate}}</span>
+ </div>
+
+ <uib-tabset id="mwtnTopology" active="vm.activeTab" ng-if="vm.googleIsReady">
+
+ <uib-tab index="0" heading="{{'MWTN_SITE' | translate}}">
+ <mwtn-topology-site-view />
+ </uib-tab>
+
+ <uib-tab index="1" heading="{{'MWTN_AIR_INTERFACE' | translate}}">
+ <mwtn-topology-physical-view />
+ </uib-tab>
+
+ <!-- [sko] no data for TST
+ <uib-tab index="2" heading="{{'MWTN_ETHERNET' | translate}}">
+ <mwtn-topology-ethernet-view />
+ </uib-tab>
+
+ <uib-tab index="3" heading="{{'MWTN_PTP' | translate}}">
+ <mwtn-topology-ieee1588-view />
+ </uib-tab> -->
+
+ </uib-tabset>
+
+ <hr />
+ <div class="owl">
+ <span>ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+ </div>
+</div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ieee1588View.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ieee1588View.tpl.html
new file mode 100755
index 00000000..4551aa6e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ieee1588View.tpl.html
@@ -0,0 +1,18 @@
+<uib-accordion close-others="false">
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.topologyIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Graph' | translate }}">
+ <mwtn-topology-ieee1588-path-graph ng-if="vm.status.topologyIsOpen" />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.portsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Clocks' | translate}}">
+ <mwtn-topology-clocks-grid />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.ethConnectionsIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'PTP links' | translate}}">
+ <mwtn-topology-ptp-links-grid />
+ </div>
+
+</uib-accordion>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linkDetails.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linkDetails.tpl.html
new file mode 100755
index 00000000..e26979a1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linkDetails.tpl.html
@@ -0,0 +1,110 @@
+<div>
+ <uib-alert type="{{status.type}}" ng-show="status.message"> <i ng-show="status.isWorking" class="fa fa-spinner fa-pulse"></i>
+ <b><span>{{status.message}}</span></b>
+ </uib-alert>
+ <div ng-show="!status.message">
+ <p>
+ <span>Sitelink name: </span>
+ <b>{{vm.link.name || vm.link.id }}</b>
+ <br/>
+ <span>Length: </span>
+ <b> {{vm.link.length || 0 | number:3 }} </b>
+ <span> km</span>
+ <br/>
+ <span>Type: </span>
+ <b> {{vm.link.type || 'traffic' }} </b>
+ <span> </span>
+ </p>
+ <table>
+ <caption class="text-left">
+ <b>{{'SITE' | translate}} A</b>
+ </caption>
+ <tbody>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">{{'MWTN_SITE_ID' | translate}}:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteA.id}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">{{'MWTN_NAME' | translate}}:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteA.name}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">Lat/Lon:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteA.location.lat | coordinateFilter:'toDMS':'lat'}} | {{vm.link.siteA.location.lng | coordinateFilter:'toDMS':'lon'}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">Azimuth:</td>
+ <td class="text-left">
+ <b> {{vm.link.azimuthA || 0 | number:1 }} </b>
+ <span> °</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <table>
+ <caption class="text-left">
+ <b>{{'MWTN_SITE' | translate}} Z</b>
+ </caption>
+ <tbody>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">{{'MWTN_SITE_ID' | translate}}:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteZ.id}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">Site-Name:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteZ.name}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">Lat/Lon:</td>
+ <td class="text-left">
+ <b>{{vm.link.siteZ.location.lat | coordinateFilter:'toDMS':'lat'}} | {{vm.link.siteZ.location.lng | coordinateFilter:'toDMS':'lon'}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td class="text-right" style="padding-right: 5px;">Azimuth:</td>
+ <td class="text-left">
+ <b> {{vm.link.azimuthB || 0 | number:1 }} </b>
+ <span> °</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br/>
+ <br/>
+ <table class='table table-striped' ng-show="vm.link.airInterfaceLinks && vm.link.airInterfaceLinks.length">
+ <caption class="text-left">
+ <b>{{'MWTN_AIR_INTERFACE_LINKS' | translate}}</b>
+ </caption>
+ <thead>
+ <tr>
+ <th>{{'MWTN_ID' | translate}}</th>
+ <th>{{'MWTN_RADIO' | translate}}</th>
+ <th>{{'MWTN_BAND' | translate}}</th>
+ <th>{{'MWTN_POLARIZATION' | translate}}</th>
+ <th>{{'MWTN_STATUS' | translate}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="airIf in vm.link.airInterfaceLinks">
+ <td> {{ airIf.id}} </td>
+ <td> {{ airIf.radio}} </td>
+ <td> {{ airIf.bandDesignator }} </td>
+ <td> {{ airIf.polarization }} </td>
+ <td> {{ airIf.mainStatus }} </td>
+
+
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/links.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/links.tpl.html
new file mode 100755
index 00000000..8299a834
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/links.tpl.html
@@ -0,0 +1,2 @@
+<div id="mwtnNodesGrid" ui-grid="gridOptionsLinks" ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns
+ class="mwtnTopologyGrid"></div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linksGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linksGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/linksGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/maps.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/maps.tpl.html
new file mode 100755
index 00000000..71e6c0ee
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/maps.tpl.html
@@ -0,0 +1,59 @@
+<!--
+<ui-gmap-google-map bounds="mapObjects.map.bounds"
+ center="mapObjects.map.center"
+ control="mapObjects.map.control"
+ dragging="mapObjects.map.dragging"
+ events="mapObjects.map.events"
+ options="mapObjects.map.options"
+ zoom="mapObjects.map.zoom">
+
+ <ui-gmap-markers
+ models="mapObjects.sites.models"
+ idkey="marker.id"
+ fit="true"
+ coords="'self'"
+ options="'options'"
+ icon="mapObjects.sites.icon"
+ doCluster="doGoogleCluster"
+ events="mapObjects.sites.events"
+ >
+ </ui-gmap-markers>
+
+ <ui-gmap-window
+ coords="mapObjects.sites.tooltip"
+ options="mapObjects.sites.tooltipOptions"
+ show="mapObjects.sites.tooltip.show">
+ </ui-gmap-window>-->
+
+ <!-- siteLinks -->
+<!--
+ <ui-gmap-polylines
+ models="mapObjects.siteLinks.models"
+ events="mapObjects.siteLinks.events"
+ path="'path'"
+ stroke="'stroke'"
+ geodesic="'geodesic'"
+ editable="'editable'"
+ draggable="'draggable'"
+ static="true"
+ visible="mapObjects.siteLinks.visible"
+ zindex="'zIndex'"
+ >
+ </ui-gmap-polylines>
+
+</ui-gmap-google-map>-->
+
+<map center="{{mapObjects.map.center}}"
+ map-type-id=“MapTypeId.HYBRID”
+ street-view-control="false">
+
+ <marker data-ng-repeat="mapObjects.sites.models"
+ position="{{}}"
+ />
+</map>
+
+<!--
+ <sigma-topology drag-nodes="true" topology-data="topologyData" trigger-resize-sigma="triggerResizeSigma" panel="panel"
+ topology-custfunc="topologyCustfunc">
+ </sigma-toppology>
+ -->
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/networkElementsGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/networkElementsGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/networkElementsGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/nodes.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/nodes.tpl.html
new file mode 100755
index 00000000..826e7dd9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/nodes.tpl.html
@@ -0,0 +1,2 @@
+<div id="mwtnNodesGrid" ui-grid="gridOptionsNodes" ui-grid-exporter ui-grid-selection ui-grid-pinning ui-grid-resize-columns ui-grid-move-columns
+ class="mwtnTopologyGrid"></div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/physicalView.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/physicalView.tpl.html
new file mode 100755
index 00000000..dfeabe4e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/physicalView.tpl.html
@@ -0,0 +1,18 @@
+<uib-accordion close-others="false">
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.graphIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'MWTN_GRAPH' | translate }}">
+ <mwtn-topology-physical-path-graph ng-if="vm.status.graphIsOpen" />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.networkElementsIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'MWTN_AIR_INTERFACES' | translate}}">
+ <mwtn-topology-network-elements-grid />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.LinksIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'MWTN_LINKS' | translate}}">
+ <mwtn-topology-links-grid />
+ </div>
+
+</uib-accordion> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/portsGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/portsGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/portsGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ptpLinksGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ptpLinksGrid.tpl.html
new file mode 100755
index 00000000..b5d3cbc7
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/ptpLinksGrid.tpl.html
@@ -0,0 +1 @@
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteDetails.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteDetails.tpl.html
new file mode 100755
index 00000000..3a06fa8d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteDetails.tpl.html
@@ -0,0 +1,77 @@
+<div class="owl">
+ <uib-alert type="{{status.type}}" ng-show="status.message">
+ <i ng-show="status.isWorking" class="fa fa-spinner fa-pulse" aria-hidden="true"></i>
+ <b><span>{{status.message}}</span></b>
+ </uib-alert>
+ <div ng-show="!status.message">
+ <p>
+ <span>{{'MWTN_SITE_ID' | translate}}: </span>
+ <b>{{vm.site.id}}</b>
+ </p>
+ <hr />
+ <p>
+ <span>{{'MWTN_SITE_NAME' | translate}}: </span>
+ <b>{{vm.site.name}}</b>
+ <br />
+ <span>{{'MWTN_LAT_LON' | translate}}</span>
+ <b>{{ vm.site.location.lat | coordinateFilter:'toDMS':'lat'}} | {{ vm.site.location.lng | coordinateFilter:'toDMS':'lon'}}</b>
+ <br />
+ <span>{{'MWTN_AMSL_GRD' | translate}}: </span>
+ <b> {{vm.site.amslGround | number:2 }} </b>
+ <span> [m]</span>
+ <br />
+ <span>{{'MWTN_TYPE' | translate}}: </span>
+ <b> {{vm.site.type || 'pyhsical-network-function' }} </b>
+ <span> </span>
+ </p>
+ <p>
+ <b>Site-Links ({{vm.site.siteLinks.length}}): </b>
+ <span style="color: #337ab7;" class="pointer glyphicon glyphicon-plus-sign" aria-hidden="true" ng-class="{'selected-site' : createNewLinkMode}"
+ ng-show="showNewLinkButton" ng-click="toggleCreateNewLinkMode()"></span>
+ <p />
+ <table class='table table-striped' ng-show="vm.site.siteLinks.length">
+ <thead>
+ <tr>
+ <th class='text-left'>Site-Link-Name</th>
+ <th class='text-right'>Azimuth A [°]</th>
+ <th class='text-right'>Azimuth Z [°]</th>
+ <th class='text-right'>Length [km]</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat='siteLink in vm.site.siteLinks'>
+ <td class='text-left'>
+ <a href='/ux/#/siteLinks/{{siteIndex}}/{{siteLink._source.id.high}}/{{siteLink._source.id.low}}' target='htSolutions'>{{siteLink.id}}</a>
+ </td>
+ <td class='text-right'>{{ siteLink.azimuthAz | number : 1 }}</td>
+ <td class='text-right'>{{ siteLink.azimuthZa | number : 1 }}</td>
+ <td class='text-right'>{{ siteLink.length | number : 3 }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <p>
+ <b>Network elements ({{vm.site.plannedNetworkElements.length}}): </b>
+ <!--
+ <span style="color: #337ab7;" class="pointer glyphicon glyphicon-plus-sign" aria-hidden="true" ng-class="{'selected-site' : createNewLinkMode}"
+ ng-show="showNewLinkButton" ng-click="toggleCreateNewLinkMode()"></span> -->
+ <p />
+ <table class='table table-striped' ng-show="vm.site.plannedNetworkElements.length">
+ <thead>
+ <tr>
+ <th class='text-left'>{{'MWTN_ID' | translate}}</th>
+ <th class='text-left'>{{'MWTN_NAME' | translate}}</th>
+ <th class='text-left'>{{'MWTN_TYPE' | translate}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat='ne in vm.site.plannedNetworkElements'>
+ <td class='text-left'>
+ <a href='#/pnfInventory/{{ne.id}}' target='htSolutions'>{{ne.id}}</a>
+ </td>
+ <td class='text-left'>{{ ne.name }}</td>
+ <td class='text-left'>{{ ne.type }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteGrid.tpl.html
new file mode 100755
index 00000000..612fb92e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteGrid.tpl.html
@@ -0,0 +1,9 @@
+<!--<h1 style="color:#000">Here is the sites grid</h1>-->
+<div class="checkbox">
+ <label>
+ <input type="checkbox" ng-model="vm.showAllSites">
+ Show all sites
+ </label>
+</div>
+
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteLinkGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteLinkGrid.tpl.html
new file mode 100755
index 00000000..ba4f270c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteLinkGrid.tpl.html
@@ -0,0 +1,8 @@
+<div class="checkbox">
+ <label>
+ <input type="checkbox" ng-model="vm.showAllLinks">
+ Show all links
+ </label>
+</div>
+
+<div class="mwtnTopologyGrid" ui-grid="vm.gridOptions" ui-grid-pagination ui-grid-pinning ui-grid-selection ui-grid-resize-columns ui-grid-move-columns></div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/sitePathGrid.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/sitePathGrid.tpl.html
new file mode 100755
index 00000000..bc1372e6
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/sitePathGrid.tpl.html
@@ -0,0 +1 @@
+<h1 style="color:#000">Here is the site paths grid</h1>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteView.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteView.tpl.html
new file mode 100755
index 00000000..e56a2273
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/siteView.tpl.html
@@ -0,0 +1,31 @@
+<uib-accordion close-others="false">
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.siteMapIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Map (' + vm.status.loadedSitesInBoundingBox + ' of ' + vm.status.totalSitesInBoundingBox + ' sites loaded)'}}">
+
+ <mwtn-topology-map ng-if="vm.status.siteMapIsOpen" manual-map-bounds="vm.status.manualMapBounds" on-bounds-changed="vm.mapBoundsChanged(data, userOriginated)">
+ <mwtn-topology-map-sites sites="vm.visibleSites" selected-site="vm.status.site" api="vm.mapSitesComponentApi" />
+ <mwtn-topology-map-site-links site-links="vm.knownSiteLinks" selected-site-link="vm.status.siteLink"
+ api="vm.mapSiteLinksComponentApi" />
+ </mwtn-topology-map>
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.siteGridIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Sites' | translate}}">
+
+ <mwtn-topology-site-grid visible-sites="vm.visibleSites" />
+ </div>
+
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.siteLinkGridIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Site links' | translate}}">
+
+ <mwtn-topology-site-link-grid known-site-links="vm.knownSiteLinks" />
+ </div>
+
+ <!-- [sko, 2017-06-23] TODO deferred
+ <div uib-accordion-group="" class="panel-primary" is-open="vm.status.sitePathGridIsOpen" template-url="src/app/mwtnTopology/templates/accordeonHeader.tpl.html"
+ heading="{{'Site paths' | translate}}">
+
+ <mwtn-topology-site-path-grid />
+ </div> -->
+</uib-accordion>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/topology.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/topology.tpl.html
new file mode 100755
index 00000000..6a71bbf8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/mwtnTopology-module/src/main/resources/mwtnTopology/templates/topology.tpl.html
@@ -0,0 +1,2 @@
+ <sigma-topology drag-nodes="true" topology-data="topologyData" trigger-resize-sigma="triggerResizeSigma" panel="panel" topology-custfunc="topologyCustfunc">
+ </sigma-toppology>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/pom.xml
new file mode 100644
index 00000000..0131f51c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/mwtnTopology/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtn</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtnTopology</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>mwtnTopology-module</module>
+ <module>mwtnTopology-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/pom.xml
new file mode 100644
index 00000000..87ebbd3c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>odlChat</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>odlChat-bundle</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>odlChat-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>odlChat-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..ad015bd2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="odlChat"/>
+ <property name="url" value="/src/app/odlChat"/>
+ <property name="directory" value="/odlChat"/>
+ <property name="requireJs" value="app/odlChat/odlChat.module"/>
+ <property name="angularJs" value="app.odlChat"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/odlChat/odlChat-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/pom.xml
new file mode 100644
index 00000000..730c40b1
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>odlChat</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>odlChat-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/logo_chat.gif b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/logo_chat.gif
new file mode 100644
index 00000000..deb44fd2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/logo_chat.gif
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat-custom.css
new file mode 100644
index 00000000..4d9f8d24
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat-custom.css
@@ -0,0 +1,3 @@
+/**
+ * Add your application related css here
+ */ \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.controller.js
new file mode 100644
index 00000000..310e05d5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.controller.js
@@ -0,0 +1,69 @@
+/*
+ * 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/odlChat/odlChat.module', 'app/odlChat/odlChat.services' ],
+ function(odlChatApp) {
+
+ var main = function($scope, $rootScope, $odlChat) {
+
+ $rootScope.section_logo = 'src/app/odlChat/odlChat.png';
+
+ $scope.collection = [];
+ $scope.chat = {
+ nickname : 'anonymous',
+ message : "Hey, what's up?!"
+ };
+
+ var listenToNotifications = function(socketLocation) {
+ try {
+ var notificatinSocket = new WebSocket(socketLocation);
+
+ notificatinSocket.onmessage = function(event) {
+ // we process our received event here
+ $odlChat.getData(event, function(info, tweet) {
+ $scope.collection.push(tweet);
+ if ($scope.collection.length > 20) {
+ $scope.collection.shift();
+ }
+
+ $scope.chat.message = info;
+ });
+ };
+ notificatinSocket.onerror = function(error) {
+ console.log("Socket error: " + JSON.stringify(error));
+ };
+ notificatinSocket.onopen = function(event) {
+ console.log("Socket connection opened.");
+ };
+ notificatinSocket.onclose = function(event) {
+ console.log("Socket connection closed.");
+ };
+ // if there is a problem on socket creation we get
+ // exception (i.e. when socket address is incorrect)
+ } catch (e) {
+ alert("Error when creating WebSocket" + e);
+ }
+ };
+
+ $scope.send = function(chat) {
+ $odlChat.send(chat, function(info) {
+ console.log(info);
+ });
+ };
+
+ var path = "/opendaylight-inventory:nodes/opendaylight-inventory:node[opendaylight-inventory:id='odlChat']";
+ $odlChat.register(path, function(socketLocation) {
+ listenToNotifications(socketLocation);
+ });
+ };
+
+ odlChatApp.register.controller('odlChatCtrl', [ '$scope', '$rootScope',
+ '$odlChat', main ]);
+
+ }); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.module.js
new file mode 100644
index 00000000..6bd5387f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.module.js
@@ -0,0 +1,50 @@
+/*
+ * 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'], function(ng) {
+ var odlChatApp = angular.module('app.odlChat', ['app.core', 'ui.router.state','config']);
+
+ odlChatApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ odlChatApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/odlChat/odlChat.controller');
+ NavHelperProvider.addToMenu('odlChat', {
+ "link" : "#/odlChat",
+ "active" : "main.odlChat",
+ "title" : "Chat",
+ "icon" : "fa-comments", // Add navigation icon css class here
+ "page" : {
+ "title" : "Chat",
+ "description" : "odlChat"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.odlChat', {
+ url: 'odlChat',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/odlChat/odlChat.tpl.html',
+ controller: 'odlChatCtrl'
+ }
+ }
+ });
+
+ });
+
+ return odlChatApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.png
new file mode 100755
index 00000000..3b79097e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.services.js
new file mode 100644
index 00000000..1a137f5c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.services.js
@@ -0,0 +1,103 @@
+/*
+ * 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/odlChat/odlChat.module'],function(odlChatApp) {
+
+ odlChatApp.register.factory('$odlChat', function($http, $mwtnCommons) {
+
+ var createStream = function(streamName, callback) {
+ var request = {
+ method : 'GET',
+ url : [ service.base, 'streams/stream/', streamName ].join('')
+ };
+ $http(request).then(function successCallback(response) {
+ console.log(response.headers('Location'));
+ callback(response.headers('Location'));
+ }, function errorCallback(response) {
+ console.error(JSON.stringify(response));
+ callback();
+ });
+ };
+
+ var service = {
+ base : window.location.origin + "/restconf/",
+ };
+
+
+ service.getData = function(event, callback) {
+
+ var request = {
+ method : 'GET',
+ url : [ service.base,
+ 'config/opendaylight-inventory:nodes/node/odlChat/' ].join('')
+ };
+ $http(request).then(function successCallback(response) {
+ tweet = {
+ nickname : response.data.node[0]['flow-node-inventory:manufacturer'],
+ message : response.data.node[0]['flow-node-inventory:description'],
+ time : JSON.stringify(new Date()).split('T')[1].substring(0, 5)
+ };
+ callback('', tweet);
+ }, function errorCallback(response) {
+ console.error(JSON.stringify(response));
+ callback('ERROR while sending ;(');
+ });
+
+ };
+
+ service.register = 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) {
+ createStream(response.data.output['stream-name'], function(
+ socketLocation) {
+ callback(socketLocation);
+ });
+ }, function errorCallback(response) {
+ console.error(JSON.stringify(response));
+ });
+ };
+
+ service.send = function(chat, callback) {
+ var request = {
+ method : 'PUT',
+ url : [ service.base,
+ 'config/opendaylight-inventory:nodes/node/odlChat' ].join(''),
+ data : {
+ "node" : [ {
+ "id" : "odlChat",
+ "flow-node-inventory:manufacturer" : chat.nickname,
+ "flow-node-inventory:software" : "",
+ "flow-node-inventory:serial-number" : "",
+ "flow-node-inventory:hardware" : "",
+ "flow-node-inventory:description" : chat.message
+ } ]
+ }
+ };
+ $http(request).then(function successCallback(response) {
+ callback('send successfully');
+ }, function errorCallback(response) {
+ console.error(JSON.stringify(response));
+ callback('ERROR while sending ;(');
+ });
+ };
+ return service;
+ });
+}); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.tpl.html
new file mode 100644
index 00000000..c3d90ae3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/odlChat-module/src/main/resources/odlChat/odlChat.tpl.html
@@ -0,0 +1,102 @@
+<!-- This is the landing page of you application, Update the content as per your requirements -->
+<div class="owl container" style="width: 800px">
+
+ <div class="row">
+ <div class="col-md-11">
+ <h4>Simple chat application based on (ODL) WebSockets</h4>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-11">
+ <hr/ >
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-11">
+ <p>
+ <span class="white">The beauty of WebSockets within OpenDaylight.</span>
+ </p>
+ <p>
+ <span class="white">Useful links:</span>
+ <ul>
+ <li>
+ <a href="https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf:Change_event_notification_subscription">
+ <span class="white">https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf:Change_event_notification_subscription</span>
+ </a>
+ </li>
+ <li>
+ <a href="https://wiki.opendaylight.org/view/OpenDaylight_DLUX:Create_application_with_archetype">
+ <span class="white">https://wiki.opendaylight.org/view/OpenDaylight_DLUX:Create_application_with_archetype</span>
+ </a>
+ </li>
+ </ul>
+ </p>
+ <p>
+ <span class="white">Code:</span>
+ <ul>
+ <li>
+ <a href="https://github.com/OpenNetworkingFoundation/CENTENNIAL/tree/master/code/ux/odlChat">
+ <span class="white">https://github.com/OpenNetworkingFoundation/CENTENNIAL/tree/master/code/ux/odlChat</span>
+ </a>
+ </li>
+ </ul>
+ </p>
+
+
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-11">
+ <hr/ >
+ </div>
+ </div>
+
+ <div class="row" ng-repeat="tweet in collection">
+ <div class="col-md-2 text-right">
+ <span class="white">{{tweet.nickname}}:</span>
+ </div>
+ <div class="col-md-8">
+ <span class="white">
+ <b>{{tweet.message}}</b>
+ </span>
+ </div>
+ <div class="col-md-1">
+ <span>{{tweet.time}}</span>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-11">
+ <hr/ >
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <input class="form-control" type="text" step="1" ng-model="chat.nickname" />
+ </div>
+ <div class="col-md-8 text-right">
+ <input class="form-control" type="text" step="1" ng-model="chat.message" />
+ </div>
+ <div class="col-md-1">
+ <button class="btn btn-primary" type="submit" ng-click="send(chat)">{{'MWTN_SEND' | translate}}</button>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-2 text-right">
+ <span class="white">{{'MWTN_NICKNAME' | translate}} </span>
+ </div>
+ <div class="col-md-8 text-right">
+ <span class="white">{{'MWTN_MESSAGE' | translate}} </span>
+ </div>
+ <div class="col-md-1"></div>
+ </div>
+</div>
+<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/odlChat/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/pom.xml
new file mode 100644
index 00000000..f81b02ed
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/odlChat/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>odlChat</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>odlChat-module</module>
+ <module>odlChat-bundle</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/pom.xml
new file mode 100644
index 00000000..3a409fe8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapAai</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapAai-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapAai-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>onapAai-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..1a2ab2ed
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="onapAai"/>
+ <property name="url" value="/src/app/onapAai"/>
+ <property name="directory" value="/onapAai"/>
+ <property name="requireJs" value="app/onapAai/onapAai.module"/>
+ <property name="angularJs" value="app.onapAai"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/onapAai/onapAai-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/pom.xml
new file mode 100644
index 00000000..6c2eef33
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapAai</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapAai-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/images/onapAai.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/images/onapAai.png
new file mode 100755
index 00000000..a3724882
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/images/onapAai.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai-custom.css
new file mode 100644
index 00000000..fc314684
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai-custom.css
@@ -0,0 +1,58 @@
+/**
+ * Add your application related css here
+ */
+.onapAaiGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.onapAaiGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.onapAaiGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.onapAaiGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.onapAaiGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.onapAaiGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.controller.js
new file mode 100644
index 00000000..6c5685e9
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.controller.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/onapAai/onapAai.module',
+ 'app/onapAai/onapAai.services'],
+ function (onapAaiApp) {
+
+ onapAaiApp.register.controller('onapAaiCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$onapAai', '$mwtnLog',
+ function (uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $onapAai, $mwtnLog) {
+
+ var COMPONENT = 'onapAaiCtrl';
+ $mwtnLog.info({ component: COMPONENT, message: 'onapAaiCtrl started!' });
+
+ $rootScope.section_logo = 'src/app/onapAai/images/onapAai.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $onapAai.highlightFilteredHeader;
+
+ // Grid
+ $scope.gridOptions = JSON.parse(JSON.stringify($onapAai.gridOptions));
+ $scope.gridOptions.columnDefs = [
+ { field: 'pnf-id', type: 'string', displayName: 'ID', headerCellClass: $scope.highlightFilteredHeader, width: 170 },
+ { field: 'pnf-name', type: 'string', displayName: 'Name', headerCellClass: $scope.highlightFilteredHeader, width: 200 },
+ { field: 'equip-type', type: 'string', displayName: 'Type', headerCellClass: $scope.highlightFilteredHeader, width: 160 },
+ { field: 'equip-vendor', type: 'string', displayName: 'Vendor', headerCellClass: $scope.highlightFilteredHeader, width: 100 },
+ { field: 'equip-model', type: 'string', displayName: 'Model', headerCellClass: $scope.highlightFilteredHeader, width: 160 },
+ { field: 'ipaddress-v4-oam', type: 'string', displayName: 'If OAM', headerCellClass: $scope.highlightFilteredHeader, width: 140 },
+ { field: 'in-maint', type: 'string', displayName: 'Maintenance', headerCellClass: $scope.highlightFilteredHeader, width: 100 },
+ { field: 'interfaces', type: 'string', displayName: '#p-interfaces', headerCellClass: $scope.highlightFilteredHeader, width: 100, visible: false },
+ { field: 'resourceVersion', type: 'string', displayName: 'Resource version', headerCellClass: $scope.highlightFilteredHeader, width: 100, visible: false }
+ ];
+
+ $onapAai.getAaiPnfs().then(function(success){
+ $scope.gridOptions.data = success.data.pnf;
+ $scope.gridOptions.data.map(function(item){
+ item.interfaces = 1;
+ });
+ }, function(error) {
+ console.log('error');
+ $scope.error = error;
+ });
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.module.js
new file mode 100644
index 00000000..a3deb333
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var onapAaiApp = angular.module('app.onapAai', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ onapAaiApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ onapAaiApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/onapAai/onapAai.controller');
+ NavHelperProvider.addToMenu('onapAai', {
+ "link" : "#/onapAai/",
+ "active" : "main.onapAai",
+ "title" : "ONAP AAI",
+ "icon" : "fa fa-th", // Add navigation icon css class here
+ "page" : {
+ "title" : "ONAP AAI",
+ "description" : "Open Network Automation Platform (ONAP) - Active and Available Inventory (AAI)"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.onapAai', {
+ url: 'onapAai/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/onapAai/onapAai.tpl.html',
+ controller: 'onapAaiCtrl'
+ }
+ }
+ });
+
+ });
+
+ return onapAaiApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.services.js
new file mode 100644
index 00000000..dfbbf473
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.services.js
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/onapAai/onapAai.module', 'app/mwtnCommons/mwtnCommons.services'], function (onapAaiApp) {
+
+ onapAaiApp.register.factory('$onapAai', function ($q, $http, Base64, $mwtnCommons, $mwtnDatabase, $mwtnLog, Device) {
+
+ var service = {};
+
+ var functionId = "mwtn";
+ var docType = "device";
+ var from = 0;
+ var size = 9999;
+ var sort = undefined;
+ var deviceLookup = {};
+ $mwtnDatabase.getAllData(functionId, docType, from, size, sort).then(
+ function successCallback(response) {
+ response.data.hits.hits.map(function(device){
+ deviceLookup[device._id] = new Device(device._source);
+ });
+ }, function errorCallback(response) {
+ deviceLookup = {};
+ });
+
+ service.checkModules = $mwtnCommons.checkModules;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.formatData = $mwtnCommons.formatData;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.deleteDocType = $mwtnDatabase.deleteDocType;
+
+
+ var transactionId = 1;
+ var getHeaders = function () {
+ return {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ 'X-TransactionId': transactionId++
+ }
+ };
+
+ // create or modify a pnf in aai
+ service.createPnf = function (pnfId, doc) {
+ var base = window.location.origin;
+ var getIp = function (extension) {
+ return extension.filter(function (item) {
+ return item['value-name'] === 'neIpAddress';
+ }).map(function (item) {
+ return item.value;
+ })[0];
+ }
+
+ var device = deviceLookup[pnfId];
+ if (!device) device = new Device({"id":pnfId,"name":pnfId,"mediator-ipv4":"127.0.0.1","netconf-port":"830","oam-ipv4":"127.0.0.1","site":"unknown","controller":"this","controller-site":"unknown","vendor":"unknown","type":"unknown","model":"unknown","version":"0.0"});
+ var data = {
+ "pnf-name": pnfId,
+ "pnf-id": doc.connect.host + ':' + doc.connect.port,
+ "equip-type": device.getType(),
+ "equip-model": device.getModel(),
+ "equip-vendor": device.getVendor(),
+ "ipaddress-v4-oam": getIp(doc['core-model:network-element'].extension) | doc.connect.host,
+ "in-maint": false
+ };
+ console.info('pnf', data);
+ var request = {
+ method: 'PUT',
+ url: base + '/aai/network/pnfs/pnf/' + pnfId, // to es config
+ // withCredentials: true,
+ headers: getHeaders(),
+ data: data
+ };
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ service.deletePnf = function (pnfId) {
+ // curl -X DELETE http://localhost:8282/aai/network/pnfs/pnf/Ericsson-A1 --insecure -v -u AAI:AAI -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-FromAppId: SDNR' -H 'X-TransactionId: 9999'
+ var base = window.location.origin;
+ var request = {
+ method: 'DELETE',
+ url: base + '/aai/network/pnfs/pnf/' + pnfId, // to es config
+ // withCredentials: true,
+ headers: getHeaders()
+ };
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ service.getAaiPnfs = function () {
+ // curl https://10.31.1.55:8443/network/pnfs -k -v -u abc:def -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-FromAppId: SDNR' -H 'X-TransactionId: 9999'
+
+ var base = window.location.origin;
+ var request = {
+ method: 'GET',
+ url: base + '/aai/network/pnfs', // to es config
+ // withCredentials: true,
+ headers: getHeaders(),
+ };
+
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ return service;
+ });
+
+ // Class Device
+ onapAaiApp.register.factory('Device', function () {
+ var Device = function (data) {
+ if (!data) {
+ data = {id:new Date(), type: 'unknown', name:'unknonw', model: 'unkonwn', vendor:'unknonw', version:'unkonwn'};
+ }
+ this.data = data;
+ this.getData = function () {
+ return this.data;
+ };
+ this.getId = function () {
+ return this.getData().id;
+ };
+ this.getType = function () {
+ return this.getData().type;
+ };
+ this.getName = function () {
+ return this.getData().name;
+ };
+ this.getModel = function () {
+ return this.getData().model;
+ };
+ this.getVendor = function () {
+ return this.getData().vendor;
+ };
+ this.getVersion = function () {
+ return this.getData().version;
+ };
+ };
+ return Device;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.tpl.html
new file mode 100644
index 00000000..c121b6d5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/onapAai-module/src/main/resources/onapAai/onapAai.tpl.html
@@ -0,0 +1,12 @@
+<ht-header help-link='sdnr/onapAai/0.4.0/README.md'></ht-header>
+<pre ng-if="error">{{ error | json }}</pre>
+
+
+<div id="onapAaiGrid" ui-grid="gridOptions" ui-grid-exporter ui-grid-selection ui-grid-pinning
+ ui-grid-resize-columns ui-grid-move-columns class="onapAaiGrid" ng-if="!error"></div>
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/pom.xml
new file mode 100644
index 00000000..6049029a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapAai/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapAai</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>onapAai-module</module>
+ <module>onapAai-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/pom.xml
new file mode 100644
index 00000000..ca91f481
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapDcae</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapDcae-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapDcae-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>onapDcae-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..18c3ba0e
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="onapDcae"/>
+ <property name="url" value="/src/app/onapDcae"/>
+ <property name="directory" value="/onapDcae"/>
+ <property name="requireJs" value="app/onapDcae/onapDcae.module"/>
+ <property name="angularJs" value="app.onapDcae"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/onapDcae/onapDcae-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/pom.xml
new file mode 100644
index 00000000..63916944
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapDcae</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapDcae-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onap-5g-architecture.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onap-5g-architecture.png
new file mode 100755
index 00000000..368bdd47
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onap-5g-architecture.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onapDcae.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onapDcae.png
new file mode 100755
index 00000000..a7f1dc25
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/images/onapDcae.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae-custom.css
new file mode 100644
index 00000000..ff7de9a0
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae-custom.css
@@ -0,0 +1,58 @@
+/**
+ * Add your application related css here
+ */
+.onapDcaeGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.onapDcaeGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.onapDcaeGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.onapDcaeGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.onapDcaeGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.onapDcaeGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.controller.js
new file mode 100644
index 00000000..565ce3a2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.controller.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/onapDcae/onapDcae.module',
+ 'app/onapDcae/onapDcae.services'],
+ function (onapDcaeApp) {
+
+ onapDcaeApp.register.controller('onapDcaeCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$onapDcae', '$mwtnLog',
+ function (uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $onapDcae, $mwtnLog) {
+
+ var COMPONENT = 'onapDcaeCtrl';
+ $mwtnLog.info({ component: COMPONENT, message: 'onapDcaeCtrl started!' });
+
+ $rootScope.section_logo = 'src/app/onapDcae/images/onapDcae.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.module.js
new file mode 100644
index 00000000..579d740c
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var onapDcaeApp = angular.module('app.onapDcae', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ onapDcaeApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ onapDcaeApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/onapDcae/onapDcae.controller');
+ NavHelperProvider.addToMenu('onapDcae', {
+ "link" : "#/onapDcae/",
+ "active" : "main.onapDcae",
+ "title" : "ONAP DCAE",
+ "icon" : "fa fa-line-chart", // Add navigation icon css class here
+ "page" : {
+ "title" : "ONAP DCAE",
+ "description" : "Open Network Automation Platform (ONAP) - Data Collection, Analytics and Events (DCAE)"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.onapDcae', {
+ url: 'onapDcae/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/onapDcae/onapDcae.tpl.html',
+ controller: 'onapDcaeCtrl'
+ }
+ }
+ });
+
+ });
+
+ return onapDcaeApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.services.js
new file mode 100644
index 00000000..ad875c6a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.services.js
@@ -0,0 +1,20 @@
+/*
+ * 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/onapDcae/onapDcae.module', 'app/mwtnCommons/mwtnCommons.services'], function (onapDcaeApp) {
+
+ onapDcaeApp.register.factory('$onapDcae', function ($q, $http, Base64, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.tpl.html
new file mode 100644
index 00000000..144bccc5
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/onapDcae-module/src/main/resources/onapDcae/onapDcae.tpl.html
@@ -0,0 +1,13 @@
+<ht-header help-link='sdnr/onapDcae/0.4.0/README.md'></ht-header>
+
+
+<h3>5G Architecture</h3>
+<img src="src/app/onapDcae/images/onap-5g-architecture.png" class="img-rounded" alt="5G Architecture" width"1200">
+
+<h1 style="margin-top: -440px; color: red; transform: rotate(-30deg);">Candidate for ONAP Beijing PoC June25</h1>
+<br/><br/><br/><br/><br/>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/pom.xml
new file mode 100644
index 00000000..b32c1efc
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapDcae/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapDcae</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>onapDcae-module</module>
+ <module>onapDcae-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/pom.xml
new file mode 100644
index 00000000..dd43c81d
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapSo</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapSo-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapSo-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>onapSo-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..e44af850
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="onapSo"/>
+ <property name="url" value="/src/app/onapSo"/>
+ <property name="directory" value="/onapSo"/>
+ <property name="requireJs" value="app/onapSo/onapSo.module"/>
+ <property name="angularJs" value="app.onapSo"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/onapSo/onapSo-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/pom.xml
new file mode 100644
index 00000000..f5d04d8f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>onapSo</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>onapSo-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onap-end-to-end-slicing.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onap-end-to-end-slicing.png
new file mode 100755
index 00000000..c798dc1a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onap-end-to-end-slicing.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onapSo.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onapSo.png
new file mode 100755
index 00000000..f2a595f3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/images/onapSo.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo-custom.css
new file mode 100644
index 00000000..f2aaeb7b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo-custom.css
@@ -0,0 +1,78 @@
+/**
+ * Add your application related css here
+ */
+
+ .app-onapSo * {
+ box-sizing: border-box;
+}
+
+.app-onapSo .col {
+height: 70px;
+width: 12.5%;
+float: left;
+padding: 15px;
+}
+
+.app-onapSo .row::after {
+ content: "";
+ clear: both;
+ display: table;
+}
+
+
+
+.onapSoGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.onapSoGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.onapSoGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.onapSoGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.onapSoGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.onapSoGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.controller.js
new file mode 100644
index 00000000..cb07fc78
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.controller.js
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/onapSo/onapSo.module',
+ 'app/onapSo/onapSo.services'],
+ function (onapSoApp) {
+
+ onapSoApp.register.controller('onapSoCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$onapSo', '$mwtnLog',
+ function (uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $onapSo, $mwtnLog) {
+
+ var COMPONENT = 'onapSoCtrl';
+ $mwtnLog.info({ component: COMPONENT, message: 'onapSoCtrl started!' });
+
+ $rootScope.section_logo = 'src/app/onapSo/images/onapSo.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $onapSo.highlightFilteredHeader;
+
+ $scope.pnf = {
+ pnfName: { id: 'pnfName', labelId: 'PNF_NAME', value: 'New-PNF' },
+ pnfId: { id: 'pnfId', labelId: 'PNF_IDENTIFIER', value: 'New-PNF network unique identifier' },
+ equipType: { id: 'equipType', labelId: 'PNF_EQUIPMENT_TYPE', value: 'Fancy equipment type' },
+ equipModel: { id: 'equipModel', labelId: 'PNF_EQUIPMENT_MODEL', value: 'Best in class' },
+ equipVendor: { id: 'equipVendor', labelId: 'PNF_EQUIPMENT_VENDOR', value: 'ONAP SDN-R Community' },
+ ipaddressV4Oam: { id: 'ipaddressV4Oam', labelId: 'PNF_IPv4ADDRESS', value: '10.10.10.10' },
+ inMaintenance: { id: 'inMaintenance', labelId: 'PNF_MAINTENANCE_MODE', value: false },
+ resourceVersion: { id: 'resourceVersion', labelId: 'PNF_RESOURCE_VERSION', value: '' }
+ }
+
+ $scope.createPnfInAai = function () {
+
+ var data = {
+ "pnf-name": $scope.pnf.pnfName.value,
+ "pnf-id": $scope.pnf.pnfId.value,
+ "equip-type": $scope.pnf.equipType.value,
+ "equip-model": $scope.pnf.equipModel.value,
+ "equip-vendor": $scope.pnf.equipVendor.value,
+ "ipaddress-v4-oam": $scope.pnf.ipaddressV4Oam.value,
+ "in-maint": $scope.pnf.inMaintenance.value
+ }
+
+ $onapSo.createPnf(data).then(function (response) {
+ console.info('successfully created: ', data['pnf-name']);
+ $onapSo.getPnf(data).then(function (success) {
+ // console.info('success', JSON.stringify(success.data));
+ $scope.pnf.resourceVersion.value = success.data['resource-version'];
+ }, function (error) {
+ console.log('error1', JSON.stringify(error.data));
+ $scope.error = error;
+ });
+ }, function (error) {
+ console.log('error2', JSON.stringify(error.data));
+ $scope.error = error;
+ });
+ }
+
+ $scope.deletePnfInAai = function () {
+ var data = {
+ "pnf-name": $scope.pnf.pnfName.value,
+ }
+ $onapSo.getPnf(data).then(function (success) {
+ console.info('success', JSON.stringify(success.data));
+ $scope.pnf.resourceVersion.value = success.data['resource-version'];
+ data['resource-version'] = success.data['resource-version'];
+ $onapSo.deletePnf(data).then(function (success) {
+ console.info('success', JSON.stringify(success));
+ $scope.pnf.resourceVersion.value = success.data['resource-version'];
+ }, function (error) {
+ console.log('error', JSON.stringify(error.data));
+ $scope.error = error;
+ });
+ }, function (error) {
+ console.log('error', JSON.stringify(error.data));
+ $scope.error = error;
+ });
+ }
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.module.js
new file mode 100644
index 00000000..b2bfec44
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var onapSoApp = angular.module('app.onapSo', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ onapSoApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ onapSoApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/onapSo/onapSo.controller');
+ NavHelperProvider.addToMenu('onapSo', {
+ "link" : "#/onapSo/",
+ "active" : "main.onapSo",
+ "title" : "ONAP SO",
+ "icon" : "fa fa-music", // Add navigation icon css class here
+ "page" : {
+ "title" : "ONAP SO",
+ "description" : "Open Network Automation Platform (ONAP) - Master Service Orchestrator (MSO)"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.onapSo', {
+ url: 'onapSo/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/onapSo/onapSo.tpl.html',
+ controller: 'onapSoCtrl'
+ }
+ }
+ });
+
+ });
+
+ return onapSoApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.services.js
new file mode 100644
index 00000000..3e14e7c2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.services.js
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/onapSo/onapSo.module', 'app/mwtnCommons/mwtnCommons.services'], function (onapSoApp) {
+
+ onapSoApp.register.factory('$onapSo', function ($q, $http, Base64, $mwtnCommons, $mwtnDatabase, $mwtnLog, Device) {
+
+ var service = {};
+
+ var functionId = "mwtn";
+ var docType = "device";
+ var from = 0;
+ var size = 9999;
+ var sort = undefined;
+ var deviceLookup = {};
+ $mwtnDatabase.getAllData(functionId, docType, from, size, sort).then(
+ function successCallback(response) {
+ response.data.hits.hits.map(function(device){
+ deviceLookup[device._id] = new Device(device._source);
+ });
+ }, function errorCallback(response) {
+ deviceLookup = {};
+ });
+
+ service.checkModules = $mwtnCommons.checkModules;
+ service.getMwtnWebSocketUrl = $mwtnCommons.getMwtnWebSocketUrl;
+ service.gridOptions = $mwtnCommons.gridOptions;
+ service.formatData = $mwtnCommons.formatData;
+ service.formatTimeStamp = $mwtnCommons.formatTimeStamp;
+ service.deleteDocType = $mwtnDatabase.deleteDocType;
+
+
+ var transactionId = 1;
+ var getHeaders = function () {
+ return {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ 'X-TransactionId': transactionId++
+ }
+ };
+
+ // create or modify a pnf in aai
+ service.createPnf = function (pnf) {
+ var base = window.location.origin;
+ var request = {
+ method: 'PUT',
+ url: base + '/aai/network/pnfs/pnf/' + pnf['pnf-name'],
+ // withCredentials: true,
+ headers: getHeaders(),
+ data: pnf
+ };
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ service.deletePnf = function (pnf) {
+ // curl -X DELETE http://localhost:8282/aai/network/pnfs/pnf/Ericsson-A1 --insecure -v -u AAI:AAI -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-FromAppId: SDNR' -H 'X-TransactionId: 9999'
+ var base = window.location.origin;
+ var request = {
+ method: 'DELETE',
+ url: base + '/aai/network/pnfs/pnf/' + pnf['pnf-name'] + '/?resource-version=' + pnf['resource-version'],
+ // withCredentials: true,
+ headers: getHeaders()
+ };
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ service.getPnf = function (pnf) {
+
+ console.log('get', JSON.stringify(pnf));
+ var base = window.location.origin;
+ var request = {
+ method: 'GET',
+ url: base + '/aai/network/pnfs/pnf/' + pnf['pnf-name'],
+ // withCredentials: true,
+ headers: getHeaders()
+ };
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ service.getAaiPnfs = function () {
+ // curl https://10.31.1.55:8443/network/pnfs -k -v -u abc:def -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'X-FromAppId: SDNR' -H 'X-TransactionId: 9999'
+
+ var base = window.location.origin;
+ var request = {
+ method: 'GET',
+ url: base + '/aai/network/pnfs', // to es config
+ // withCredentials: true,
+ headers: getHeaders(),
+ };
+
+ var deferred = $q.defer();
+ $http(request).then(function successCallback(response) {
+ deferred.resolve(response);
+ }, function errorCallback(response) {
+ deferred.reject(response);
+ });
+
+ return deferred.promise;
+ };
+
+ return service;
+ });
+
+ // Class Device
+ onapSoApp.register.factory('Device', function () {
+ var Device = function (data) {
+ if (!data) {
+ data = {id:new Date(), type: 'unknown', name:'unknonw', model: 'unkonwn', vendor:'unknonw', version:'unkonwn'};
+ }
+ this.data = data;
+ this.getData = function () {
+ return this.data;
+ };
+ this.getId = function () {
+ return this.getData().id;
+ };
+ this.getType = function () {
+ return this.getData().type;
+ };
+ this.getName = function () {
+ return this.getData().name;
+ };
+ this.getModel = function () {
+ return this.getData().model;
+ };
+ this.getVendor = function () {
+ return this.getData().vendor;
+ };
+ this.getVersion = function () {
+ return this.getData().version;
+ };
+ };
+ return Device;
+ });
+
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.tpl.html
new file mode 100644
index 00000000..777e2713
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/onapSo-module/src/main/resources/onapSo/onapSo.tpl.html
@@ -0,0 +1,103 @@
+<ht-header help-link='sdnr/onapSo/0.4.0/README.md'></ht-header>
+
+<!--
+"pnf-name": "@pnfId@",
+"pnf-id": "@pnfId@",
+"equip-type": "@type@",
+"equip-model": "@model@",
+"equip-vendor": "@vendor@",
+"ipaddress-v4-oam": "@oamIp@",
+"in-maint": true,
+-->
+
+<div class="app-onapSo container owl">
+
+ <div class="row">
+
+ <div class="col-md-12">
+ <h3>Design Phase</h3>
+ <h4>Create PNF via SO in A&amp;AI</h4>
+ </div>
+
+ </div>
+ <div class="row">
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.pnfName.id }}">{{ pnf.pnfName.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.pnfName.id }}" ng-model="pnf.pnfName.value">
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.pnfId.id }}">{{ pnf.pnfId.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.pnfId.id }}" ng-model="pnf.pnfId.value">
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.equipType.id }}">{{ pnf.equipType.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.equipType.id }}" ng-model="pnf.equipType.value">
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.equipModel.id }}">{{ pnf.equipModel.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.equipModel.id }}" ng-model="pnf.equipModel.value">
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.equipVendor.id }}">{{ pnf.equipVendor.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.equipVendor.id }}" ng-model="pnf.equipVendor.value">
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.ipaddressV4Oam.id }}">{{ pnf.ipaddressV4Oam.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.ipaddressV4Oam.id }}" ng-model="pnf.ipaddressV4Oam.value">
+ </div>
+
+ <div class="col-md-3 form-check">
+ <input type="checkbox" class="form-check-input" id="{{ pnf.inMaintenance.id }}" ng-model="pnf.inMaintenance.value">
+ <label class="form-check-label" for="{{ pnf.inMaintenance.id }}">
+ <span>{{ pnf.inMaintenance.labelId | translate }}</span>
+ </label>
+ </div>
+
+ <div class="col-md-3 form-group">
+ <label for="{{ pnf.resourceVersion.id }}">{{ pnf.resourceVersion.labelId | translate }}</label>
+ <br/>
+ <input type="text" class="form-control" id="{{ pnf.resourceVersion.id }}" ng-model="pnf.resourceVersion.value">
+ </div>
+
+ </div>
+
+ <div class="row">
+
+ <div class="col-md-12">
+ <button type="button" class="btn btn-primary" ng-click="createPnfInAai()">
+ <i class="fa fa-plus" aria-hidden="true"></i>
+ <span>{{'PNF_CREATE_IN_AAI' | translate}}</span>
+ </button>
+ </div>
+
+ </div>
+ <!-- api gateway must be enhanced to support query
+ <div class="row">
+
+ <div class="col-md-12">
+ <button type="button" class="btn btn-danger" ng-click="deletePnfInAai()">
+ <i class="fa fa-minus" aria-hidden="true"></i>
+ <span>{{'PNF_DELETE_IN_AAI' | translate}}</span>
+ </button>
+ </div>
+
+ </div>-->
+
+</div>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/pom.xml
new file mode 100644
index 00000000..6dc13ae8
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/onapSo/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>onapSo</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>onapSo-module</module>
+ <module>onapSo-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/pom.xml
new file mode 100644
index 00000000..25624e32
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>otnBrowser</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>otnBrowser-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <name>${prefix} ${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${osgi.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${apache.felix.compendium}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>${dlux.loader.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>otnBrowser-module</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <!--loader Resources -->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <includeArtifactIds>otnBrowser-module</includeArtifactIds>
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <!- - here the phase you need - ->
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>../../deploy</outputDirectory>
+ <resources>
+ <resource>
+ <directory>target</directory>
+ <includes>
+ <include>${project.artifactId}-${project.version}.jar</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..745b231b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="otnBrowser"/>
+ <property name="url" value="/src/app/otnBrowser"/>
+ <property name="directory" value="/otnBrowser"/>
+ <property name="requireJs" value="app/otnBrowser/otnBrowser.module"/>
+ <property name="angularJs" value="app.otnBrowser"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/otnBrowser/otnBrowser-custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/pom.xml
new file mode 100644
index 00000000..78e9affb
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>otnBrowser</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>otnBrowser-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <packaging>jar</packaging>
+</project> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/images/otnBrowser.png b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/images/otnBrowser.png
new file mode 100755
index 00000000..f7538980
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/images/otnBrowser.png
Binary files differ
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser-custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser-custom.css
new file mode 100644
index 00000000..e2123e95
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser-custom.css
@@ -0,0 +1,58 @@
+/**
+ * Add your application related css here
+ */
+.otnBrowserGrid {
+ height: 600px;
+ background-color: white;
+}
+
+.otnBrowserGrid span {
+ color: #393939;
+}
+.ht-pagination span {
+ color: #393939;
+}
+.ht-pagination span.dark {
+ color: #393939;
+}
+.dark {
+ color: #393939;
+}
+
+
+
+.otnBrowserGrid div.debug {
+ color: #393939;
+ background-color: white;
+}
+.otnBrowserGrid div.error {
+ color: #ff0000;
+ background-color: #ffeeee;
+ font-weight: bold;
+}
+
+.otnBrowserGrid div.info {
+ color: #3276b1;
+ background-color: #eeeeff;
+}
+
+.otnBrowserGrid div.warning {
+ color: #ffa500;
+ background-color: #ffeedd;
+}
+
+.rotated {
+ transform: rotate(180deg);
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ -moz-transform: rotate(180deg);
+ -o-transform: rotate(180deg);
+}
+
+h3.modal-title {
+ color: #393939;
+}
+
+.modal-body span {
+ color: #393939;
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.controller.js
new file mode 100644
index 00000000..8dc0fdb2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.controller.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/otnBrowser/otnBrowser.module',
+ 'app/otnBrowser/otnBrowser.services'],
+ function (otnBrowserApp) {
+
+ otnBrowserApp.register.controller('otnBrowserCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$otnBrowser', '$mwtnLog',
+ function (uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $otnBrowser, $mwtnLog) {
+
+ var COMPONENT = 'otnBrowserCtrl';
+ $mwtnLog.info({ component: COMPONENT, message: 'otnBrowserCtrl started!' });
+
+ $rootScope.section_logo = 'src/app/otnBrowser/images/otnBrowser.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
+
+ $scope.highlightFilteredHeader = $otnBrowser.highlightFilteredHeader;
+
+ }]);
+
+ });
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.module.js
new file mode 100644
index 00000000..7dc6802a
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.module.js
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['angularAMD',
+ 'app/routingConfig',
+ 'app/core/core.services',
+ 'common/config/env.module',
+ 'app/mwtnCommons/mwtnCommons.module'], function(ng) {
+ var otnBrowserApp = angular.module('app.otnBrowser', ['ui.grid', 'ui.bootstrap', 'app.core',
+ 'ui.router.state', 'config', 'ui.grid.exporter',
+ 'ui.grid.moveColumns', 'ui.grid.pinning', 'ui.grid.selection',
+ 'ui.grid.resizeColumns', 'ui.grid.infiniteScroll','ui.grid.pagination' ]);
+
+ otnBrowserApp.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+ otnBrowserApp.register = {
+ controller : $controllerProvider.register,
+ directive : $compileProvider.directive,
+ factory : $provide.factory,
+ service : $provide.service
+ };
+
+
+ NavHelperProvider.addControllerUrl('app/otnBrowser/otnBrowser.controller');
+ NavHelperProvider.addToMenu('otnBrowser', {
+ "link" : "#/otnBrowser/",
+ "active" : "main.otnBrowser",
+ "title" : "OTN Config",
+ "icon" : "fa fa-cogs", // Add navigation icon css class here
+ "page" : {
+ "title" : "OTN Config",
+ "description" : "Optical Transport Network (OTN) - Configuration"
+ }
+ });
+
+ var access = routingConfig.accessLevels;
+
+ $stateProvider.state('main.otnBrowser', {
+ url: 'otnBrowser/:nodeId',
+ access: access.admin,
+ views : {
+ 'content' : {
+ templateUrl: 'src/app/otnBrowser/otnBrowser.tpl.html',
+ controller: 'otnBrowserCtrl'
+ }
+ }
+ });
+
+ });
+
+ return otnBrowserApp;
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.services.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.services.js
new file mode 100644
index 00000000..64b87729
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.services.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 highstreet technologies GmbH and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+define(['app/otnBrowser/otnBrowser.module', 'app/mwtnCommons/mwtnCommons.services'], function (otnBrowserApp) {
+
+ otnBrowserApp.register.factory('$otnBrowser', function ($q, $http, Base64, $mwtnCommons, $mwtnDatabase, $mwtnLog) {
+
+ var service = {};
+
+ service.checkModules = $mwtnCommons.checkModules;
+
+
+ return service;
+ });
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.tpl.html
new file mode 100644
index 00000000..c5d55444
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/otnBrowser-module/src/main/resources/otnBrowser/otnBrowser.tpl.html
@@ -0,0 +1,9 @@
+<ht-header help-link='sdnr/otnBrowser/0.4.0/README.md'></ht-header>
+
+<h1 style="color: red; transform: rotate(-30deg);">Under Construction</h1>
+<br/><br/><br/><br/><br/>
+
+<hr />
+<div class="owl">
+ <span class="white">ONAP SDN-R | ONF Wireless for @distversion@ - Build: @buildtime@</span>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/pom.xml
new file mode 100644
index 00000000..c363ee55
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/otnBrowser/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>mwtn</artifactId>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <version>0.5.1-SNAPSHOT</version>
+ </parent>
+ <packaging>pom</packaging>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>otnBrowser</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>${prefix} ${project.artifactId}</name>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>otnBrowser-module</module>
+ <module>otnBrowser-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/pom.xml
new file mode 100644
index 00000000..1aa61d8f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.8.1-Carbon</version>
+ <relativePath />
+ </parent>
+
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtn</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <name>ONF :: Wireless :: ${project.artifactId}</name>
+ <packaging>pom</packaging>
+
+ <prerequisites>
+ <maven>3.3.3</maven>
+ </prerequisites>
+
+ <properties>
+ <prefix>ONF :: Wireless :: </prefix>
+
+ <apache.felix.compendium>1.4.0</apache.felix.compendium>
+ <decanter.version>1.1.0</decanter.version>
+ <elasticsearch.version>2.2.0</elasticsearch.version>
+ <osgi.core.version>5.0.0</osgi.core.version>
+
+ <dlux.version>0.5.1-Carbon</dlux.version>
+ <mdsal.version>1.5.1-Carbon</mdsal.version>
+ <mdsal.model.version>0.10.1-Carbon</mdsal.model.version>
+ <restconf.version>1.5.1-Carbon</restconf.version>
+ <yangtools.version>1.1.1-Carbon</yangtools.version>
+ <openflow.plugin.version>0.4.1-Carbon</openflow.plugin.version>
+ <netconf.version>1.2.1-Carbon</netconf.version>
+ <l2switch.version>0.5.1-Carbon</l2switch.version>
+ <dlux.loader.version>0.5.1-Carbon</dlux.loader.version>
+
+ <configfile.directory>etc/opendaylight/karaf</configfile.directory>
+
+ <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
+ <buildtime>${maven.build.timestamp} UTC</buildtime>
+ <distversion>OpenDaylight Carbon-SR1</distversion>
+
+ </properties>
+
+ <modules>
+ <module>mwtnCommons</module>
+ <module>mwtnConnect</module>
+ <module>onapAai</module>
+ <module>onapDcae</module>
+ <module>onapSo</module>
+
+ <!-- <module>ethService</module>
+ <module>otnBrowser</module> -->
+
+ <module>mwtnFault</module>
+ <module>mwtnBrowser</module>
+ <module>mwtnPerformanceCurrent</module>
+ <module>mwtnPerformanceHistory</module>
+ <module>mwtnPerformanceLink</module>
+ <module>security</module>
+
+ <module>mwtnInventory</module>
+ <!-- <module>emergency</module> -->
+
+ <module>mwtnTopology</module>
+
+ <module>mwtnTdm</module>
+
+ <!-- sko not updated to core-model 1.2
+ <module>mwtnCompare</module>
+ <module>mwtnSpectrum</module>
+ <module>mwtnClosedLoop</module> -->
+
+ <module>mwtnMediator</module>
+ <module>mwtnEvents</module>
+ <module>mwtnTest</module>
+ <module>mwtnLog</module>
+
+ <module>odlChat</module>
+
+ <module>help</module>
+ <module>features</module>
+
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>com.google.code.maven-replacer-plugin</groupId>
+ <artifactId>replacer</artifactId>
+ <version>1.5.3</version>
+ <executions>
+ <execution>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>replace</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <basedir>${project.basedir}/target/classes</basedir>
+ <includes>
+ <include>**/*.html</include>
+ <include>**/*.js</include>
+ <include>**/*.css</include>
+ </includes>
+ <replacements>
+ <replacement>
+ <token>@distversion@</token>
+ <value>${distversion}</value>
+ </replacement>
+ <replacement>
+ <token>@buildtime@</token>
+ <value>${buildtime}</value>
+ </replacement>
+ </replacements>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/pom.xml
new file mode 100644
index 00000000..8973079b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.highstreet.technologies.odl.dlux</groupId>
+ <artifactId>mwtn</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <artifactId>security</artifactId>
+ <!-- <name> formatting is used by autorelease to parse and notify projects on
+ build failure. Please do not modify this unless you have a good reason. -->
+ <name>${prefix} ${project.artifactId}</name>
+ <version>0.5.1</version>
+ <packaging>pom</packaging>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>security-module</module>
+ <module>security-bundle</module>
+ </modules>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/pom.xml
new file mode 100644
index 00000000..34358bbe
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <artifactId>security</artifactId>
+ <version>0.5.1</version>
+ </parent>
+
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <artifactId>security-bundle</artifactId>
+ <packaging>bundle</packaging>
+ <!-- <name> formatting is used by autorelease to parse and notify projects on
+ build failure. Please do not modify this unless you have a good reason. -->
+ <name>${prefix} ${project.artifactId}</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.dlux</groupId>
+ <artifactId>loader</artifactId>
+ <version>0.5.1-Carbon</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <artifactId>security-module</artifactId>
+ <version>0.5.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>target/generated-resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <!--loader Resources-->
+ <execution>
+ <id>unpack-loader-resources</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <includeArtifactIds>security-module</includeArtifactIds>
+ <!-- <includes>security/src\/**</includes> -->
+ <excludes>META-INF\/**</excludes>
+ <excludeTransitive>true</excludeTransitive>
+ <ignorePermissions>false</ignorePermissions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.osgi.service.http,
+ org.osgi.framework;version="1.0.0",
+ org.opendaylight.dlux.loader
+ </Import-Package>
+ <Export-Package></Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..65ef78a3
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,19 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
+ <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
+
+ <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
+ <property name="httpService" ref="httpService"/>
+ <property name="loader" ref="loader"/>
+ <property name="moduleName" value="security"/>
+ <property name="url" value="/src/app/security"/>
+ <property name="directory" value="/security/src"/>
+ <property name="requireJs" value="app/security/security.module"/>
+ <property name="angularJs" value="app.security"/>
+ <property name="cssDependencies">
+ <list>
+ <value>src/app/security/security.custom.css</value>
+ </list>
+ </property>
+ </bean>
+</blueprint>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/pom.xml b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/pom.xml
new file mode 100644
index 00000000..95ae27b2
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>security</artifactId>
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <version>0.5.1</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <groupId>org.onap.sdnc.dluxapps</groupId>
+ <artifactId>security-module</artifactId>
+ <name>${prefix} ${project.artifactId}</name>
+ <version>0.5.1</version>
+ <packaging>jar</packaging>
+
+ </project>
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/build.config.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/build.config.js
new file mode 100644
index 00000000..c8396a3f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/build.config.js
@@ -0,0 +1,42 @@
+/**
+ * This file/module contains all configuration for the build process.
+ */
+module.exports = {
+ build_dir: 'build',
+ app_dir: 'app',
+
+ app_files: {
+ js: [
+ 'src/*/**/*.js',
+ '!node/**/*.*',
+ '!node_modules/**/*.*',
+ '!src/vendor/**/*.*'
+ ],
+ root_js: [
+ 'src/*.js'
+ ],
+ less: [
+ 'src/assets/less/*.less'
+ ],
+ img: [
+ 'src/assets/img/*.*'
+ ],
+
+ templates: [
+ 'src/*/**/*.tpl.html',
+ 'src/*.tpl.html'
+ ]
+ },
+
+ assets_files: {
+ less: [],
+ css: [],
+ data: []
+ },
+
+ vendor_files: {
+ js: [],
+ css: [],
+ fonts: []
+ }
+};
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/gulpfile.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/gulpfile.js
new file mode 100644
index 00000000..c3a15c45
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/gulpfile.js
@@ -0,0 +1,142 @@
+var gulp = require('gulp'),
+ del = require('del'),
+ gutil = require('gulp-util'),
+ concat = require('gulp-concat'),
+ runSequence = require('run-sequence'),
+ install = require("gulp-install"),
+ connect = require('gulp-connect'),
+ open = require('gulp-open'),
+ argv = require('yargs').argv,
+ less = require('gulp-less'),
+ debug = require('gulp-debug'),
+ replace = require('gulp-replace-task');
+
+var config = require( './build.config.js');
+
+
+/**
+ * Task for cleaning build directory
+ */
+gulp.task('clean', function() {
+ // You can use multiple globbing patterns as you would with `gulp.src`
+ return del(config.build_dir);
+});
+
+/**
+ * Copy assets
+ */
+gulp.task('copyAssetsCss', function () {
+ return gulp.src(config.assets_files.css)
+ .pipe(
+ gulp.dest(
+ (config.build_dir) + '/assets/css'
+ )
+ );
+});
+
+gulp.task('copyAssetsData', function () {
+ return gulp.src(config.assets_files.data)
+ .pipe(gulp.dest((config.build_dir) + '/assets/data'));
+});
+
+/**
+ * Copy app files
+ */
+gulp.task('copyTemplates', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying APP Template files'));
+ // Copy html
+ return gulp.src(config.app_files.templates)
+ .pipe(gulp.dest(config.build_dir));
+});
+
+gulp.task('copyAppJs', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying APP Controller JS files'));
+ return gulp.src(config.app_files.js)
+ .pipe(gulp.dest(config.build_dir));
+});
+
+gulp.task('copyRootJs', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying APP Root JS files'));
+ return gulp.src(config.app_files.root_js)
+ .pipe(gulp.dest(config.build_dir));
+});
+
+/**
+ * Compile css from less files
+ */
+gulp.task('less', function () {
+ gutil.log(gutil.colors.cyan('INFO :: compiling LESS file'));
+ return gulp.src(config.app_files.less)
+ .pipe(less())
+ .pipe(gulp.dest((config.build_dir) + '/assets/css'));
+});
+
+/**
+ * Copy app assets images
+ */
+gulp.task('copyAppImgs', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying image files'));
+ return gulp.src(config.app_files.img)
+ .pipe(gulp.dest((config.build_dir) + '/assets/img'));
+
+});
+
+/**
+ * Copy vendor files
+ */
+gulp.task('copyVendorCss', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying VENDOR css'));
+ return gulp.src(config.vendor_files.css, { cwd : 'node_modules/**' })
+ .pipe(gulp.dest((config.build_dir) + '/vendor'));
+});
+
+gulp.task('copyVendorFonts', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying VENDOR fonts'));
+ return gulp.src(config.vendor_files.fonts, { cwd : 'node_modules/**' })
+ .pipe(gulp.dest((config.build_dir) + '/vendor'));
+});
+
+gulp.task('copyVendorJs', function () {
+ gutil.log(gutil.colors.cyan('INFO :: copying VENDOR js files'));
+ return gulp.src(config.vendor_files.js, { cwd : 'node_modules/**' })
+ .pipe(gulp.dest((config.build_dir) + '/vendor'));
+});
+
+/**
+ * Copy task aggregated
+ */
+gulp.task('copy', function() {
+ runSequence('less', [
+ 'copyAssetsCss',
+ 'copyAssetsData',
+ 'copyTemplates',
+ 'copyAppJs',
+ 'copyRootJs',
+ 'copyVendorCss',
+ 'copyVendorFonts',
+ 'copyAppImgs'
+ ], 'copyVendorJs');
+});
+
+/**
+ * Build task
+ */
+gulp.task('build', function(){
+ runSequence('clean', 'copy');
+});
+
+
+/**
+ * Live preview main task for development
+ * argument --live should be used to force build task to build only live preview
+ */
+gulp.task('default', function (){
+
+ if (!argv.live) {
+ gutil.log(gutil.colors.red('ERROR :: --live argument must be used for live preview!'));
+ }
+
+ gutil.log(gutil.colors.cyan('INFO :: opening new browser tab live:' + argv.live));
+
+ runSequence('build');
+});
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/package.json b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/package.json
new file mode 100644
index 00000000..2fb0b713
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "odl-dluxapps-security",
+ "version": "0.5.1",
+ "main": "main.js",
+ "devDependencies": {
+ "gulp-bower": "0.0.13"
+ },
+ "dependencies": {
+ "del": "^2.2.0",
+ "gulp": "^3.9.1",
+ "gulp-concat": "^2.6.0",
+ "gulp-connect": "^5.0.0",
+ "gulp-debug": "^3.0.0",
+ "gulp-install": "^0.6.0",
+ "gulp-less": "^3.1.0",
+ "gulp-open": "^2.0.0",
+ "gulp-replace-task": "^0.11.0",
+ "gulp-util": "^3.0.7",
+ "run-sequence": "^1.1.5"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://git.opendaylight.org/gerrit/dluxapps"
+ },
+ "license": "EPL",
+ "keywords": [
+ "odl"
+ ]
+}
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.js
new file mode 100644
index 00000000..e7f12c22
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.js
@@ -0,0 +1,149 @@
+define("security.service", ["require", "exports", "angularAMD"], function (require, exports, angular) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var security = angular.module('app.security');
+ var SecurityService = /** @class */ (function () {
+ function SecurityService($q, $http, $window, env) {
+ this.$q = $q;
+ this.$http = $http;
+ this.$window = $window;
+ this.env = env;
+ this.ensureCrendentials();
+ }
+ SecurityService.prototype.ensureCrendentials = function () {
+ var credentialsDefer = this.$q.defer();
+ this.credentials = credentialsDefer.promise;
+ var url = this.env.getBaseURL('MD_SAL') + "/oauth2/token";
+ this.$http({
+ method: "POST",
+ url: url,
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ data: "grant_type=password&username=" + this.$window.sessionStorage.odlUser + "&password=" + this.$window.sessionStorage.odlPass + "&scope=sdn"
+ }).then(function (res) {
+ credentialsDefer.resolve(res.data && res.data.access_token);
+ }, function (err) {
+ credentialsDefer.reject(err);
+ });
+ };
+ Object.defineProperty(SecurityService.prototype, "token", {
+ get: function () {
+ return this.credentials;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ SecurityService.prototype.getAllUsers = function () {
+ var _this = this;
+ var url = this.env.getBaseURL('MD_SAL') + "/auth/v1/users";
+ return this.token.then(function (token) {
+ return _this.$http({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': "Bearer " + token }
+ }).then(function (result) { return result.data && result.data.users; });
+ });
+ };
+ SecurityService.prototype.getAllRoles = function () {
+ var _this = this;
+ var url = this.env.getBaseURL('MD_SAL') + "/auth/v1/roles";
+ return this.token.then(function (token) {
+ return _this.$http({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': "Bearer " + token }
+ }).then(function (result) { return result.data && result.data.roles; });
+ });
+ };
+ SecurityService.prototype.getUserById = function (userId) {
+ var _this = this;
+ var url = this.env.getBaseURL('MD_SAL') + "/auth/v1/users/" + userId;
+ return this.token.then(function (token) {
+ return _this.$http({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': "Bearer " + token }
+ }).then(function (result) { return result.data && result.data; });
+ });
+ };
+ SecurityService.prototype.getRolesForDomainUser = function (userId, domain) {
+ var _this = this;
+ if (domain === void 0) { domain = "sdn"; }
+ var url = this.env.getBaseURL('MD_SAL') + "/auth/v1/domains/" + domain + "/users/" + userId + "/roles";
+ return this.token.then(function (token) {
+ return _this.$http({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': "Bearer " + token }
+ }).then(function (result) { return result.data && result.data.roles; });
+ });
+ };
+ return SecurityService;
+ }());
+ exports.SecurityService = SecurityService;
+ security.service('securityService', ['$q', '$http', '$window', 'ENV', SecurityService]);
+});
+define( ["require", "exports", "security.service"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var security = angular.module('app.security');
+ var UserDetailsCtrl = /** @class */ (function () {
+ function UserDetailsCtrl($scope, $uibModalInstance, userid, roles) {
+ var _this = this;
+ this.$uibModalInstance = $uibModalInstance;
+ this.userid = userid;
+ this.roles = roles;
+ this.ok = function () {
+ _this.$uibModalInstance.close( /* Parameter*/);
+ };
+ this.cancel = function () {
+ _this.$uibModalInstance.dismiss('cancel');
+ };
+ }
+ return UserDetailsCtrl;
+ }());
+ security.controller('userDetailsCtrl', ['$scope', '$uibModalInstance', 'userid', 'roles', UserDetailsCtrl]);
+ var SecurityCtrl = /** @class */ (function () {
+ function SecurityCtrl($scope, $timeout, $q, $uibModal, $document, $mwtnCommons, securityService) {
+ this.$q = $q;
+ this.$uibModal = $uibModal;
+ this.$document = $document;
+ this.securityService = securityService;
+ $scope.message = "Empty";
+ $scope.users = [];
+ $scope.roles = [];
+ $scope.currentUser = {};
+ $scope.getCurrentUserById = function (id) {
+ id !== null && securityService.getRolesForDomainUser(id).then(function (roles) {
+ var parentElem = angular.element($document[0].querySelector('#security'));
+ var modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/security/templates/userDetails.html',
+ controller: 'userDetailsCtrl',
+ controllerAs: 'vm',
+ appendTo: parentElem,
+ size: 'sm',
+ resolve: {
+ roles: function () { return roles; },
+ userid: function () { return id; },
+ }
+ });
+ });
+ };
+ securityService.token.then(function (res) {
+ $q.all([
+ securityService.getAllUsers(),
+ securityService.getAllRoles()
+ ]).then(function (_a) {
+ var users = _a[0], roles = _a[1];
+ $scope.users = users;
+ $scope.roles = roles;
+ });
+ });
+ }
+ return SecurityCtrl;
+ }());
+ security.controller('securityCtrl', ['$scope', '$timeout', '$q', '$uibModal', '$document', '$mwtnCommons', 'securityService', SecurityCtrl]);
+});
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHkuY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9hcHAvc2VjdXJpdHkvc2VjdXJpdHkuc2VydmljZS50cyIsInNyYy9hcHAvc2VjdXJpdHkvc2VjdXJpdHkuY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7SUFFQSxJQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBdUJoRDtRQUdFLHlCQUFvQixFQUFnQixFQUFVLEtBQXNCLEVBQVUsT0FBTyxFQUFVLEdBQWdCO1lBQTNGLE9BQUUsR0FBRixFQUFFLENBQWM7WUFBVSxVQUFLLEdBQUwsS0FBSyxDQUFpQjtZQUFVLFlBQU8sR0FBUCxPQUFPLENBQUE7WUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFhO1lBQzdHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzVCLENBQUM7UUFFTyw0Q0FBa0IsR0FBMUI7WUFDRSxJQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFVLENBQUM7WUFDakQsSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUM7WUFFNUMsSUFBTSxHQUFHLEdBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGtCQUFlLENBQUM7WUFDNUQsSUFBSSxDQUFDLEtBQUssQ0FBMkI7Z0JBQ25DLE1BQU0sRUFBRSxNQUFNO2dCQUNkLEdBQUcsRUFBRSxHQUFHO2dCQUNSLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxtQ0FBbUMsRUFBRTtnQkFDaEUsSUFBSSxFQUFFLGtDQUFnQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLGtCQUFhLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sZUFBWTthQUN0SSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRztnQkFDVCxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzlELENBQUMsRUFBRSxVQUFBLEdBQUc7Z0JBQ0osZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELHNCQUFXLGtDQUFLO2lCQUFoQjtnQkFDRSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDMUIsQ0FBQzs7O1dBQUE7UUFFTSxxQ0FBVyxHQUFsQjtZQUFBLGlCQVNDO1lBUkMsSUFBTSxHQUFHLEdBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLG1CQUFnQixDQUFDO1lBQzdELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBQSxLQUFLO2dCQUMxQixPQUFPLEtBQUksQ0FBQyxLQUFLLENBQW9CO29CQUNuQyxNQUFNLEVBQUUsS0FBSztvQkFDYixHQUFHLEVBQUUsR0FBRztvQkFDUixPQUFPLEVBQUUsRUFBRSxlQUFlLEVBQUUsWUFBVSxLQUFPLEVBQUU7aUJBQ2hELENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQSxNQUFNLElBQUksT0FBQSxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFoQyxDQUFnQyxDQUFDLENBQUE7WUFDckQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRU0scUNBQVcsR0FBbEI7WUFBQSxpQkFTQztZQVJDLElBQU0sR0FBRyxHQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxtQkFBZ0IsQ0FBQztZQUM3RCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQUEsS0FBSztnQkFDMUIsT0FBTyxLQUFJLENBQUMsS0FBSyxDQUFvQjtvQkFDbkMsTUFBTSxFQUFFLEtBQUs7b0JBQ2IsR0FBRyxFQUFFLEdBQUc7b0JBQ1IsT0FBTyxFQUFFLEVBQUUsZUFBZSxFQUFFLFlBQVUsS0FBTyxFQUFFO2lCQUNoRCxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsTUFBTSxJQUFJLE9BQUEsTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBaEMsQ0FBZ0MsQ0FBQyxDQUFBO1lBQ3JELENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVNLHFDQUFXLEdBQWxCLFVBQW1CLE1BQWM7WUFBakMsaUJBU0M7WUFSQyxJQUFNLEdBQUcsR0FBTSxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsdUJBQWtCLE1BQVEsQ0FBQztZQUN2RSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQUEsS0FBSztnQkFDMUIsT0FBTyxLQUFJLENBQUMsS0FBSyxDQUFPO29CQUN0QixNQUFNLEVBQUUsS0FBSztvQkFDYixHQUFHLEVBQUUsR0FBRztvQkFDUixPQUFPLEVBQUUsRUFBRSxlQUFlLEVBQUUsWUFBVSxLQUFPLEVBQUU7aUJBQ2hELENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQSxNQUFNLElBQUksT0FBQSxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQTFCLENBQTBCLENBQUMsQ0FBQTtZQUMvQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFTSwrQ0FBcUIsR0FBNUIsVUFBNkIsTUFBYyxFQUFFLE1BQXFCO1lBQWxFLGlCQVNDO1lBVDRDLHVCQUFBLEVBQUEsY0FBcUI7WUFDaEUsSUFBTSxHQUFHLEdBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLHlCQUFvQixNQUFNLGVBQVUsTUFBTSxXQUFRLENBQUM7WUFDL0YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFBLEtBQUs7Z0JBQzFCLE9BQU8sS0FBSSxDQUFDLEtBQUssQ0FBb0I7b0JBQ25DLE1BQU0sRUFBRSxLQUFLO29CQUNiLEdBQUcsRUFBRSxHQUFHO29CQUNSLE9BQU8sRUFBRSxFQUFFLGVBQWUsRUFBRSxZQUFVLEtBQU8sRUFBRTtpQkFDaEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLE1BQU0sSUFBSSxPQUFBLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQWhDLENBQWdDLENBQUMsQ0FBQTtZQUNyRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDSCxzQkFBQztJQUFELENBQUMsQUF2RUQsSUF1RUM7SUF2RVksMENBQWU7SUF5RTVCLFFBQVEsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQzs7Ozs7SUM1RnhGLElBQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7SUFFaEQ7UUFDRSx5QkFBWSxNQUFNLEVBQVUsaUJBQWlCLEVBQVMsTUFBYyxFQUFTLEtBQWE7WUFBMUYsaUJBRUM7WUFGMkIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFBO1lBQVMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtZQUFTLFVBQUssR0FBTCxLQUFLLENBQVE7WUFJbkYsT0FBRSxHQUFHO2dCQUNWLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUMsY0FBYyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBRUssV0FBTSxHQUFHO2dCQUNkLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0MsQ0FBQyxDQUFDO1FBUkYsQ0FBQztRQVNILHNCQUFDO0lBQUQsQ0FBQyxBQVpELElBWUM7SUFFRCxRQUFRLENBQUMsVUFBVSxDQUFDLGlCQUFpQixFQUFFLENBQUMsUUFBUSxFQUFFLG1CQUFtQixFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUU1RztRQUNFLHNCQUFZLE1BQU0sRUFBRSxRQUFRLEVBQVUsRUFBZ0IsRUFBVSxTQUFTLEVBQVUsU0FBK0IsRUFBRyxZQUFZLEVBQVUsZUFBZ0M7WUFBckksT0FBRSxHQUFGLEVBQUUsQ0FBYztZQUFVLGNBQVMsR0FBVCxTQUFTLENBQUE7WUFBVSxjQUFTLEdBQVQsU0FBUyxDQUFzQjtZQUF5QixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7WUFDekssTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDekIsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDbEIsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDbEIsTUFBTSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7WUFFeEIsTUFBTSxDQUFDLGtCQUFrQixHQUFHLFVBQVUsRUFBVTtnQkFDOUMsRUFBRSxLQUFLLElBQUksSUFBSSxlQUFlLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsS0FBSztvQkFDakUsSUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7b0JBQzVFLElBQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7d0JBQ25DLFNBQVMsRUFBRSxJQUFJO3dCQUNmLGNBQWMsRUFBRSxhQUFhO3dCQUM3QixlQUFlLEVBQUUsWUFBWTt3QkFDN0IsV0FBVyxFQUFFLDZDQUE2Qzt3QkFDMUQsVUFBVSxFQUFFLGlCQUFpQjt3QkFDN0IsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLFFBQVEsRUFBRSxVQUFVO3dCQUNwQixJQUFJLEVBQUUsSUFBSTt3QkFDVixPQUFPLEVBQUU7NEJBQ1AsS0FBSyxFQUFFLGNBQU0sT0FBQSxLQUFLLEVBQUwsQ0FBSzs0QkFDbEIsTUFBTSxFQUFFLGNBQU0sT0FBQSxFQUFFLEVBQUYsQ0FBRTt5QkFDakI7cUJBQ0YsQ0FBQyxDQUFBO2dCQUNKLENBQUMsQ0FBQyxDQUFBO1lBQ0osQ0FBQyxDQUFDO1lBRUYsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHO2dCQUM1QixFQUFFLENBQUMsR0FBRyxDQUFDO29CQUNMLGVBQWUsQ0FBQyxXQUFXLEVBQUU7b0JBQzdCLGVBQWUsQ0FBQyxXQUFXLEVBQUU7aUJBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLEVBQWM7d0JBQWIsYUFBSyxFQUFFLGFBQUs7b0JBQ2pELE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUNyQixNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztnQkFDekIsQ0FBQyxDQUFDLENBQUE7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDSCxtQkFBQztJQUFELENBQUMsQUFwQ0QsSUFvQ0M7SUFFRCxRQUFRLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBQyxXQUFXLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLFlBQVksQ0FBRSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhbmd1bGFyIGZyb20gJ2FuZ3VsYXJBTUQnO1xuXG5jb25zdCBzZWN1cml0eSA9IGFuZ3VsYXIubW9kdWxlKCdhcHAuc2VjdXJpdHknKTtcblxuaW50ZXJmYWNlIElFbnZTZXJ2aWNlIHtcbiAgZ2V0QmFzZVVSTChwb3J0OiBzdHJpbmcpOiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFVzZXIgPSB7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGRvbWFpbmlkOiBzdHJpbmc7XG4gIGVtYWlsOiBzdHJpbmc7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIHBhc3N3b3JkOiBzdHJpbmc7XG4gIHNhbHQ6IHN0cmluZztcbiAgdXNlcmlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFJvbGUgPSB7XG4gIHJvbGVpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGRvbWFpbmlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBTZWN1cml0eVNlcnZpY2Uge1xuICBwcml2YXRlIGNyZWRlbnRpYWxzOiBuZy5JUHJvbWlzZTxzdHJpbmc+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgJHE6IG5nLklRU2VydmljZSwgcHJpdmF0ZSAkaHR0cDogbmcuSUh0dHBTZXJ2aWNlLCBwcml2YXRlICR3aW5kb3csIHByaXZhdGUgZW52OiBJRW52U2VydmljZSkge1xuICAgIHRoaXMuZW5zdXJlQ3JlbmRlbnRpYWxzKCk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUNyZW5kZW50aWFscygpIHtcbiAgICBjb25zdCBjcmVkZW50aWFsc0RlZmVyID0gdGhpcy4kcS5kZWZlcjxzdHJpbmc+KCk7XG4gICAgdGhpcy5jcmVkZW50aWFscyA9IGNyZWRlbnRpYWxzRGVmZXIucHJvbWlzZTtcblxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuZW52LmdldEJhc2VVUkwoJ01EX1NBTCcpfS9vYXV0aDIvdG9rZW5gO1xuICAgIHRoaXMuJGh0dHA8eyBhY2Nlc3NfdG9rZW46IHN0cmluZyB9Pih7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgdXJsOiB1cmwsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LFxuICAgICAgZGF0YTogYGdyYW50X3R5cGU9cGFzc3dvcmQmdXNlcm5hbWU9JHt0aGlzLiR3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uub2RsVXNlcn0mcGFzc3dvcmQ9JHt0aGlzLiR3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uub2RsUGFzc30mc2NvcGU9c2RuYFxuICAgIH0pLnRoZW4ocmVzID0+IHtcbiAgICAgIGNyZWRlbnRpYWxzRGVmZXIucmVzb2x2ZShyZXMuZGF0YSAmJiByZXMuZGF0YS5hY2Nlc3NfdG9rZW4pO1xuICAgIH0sIGVyciA9PiB7XG4gICAgICBjcmVkZW50aWFsc0RlZmVyLnJlamVjdChlcnIpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldCB0b2tlbigpIHtcbiAgICByZXR1cm4gdGhpcy5jcmVkZW50aWFscztcbiAgfVxuXG4gIHB1YmxpYyBnZXRBbGxVc2VycygpOiBuZy5JUHJvbWlzZTxVc2VyW10+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmVudi5nZXRCYXNlVVJMKCdNRF9TQUwnKX0vYXV0aC92MS91c2Vyc2A7XG4gICAgcmV0dXJuIHRoaXMudG9rZW4udGhlbih0b2tlbiA9PiB7XG4gICAgICByZXR1cm4gdGhpcy4kaHR0cDx7IHVzZXJzOiBVc2VyW10gfT4oe1xuICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgIHVybDogdXJsLFxuICAgICAgICBoZWFkZXJzOiB7ICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke3Rva2VufWAgfVxuICAgICAgfSkudGhlbihyZXN1bHQgPT4gcmVzdWx0LmRhdGEgJiYgcmVzdWx0LmRhdGEudXNlcnMpXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0QWxsUm9sZXMoKTogbmcuSVByb21pc2U8Um9sZVtdPiB7XG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5lbnYuZ2V0QmFzZVVSTCgnTURfU0FMJyl9L2F1dGgvdjEvcm9sZXNgO1xuICAgIHJldHVybiB0aGlzLnRva2VuLnRoZW4odG9rZW4gPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuJGh0dHA8eyByb2xlczogUm9sZVtdIH0+KHtcbiAgICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgICB1cmw6IHVybCxcbiAgICAgICAgaGVhZGVyczogeyAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt0b2tlbn1gIH1cbiAgICAgIH0pLnRoZW4ocmVzdWx0ID0+IHJlc3VsdC5kYXRhICYmIHJlc3VsdC5kYXRhLnJvbGVzKVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldFVzZXJCeUlkKHVzZXJJZDogc3RyaW5nKTogbmcuSVByb21pc2U8VXNlcj4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuZW52LmdldEJhc2VVUkwoJ01EX1NBTCcpfS9hdXRoL3YxL3VzZXJzLyR7dXNlcklkfWA7XG4gICAgcmV0dXJuIHRoaXMudG9rZW4udGhlbih0b2tlbiA9PiB7XG4gICAgICByZXR1cm4gdGhpcy4kaHR0cDxVc2VyPih7XG4gICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7dG9rZW59YCB9XG4gICAgICB9KS50aGVuKHJlc3VsdCA9PiByZXN1bHQuZGF0YSAmJiByZXN1bHQuZGF0YSlcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRSb2xlc0ZvckRvbWFpblVzZXIodXNlcklkOiBzdHJpbmcsIGRvbWFpbjogc3RyaW5nPSBcInNkblwiKTogbmcuSVByb21pc2U8Um9sZVtdPiB7XG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5lbnYuZ2V0QmFzZVVSTCgnTURfU0FMJyl9L2F1dGgvdjEvZG9tYWlucy8ke2RvbWFpbn0vdXNlcnMvJHt1c2VySWR9L3JvbGVzYDtcbiAgICByZXR1cm4gdGhpcy50b2tlbi50aGVuKHRva2VuID0+IHtcbiAgICAgIHJldHVybiB0aGlzLiRodHRwPHsgcm9sZXM6IFJvbGVbXSB9Pih7XG4gICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7dG9rZW59YCB9XG4gICAgICB9KS50aGVuKHJlc3VsdCA9PiByZXN1bHQuZGF0YSAmJiByZXN1bHQuZGF0YS5yb2xlcylcbiAgICB9KTtcbiAgfVxufVxuXG5zZWN1cml0eS5zZXJ2aWNlKCdzZWN1cml0eVNlcnZpY2UnLCBbJyRxJywgJyRodHRwJywgJyR3aW5kb3cnLCAnRU5WJywgU2VjdXJpdHlTZXJ2aWNlXSk7IiwiZGVjbGFyZSB2YXIgYW5ndWxhcjogYW5ndWxhci5JQW5ndWxhclN0YXRpYzsgXG5cbmltcG9ydCB7IFNlY3VyaXR5U2VydmljZSwgUm9sZSB9IGZyb20gXCIuL3NlY3VyaXR5LnNlcnZpY2VcIjsgXG5cbmltcG9ydCBcIi4vc2VjdXJpdHkuc2VydmljZVwiO1xuXG5jb25zdCBzZWN1cml0eSA9IGFuZ3VsYXIubW9kdWxlKCdhcHAuc2VjdXJpdHknKTtcblxuY2xhc3MgVXNlckRldGFpbHNDdHJsIHtcbiAgY29uc3RydWN0b3IoJHNjb3BlLCBwcml2YXRlICR1aWJNb2RhbEluc3RhbmNlLCBwdWJsaWMgdXNlcmlkOiBzdHJpbmcsIHB1YmxpYyByb2xlczogUm9sZVtdKSB7XG5cbiAgfVxuXG4gIHB1YmxpYyBvayA9ICgpID0+IHtcbiAgICB0aGlzLiR1aWJNb2RhbEluc3RhbmNlLmNsb3NlKC8qIFBhcmFtZXRlciovKTtcbiAgfTtcblxuICBwdWJsaWMgY2FuY2VsID0gKCkgPT4ge1xuICAgIHRoaXMuJHVpYk1vZGFsSW5zdGFuY2UuZGlzbWlzcygnY2FuY2VsJyk7XG4gIH07XG59XG5cbnNlY3VyaXR5LmNvbnRyb2xsZXIoJ3VzZXJEZXRhaWxzQ3RybCcsIFsnJHNjb3BlJywgJyR1aWJNb2RhbEluc3RhbmNlJywgJ3VzZXJpZCcsICdyb2xlcycsIFVzZXJEZXRhaWxzQ3RybF0pO1xuXG5jbGFzcyBTZWN1cml0eUN0cmwge1xuICBjb25zdHJ1Y3Rvcigkc2NvcGUsICR0aW1lb3V0LCBwcml2YXRlICRxOiBuZy5JUVNlcnZpY2UsIHByaXZhdGUgJHVpYk1vZGFsLCBwcml2YXRlICRkb2N1bWVudCA6IG5nLklEb2N1bWVudFNlcnZpY2UsICAkbXd0bkNvbW1vbnMsIHByaXZhdGUgc2VjdXJpdHlTZXJ2aWNlOiBTZWN1cml0eVNlcnZpY2UpIHtcbiAgICAkc2NvcGUubWVzc2FnZSA9IFwiRW1wdHlcIjtcbiAgICAkc2NvcGUudXNlcnMgPSBbXTtcbiAgICAkc2NvcGUucm9sZXMgPSBbXTtcbiAgICAkc2NvcGUuY3VycmVudFVzZXIgPSB7fTtcblxuICAgICRzY29wZS5nZXRDdXJyZW50VXNlckJ5SWQgPSBmdW5jdGlvbiAoaWQ6IHN0cmluZykge1xuICAgICAgaWQgIT09IG51bGwgJiYgc2VjdXJpdHlTZXJ2aWNlLmdldFJvbGVzRm9yRG9tYWluVXNlcihpZCkudGhlbihyb2xlcyA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmVudEVsZW0gPSBhbmd1bGFyLmVsZW1lbnQoJGRvY3VtZW50WzBdLnF1ZXJ5U2VsZWN0b3IoJyNzZWN1cml0eScpKTtcbiAgICAgICAgY29uc3QgbW9kYWxJbnN0YW5jZSA9ICR1aWJNb2RhbC5vcGVuKHtcbiAgICAgICAgICBhbmltYXRpb246IHRydWUsXG4gICAgICAgICAgYXJpYUxhYmVsbGVkQnk6ICdtb2RhbC10aXRsZScsXG4gICAgICAgICAgYXJpYURlc2NyaWJlZEJ5OiAnbW9kYWwtYm9keScsXG4gICAgICAgICAgdGVtcGxhdGVVcmw6ICdzcmMvYXBwL3NlY3VyaXR5L3RlbXBsYXRlcy91c2VyRGV0YWlscy5odG1sJyxcbiAgICAgICAgICBjb250cm9sbGVyOiAndXNlckRldGFpbHNDdHJsJyxcbiAgICAgICAgICBjb250cm9sbGVyQXM6ICd2bScsXG4gICAgICAgICAgYXBwZW5kVG86IHBhcmVudEVsZW0sXG4gICAgICAgICAgc2l6ZTogJ3NtJyxcbiAgICAgICAgICByZXNvbHZlOiB7XG4gICAgICAgICAgICByb2xlczogKCkgPT4gcm9sZXMsXG4gICAgICAgICAgICB1c2VyaWQ6ICgpID0+IGlkLFxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfTsgIFxuXG4gICAgc2VjdXJpdHlTZXJ2aWNlLnRva2VuLnRoZW4ocmVzID0+IHtcbiAgICAgICRxLmFsbChbXG4gICAgICAgIHNlY3VyaXR5U2VydmljZS5nZXRBbGxVc2VycygpLFxuICAgICAgICBzZWN1cml0eVNlcnZpY2UuZ2V0QWxsUm9sZXMoKV0pLnRoZW4oKFt1c2Vycywgcm9sZXNdKSA9PiB7XG4gICAgICAgICAgJHNjb3BlLnVzZXJzID0gdXNlcnM7XG4gICAgICAgICAgJHNjb3BlLnJvbGVzID0gcm9sZXM7XG4gICAgICB9KVxuICAgIH0pO1xuICB9XG59XG5cbnNlY3VyaXR5LmNvbnRyb2xsZXIoJ3NlY3VyaXR5Q3RybCcsIFsnJHNjb3BlJywgJyR0aW1lb3V0JywgJyRxJywgJyR1aWJNb2RhbCcsJyRkb2N1bWVudCcsICckbXd0bkNvbW1vbnMnLCAnc2VjdXJpdHlTZXJ2aWNlJywgU2VjdXJpdHlDdHJsIF0pOyJdfQ== \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.ts
new file mode 100644
index 00000000..49315319
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.controller.ts
@@ -0,0 +1,63 @@
+declare var angular: angular.IAngularStatic;
+
+import { SecurityService, Role } from "./security.service";
+
+import "./security.service";
+
+const security = angular.module('app.security');
+
+class UserDetailsCtrl {
+ constructor($scope, private $uibModalInstance, public userid: string, public roles: Role[]) {
+
+ }
+
+ public ok = () => {
+ this.$uibModalInstance.close(/* Parameter*/);
+ };
+
+ public cancel = () => {
+ this.$uibModalInstance.dismiss('cancel');
+ };
+}
+
+security.controller('userDetailsCtrl', ['$scope', '$uibModalInstance', 'userid', 'roles', UserDetailsCtrl]);
+
+class SecurityCtrl {
+ constructor($scope, $timeout, private $q: ng.IQService, private $uibModal, private $document : ng.IDocumentService, $mwtnCommons, private securityService: SecurityService) {
+ $scope.message = "Empty";
+ $scope.users = [];
+ $scope.roles = [];
+ $scope.currentUser = {};
+
+ $scope.getCurrentUserById = function (id: string) {
+ id !== null && securityService.getRolesForDomainUser(id).then(roles => {
+ const parentElem = angular.element($document[0].querySelector('#security'));
+ const modalInstance = $uibModal.open({
+ animation: true,
+ ariaLabelledBy: 'modal-title',
+ ariaDescribedBy: 'modal-body',
+ templateUrl: 'src/app/security/templates/userDetails.html',
+ controller: 'userDetailsCtrl',
+ controllerAs: 'vm',
+ appendTo: parentElem,
+ size: 'sm',
+ resolve: {
+ roles: () => roles,
+ userid: () => id,
+ }
+ })
+ })
+ };
+
+ securityService.token.then(res => {
+ $q.all([
+ securityService.getAllUsers(),
+ securityService.getAllRoles()]).then(([users, roles]) => {
+ $scope.users = users;
+ $scope.roles = roles;
+ })
+ });
+ }
+}
+
+security.controller('securityCtrl', ['$scope', '$timeout', '$q', '$uibModal','$document', '$mwtnCommons', 'securityService', SecurityCtrl ]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.custom.css b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.custom.css
new file mode 100644
index 00000000..67bd4579
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.custom.css
@@ -0,0 +1,11 @@
+#security table > thead > tr > th {
+ background: #ddd
+}
+
+#security table > tbody > tr > td {
+ background: #ddd
+}
+
+#security table > tbody > tr:nth-child(odd) > td {
+ background: #eee
+} \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.js b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.js
new file mode 100644
index 00000000..dfd7e229
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.js
@@ -0,0 +1,33 @@
+define( ["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.security = angular.module('app.security', ['app.core']);
+ exports.security.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+ //$translatePartialLoaderProvider.addPart('app/security/locale/locale');
+ NavHelperProvider.addControllerUrl('app/security/security.controller');
+ NavHelperProvider.addToMenu('security', {
+ "link": "#/security",
+ "active": "main.security",
+ "title": "Security",
+ "icon": "fa fa-shield",
+ "page": {
+ "title": "Security",
+ "description": "security"
+ }
+ });
+ $stateProvider.state('main.security', {
+ url: 'security',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/security/security.tpl.html',
+ controller: 'securityCtrl'
+ }
+ }
+ });
+ });
+});
+/* non ES6 export */
+// export = security;
+// export default security;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHkubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2FwcC9zZWN1cml0eS9zZWN1cml0eS5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0lBR2EsUUFBQSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBRXJFLGdCQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsK0JBQStCO1FBRTlLLHdFQUF3RTtRQUV4RSxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1FBQ3ZFLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUU7WUFDdEMsTUFBTSxFQUFFLFlBQVk7WUFDcEIsUUFBUSxFQUFFLGVBQWU7WUFDekIsT0FBTyxFQUFFLFVBQVU7WUFDbkIsTUFBTSxFQUFFLGVBQWU7WUFDdkIsTUFBTSxFQUFFO2dCQUNOLE9BQU8sRUFBRSxVQUFVO2dCQUNuQixhQUFhLEVBQUUsVUFBVTthQUMxQjtTQUNGLENBQUMsQ0FBQztRQUVILGNBQWMsQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFO1lBQ3BDLEdBQUcsRUFBRSxVQUFVO1lBQ2YsTUFBTSxFQUFFLENBQUM7WUFDVCxLQUFLLEVBQUU7Z0JBQ0wsU0FBUyxFQUFFO29CQUNULFdBQVcsRUFBRSxvQ0FBb0M7b0JBQ2pELFVBQVUsRUFBRSxjQUFjO2lCQUMzQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7O0FBRUgsb0JBQW9CO0FBQ3BCLHFCQUFxQjtBQUNyQiwyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBpbXBvcnQgKiBhcyBhbmd1bGFyIGZyb20gJ2FuZ3VsYXJBTUQnO1xuZGVjbGFyZSB2YXIgYW5ndWxhcjogYW5ndWxhci5JQW5ndWxhclN0YXRpYzsgXG5cbmV4cG9ydCBjb25zdCBzZWN1cml0eSA9IGFuZ3VsYXIubW9kdWxlKCdhcHAuc2VjdXJpdHknLCBbJ2FwcC5jb3JlJ10pO1xuXG5zZWN1cml0eS5jb25maWcoZnVuY3Rpb24gKCRzdGF0ZVByb3ZpZGVyLCAkY29tcGlsZVByb3ZpZGVyLCAkY29udHJvbGxlclByb3ZpZGVyLCAkcHJvdmlkZSwgTmF2SGVscGVyUHJvdmlkZXIsICRodHRwUHJvdmlkZXIsICR0cmFuc2xhdGVQcm92aWRlciwgJHRyYW5zbGF0ZVBhcnRpYWxMb2FkZXJQcm92aWRlcikge1xuXG4gIC8vJHRyYW5zbGF0ZVBhcnRpYWxMb2FkZXJQcm92aWRlci5hZGRQYXJ0KCdhcHAvc2VjdXJpdHkvbG9jYWxlL2xvY2FsZScpO1xuXG4gIE5hdkhlbHBlclByb3ZpZGVyLmFkZENvbnRyb2xsZXJVcmwoJ2FwcC9zZWN1cml0eS9zZWN1cml0eS5jb250cm9sbGVyJyk7XG4gIE5hdkhlbHBlclByb3ZpZGVyLmFkZFRvTWVudSgnc2VjdXJpdHknLCB7XG4gICAgXCJsaW5rXCI6IFwiIy9zZWN1cml0eVwiLFxuICAgIFwiYWN0aXZlXCI6IFwibWFpbi5zZWN1cml0eVwiLFxuICAgIFwidGl0bGVcIjogXCJTZWN1cml0eVwiLFxuICAgIFwiaWNvblwiOiBcImZhICBmYS1zaGllbGRcIiwgIC8vIEFkZCBuYXZpZ2F0aW9uIGljb24gY3NzIGNsYXNzIGhlcmVcbiAgICBcInBhZ2VcIjoge1xuICAgICAgXCJ0aXRsZVwiOiBcIlNlY3VyaXR5XCIsXG4gICAgICBcImRlc2NyaXB0aW9uXCI6IFwic2VjdXJpdHlcIlxuICAgIH1cbiAgfSk7XG5cbiAgJHN0YXRlUHJvdmlkZXIuc3RhdGUoJ21haW4uc2VjdXJpdHknLCB7XG4gICAgdXJsOiAnc2VjdXJpdHknLFxuICAgIGFjY2VzczogMixcbiAgICB2aWV3czoge1xuICAgICAgJ2NvbnRlbnQnOiB7XG4gICAgICAgIHRlbXBsYXRlVXJsOiAnc3JjL2FwcC9zZWN1cml0eS9zZWN1cml0eS50cGwuaHRtbCcsXG4gICAgICAgIGNvbnRyb2xsZXI6ICdzZWN1cml0eUN0cmwnXG4gICAgICB9XG4gICAgfVxuICB9KTtcbn0pO1xuXG4vKiBub24gRVM2IGV4cG9ydCAqL1xuLy8gZXhwb3J0ID0gc2VjdXJpdHk7XG4vLyBleHBvcnQgZGVmYXVsdCBzZWN1cml0eTsiXX0= \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.ts
new file mode 100644
index 00000000..e06ae9ac
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.module.ts
@@ -0,0 +1,36 @@
+// import * as angular from 'angularAMD';
+declare var angular: angular.IAngularStatic;
+
+export const security = angular.module('app.security', ['app.core']);
+
+security.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $httpProvider, $translateProvider, $translatePartialLoaderProvider) {
+
+ //$translatePartialLoaderProvider.addPart('app/security/locale/locale');
+
+ NavHelperProvider.addControllerUrl('app/security/security.controller');
+ NavHelperProvider.addToMenu('security', {
+ "link": "#/security",
+ "active": "main.security",
+ "title": "Security",
+ "icon": "fa fa-shield", // Add navigation icon css class here
+ "page": {
+ "title": "Security",
+ "description": "security"
+ }
+ });
+
+ $stateProvider.state('main.security', {
+ url: 'security',
+ access: 2,
+ views: {
+ 'content': {
+ templateUrl: 'src/app/security/security.tpl.html',
+ controller: 'securityCtrl'
+ }
+ }
+ });
+});
+
+/* non ES6 export */
+// export = security;
+// export default security; \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.service.ts b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.service.ts
new file mode 100644
index 00000000..c881c53f
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.service.ts
@@ -0,0 +1,99 @@
+import * as angular from 'angularAMD';
+
+const security = angular.module('app.security');
+
+interface IEnvService {
+ getBaseURL(port: string): string;
+}
+
+export type User = {
+ description: string;
+ domainid: string;
+ email: string;
+ enabled: boolean;
+ password: string;
+ salt: string;
+ userid: string;
+}
+
+export type Role = {
+ roleid: string;
+ name: string;
+ description: string;
+ domainid: string;
+}
+
+export class SecurityService {
+ private credentials: ng.IPromise<string>;
+
+ constructor(private $q: ng.IQService, private $http: ng.IHttpService, private $window, private env: IEnvService) {
+ this.ensureCrendentials();
+ }
+
+ private ensureCrendentials() {
+ const credentialsDefer = this.$q.defer<string>();
+ this.credentials = credentialsDefer.promise;
+
+ const url = `${this.env.getBaseURL('MD_SAL')}/oauth2/token`;
+ this.$http<{ access_token: string }>({
+ method: "POST",
+ url: url,
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ data: `grant_type=password&username=${this.$window.sessionStorage.odlUser}&password=${this.$window.sessionStorage.odlPass}&scope=sdn`
+ }).then(res => {
+ credentialsDefer.resolve(res.data && res.data.access_token);
+ }, err => {
+ credentialsDefer.reject(err);
+ });
+ }
+
+ public get token() {
+ return this.credentials;
+ }
+
+ public getAllUsers(): ng.IPromise<User[]> {
+ const url = `${this.env.getBaseURL('MD_SAL')}/auth/v1/users`;
+ return this.token.then(token => {
+ return this.$http<{ users: User[] }>({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': `Bearer ${token}` }
+ }).then(result => result.data && result.data.users)
+ });
+ }
+
+ public getAllRoles(): ng.IPromise<Role[]> {
+ const url = `${this.env.getBaseURL('MD_SAL')}/auth/v1/roles`;
+ return this.token.then(token => {
+ return this.$http<{ roles: Role[] }>({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': `Bearer ${token}` }
+ }).then(result => result.data && result.data.roles)
+ });
+ }
+
+ public getUserById(userId: string): ng.IPromise<User> {
+ const url = `${this.env.getBaseURL('MD_SAL')}/auth/v1/users/${userId}`;
+ return this.token.then(token => {
+ return this.$http<User>({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': `Bearer ${token}` }
+ }).then(result => result.data && result.data)
+ });
+ }
+
+ public getRolesForDomainUser(userId: string, domain: string= "sdn"): ng.IPromise<Role[]> {
+ const url = `${this.env.getBaseURL('MD_SAL')}/auth/v1/domains/${domain}/users/${userId}/roles`;
+ return this.token.then(token => {
+ return this.$http<{ roles: Role[] }>({
+ method: "GET",
+ url: url,
+ headers: { 'Authorization': `Bearer ${token}` }
+ }).then(result => result.data && result.data.roles)
+ });
+ }
+}
+
+security.service('securityService', ['$q', '$http', '$window', 'ENV', SecurityService]); \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.tpl.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.tpl.html
new file mode 100644
index 00000000..ea08892b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/security.tpl.html
@@ -0,0 +1,50 @@
+<div id="security">
+ <h2>Users</h2>
+ <table class="table">
+ <thead>
+ <tr>
+ <th>UserID</th>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Enabled</th>
+ <th>eMail</th>
+ <th>Domain</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="user in users">
+ <td>{{user.userid}}</td>
+ <td>{{user.name}}</td>
+ <td>{{user.description}}</td>
+ <td>{{user.enabled}}</td>
+ <td>{{user.email}}</td>
+ <td>{{user.domainid}}</td>
+ <td>
+ <button class="btn btn-sm btn-success"
+ ng-click="getCurrentUserById(user.userid)">Info</button></td>
+ </tr>
+ </tbody>
+ </table>
+<h2>Roles</h2>
+<table class="table">
+ <thead>
+ <tr>
+ <th>RoleID</th>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Domain</th>
+ <!-- <th>Actions</th> -->
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="role in roles">
+ <td>{{role.roleid}}</td>
+ <td>{{role.name}}</td>
+ <td>{{role.description}}</td>
+ <td>{{role.domainid}}</td>
+ <!-- <td><button class="btn btn-sm btn-success">Info</button></td> -->
+ </tr>
+ </tbody>
+</table>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/templates/userDetails.html b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/templates/userDetails.html
new file mode 100644
index 00000000..5589263b
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/security/security-module/src/main/resources/security/src/templates/userDetails.html
@@ -0,0 +1,14 @@
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title" style="color: #333;">{{ vm.userid }}</h3>
+</div>
+<div class="modal-body" id="modal-body">
+ <div><b>Roles</b></div>
+ <ul>
+ <li ng-repeat="role in vm.roles">{{ role.name }}</li>
+ </ul>
+
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="vm.ok()">OK</button>
+ <button class="btn btn-warning" type="button" ng-click="vm.cancel()">Cancel</button>
+</div> \ No newline at end of file
diff --git a/sdnr/wireless-transport/code-Carbon-SR1/ux/ux-dev.sh b/sdnr/wireless-transport/code-Carbon-SR1/ux/ux-dev.sh
new file mode 100755
index 00000000..b34f8718
--- /dev/null
+++ b/sdnr/wireless-transport/code-Carbon-SR1/ux/ux-dev.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+# build ux
+mvn clean install -DskipTests
+
+# clean
+rm -rf ~/.m2/repository/com/highstreet/technologies/odl/app/closedLoopAutomation-karaf/
+rm -rf ~/.m2/repository/com/highstreet/technologies/odl/app/spectrum/scheduler-karaf/
+find ~/.m2/repository/org/opendaylight/mwtn/* -type d -name "*-module" -exec rm -rf {} \;
+find ~/.m2/repository/com/highstreet/* -type d -name "*-module" -exec rm -rf {} \;
+rm -rf ../dist/cache/schema/tailf*.yang
+rm -rf ../dist/cache/schema/yuma*.yang
+# rm -rf ../dist/data/log/*
+rm -rf ../dist/system/org/opendaylight/mwtn
+rm -rf ../dist/system/com/highstreet
+
+# deploy
+cp -R ~/.m2/repository/org/opendaylight/mwtn ../dist/system/org/opendaylight
+cp -R ~/.m2/repository/com/highstreet ../dist/system/com
+
+# uninstall bundles
+## declare array of bundleNames
+declare -a bundleNames=(
+ "ONF :: Wireless :: odlChat-bundle"
+ "ONF :: Wireless :: help-bundle"
+ "ONF :: Wireless :: mwtnLog-bundle"
+ "ONF :: Wireless :: mwtnTest-bundle"
+ "ONF :: Wireless :: mwtnMediator-bundle"
+ "ONF :: Wireless :: mwtnEvents-bundle"
+ "ONF :: Wireless :: mwtnClosedLoop-bundle"
+ "ONF :: Wireless :: mwtnSpectrum-bundle"
+ "ONF :: Wireless :: mwtnCompare-bundle"
+ "ONF :: Wireless :: mwtnTdm-bundle"
+ "ONF :: Wireless :: mwtnTopology-bundle"
+ "ONF :: Wireless :: mwtnInventory-bundle"
+ "ONF :: Wireless :: mwtnPerformanceLink-bundle"
+ "ONF :: Wireless :: mwtnPerformanceHistory-bundle"
+ "ONF :: Wireless :: mwtnPerformanceCurrent-bundle"
+ "ONF :: Wireless :: mwtnFault-bundle"
+ "ONF :: Wireless :: mwtnBrowser-bundle"
+ "ONF :: Wireless :: otnBrowser-bundle"
+ "ONF :: Wireless :: ethService-bundle"
+ "ONF :: Wireless :: onapMso-bundle"
+ "ONF :: Wireless :: onapDcae-bundle"
+ "ONF :: Wireless :: onapAai-bundle"
+ "ONF :: Wireless :: mwtnConnect-bundle"
+ "ONF :: Wireless :: mwtnCommons-bundle"
+)
+
+## execute bundle uninstall
+names=""
+for bundleName in "${bundleNames[@]}"
+do
+ names+="\"$bundleName\" "
+done
+../dist/bin/client -u karaf "bundle:uninstall $names"
+
+# install bundles
+## declare array of bundleNames
+declare -a bundles=(
+ mvn:com.highstreet.technologies.odl.dlux/mwtnCommons-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnConnect-bundle/0.5.1-SNAPSHOT
+
+ mvn:com.highstreet.technologies.odl.dlux/onapAai-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/onapDcae-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/onapMso-bundle/0.5.1-SNAPSHOT
+
+ # mvn:com.highstreet.technologies.odl.dlux/ethService-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/otnBrowser-bundle/0.5.1-SNAPSHOT
+
+ mvn:com.highstreet.technologies.odl.dlux/mwtnFault-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnBrowser-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceCurrent-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceHistory-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnPerformanceLink-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnInventory-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnTopology-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnTdm-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnCompare-bundle/0.5.1-SNAPSHOT
+ # mvn:cn.com.zte.odl.dlux/mwtnSpectrum-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnClosedLoop-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnEvents-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnTest-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/mwtnMediator-bundle/0.5.1-SNAPSHOT
+ mvn:com.highstreet.technologies.odl.dlux/help-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/mwtnLog-bundle/0.5.1-SNAPSHOT
+ # mvn:com.highstreet.technologies.odl.dlux/odlChat-bundle/0.5.1-SNAPSHOT
+)
+
+## execute bundle uninstall
+bundleMvns=""
+for bundle in "${bundles[@]}"
+do
+ bundleMvns+="$bundle "
+done
+../dist/bin/client -u karaf "bundle:install -s $bundleMvns"
+
+# open brwoser
+x-www-browser http://localhost:8181/index.html
+
+# remove target folders for easy search functionality
+mvn clean
+find * -type d -name "target-ide" -exec rm -rf {} \; \ No newline at end of file