aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wireless-transport/code-Carbon-SR1/ux
diff options
context:
space:
mode:
authordemx8as6 <martin.skorupski@highstreet-technologies.com>2018-07-10 18:07:44 +0200
committerTimoney, Dan (dt5972) <dt5972@att.com>2018-07-11 16:30:28 -0400
commit27fb2d06608fbb070ae2c15a5580a4f5b2423d15 (patch)
treeccd717991b4e556b67f1fd2cacb345b4d174b41f /sdnr/wireless-transport/code-Carbon-SR1/ux
parent60315525ab5e7c12a9f47c409092e8dba6ad656d (diff)
Add seed code for sdnr app based on ONF Centennial
At this point in time all the Carbon code from ONF Centennial is added to ONAP. Later it needs to be refactored and modified for ODL Oxygen. Change-Id: Iff85dd940c05c3827f1c4e6f9542ecd060c58a46 Issue-ID: SDNC-374 Signed-off-by: demx8as6 <martin.skorupski@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wireless-transport/code-Carbon-SR1/ux')
-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