[CORD-2640] Storing active enodeb relation in the datamodel and not in memory

Change-Id: I950dacc6ace738e2816f6e949400e633cc8554a5
diff --git a/xos/models/models.py b/xos/models/models.py
index bf9161f..692b1aa 100644
--- a/xos/models/models.py
+++ b/xos/models/models.py
@@ -64,21 +64,14 @@
         except IndexError:
             raise XOSValidationError("Service Progran cannot be found, please make sure that the model exists.")
 
-        # NOTE if the instance is new, check that the name is not duplicated
-        instances_with_same_name = None
-        # FIXME This may leave us vulnerable to someone changing the name at a later time and causing a conflict.
-        # If that's important to prevent, we could prevent that case when `self.pk!=None`,
-        # filter for ProgranServiceInstance with the same name but `pk!=self.pk`.
-        if self.pk is None:
-            try:
-                instances_with_same_name = ProgranServiceInstance.objects.get(name=self.name)
-            except self.DoesNotExist:
-                # it's ok not to find anything here
-                pass
+        # prevent name duplicates
+        try:
+            instances_with_same_name = ProgranServiceInstance.objects.get(name=self.name)
 
-        if instances_with_same_name:
-            raise XOSValidationError("A ProgranServiceInstance with name '%s' already exists" % self.name)
-
+            if (not self.pk and instances_with_same_name) or (self.pk and self.pk != instances_with_same_name.pk):
+                raise XOSValidationError("A ProgranServiceInstance with name '%s' already exists" % self.name)
+        except self.DoesNotExist:
+            pass
 
         # TODO when saving set status to "in progress"
         super(ProgranServiceInstance, self).save(*args, **kwargs)
diff --git a/xos/models/progran.xproto b/xos/models/progran.xproto
index ad0a378..5b1a54c 100644
--- a/xos/models/progran.xproto
+++ b/xos/models/progran.xproto
@@ -50,6 +50,7 @@
     required string SubsProfile = 13 [ db_index = False, null = True, blank = True];
     optional manytoone enodeb->ENodeB:profiles = 14 [null = True, blank = True];
     required manytoone handover->Handover:profiles = 15 [null = False, blank = False];
+    optional int32 active_enodeb_id = 16 [null = True, blank = True, gui_hidden = True];
 }
 
 
diff --git a/xos/synchronizer/steps/sync_progranserviceinstance.py b/xos/synchronizer/steps/sync_progranserviceinstance.py
index bcfadfd..6529088 100644
--- a/xos/synchronizer/steps/sync_progranserviceinstance.py
+++ b/xos/synchronizer/steps/sync_progranserviceinstance.py
@@ -18,7 +18,7 @@
 import sys
 from synchronizers.new_base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
 from synchronizers.new_base.ansible_helper import run_template
-from synchronizers.new_base.modelaccessor import ProgranServiceInstance
+from synchronizers.new_base.modelaccessor import ProgranServiceInstance, ENodeB
 
 from xosconfig import Config
 from multistructlog import create_logger
@@ -37,10 +37,6 @@
 
     observes = ProgranServiceInstance
 
-    # NOTE I need to keep track of the relations between profile and enodebs to remove them
-    # it contains: <profile-id>:<enodeb_id>
-    profile_enodebs = {}
-
     def skip_ansible_fields(self, o):
         # FIXME This model does not have an instance, this is a workaroung to make it work,
         # but it need to be cleaned up creating a general SyncUsingAnsible base class
@@ -105,8 +101,10 @@
         profile_fields.update(base_field)
         self.run_playbook(o, profile_fields)
 
+        # import pdb; pdb.set_trace()
+
         # progran enodeb specific fields
-        if o.enodeb:
+        if o.enodeb_id:
             log.info("adding profile %s to enodeb %s" % (o.id, o.enodeb.enbId), object=str(o), **o.tologdict())
             enodeb_fields = {
                 'body': json.dumps({
@@ -121,25 +119,22 @@
             enodeb_fields.update(base_field)
             self.run_playbook(o, enodeb_fields)
 
-            # update local state
-            self.profile_enodebs[o.id] = o.enodeb.enbId
-        else:
-            try:
-                enbid = self.profile_enodebs[o.id]
-            except KeyError:
-                enbid = None
-            if enbid:
-                print enbid
-                log.info("removing profile %s from enodeb %s" % (o.id, self.profile_enodebs[o.id]), object=str(o), **o.tologdict())
-                enodeb_fields = {
-                    'body': '',
-                    'method': 'DELETE',
-                    'endpoint': 'enodeb/%s/profile/%s' % (enbid, o.name)
-                }
-                enodeb_fields["ansible_tag"] = o.__class__.__name__ + "_" + str(o.id) + "_rm_enodeb_from_profile"
-                enodeb_fields.update(base_field)
-                self.run_playbook(o, enodeb_fields)
-                del self.profile_enodebs[o.id]
+            o.active_enodeb_id = o.enodeb_id
+
+        elif o.active_enodeb_id:
+
+            enb_id = ENodeB.objects.get(id=o.active_enodeb_id).enbId
+
+            log.info("removing profile %s from enodeb %s" % (o.name, o.active_enodeb_id), object=str(o), **o.tologdict())
+            enodeb_fields = {
+                'body': '',
+                'method': 'DELETE',
+                'endpoint': 'enodeb/%s/profile/%s' % (enb_id, o.name)
+            }
+            enodeb_fields["ansible_tag"] = o.__class__.__name__ + "_" + str(o.id) + "_rm_enodeb_from_profile"
+            enodeb_fields.update(base_field)
+            self.run_playbook(o, enodeb_fields)
+            o.active_enodeb_id = 0
 
         o.save()