CORD-2753 Allow owner_class_name to be set for ServiceInstances
Change-Id: Ia67882027a3c18bfada099bcf83cd016558c47cf
diff --git a/lib/xos-genx/xosgenx/targets/service.xtarget b/lib/xos-genx/xosgenx/targets/service.xtarget
index 9d2915d..a9ca934 100644
--- a/lib/xos-genx/xosgenx/targets/service.xtarget
+++ b/lib/xos-genx/xosgenx/targets/service.xtarget
@@ -43,6 +43,10 @@
KIND = {{ xproto_first_non_empty([m.options.kind, options.kind, options.name, "Set a kind in your xproto!"]) }}
+ {% if m.options.owner_class_name %}
+ OWNER_CLASS_NAME = {{ m.options.owner_class_name }}
+ {% endif %}
+
class Meta:
app_label = {{ xproto_first_non_empty([m.options.app_label, options.app_label, options.name, "Set an app label in your xproto!"]) | lower}}
# name = {{ xproto_first_non_empty([m.options.name, options.name, "Set a name in your xproto!"]) }}
diff --git a/xos/core/models/serviceinstance.py b/xos/core/models/serviceinstance.py
index 9cc6dab..a4ab59d 100644
--- a/xos/core/models/serviceinstance.py
+++ b/xos/core/models/serviceinstance.py
@@ -63,3 +63,33 @@
return None
return sorted(st, key=attrgetter('id'))[0]
+ def save(self, *args, **kwargs):
+ if hasattr(self, "OWNER_CLASS_NAME"):
+ owner_class = self.get_model_class_by_name(self.OWNER_CLASS_NAME)
+ if not owner_class:
+ raise XOSValidationError("Cannot find owner class %s" % self.OWNER_CLASS_NAME)
+
+ need_set_owner = True
+ if self.owner_id:
+ # Check to see if owner is set to a valid instance of owner_class. If it is, then we already have an
+ # owner. If it is not, then some other misbehaving class must have altered the ServiceInstance.meta
+ # to point to its own default (these services are being cleaned up).
+ if owner_class.objects.filter(id=self.owner_id).exists():
+ need_set_owner = False
+
+ if need_set_owner:
+ owners = owner_class.objects.all()
+ if not owners:
+ raise XOSValidationError("Cannot find eligible owner of class %s" % self.OWNER_CLASS_NAME)
+
+ self.owner = owners[0]
+
+ # If the model has a Creator and it's not specified, then attempt to default to the Caller. Caller is
+ # automatically filled in my the API layer. This code was typically used by ServiceInstances that lead to
+ # instance creation.
+ if (hasattr(self, "creator")) and (not self.creator) and (hasattr(self, "caller")) and (self.caller):
+ self.creator = self.caller
+
+ super(ServiceInstance, self).save(*args, **kwargs)
+
+
diff --git a/xos/core/models/xosbase_header.py b/xos/core/models/xosbase_header.py
index f16b611..ae42c3e 100644
--- a/xos/core/models/xosbase_header.py
+++ b/xos/core/models/xosbase_header.py
@@ -144,6 +144,15 @@
def get_field_diff(self, field_name):
return self.diff.get(field_name, None)
+ @classmethod
+ def get_model_class_by_name(cls, name):
+ all_models = django.apps.apps.get_models(include_auto_created=False)
+ all_models_by_name = {}
+ for model in all_models:
+ all_models_by_name[model.__name__] = model
+
+ return all_models_by_name.get(name)
+
@property
def leaf_model(self):
leaf_model_name = getattr(self, "leaf_model_name", None)
@@ -153,12 +162,7 @@
if (leaf_model_name == self.__class__.__name__):
return self
- all_models = django.apps.apps.get_models(include_auto_created=False)
- all_models_by_name = {}
- for model in all_models:
- all_models_by_name[model.__name__] = model
-
- leaf_model_class = all_models_by_name.get(self.leaf_model_name)
+ leaf_model_class = self.get_model_class_by_name(self.leaf_model_name)
assert (self.id)