Coverage for flexnetsim/controller.py: 100%
71 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-22 20:03 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-22 20:03 +0000
1import os
2import sys
3from .network import Network
4from .connection import Connection
5from .bitrate import Bitrate
6from enum import Enum
7import json
10class Controller:
11 """
12 This class allows you to create the object Controller and manipulate it by
13 its methods. The importance of this object is that it handles connection
14 requests generated inside the Simulator by executing an allocation algorithm
15 from the Allocator object on the network. Once the process is completed, it
16 returns the result to the simulator. The Controller is the link between the
17 Simulator and the Network.
19 Attributes:
20 network (Network): Object that contains all the information about the network,
21 nodes, routes, path length and slots.
23 allocator (Allocator): The Allocator object handles the assignment of connections
24 inside a Network.
26 path (list(list(list))): Paths in the network. These are represented by three lists
27 [source][destination][path]. Source and destination are Nodes, and [path] is the path
28 between this two nodes, these nodes may have zero or more available paths. For example:
29 source node = 2, destination node = 5, and path number 2. The result is the path [2,4,6,8,5].
31 connections (list(Connection)): List of Connection objects. Connection contains the
32 information regarding the connections that are made between the nodes on a network
33 during the allocation process.
36 allocationStatus (status): Result of the allocation process, whether the
37 allocation was succesful or not. This is type allocationStatus, there are
38 three states: ALLOCATED, NOT_ALLOCATED, NA (not assigned).
40 """
41 status = Enum("status", "ALLOCATED NOT_ALLOCATED NA")
43 def __init__(self, network: Network = None):
44 """
45 Init method of class Controller.
47 Args:
48 network (:obj: Network, optional): Network object with all the information about the network,
49 nodes, routes, path length and slots.
51 """
52 self.__network = network
53 self.__allocator = None
54 self.__path = None
55 self.__connections = list()
56 self.__allocationStatus = None
58 @property
59 def network(self):
60 """
61 Get or set the attribute network.
62 """
63 return self.__network
65 @network.setter
66 def network(self, network):
67 if type(network) == Network:
68 self.__network = network
69 else:
70 raise AttributeError("You must pass a Network object")
72 @property
73 def allocator(self):
74 """
75 Get or set the attribute allocator.
76 """
77 return self.__allocator
79 @allocator.setter
80 def allocator(self, allocator):
81 self.__allocator = allocator
83 def assignConnection(self, src, dst, bit_rate, id_connection):
84 """
85 Assigns a connection between a source and a destination node through
86 an allocation method from the Allocator. It creates a connection object
87 with idConnection as its id, upon which the connections between nodes are
88 generated.
90 Args:
91 src (int): The source node of the connection
93 dst (int): The destination node of the connection
95 bit_rate (BitRate): BitRate object of the connection
97 id_connection (int): The id of the new connection object. It serves to
98 identify the connection within the attribute connections.
100 Returns:
101 The result of the allocation process, whether the
102 allocation was succesful or not. This is type allocationStatus, there are
103 three states: ALLOCATED, NOT_ALLOCATED, NA (not assigned).
105 """
107 connection = Connection(id_connection)
108 self.__allocationStatus, connection = self.__allocator(
109 src, dst, bit_rate, connection, self.__network, self.__path)
110 if self.__allocationStatus == Controller.status.ALLOCATED:
111 self.__connections.append(connection)
112 for i in range(0, len(connection.links)):
113 for j in range(0, len(connection.slots[i])):
114 self.__network.use_slot(
115 connection.links[i], slot_pos=connection.slots[i][j])
117 return self.__allocationStatus
119 def unassignConnection(self, id_connection):
120 """
121 Unnasigns the requested connection making the resources that were
122 being used become available again. It deactivates the slots that were
123 taken in the connection.
125 Args:
126 id_connection (int): The id of the new connection object. It serves to
127 identify the connection within the attribute connections.
129 Returns:
130 Number zero if unsuccessful.
132 """
134 for i in range(0, len(self.__connections)):
135 if self.__connections[i].id == id_connection:
136 for j in range(0, len(self.__connections[i].links)):
137 for k in range(0, len(self.__connections[i].slots[j])):
138 self.__network.unuse_slot(
139 self.__connections[i].links[j], slot_pos=self.__connections[i].slots[j][k])
140 self.__connections.pop(i)
141 break
142 return 0
144 # the file is within a folder called json
145 def set_paths(self, file_name):
146 """
147 Sets the path attribute from the routes on a JSON file. From this
148 file, the method creates the paths attribute based on an lists of routes. This
149 lists contains the source and destination nodes, as well as an list with all
150 the existing paths between them. The path attribute is important because it is
151 all the nodes and the respective routes that link them.
153 In the example below, the network consists of three nodes: 0, 1 and 2. Node
154 0 is connected to node 1 directly and through node 2, to which it's directly
155 connected as well. Node 2 is connected directly to node one. All the
156 connections are unidirectional.
158 Args:
159 file_name (str): Name of the JSON file that contains the routes. Example of
160 this: "routes.json"
162 Example:
163 code-block:: JSON
164 {
165 "name": "Example routes between 3 nodes",
166 "alias": "example",
167 "routes": [
168 {
169 "src": 0,
170 "dst": 1,
171 "paths": [
172 [
173 0,
174 1
175 ],
176 [
177 0,
178 2,
179 1
180 ]
181 ]
182 },
183 {
184 "src": 0,
185 "dst": 2,
186 "paths": [
187 [
188 0,
189 2
190 ]
191 ]
192 },
193 {
194 "src": 2,
195 "dst": 1,
196 "paths": [
197 [
198 2,
199 1
200 ]
201 ]
202 }
203 ]
204 };
206 """
208 self.__path = []
210 f = open(file_name)
211 data = json.load(f)
213 numberOfNodes = self.__network.node_counter
215 # set list for paths
216 for i in range(numberOfNodes):
217 self.__path.append([])
218 for t in range(numberOfNodes):
219 self.__path[i].append([])
221 routesNumber = len(data["routes"])
223 for i in range(routesNumber):
224 pathsNumber = len(data["routes"][i]["paths"])
225 src = data["routes"][i]["src"]
226 dst = data["routes"][i]["dst"]
228 for m in range(pathsNumber):
229 self.__path[src][dst].append([])
231 for b in range(pathsNumber):
232 nodesPathNumber = len(data["routes"][i]["paths"][b])
233 lastNode = nodesPathNumber - 1
234 for c in range(lastNode):
235 actNode = data["routes"][i]["paths"][b][c]
236 nextNode = data["routes"][i]["paths"][b][c + 1]
237 idLink = self.__network.is_connected(actNode, nextNode)
238 self.__path[src][dst][b].append(idLink)