CORD-2919 Prevent fabric service from failing if missing instance encountered
Change-Id: Ic7747bc23623abdec5e4b9554d7c6dd7f88fbe7c
diff --git a/xos/synchronizer/steps/sync_addressmanagerserviceinstance.py b/xos/synchronizer/steps/sync_addressmanagerserviceinstance.py
index 8f48b45..8c15676 100644
--- a/xos/synchronizer/steps/sync_addressmanagerserviceinstance.py
+++ b/xos/synchronizer/steps/sync_addressmanagerserviceinstance.py
@@ -16,9 +16,11 @@
import requests
from synchronizers.new_base.syncstep import SyncStep, DeferredException
from synchronizers.new_base.modelaccessor import *
-from xos.logger import Logger, logging
-logger = Logger(level=logging.INFO)
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get('logging'))
DATAPLANE_IP = "dataPlaneIp"
PREFIX = "prefix"
@@ -63,30 +65,35 @@
fs = FabricService.objects.first()
if (not fs) or (not fs.autoconfig):
- logger.info("Not FabricServer or not autoconfig. Returning []");
+ log.info("Not FabricServer or not autoconfig. Returning []");
return []
objs = super(SyncAddressManagerServiceInstance, self).fetch_pending(deleted)
objs = list(objs)
# Check that each is a valid VSG tenant or instance
- for address_si in objs:
+ for address_si in objs[:]:
sub = self.get_subscriber(address_si)
if sub:
- if not sub.instance:
- logger.info("Skipping %s because it has no instance" % address_si)
+ # TODO: This check is making assumptions about the subscriber service. Consider breaking hardcoded
+ # dependency.
+ if (not hasattr(sub, "instance")) or (not sub.instance):
+ log.info("Skipping %s because it has no instance" % address_si)
objs.remove(address_si)
else:
# Maybe the Address is for an instance
# TODO: tenant_for_instance_id needs to be a real database field
instance_id = address_si.get_attribute("tenant_for_instance_id")
if not instance_id:
- logger.info("Skipping %s because it has no tenant_for_instance_id" % address_si)
+ log.info("Skipping %s because it has no tenant_for_instance_id" % address_si)
objs.remove(address_si)
else:
- instance = Instance.objects.filter(id=instance_id)[0]
- if not instance.instance_name:
- logger.info("Skipping %s because it has no instance.instance_name" % address_si)
+ instances = Instance.objects.filter(id=instance_id)
+ if not instances:
+ log.error("Skipping %s because it appears to be linked to a dead instance" % address_si)
+ objs.remove(address_si)
+ elif not instances[0].instance_name:
+ log.info("Skipping %s because it has no instance.instance_name" % address_si)
objs.remove(address_si)
return objs
@@ -105,17 +112,20 @@
def get_routes_url(self, fos):
url = 'http://%s:%s/onos/routeservice/routes' % (fos.rest_hostname, fos.rest_port)
- logger.info("url: %s" % url)
+ log.info("url: %s" % url)
return url
def sync_record(self, address_si):
fos = self.get_fabric_onos_service()
data = self.map_tenant_to_route(address_si)
+ if not data:
+ # Raise an exception so the synchronizer does not mark this record as synced
+ raise Exception("map_tenant_to_route returned no data for %s" % address_si)
r = self.post_route(fos, data)
- logger.info("Posted %s: status: %s result '%s'" % (address_si, r.status_code, r.text))
+ log.info("Posted %s: status: %s result '%s'" % (address_si, r.status_code, r.text))
def delete_record(self, address_si):
pass
@@ -133,10 +143,18 @@
sub = self.get_subscriber(address_si)
if sub:
- instance = sub.instance
+ # TODO: This check is making assumptions about the subscriber service. Consider breaking hardcoded
+ # dependency.
+ if hasattr(sub, "instance"):
+ instance = sub.instance
else:
instance_id = address_si.get_attribute("tenant_for_instance_id")
- instance = Instance.objects.filter(id=instance_id)[0]
+ instances = Instance.objects.filter(id=instance_id)
+ if instances:
+ instance = instances[0]
+
+ if not instance:
+ return None
node = instance.node
dataPlaneIp = node.dataPlaneIp
@@ -156,8 +174,8 @@
r = requests.delete(url, json=route, auth=(fos.rest_username, fos.rest_password))
- logger.info("status: %s" % r.status_code)
- logger.info('result: %s' % r.text)
+ log.info("status: %s" % r.status_code)
+ log.info('result: %s' % r.text)
return r