15c18ad127a6fc11cbb63db696065e2c48d215d4
[nepi.git] / src / nepi / util / parser / base.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import sys
5
6 class ExperimentData(object):
7     def __init__(self):
8         self.data = dict()
9
10     @property
11     def guids(self):
12         return self.data.keys()
13
14     def add_testbed_data(self, guid, testbed_id, testbed_version):
15         testbed_data = dict()
16         testbed_data["testbed_id"] = testbed_id
17         testbed_data["testbed_version"] = testbed_version
18         self.data[guid] = testbed_data
19
20     def add_box_data(self, guid, testbed_guid, factory_id):
21         box_data = dict()
22         box_data["testbed_guid"] = testbed_guid
23         box_data["factory_id"] = factory_id
24         self.data[guid] = box_data
25
26     def add_graphical_info_data(self, guid, x, y, width, height, label):
27         data = self.data[guid]
28         if not "graphical_info" in data:
29             data["graphical_info"] = dict()
30         graphical_info_data = data["graphical_info"]
31         graphical_info_data["x"] = x
32         graphical_info_data["y"] = y
33         graphical_info_data["width"] = width
34         graphical_info_data["height"] = height
35         graphical_info_data["label"] = label
36
37     def add_factory_attribute_data(self, guid, name, value):
38         data = self.data[guid]
39         if not "factory_attributes" in data:
40             data["factory_attributes"] = dict()
41         factory_attributes_data = data["factory_attributes"]
42         factory_attributes_data[name] = value
43
44     def add_attribute_data(self, guid, name, value):
45         data = self.data[guid]
46         if not "attributes" in data:
47             data["attributes"] = dict()
48         attributes_data = data["attributes"]
49         attributes_data[name] = value
50
51     def add_trace_data(self, guid, trace_name):
52         data = self.data[guid]
53         if not "traces" in data:
54             data["traces"] = list()
55         traces_data = data["traces"]
56         traces_data.append(trace_name)
57
58     def add_connection_data(self, guid, connector_type_name, other_guid,
59             other_connector_type_name):
60         data = self.data[guid]
61         if not "connections" in data:
62             data["connections"] = dict()
63         connections_data = data["connections"]
64         if not connector_type_name in connections_data:
65             connections_data[connector_type_name] = dict()
66         connection_data = connections_data[connector_type_name]
67         connection_data[other_guid] = other_connector_type_name
68
69     def add_address_data(self, guid, autoconf, address, family, netprefix, 
70             broadcast):
71         data = self.data[guid]
72         if not "addresses" in data:
73             data["addresses"] = list()
74         addresses_data = data["addresses"]
75         address_data = dict()
76         if autoconf:
77             address_data["AutoConfigure"] = autoconf
78         if address:
79             address_data["Address"] = address
80         if family:
81             address_data["Family"] = family
82         if netprefix:
83             address_data["NetPrefix"] = netprefix
84         if broadcast:
85             address_data["Broadcast"] = broadcast
86         addresses_data.append(address_data)
87
88     def add_route_data(self, guid, family, destination, netprefix, nexthop, 
89             interface):
90         data = self.data[guid]
91         if not "routes" in data:
92             data["routes"] = list()
93         routes_data = data["routes"]
94         route_data = dict({
95             "Family": family, 
96             "Destination": destination,
97             "NetPrefix": netprefix, 
98             "NextHop": nexthop, 
99             "Interface": Interface
100             })
101         routes_data.append(route_data)
102
103     def is_testbed_data(self, guid):
104         return True if "testbed_id" in self.data[guid] else None
105
106     def get_testbed_data(self, guid):
107         testbed_data = self.data[guid]
108         return (testbed_data["testbed_id"], testbed_data["testbed_version"])
109
110     def get_box_data(self, guid):
111         box_data = self.data[guid]
112         return (box_data["testbed_guid"], box_data["factory_id"])
113
114     def get_graphical_info_data(self, guid):
115         data = self.data[guid]
116         if not "graphical_info" in data:
117             return (0, 0, 0, 0, "") 
118         graphical_info_data = data["graphical_info"]
119         return (graphical_info_data["x"],
120                 graphical_info_data["y"],
121                 graphical_info_data["width"],
122                 graphical_info_data["height"],
123                 graphical_info_data["label"])
124
125     def get_factory_attribute_data(self, guid):
126         data = self.data[guid]
127         if not "factory_attributes" in data:
128             return []
129         factory_attributes_data = data["factory_attributes"]
130         return [(name, value) for name, value \
131                 in factory_attributes_data.iteritems()]
132
133     def get_attribute_data(self, guid):
134         data = self.data[guid]
135         if not "attributes" in data:
136             return []
137         attributes_data = data["attributes"]
138         return [(name, value) for name, value \
139                 in attributes_data.iteritems()]
140
141     def get_trace_data(self, guid):
142         data = self.data[guid]
143         if not "traces" in data:
144             return []
145         return [trace_name for trace_name in data["traces"]]
146
147     def get_connection_data(self, guid):
148         data = self.data[guid]
149         if not "connections" in data:
150             return []
151         connections_data = data["connections"]
152         return [(connector_type_name, other_guid, other_connector_type_name) \
153                     for connector_type_name, connection_data \
154                         in connections_data.iteritems() \
155                             for other_guid, other_connector_type_name \
156                                 in connection_data.iteritems()]
157
158     def get_address_data(self, guid):
159         data = self.data[guid]
160         if not "addresses" in data:
161             return []
162         addresses_data = data["addresses"]
163         return [(data["AutoConfigure"] if "AutoConfigure" in data else None,
164                  data["Address"] if "Address" in data else None,
165                  data["Family"] if "Family" in data else None,
166                  data["NetPrefix"] if "NetPrefix" in data else None,
167                  data["Broadcast"] if "Broadcast" in data else None) \
168                  for data in addresses_data]
169
170     def get_route_data(self, guid):
171         data = self.data[guid]
172         if not "routes" in data:
173             return []
174         routes_data = data["routes"]
175         return [(data["Family"],
176                  data["Destination"],
177                  data["NetPrefix"],
178                  data["NextHop"],
179                  data["Interface"]) \
180                  for data in routes_data]
181
182 class ExperimentParser(object):
183     def to_data(self, experiment_description):
184         data = ExperimentData()
185         for testbed_description in experiment_description.testbed_descriptions:
186             guid = testbed_description.guid
187             testbed_id = testbed_description.provider.testbed_id
188             testbed_version = testbed_description.provider.testbed_version
189             data.add_testbed_data(guid, testbed_id, testbed_version)
190             self.graphical_info_to_data(data, guid, 
191                     testbed_description.graphical_info)
192             self.attributes_to_data(data, guid, testbed_description.attributes)
193             for box in testbed_description.boxes:
194                 data.add_box_data(box.guid, guid, box.factory_id)
195                 self.graphical_info_to_data(data, box.guid, box.graphical_info)
196                 self.factory_attributes_to_data(data, box.guid, 
197                         box.factory_attributes)
198                 self.attributes_to_data(data, box.guid, box.attributes)
199                 self.traces_to_data(data, box.guid, box.traces)
200                 self.connections_to_data(data, box.guid, box.connectors)
201                 self.addresses_to_data(data, box.guid, box.addresses)
202                 self.routes_to_data(data, box.guid, box.routes)
203         return data
204
205     def graphical_info_to_data(self, data, guid, g_info):
206         data.add_graphical_info_data(guid, g_info.x, g_info.y, g_info.width, 
207                 g_info.height, g_info.label)
208
209     def factory_attributes_to_data(self, data, guid, attributes):
210         for attribute in attributes:
211             if attribute.modified:
212                 data.add_factory_attribute_data(guid, attribute.name, 
213                         attribute.value)
214
215     def attributes_to_data(self, data, guid, attributes):
216         for attribute in attributes:
217             if attribute.modified:
218                 data.add_attribute_data(guid, attribute.name, attribute.value)
219
220     def traces_to_data(self, data, guid, traces):
221         for trace in traces:
222             if trace.enabled:
223                 data.add_trace_data(guid, trace.name)
224
225     def connections_to_data(self, data, guid, connectors):
226         for connector in connectors:
227             connector_type_name = connector.connector_type.name
228             for other_connector in connector.connections:
229                 other_guid = other_connector.box.guid
230                 other_connector_type_name = other_connector.connector_type.name
231                 data.add_connection_data(guid, connector_type_name, other_guid,
232                         other_connector_type_name)
233
234     def addresses_to_data(self, data, guid, addresses):
235         for addr in addresses:
236              autoconf = addr.get_attribute_value("AutoConfigure") \
237                     if addr.is_attribute_modified("AutoConfigure") else None
238              address = addr.get_attribute_value("Address") \
239                     if addr.is_attribute_modified("Address") else None
240              netprefix = addr.get_attribute_value("NetPrefix") \
241                     if addr.is_attribute_modified("NetPrefix") else None
242              family = addr.get_attribute_value("Family") \
243                     if addr.is_attribute_modified("Family") else None
244              broadcast = addr.get_attribute_value("Broadcast") \
245                     if addr.has_attribute("Broadcast") and \
246                      addr.is_attribute_modified("Broadcast") else None
247              data.add_address_data(guid, autoconf, address, family, netprefix, 
248                     broadcast)
249
250     def routes_to_data(self, data, guid, routes):
251         for route in routes:
252              family = route.get_attribute_value("Family")
253              destination = route.get_attribute_value("Destination")
254              netprefix = route.get_attribute_value("NetPrefix")
255              nexthop = route.get_attribute_value("NextHop")
256              interface = route.get_attribute_value("Interface")
257              data.add_route_data(guid, family, destination, netprefix, nexthop, 
258                     interface)
259
260     def from_data(self, experiment_description, data):
261         box_guids = list()
262         for guid in data.guids:
263             if data.is_testbed_data(guid):
264                 self.testbed_from_data(experiment_description, guid, data)
265             else:
266                 self.box_from_data(experiment_description, guid, data)
267                 box_guids.append(guid)
268         self.connections_from_data(experiment_description, box_guids, data)
269
270     def testbed_from_data(self, experiment_description, guid, data):
271         (testbed_id, testbed_version) = data.get_testbed_data(guid)
272         mod_name = 'nepi.testbeds.%s' % testbed_id
273         if not mod_name in sys.modules:
274             __import__(mod_name)
275         testbed_mod = sys.modules[mod_name]
276         provider = testbed_mod.TestbedFactoriesProvider(testbed_version)
277         experiment_description.add_testbed_description(provider)
278         testbed_description = experiment_description.testbed_description(guid)
279         self.attributes_from_data(testbed_description, data)
280
281     def box_from_data(self, experiment_description, guid, data):
282         (testbed_guid, factory_id) = data.get_box_data(guid)
283         testbed_description = experiment_description.testbed_description(
284                 testbed_guid)
285         self.factory_attributes_from_data(testbed_description, factory_id,
286                 guid, data)
287         box = testbed_description.create(factory_id)
288         self.graphical_info_from_data(box, data)
289         self.attributes_from_data(box, data)
290         self.traces_from_data(box, data)
291         self.addresses_from_data(box, data)
292         self.routes_from_data(box, data)
293
294     def graphical_info_from_data(self, element, data):
295         (x, y, width, height, label) =  data.get_graphical_info_data(
296                 element.guid)
297         element.graphical_info.x = x
298         element.graphical_info.y = y
299         element.graphical_info.width = width
300         element.graphical_info.height = height
301         element.graphical_info.label = label
302
303     def factory_attributes_from_data(self, testbed_description, factory_id, 
304             guid, data):
305         factory = testbed_description.provider.factory(factory_id)
306         for (name, value) in data.get_factory_attribute_data(guid):
307             factory.set_attribute_value(name, value)
308
309     def attributes_from_data(self, element, data):
310         for name, value in data.get_attribute_data(element.guid):
311             element.set_attribute_value(name, value)
312
313     def traces_from_data(self, box, data):
314         for name in data.get_trace_data(box.guid):
315             box.trace(name).enable()
316
317     def addresses_from_data(self, box, data):
318         for (autoconf, address, family, netprefix, broadcast) \
319                 in data.get_address_data(box.guid):
320             addr = box.add_address()
321             if autoconf:
322                 addr.set_attribute_value("AutoConfigure", autoconf)
323             if address:
324                 addr.set_attribute_value("Address", address)
325             if family:
326                 addr.set_attribute_value("Family", family)
327             if netprefix:
328                 addr.set_attribute_value("NetPrefix", netprefix)
329             if broadcast:
330                 addr.set_attribute_value("Broadcast", broadcast)
331
332     def routes_from_data(self, box, data):
333          for (family, destination, netprefix, nexthop, interface) \
334                 in data.get_route_data(box.guid):
335             addr = box.add_route(family)
336             addr.set_attribute_value("Destination", destination)
337             addr.set_attribute_value("NetPrefix", netprefix)
338             addr.set_attribute_value("NextHop", nexthop)
339             addr.set_attribute_value("Interface", interface)
340
341     def connections_from_data(self, experiment_description, guids, data):
342         for guid in guids:
343             box = experiment_description.box(guid)
344             for (connector_type_name, other_guid, other_connector_type_name) \
345                     in data.get_connection_data(guid):
346                     other_box = experiment_description.box(other_guid)
347                     connector = box.connector(connector_type_name)
348                     other_connector = other_box.connector(
349                             other_connector_type_name)
350                     if not connector.is_connected(other_connector):
351                         connector.connect(other_connector)
352
353