[CORD-2553] enhance graph traversal functions and change branch conditions for playbook

Change-Id: I0cbf3b17e03502a735f984d4a700f0c0b49308ac
diff --git a/xos/synchronizer/steps/sync_vspgwctenant.py b/xos/synchronizer/steps/sync_vspgwctenant.py
index 715916e..0318ad6 100644
--- a/xos/synchronizer/steps/sync_vspgwctenant.py
+++ b/xos/synchronizer/steps/sync_vspgwctenant.py
@@ -117,7 +117,7 @@
         fields['s11_sgw_ip'] = self.get_ip_address_from_peer_service_instance_instance(
             's11_network', o, o, 's11_sgw_ip')
         fields['s1u_sgw_ip'] = self.get_ip_address_from_peer_service_instance(
-            's1u_network', "VSPGWUTenant", o, 's1u_sgw_ip')
+            'flat_network_s1u', "VSPGWUTenant", o, 's1u_sgw_ip')
         fields['s11_mme_ip'] = self.get_ip_address_from_peer_service_instance(
             's11_network', "VMMETenant", o, 's11_mme_ip')
 
@@ -184,25 +184,62 @@
         return ip_address
 
     def get_peer_serviceinstance_of_type(self, sitype, o):
-        prov_link_set = ServiceInstanceLink.objects.filter(
-            subscriber_service_instance_id=o.id)
+
+        global_list = self.get_all_instances_in_graph(o)
 
         try:
-            peer_service = next(
-                p.provider_service_instance for p in prov_link_set if p.provider_service_instance.leaf_model_name == sitype)
-        except StopIteration:
-            sub_link_set = ServiceInstanceLink.objects.filter(
-                provider_service_instance_id=o.id)
-            try:
-                peer_service = next(
-                    s.subscriber_service_instance for s in sub_link_set if s.subscriber_service_instance.leaf_model_name == sitype)
-            except StopIteration:
-                self.log.error(
-                    'Could not find service type in service graph', service_type=sitype, object=o)
-                raise ServiceGraphException(
-                    "Synchronization failed due to incomplete service graph")
+            peer_service = next(p for p in global_list if p.leaf_model_name == sitype)
 
-        return peer_service 
+        except StopIteration:
+            self.log.error(
+                'Could not find service type in service graph', service_type=sitype, object=o)
+            raise ServiceGraphException(
+                "Synchronization failed due to incomplete service graph")
+
+        return peer_service
+
+    def has_instance_in_list(self, list, o):
+        for instance in list:
+            if instance.leaf_model_name == o.leaf_model_name:
+                return True
+
+        return False
+
+    def get_all_instances_in_graph(self, o):
+
+        to_search_list = self.get_one_hop_instances_in_graph(o)
+        result_list = []
+
+        while len(to_search_list) > 0:
+            tmp_obj = to_search_list[0]
+            to_search_list.remove(tmp_obj)
+            tmp_list = self.get_one_hop_instances_in_graph(tmp_obj)
+
+            for index_obj in tmp_list:
+                if (not self.has_instance_in_list(to_search_list, index_obj)) and (
+                not self.has_instance_in_list(result_list, index_obj)):
+                    to_search_list.append(index_obj)
+
+            result_list.append(tmp_obj)
+        return result_list
+
+    def get_one_hop_instances_in_graph(self, o):
+        instance_list = []
+
+        # 1 hop forward and backward
+        prov_links = ServiceInstanceLink.objects.filter(subscriber_service_instance_id=o.id)
+        subs_links = ServiceInstanceLink.objects.filter(provider_service_instance_id=o.id)
+
+        # add instances located in 1 hop into instance_list
+        for tmp_link1 in prov_links:
+            if not self.has_instance_in_list(instance_list, tmp_link1.provider_service_instance):
+                instance_list.append(tmp_link1.provider_service_instance)
+
+        for tmp_link1 in subs_links:
+            if not self.has_instance_in_list(instance_list, tmp_link1.subscriber_service_instance):
+                instance_list.append(tmp_link1.subscriber_service_instance)
+
+        return instance_list
 
     # To get each network id
     def get_network_id(self, network_name):