CORD-1341: Extend IR with reverse link information
Change-Id: I582eda399f2e43e06dcd9766ecb2d5a6b1f2524b
diff --git a/xos/genx/targets/dot.xtarget b/xos/genx/targets/dot.xtarget
index d0e0369..a51ccb8 100644
--- a/xos/genx/targets/dot.xtarget
+++ b/xos/genx/targets/dot.xtarget
@@ -1,6 +1,7 @@
+digraph {
{% for m in proto.messages %}
{%- for l in m.links %}
- {{ l.src_port }} -> {{ l.dst_port }};
+ {{ m.name }} -> {{ l.peer }};
{%- endfor %}
-}
{% endfor %}
+}
diff --git a/xos/genx/tool/tests/rlinks_test.py b/xos/genx/tool/tests/rlinks_test.py
new file mode 100644
index 0000000..649fbe2
--- /dev/null
+++ b/xos/genx/tool/tests/rlinks_test.py
@@ -0,0 +1,45 @@
+from xproto_test_base import *
+
+class XProtoRlinkTests(XProtoTest):
+ def test_proto_generator(self):
+ xproto = \
+"""
+message VRouterPort (PlCoreBase){
+ optional string name = 1 [help_text = "port friendly name", max_length = 20, null = True, db_index = False, blank = True];
+ required string openflow_id = 2 [help_text = "port identifier in ONOS", max_length = 21, null = False, db_index = False, blank = False];
+ required manytoone vrouter_device->VRouterDevice:ports = 3 [db_index = True, null = False, blank = False];
+ required manytoone vrouter_service->VRouterService:device_ports = 4 [db_index = True, null = False, blank = False];
+}
+
+message VRouterService (Service) {
+ optional string rest_hostname = 1 [db_index = False, max_length = 255, null = True, content_type = "stripped", blank = True];
+ required int32 rest_port = 2 [default = 8181, null = False, db_index = False, blank = False];
+ required string rest_user = 3 [default = "onos", max_length = 255, content_type = "stripped", blank = False, null = False, db_index = False];
+ required string rest_pass = 4 [default = "rocks", max_length = 255, content_type = "stripped", blank = False, null = False, db_index = False];
+}
+
+message VRouterDevice (PlCoreBase){
+ optional string name = 1 [help_text = "device friendly name", max_length = 20, null = True, db_index = False, blank = True];
+ required string openflow_id = 2 [help_text = "device identifier in ONOS", max_length = 20, null = False, db_index = False, blank = False];
+ required string config_key = 3 [default = "basic", max_length = 32, blank = False, help_text = "configuration key", null = False, db_index = False];
+ required string driver = 4 [help_text = "driver type", max_length = 32, null = False, db_index = False, blank = False];
+ required manytoone vrouter_service->VRouterService:devices = 5 [db_index = True, null = False, blank = False];
+}
+"""
+ target = \
+"""
+{% for m in proto.messages %}
+ {% for r in m.rlinks %}
+ {{ r }}
+ {% endfor %}
+{% endfor %}
+"""
+
+ self.generate(xproto = xproto, target = target)
+ self.assertIn("'src_port': 'device_ports'", self.get_output())
+ self.assertIn("'src_port': 'ports'", self.get_output())
+
+if __name__ == '__main__':
+ unittest.main()
+
+
diff --git a/xos/genx/tool/xos2jinja.py b/xos/genx/tool/xos2jinja.py
index d7004ad..2a20612 100644
--- a/xos/genx/tool/xos2jinja.py
+++ b/xos/genx/tool/xos2jinja.py
@@ -6,6 +6,7 @@
import sys
import jinja2
import os
+import copy
def count_messages(body):
count = 0
@@ -21,6 +22,36 @@
count+=1
return count
+def compute_rlinks(messages):
+ rev_links = {}
+
+ link_opposite = {
+ 'manytomany': 'manytomany',
+ 'manytoone' : 'onetomany',
+ 'onetoone' : 'onetoone',
+ 'onetomany' : 'manytoone'
+ }
+
+ for m in messages:
+ for l in m['links']:
+ rlink = copy.deepcopy(l)
+ rlink['_type'] = 'rlink' # An implicit link, not declared in the model
+ rlink['src_port'] = l['dst_port']
+ rlink['dst_port'] = l['src_port']
+ rlink['peer'] = m['name']
+ rlink['link_type'] = link_opposite[l['link_type']]
+
+ try:
+ rev_links[l['peer']].append(rlink)
+ except KeyError:
+ rev_links[l['peer']] = [rlink]
+
+ for m in messages:
+ try:
+ m['rlinks'] = rev_links[m['name']]
+ except KeyError:
+ pass
+
class Stack(list):
def push(self,x):
self.append(x)
@@ -243,6 +274,7 @@
messages.insert(0,m)
+ compute_rlinks(messages)
self.messages = messages
return True