-
Notifications
You must be signed in to change notification settings - Fork 22
/
main.py
103 lines (79 loc) · 3.31 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""Main module of kytos/pathfinder Kytos Network Application."""
from flask import jsonify, request
from kytos.core import KytosNApp, log, rest
from kytos.core.helpers import listen_to
# pylint: disable=import-error
from napps.kytos.pathfinder.graph import KytosGraph
# pylint: enable=import-error
class Main(KytosNApp):
"""Main class of kytos/pathfinder NApp.
This class is the entry point for this napp.
"""
def setup(self):
"""Create a graph to handle the nodes and edges."""
self.graph = KytosGraph()
self._topology = None
def execute(self):
"""Do nothing."""
def shutdown(self):
"""Shutdown the napp."""
def _filter_paths(self, paths, desired, undesired):
"""Apply filters to the paths list.
Make sure that each path in the list has all the desired links and none
of the undesired ones.
"""
filtered_paths = []
if desired:
for link_id in desired:
try:
endpoint_a = self._topology.links[link_id].endpoint_a.id
endpoint_b = self._topology.links[link_id].endpoint_b.id
except KeyError:
return []
for path in paths:
head = path['hops'][:-1]
tail = path['hops'][1:]
if (((endpoint_a, endpoint_b) in zip(head, tail)) or
((endpoint_b, endpoint_a) in zip(head, tail))):
filtered_paths.append(path)
else:
filtered_paths = paths
if undesired:
for link_id in undesired:
try:
endpoint_a = self._topology.links[link_id].endpoint_a.id
endpoint_b = self._topology.links[link_id].endpoint_b.id
except KeyError:
continue
for path in paths:
head = path['hops'][:-1]
tail = path['hops'][1:]
if (((endpoint_a, endpoint_b) in zip(head, tail)) or
((endpoint_b, endpoint_a) in zip(head, tail))):
filtered_paths.remove(path)
return filtered_paths
@rest('v2/', methods=['POST'])
def shortest_path(self):
"""Calculate the best path between the source and destination."""
data = request.get_json()
desired = data.get('desired_links')
undesired = data.get('undesired_links')
parameter = data.get('parameter')
paths = []
for path in self.graph.shortest_paths(data['source'],
data['destination'],
parameter):
paths.append({'hops': path})
paths = self._filter_paths(paths, desired, undesired)
return jsonify({'paths': paths})
@listen_to('kytos.topology.updated')
def update_topology(self, event):
"""Update the graph when the network topology was updated.
Clear the current graph and create a new with the most topoly updated.
"""
if 'topology' not in event.content:
return
topology = event.content['topology']
self._topology = topology
self.graph.update_topology(topology)
log.debug('Topology graph updated.')