build.graph.KytosGraph.update_links()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
nop 2
dl 0
loc 13
rs 9.85
c 0
b 0
f 0
ccs 11
cts 11
cp 1
crap 4
1
"""Module Graph of kytos/pathfinder Kytos Network Application."""
2
3 1
from kytos.core import log
4
5 1
try:
6 1
    import networkx as nx
7 1
    from networkx.exception import NodeNotFound, NetworkXNoPath
8
except ImportError:
9
    PACKAGE = 'networkx>=2.2'
10
    log.error(f"Package {PACKAGE} not found. Please 'pip install {PACKAGE}'")
11
12
13 1
class KytosGraph:
14
    """Class responsible for the graph generation."""
15
16 1
    def __init__(self):
17 1
        self.graph = nx.Graph()
18
19 1
    def clear(self):
20
        """Remove all nodes and links registered."""
21 1
        self.graph.clear()
22
23 1
    def update_topology(self, topology):
24
        """Update all nodes and links inside the graph."""
25 1
        self.graph.clear()
26 1
        self.update_nodes(topology.switches)
27 1
        self.update_links(topology.links)
28
29 1
    def update_nodes(self, nodes):
30
        """Update all nodes inside the graph."""
31 1
        for node in nodes.values():
32 1
            try:
33 1
                self.graph.add_node(node.id)
34
35 1
                for interface in node.interfaces.values():
36 1
                    self.graph.add_node(interface.id)
37 1
                    self.graph.add_edge(node.id, interface.id)
38
39
            except AttributeError:
40
                pass
41
42 1
    def update_links(self, links):
43
        """Update all links inside the graph."""
44 1
        keys = []
45 1
        for link in links.values():
46 1
            if link.is_active():
47 1
                self.graph.add_edge(link.endpoint_a.id, link.endpoint_b.id)
48 1
                for key, value in link.metadata.items():
49 1
                    keys.append(key)
50 1
                    endpoint_a = link.endpoint_a.id
51 1
                    endpoint_b = link.endpoint_b.id
52 1
                    self.graph[endpoint_a][endpoint_b][key] = value
53
54 1
        self._set_default_metadata(keys)
55
56 1
    def _set_default_metadata(self, keys):
57
        """Set metadata to all links.
58
59
        Set the value to zero for inexistent metadata in a link to make those
60
        irrelevant in pathfinding.
61
        """
62 1
        for key in keys:
63 1
            for endpoint_a, endpoint_b in self.graph.edges:
64 1
                if key not in self.graph[endpoint_a][endpoint_b]:
65 1
                    self.graph[endpoint_a][endpoint_b][key] = 0
66
67 1
    @staticmethod
68
    def _remove_switch_hops(circuit):
69
        """Remove switch hops from a circuit hops list."""
70 1
        for hop in circuit['hops']:
71 1
            if len(hop.split(':')) == 8:
72 1
                circuit['hops'].remove(hop)
73
74 1
    def shortest_paths(self, source, destination, parameter=None):
75
        """Calculate the shortest paths and return them."""
76 1
        try:
77 1
            paths = list(nx.shortest_simple_paths(self.graph,
78
                                                  source,
79
                                                  destination, parameter))
80
        except (NodeNotFound, NetworkXNoPath):
81
            return []
82
        return paths
83