[SEBA-568] Using the serialNumber provided in the event

Change-Id: Id29efc0c68f5adeddd4db31004629a5ef2728eaa
diff --git a/VERSION b/VERSION
index b98c315..9fcb048 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-1.2.1
+1.2.2-dev
 
diff --git a/docs/README.md b/docs/README.md
index 9519d64..f337ee7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -119,6 +119,7 @@
   "timestamp": "2018-09-11T00:41:47.483Z",
   "deviceId": "of:000000000a5a0072", // OLT OpenFlow Id
   "portNumber": "16", // uni port
+  "serialNumber": "ALPHe3d1cfde", // ONU serial number
   "authenticationState": "STARTED" // REQUESTED, APPROVED, DENIED
 }
 ```
@@ -131,6 +132,7 @@
   "portNumber" : "16",
   "macAddress" : "90:e2:ba:82:fa:81",
   "ipAddress" : "10.11.1.1"
+  "serialNumber": "ALPHe3d1cfde", // ONU serial number
 }
 ```
 
diff --git a/xos/synchronizer/event_steps/auth_event.py b/xos/synchronizer/event_steps/auth_event.py
index b7124a9..f6992d8 100644
--- a/xos/synchronizer/event_steps/auth_event.py
+++ b/xos/synchronizer/event_steps/auth_event.py
@@ -27,16 +27,9 @@
 
     def process_event(self, event):
         value = json.loads(event.value)
-
-        onu_sn = AttHelpers.get_onu_sn(self.model_accessor, self.log, value)
-        si = AttHelpers.get_si_by_sn(self.model_accessor, self.log, onu_sn)
-        if not si:
-            self.log.exception(
-                "authentication.events: Cannot find att-workflow-driver service instance for this event",
-                kafka_event=value)
-            raise Exception("authentication.events: Cannot find att-workflow-driver service instance for this event")
-
-        self.log.info("authentication.events: Got event for subscriber", event_value=value, onu_sn=onu_sn, si=si)
-
+        self.log.info("authentication.events: Got event for subscriber", event_value=value)
+        
+        si = AttHelpers.find_or_create_att_si(self.model_accessor, self.log, value)
+        self.log.debug("authentication.events: Updating service instance", si=si)
         si.authentication_state = value["authenticationState"]
         si.save_changed_fields(always_update_timestamp=True)
diff --git a/xos/synchronizer/event_steps/dhcp_event.py b/xos/synchronizer/event_steps/dhcp_event.py
index 06abc5a..a256fd6 100644
--- a/xos/synchronizer/event_steps/dhcp_event.py
+++ b/xos/synchronizer/event_steps/dhcp_event.py
@@ -27,20 +27,11 @@
 
     def process_event(self, event):
         value = json.loads(event.value)
+        self.log.info("dhcp.events: Got event for subscriber", event_value=value)
 
-        onu_sn = AttHelpers.get_onu_sn(self.model_accessor, self.log, value)
-        si = AttHelpers.get_si_by_sn(self.model_accessor, self.log, onu_sn)
-
-        if not si:
-            self.log.exception(
-                "dhcp.events: Cannot find att-workflow-driver service instance for this event",
-                kafka_event=value)
-            raise Exception("dhcp.events: Cannot find att-workflow-driver service instance for this event")
-
-        self.log.info("dhcp.events: Got event for subscriber", event_value=value, onu_sn=onu_sn, si=si)
-
+        si = AttHelpers.find_or_create_att_si(self.model_accessor, self.log, value)
+        self.log.debug("dhcp.events: Updating service instance", si=si)
         si.dhcp_state = value["messageType"]
         si.ip_address = value["ipAddress"]
         si.mac_address = value["macAddress"]
-
         si.save_changed_fields(always_update_timestamp=True)
diff --git a/xos/synchronizer/event_steps/onu_event.py b/xos/synchronizer/event_steps/onu_event.py
index bc55f16..9a6c6f8 100644
--- a/xos/synchronizer/event_steps/onu_event.py
+++ b/xos/synchronizer/event_steps/onu_event.py
@@ -16,6 +16,7 @@
 
 import json
 from xossynchronizer.event_steps.eventstep import EventStep
+from helpers import AttHelpers
 
 
 class ONUEventStep(EventStep):
@@ -27,34 +28,16 @@
     def __init__(self, *args, **kwargs):
         super(ONUEventStep, self).__init__(*args, **kwargs)
 
-    def get_att_si(self, event):
-        try:
-            att_si = self.model_accessor.AttWorkflowDriverServiceInstance.objects.get(
-                serial_number=event["serialNumber"])
-            att_si.no_sync = False
-            att_si.uni_port_id = long(event["portNumber"])
-            att_si.of_dpid = event["deviceId"]
-            self.log.debug("onu.events: Found existing AttWorkflowDriverServiceInstance", si=att_si)
-        except IndexError:
-            # create an AttWorkflowDriverServiceInstance, the validation will be
-            # triggered in the corresponding sync step
-            att_si = self.model_accessor.AttWorkflowDriverServiceInstance(
-                serial_number=event["serialNumber"],
-                of_dpid=event["deviceId"],
-                uni_port_id=long(event["portNumber"]),
-                # we assume there is only one AttWorkflowDriverService
-                owner=self.model_accessor.AttWorkflowDriverService.objects.first()
-            )
-            self.log.debug("onu.events: Created new AttWorkflowDriverServiceInstance", si=att_si)
-        return att_si
-
     def process_event(self, event):
         value = json.loads(event.value)
         self.log.info("onu.events: received event", value=value)
 
         if value["status"] == "activated":
             self.log.info("onu.events: activated onu", value=value)
-            att_si = self.get_att_si(value)
+            att_si = AttHelpers.find_or_create_att_si(self.model_accessor, self.log, value)
+            att_si.no_sync = False
+            att_si.uni_port_id = long(value["portNumber"])
+            att_si.of_dpid = value["deviceId"]
             att_si.onu_state = "ENABLED"
             att_si.save_changed_fields(always_update_timestamp=True)
         elif value["status"] == "disabled":
diff --git a/xos/synchronizer/event_steps/test_auth_event.py b/xos/synchronizer/event_steps/test_auth_event.py
index e875c43..a2ec52f 100644
--- a/xos/synchronizer/event_steps/test_auth_event.py
+++ b/xos/synchronizer/event_steps/test_auth_event.py
@@ -61,13 +61,9 @@
 
         self.event = Mock()
 
-        self.volt = Mock()
-        self.volt.name = "vOLT"
-        self.volt.leaf_model = Mock()
-
-        self.hippie_si = AttWorkflowDriverServiceInstance()
-        self.hippie_si.serial_number = "BRCM1234"
-        self.hippie_si.save = Mock()
+        self.att_si = AttWorkflowDriverServiceInstance()
+        self.att_si.serial_number = "BRCM1234"
+        self.att_si.save = Mock()
 
     def tearDown(self):
         sys.path = self.sys_path_save
@@ -78,24 +74,22 @@
             'authenticationState': "APPROVED",
             'deviceId': "of:0000000ce2314000",
             'portNumber': "101",
+            'serialNumber': "BRCM1234",
         })
 
-        with patch.object(VOLTService.objects, "get_items") as volt_service_mock, \
-                patch.object(AttWorkflowDriverServiceInstance.objects, "get_items") as hippie_si_mock, \
-                patch.object(self.volt, "get_onu_sn_from_openflow") as get_onu_sn:
+        with patch.object(AttWorkflowDriverServiceInstance.objects, "get_items") as att_si_mock:
 
-            volt_service_mock.return_value = [self.volt]
-            get_onu_sn.return_value = "BRCM1234"
-            hippie_si_mock.return_value = [self.hippie_si]
+            att_si_mock.return_value = [self.att_si]
 
             self.event_step.process_event(self.event)
 
-            self.hippie_si.save.assert_called_with(
+            self.att_si.save.assert_called()
+            self.att_si.save.assert_called_with(
                 always_update_timestamp=True, update_fields=[
                     'authentication_state', 'serial_number', 'updated'])
-            self.assertEqual(self.hippie_si.authentication_state, 'APPROVED')
+            self.assertEqual(self.att_si.authentication_state, 'APPROVED')
 
 
 if __name__ == '__main__':
-    sys.path.append("..")  # for import of helpers.py
+    sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))  # for import of helpers.py
     unittest.main()
diff --git a/xos/synchronizer/event_steps/test_dhcp_event.py b/xos/synchronizer/event_steps/test_dhcp_event.py
index 7176ba9..275c1ef 100644
--- a/xos/synchronizer/event_steps/test_dhcp_event.py
+++ b/xos/synchronizer/event_steps/test_dhcp_event.py
@@ -86,17 +86,12 @@
             "portNumber": "1",
             "macAddress": self.mac_address,
             "ipAddress": self.ip_address,
-            "messageType": "DHCPREQUEST"
+            "messageType": "DHCPREQUEST",
+            'serialNumber': "BRCM1234",
         })
 
-        with patch.object(VOLTService.objects, "get_items") as volt_service_mock, \
-                patch.object(AttWorkflowDriverServiceInstance.objects, "get_items") as si_mock, \
-                patch.object(self.volt, "get_onu_sn_from_openflow") as get_onu_sn:
+        with patch.object(AttWorkflowDriverServiceInstance.objects, "get_items") as si_mock:
 
-            self.assertTrue(VOLTService.objects.first() is not None)
-
-            volt_service_mock.return_value = [self.volt]
-            get_onu_sn.return_value = "BRCM1234"
             si_mock.return_value = [self.si]
 
             self.event_step.process_event(self.event)
diff --git a/xos/synchronizer/helpers.py b/xos/synchronizer/helpers.py
index 9a2d035..afc471b 100644
--- a/xos/synchronizer/helpers.py
+++ b/xos/synchronizer/helpers.py
@@ -58,19 +58,21 @@
         return [True, "ONU has been validated"]
 
     @staticmethod
-    def get_onu_sn(model_accessor, log, event):
-        olt_service = model_accessor.VOLTService.objects.first()
-        onu_sn = olt_service.get_onu_sn_from_openflow(event["deviceId"], event["portNumber"])
-        if not onu_sn or onu_sn is None:
-            log.exception("Cannot find onu serial number for this event", kafka_event=event)
-            raise Exception("Cannot find onu serial number for this event")
-
-        return onu_sn
-
-    @staticmethod
-    def get_si_by_sn(model_accessor, log, serial_number):
+    def find_or_create_att_si(model_accessor, log, event):
         try:
-            return model_accessor.AttWorkflowDriverServiceInstance.objects.get(serial_number=serial_number)
+            att_si = model_accessor.AttWorkflowDriverServiceInstance.objects.get(
+                serial_number=event["serialNumber"]
+            )
+            log.debug("AttHelpers: Found existing AttWorkflowDriverServiceInstance", si=att_si)
         except IndexError:
-            log.exception("Cannot find att-workflow-driver service instance for this serial number", serial_number=serial_number)
-            raise Exception("Cannot find att-workflow-driver service instance for this serial number %s", serial_number)
\ No newline at end of file
+            # create an AttWorkflowDriverServiceInstance, the validation will be
+            # triggered in the corresponding sync step
+            att_si = model_accessor.AttWorkflowDriverServiceInstance(
+                serial_number=event["serialNumber"],
+                of_dpid=event["deviceId"],
+                uni_port_id=long(event["portNumber"]),
+                # we assume there is only one AttWorkflowDriverService
+                owner=model_accessor.AttWorkflowDriverService.objects.first()
+            )
+            log.debug("AttHelpers: Created new AttWorkflowDriverServiceInstance", si=att_si)
+        return att_si