[ONOS-7883] modify tapiHelper.py to enable line-side service random creation and client-side service ordered creation on TX<->OLS<->TX transimission system
Change-Id: I2b2d6e88dd2484c6af59767ff0f6d62c6b5fe71a
diff --git a/tools/test/scenarios/bin/tapiHelper.py b/tools/test/scenarios/bin/tapiHelper.py
index f5bfcc8..036e27b 100755
--- a/tools/test/scenarios/bin/tapiHelper.py
+++ b/tools/test/scenarios/bin/tapiHelper.py
@@ -2,6 +2,8 @@
import requests
import json
+import random
+from sets import Set
#
@@ -16,14 +18,13 @@
"service-interface-point": {
"service-interface-point-uuid" : sip_uuids[0]
}
- }
- ,
+ },
{
"local-id": sip_uuids[1],
"service-interface-point": {
"service-interface-point-uuid" : sip_uuids[1]
}
- }
+ }
]
}
}
@@ -36,28 +37,28 @@
def tapi_line_input(sip_uuids):
create_input = {
"tapi-connectivity:input" : {
- "end-point" : [
+ "end-point": [
{
- "layer-protocol-qualifier" : "tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC",
- "role" : "UNKNOWN",
- "local-id" : "Src_end_point",
- "direction" : "BIDIRECTIONAL",
- "service-interface-point" : {
+ "layer-protocol-qualifier": "tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC",
+ "role": "UNKNOWN",
+ "local-id": "Src_end_point",
+ "direction": "BIDIRECTIONAL",
+ "service-interface-point": {
"service-interface-point-uuid" : sip_uuids[0]
},
- "protection-role" : "WORK",
- "layer-protocol-name" : "PHOTONIC_MEDIA"
+ "protection-role": "WORK",
+ "layer-protocol-name": "PHOTONIC_MEDIA"
},
{
- "direction" : "BIDIRECTIONAL",
- "service-interface-point" : {
- "service-interface-point-uuid" : sip_uuids[1]
+ "direction": "BIDIRECTIONAL",
+ "service-interface-point": {
+ "service-interface-point-uuid": sip_uuids[1]
},
- "protection-role" : "WORK",
- "layer-protocol-name" : "PHOTONIC_MEDIA",
- "layer-protocol-qualifier" : "tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC",
- "role" : "UNKNOWN",
- "local-id" : "Dst_end_point"
+ "protection-role": "WORK",
+ "layer-protocol-name": "PHOTONIC_MEDIA",
+ "layer-protocol-qualifier": "tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC",
+ "role": "UNKNOWN",
+ "local-id": "Dst_end_point"
}
]
}
@@ -76,6 +77,75 @@
#
+# Check if the node is transponder.
+# True - transponder
+# False - OLS
+#
+def is_transponder_node(node):
+ if len(node["owned-node-edge-point"]) > 0 and "mapped-service-interface-point" in node["owned-node-edge-point"][0]:
+ return True
+ else:
+ return False
+
+
+#
+# Parse src and dst sip-uuids of specific link from topo.
+#
+def parse_src_dst(topo, link_index=-1):
+ if link_index == -1:
+ # select a link randomly from all links of topo
+ link_index = random.randint(0, len(topo["link"]) - 1)
+ nep_pair = topo["link"][link_index]["node-edge-point"]
+ assert topo["uuid"] == nep_pair[0]["topology-uuid"]
+ assert topo["uuid"] == nep_pair[1]["topology-uuid"]
+ src_onep, dst_onep = (find_line_onep(nep_pair[0], topo["node"]),
+ find_line_onep(nep_pair[1], topo["node"]))
+ if src_onep is not None and dst_onep is not None:
+ # If the link is between two transponders directly
+ pass
+ elif src_onep is None and dst_onep is None:
+ raise AssertionError("Impossible for that both two ports are OLS port")
+ else:
+ # If one of src_onep and dst_onep is None, then make src_onep not None,
+ # and find a new dst_onep with same connection id.
+ if src_onep is None:
+ src_onep = dst_onep
+ dst_onep = None
+ conn_id = parse_value(src_onep["name"])["odtn-connection-id"]
+ for node in topo["node"]:
+ cep = src_onep["tapi-connectivity:cep-list"]["connection-end-point"]
+ assert len(cep) == 1
+ if cep[0]["parent-node-edge-point"]["node-uuid"] != node["uuid"] and is_transponder_node(node):
+ # If this node is not the node that includes src_onep, and not a OLS node
+ for onep in node["owned-node-edge-point"]:
+ if parse_value(onep["name"])["odtn-connection-id"] == conn_id:
+ dst_onep = onep
+ break
+ if dst_onep is not None:
+ break
+
+ src_sip_uuid, dst_sip_uuid = \
+ (src_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"],
+ dst_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"])
+
+ return src_onep, dst_onep, src_sip_uuid, dst_sip_uuid
+
+
+#
+# Check whether the sip uuid is used in other existed services.
+#
+def is_port_used(sip_uuid, conn_context):
+ try:
+ for service in conn_context["connectivity-service"]:
+ for id in [0, 1]:
+ if service["end-point"][id]["service-interface-point"]["service-interface-point-uuid"] == sip_uuid:
+ return True
+ except KeyError:
+ print "There is no line-side service in ONOS now."
+ return False
+
+
+#
# Requests a connectivity service
#
def request_connection(url_connectivity, context):
@@ -127,37 +197,104 @@
#
+# Find mapped client-side sip_uuid according to a line-side sip_uuid.
+# connection-ids of these two owned-node-edge-point should be the same.
+#
+def find_mapped_client_sip_uuid(line_sip_uuid, nodes):
+ line_node = None
+ line_onep = None
+ for node in nodes:
+ if is_transponder_node(node):
+ for onep in node["owned-node-edge-point"]:
+ if onep["mapped-service-interface-point"][0]["service-interface-point-uuid"] == line_sip_uuid:
+ line_node = node
+ line_onep = onep
+ break
+ if line_node is None:
+ raise AssertionError("Cannot match line-side sip uuid in topology.")
+ conn_id = parse_value(line_onep["name"])["odtn-connection-id"]
+ for onep in line_node["owned-node-edge-point"]:
+ vals = parse_value(onep["name"])
+ if vals["odtn-connection-id"] == conn_id and vals["odtn-port-type"] == "client":
+ return onep["mapped-service-interface-point"][0]["service-interface-point-uuid"], vals
+ return None
+
+
+#
# Create a client-side connection. Firstly, get the context, parsing for SIPs that connect
# with each other in line-side; Secondly, issue the request
#
def create_client_connection(url_context, url_connectivity):
+ headers = {'Content-type': 'application/json'}
context = get_context(url_context)
# select the first topo from all topologies
topo = context["tapi-common:context"]["tapi-topology:topology-context"]["topology"][0]
+ # Gather all current used sip_uuids
+ used_sip_uuids = Set()
+ try:
+ services = context["tapi-common:context"]["tapi-connectivity:connectivity-context"]["connectivity-service"]
+ for service in services:
+ used_sip_uuids.add(service["end-point"][0]["service-interface-point"]["service-interface-point-uuid"])
+ used_sip_uuids.add(service["end-point"][1]["service-interface-point"]["service-interface-point-uuid"])
+ except KeyError:
+ print "There is no existed connectivity service inside ONOS."
- # select the first link from all links of topo
- nep_pair = topo["link"][0]["node-edge-point"]
- assert topo["uuid"] == nep_pair[0]["topology-uuid"]
- assert topo["uuid"] == nep_pair[1]["topology-uuid"]
- (src_onep, dst_onep) = (find_client_onep(nep_pair[0], topo["node"]),
- find_client_onep(nep_pair[1], topo["node"]))
- print "client side neps", (src_onep, dst_onep)
+ # select the first available line-side service as bridge. If there is no available line-side service,
+ # then only create a client-to-client service for src and dst node.
+ empty_client_src_sip_uuid, empty_client_dst_sip_uuid = None, None
+ empty_src_name, empty_dst_name, empty_client_src_name, empty_client_dst_name = None, None, None, None
+ for link_index in range(0, len(topo["link"])):
+ src_onep, dst_onep, src_sip_uuid, dst_sip_uuid = parse_src_dst(topo, link_index)
+ client_src_sip_uuid, client_src_name = find_mapped_client_sip_uuid(src_sip_uuid, topo["node"])
+ client_dst_sip_uuid, client_dst_name = find_mapped_client_sip_uuid(dst_sip_uuid, topo["node"])
+ # firstly, check if line-side service exists
+ # If line-side service exists
+ if src_sip_uuid in used_sip_uuids and dst_sip_uuid in used_sip_uuids:
+ # secondly, check if mapped client-side service exists
+ if (client_src_sip_uuid not in used_sip_uuids) and (client_dst_sip_uuid not in used_sip_uuids):
+ # If there is no such client-side connection exists
+ # Create new client-side connection directly
+ print "Create client-side connection between %s and %s." % \
+ (client_src_name["onos-cp"], client_dst_name["onos-cp"])
+ create_input_json = json.dumps(tapi_client_input((client_src_sip_uuid, client_dst_sip_uuid)))
+ resp = requests.post(url_connectivity, data=create_input_json, headers=headers,
+ auth=('onos', 'rocks'))
+ if resp.status_code != 200:
+ raise Exception('POST {}'.format(resp.status_code))
+ return resp
+ else:
+ # If there exists such client-side connection
+ # Do nothing, just continue
+ pass
+ else:
+ # If line-side service doesn't exist
+ # save 4 sip uuids, and continue
+ empty_client_src_sip_uuid = client_src_sip_uuid
+ empty_client_dst_sip_uuid = client_dst_sip_uuid
+ empty_client_src_name = client_src_name
+ empty_client_dst_name = client_dst_name
+ empty_src_name = parse_value(src_onep["name"])
+ empty_dst_name = parse_value(dst_onep["name"])
+ pass
- src_sip_uuid, dst_sip_uuid = \
- (src_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"],
- dst_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"])
- print "\nBuild client-side connectivity:\n|Item|SRC|DST|\n|:--|:--|:--|\n|onos-cp|%s|%s|\n|connection id|%s|%s|\n|sip uuid|%s|%s|" % \
- (src_onep["name"][2]["value"], dst_onep["name"][2]["value"],
- src_onep["name"][1]["value"], dst_onep["name"][1]["value"],
- src_sip_uuid, dst_sip_uuid)
- create_input_json = json.dumps(tapi_client_input((src_sip_uuid, dst_sip_uuid)))
- print "\nThe json content of creation operation for client-side connectivity service is \n\t\t%s." % \
- create_input_json
- headers = {'Content-type': 'application/json'}
- resp = requests.post(url_connectivity, data=create_input_json, headers=headers, auth=('onos', 'rocks'))
- if resp.status_code != 200:
- raise Exception('POST {}'.format(resp.status_code))
- return resp
+ # After FOR loop, if this method doesn't return, there is no available line-side
+ # service for mapped client-side service creation.
+ # So, we need to create two client-side services.
+ if empty_client_src_sip_uuid is None:
+ # None case means all client-side services exist.
+ raise AssertionError("There is no available client-side service could be created.")
+ else:
+ print "Create client-side services:"
+ print "\t- from %s to %s." % (empty_client_src_name["onos-cp"], empty_client_dst_name["onos-cp"])
+ print "This service should go through:"
+ print "\t- %s and %s." % (empty_src_name["onos-cp"], empty_dst_name["onos-cp"])
+ create_input_json = json.dumps(tapi_client_input((empty_client_src_sip_uuid, empty_client_dst_sip_uuid)))
+ resp = requests.post(url_connectivity, data=create_input_json, headers=headers,
+ auth=('onos', 'rocks'))
+ if resp.status_code != 200:
+ raise Exception('POST {}'.format(resp.status_code))
+ return resp
+
#
# Parse array structure "name" under structure "owned node edge point"
@@ -168,6 +305,7 @@
rtn[item["value-name"]] = item["value"]
return rtn
+
#
# Find node edge point of node structure in topology with client-side port, by using nep with line-side port.
# The odtn-connection-id should be the same in both line-side nep and client-side nep
@@ -201,16 +339,12 @@
context = get_context(url_context)
# select the first topo from all topologies
topo = context["tapi-common:context"]["tapi-topology:topology-context"]["topology"][0]
+ # select randomly the src_sip_uuid and dst_sip_uuid with same connection id.
+ src_onep, dst_onep, src_sip_uuid, dst_sip_uuid = parse_src_dst(topo)
+ while is_port_used(src_sip_uuid, context["tapi-common:context"]["tapi-connectivity:connectivity-context"]):
+ print "Conflict occurs between randomly selected line-side link and existed ones."
+ src_onep, dst_onep, src_sip_uuid, dst_sip_uuid = parse_src_dst(topo)
- # select the first link from all links of topo
- nep_pair = topo["link"][0]["node-edge-point"]
- assert topo["uuid"] == nep_pair[0]["topology-uuid"]
- assert topo["uuid"] == nep_pair[1]["topology-uuid"]
- src_onep, dst_onep = (find_line_onep(nep_pair[0], topo["node"]),
- find_line_onep(nep_pair[1], topo["node"]))
- src_sip_uuid, dst_sip_uuid = \
- (src_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"],
- dst_onep["mapped-service-interface-point"][0]["service-interface-point-uuid"])
print "\nBuild line-side connectivity:\n|Item|SRC|DST|\n|:--|:--|:--|\n|onos-cp|%s|%s|\n|connection id|%s|%s|\n|sip uuid|%s|%s|" % \
(src_onep["name"][2]["value"], dst_onep["name"][2]["value"],
src_onep["name"][1]["value"], dst_onep["name"][1]["value"],
@@ -225,14 +359,20 @@
return resp
+#
+# find owned-node-edge-point from all nodes according to line_nep_in_links
+#
def find_line_onep(line_nep_in_link, nodes):
for node in nodes:
if node["uuid"] == line_nep_in_link["node-uuid"]:
+ if not is_transponder_node(node):
+ break
for onep in node["owned-node-edge-point"]:
if onep["uuid"] == line_nep_in_link["node-edge-point-uuid"]:
# check the length equals 1 to verify the 1-to-1 mapping relationship
assert len(onep["mapped-service-interface-point"]) == 1
return onep
+ # When node is OLS, this method will return None
return None