[CORD-2887] Adding convenience method for subscribed_services and provided_services

Change-Id: I97ab6cb47614387a8d906f88cd6326c9c77caeb8
diff --git a/xos/xos_client/xosapi/convenience/service.py b/xos/xos_client/xosapi/convenience/service.py
index 063e73c..f8d108f 100644
--- a/xos/xos_client/xosapi/convenience/service.py
+++ b/xos/xos_client/xosapi/convenience/service.py
@@ -48,5 +48,21 @@
     def get_service_instance_class(self):
         return getattr(self.stub, self.get_service_instance_class_name())
 
+    @property
+    def provider_services(self):
+        svcs = []
+        service_deps = self.subscribed_dependencies.all()
+        for dep in service_deps:
+            svcs.append(dep.provider_service)
+        return svcs
+
+    @property
+    def subscriber_services(self):
+        svcs = []
+        service_deps = self.provided_dependencies.all()
+        for dep in service_deps:
+            svcs.append(dep.subscriber_service)
+        return svcs
+
 
 register_convenience_wrapper("Service", ORMWrapperService)
diff --git a/xos/xos_client/xosapi/convenience/serviceinstance.py b/xos/xos_client/xosapi/convenience/serviceinstance.py
index 5bc79d7..5ed3883 100644
--- a/xos/xos_client/xosapi/convenience/serviceinstance.py
+++ b/xos/xos_client/xosapi/convenience/serviceinstance.py
@@ -75,12 +75,15 @@
         wi = self.westbound_service_instances
 
         if len(wi) == 0:
-            raise Exception('ServiceInstance %s has no westbound service instances')
+            log.error("ServiceInstance with id %s has no westbound service instances, can't find property %s in the chain" % (self.id, prop_name))
+            raise Exception("ServiceInstance with id %s has no westbound service instances" % self.id)
 
         for i in wi:
             if hasattr(i, prop_name):
                 return getattr(i, prop_name)
             else:
+                # cast to the ServiceInstance model
+                i = self.stub.ServiceInstance.objects.get(id=i.id)
                 return i.get_westbound_service_instance_properties(prop_name)
 
 register_convenience_wrapper("ServiceInstance", ORMWrapperServiceInstance)
\ No newline at end of file
diff --git a/xos/xos_client/xosapi/convenience/voltserviceinstance.py b/xos/xos_client/xosapi/convenience/voltserviceinstance.py
index aff3ac4..9d2b7aa 100644
--- a/xos/xos_client/xosapi/convenience/voltserviceinstance.py
+++ b/xos/xos_client/xosapi/convenience/voltserviceinstance.py
@@ -55,18 +55,65 @@
             'VOLTServiceInstance.c_tag is DEPRECATED, use get_westbound_service_instance_properties instead')
         return self.subscriber.c_tag
 
-    @property
-    def s_tag(self):
-        log.warning(
-            'VOLTServiceInstance.s_tag is DEPRECATED, use get_westbound_service_instance_properties instead')
+    def get_olt_device_by_subscriber(self):
         if not self.subscriber:
-            raise Exception("vOLT %s has no subscriber" % self.name)
+            raise Exception("vOLTServiceInstance %s has no subscriber" % self.name)
 
         olt_device = self.stub.OLTDevice.objects.get(name=self.subscriber.olt_device)
-        olt_port = self.stub.PONPort.objects.get(name=self.subscriber.olt_port, olt_device_id=olt_device.id)
+        return olt_device
 
-        if olt_port:
-            return olt_port.s_tag
-        return None
+    def get_olt_port_by_subscriber(self):
+        if not self.subscriber:
+            raise Exception("vOLTServiceInstance %s has no subscriber" % self.name)
+
+        olt_device = self.get_olt_device_by_subscriber()
+        olt_port = self.stub.PONPort.objects.get(name=self.subscriber.olt_port, olt_device_id=olt_device.id)
+        return olt_port
+
+    @property
+    def s_tag(self):
+        try:
+            olt_port = self.get_olt_device_by_subscriber()
+
+            if olt_port:
+                return olt_port.s_tag
+            return None
+        except Exception, e:
+            log.warning('Error while reading c_tag: %s' % e.message)
+            return None
+
+    @property
+    def switch_datapath_id(self):
+        try:
+            olt_device = self.get_olt_device_by_subscriber()
+            if olt_device:
+                return olt_device.switch_datapath_id
+            return None
+        except Exception, e:
+            log.warning('Error while reading switch_datapath_id: %s' % e.message)
+            return None
+
+    @property
+    def switch_port(self):
+        try:
+            olt_device = self.get_olt_device_by_subscriber()
+            if olt_device:
+                return olt_device.switch_port
+            return None
+        except Exception, e:
+            log.warning('Error while reading switch_port: %s' % e.message)
+            return None
+
+    @property
+    def outer_tpid(self):
+        try:
+            olt_device = self.get_olt_device_by_subscriber()
+            if olt_device:
+                return olt_device.outer_tpid
+            return None
+        except Exception, e:
+            log.warning('Error while reading outer_tpid: %s' % e.message)
+            return None
+
 
 register_convenience_wrapper("VOLTServiceInstance", ORMWrapperVOLTServiceInstance)