Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / plugins / launchpad / api / transforms.js
diff --git a/skyquake/plugins/launchpad/api/transforms.js b/skyquake/plugins/launchpad/api/transforms.js
new file mode 100644 (file)
index 0000000..d3044b8
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   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.
+ *
+ */
+var _ = require('lodash');
+
+/**
+ * Merges vnfr["nfvi-metrics"] with nsr["nfvi-metrics"] into a format consumable by the UI LP and Record Cards
+ * @param  {Array} vnfr vnfr nfvi metrics
+ * @param  {Array} nsr  nsr nfvi metrics
+ * @return {Array}      Merged NSR nfvi metrics
+ */
+function mergeVnfrNfviMetrics(vnfr, nsr) {
+    for (var i = 0; i < vnfr.length; i ++) {
+        var title = vnfr[i].title;
+        var matched = false;
+        for (var j = 0; j < nsr.length; j++) {
+            if (nsr[j] && nsr[j].title == title) {
+                matched = true;
+                nsr[j].data = nsr[j].data.concat(vnfr[i].data).sort(function(a,b) {
+                    return (a.name > b.name) ? 1 : -1;
+                });
+                break;
+            }
+        }
+        if (!matched) {
+            nsr.push({
+                title: title,
+                data: vnfr[i].data
+            });
+        }
+    }
+}
+
+function terminationPointValues (node) {
+    var tpids = [];
+    var attrs = { 'tp-id': [] };
+    var TERM_PT_KEY = 'ietf-network-topology:termination-point';
+    var TERM_PT_ATTR_KEY = 'ietf-l2-topology:l2-termination-point-attributes';
+
+    var node_id = node['node-id'];
+    node[TERM_PT_KEY].forEach(
+        function(elem, index, array) {
+            if ('tp-id' in elem) {
+                attrs['tp-id'].push(elem['tp-id'])
+            }
+            if (TERM_PT_ATTR_KEY in elem) {
+                for (var key in elem[TERM_PT_ATTR_KEY]) {
+                    if (!(key in attrs)) {
+                        attrs[key] = _.cloneDeep(elem[TERM_PT_ATTR_KEY][key]);
+                    }
+                }
+            }
+        });
+    return {
+        'node-id': node_id,
+        attrs: attrs
+    }
+}
+
+// Transforms one or more topologies into a collection of nodes, links
+// usable by D3.js
+function transformNetworkTopology(raw) {
+    var nodes = [];
+    var links = [];
+
+    var y = 0;
+    var id = 1;
+
+    var node_mapper = {};
+    var network_ids = [];
+
+    var networks = raw;
+    if ('collection' in raw) {
+        networks = raw.collection;
+    }
+    if ('ietf-network:network' in networks) {
+        networks = networks['ietf-network:network'];
+    }
+
+    // for each network in the array of networks
+    for (var net_index=0, tot_networks=networks.length; net_index < tot_networks; net_index++) {
+        var network = networks[net_index];
+        var network_id = networks[net_index]['network-id'];
+        if (network_ids.indexOf(network_id) == -1) {
+            network_ids.push(network_id);
+        }
+        var raw_nodes = network['node'] || [];
+        var x = 0;
+        for (var index=0, tot=raw_nodes.length; index < tot; index++) {
+            var termination_point = [];
+            var new_node = {
+                id: id,
+                // TODO: make short name,
+                name: raw_nodes[index]['node-id'],
+                full_name: raw_nodes[index]['node-id'],
+                network: network_id,
+                x: x,
+                y: y,
+                attr: terminationPointValues(raw_nodes[index]).attrs
+            };
+            nodes.push(new_node);
+            // What do wse do if the name is already collected
+            node_mapper[new_node.name] = nodes.length-1;
+            x += 20;
+            id++;
+        }
+
+        var raw_links = network['ietf-network-topology:link'];
+        if (raw_links) {
+            for (var index=0, tot=raw_links.length; index < tot; index++) {
+                var source_name = raw_links[index]['source']['source-node'];
+                var dest_name = raw_links[index]['destination']['dest-node'];
+                var new_link = {
+                    source: node_mapper[source_name],
+                    target: node_mapper[dest_name]
+                };
+                links.push(new_link);
+            }
+        }
+        // prep for next network
+        y += 20;
+    }
+
+    // D3 is expecting array indexes of the nodes for the links
+    // Now for the links to find the nodes
+
+    return {
+        nodes: nodes,
+        links: links,
+        network_ids: network_ids
+    };
+}
+
+
+module.exports = {
+    transformNetworkTopology: transformNetworkTopology,
+    mergeVnfrNfviMetrics: mergeVnfrNfviMetrics
+}