Skip to content
Snippets Groups Projects
Commit 342c0e66 authored by Jorrit Schaap's avatar Jorrit Schaap
Browse files

TMSS-272: added documentation, renamed method.

parent 1d6b1119
No related branches found
No related tags found
1 merge request!213Resolve TMSS-272
......@@ -12,7 +12,7 @@ from django.db.models import ForeignKey, CharField, DateTimeField, BooleanField,
ManyToManyField, CASCADE, SET_NULL, PROTECT, QuerySet
from django.contrib.postgres.fields import ArrayField, JSONField
from django.contrib.auth.models import User
from .specification import AbstractChoice, BasicCommon, Template, NamedCommon, check_doc_against_template
from .specification import AbstractChoice, BasicCommon, Template, NamedCommon, annotate_validate_add_defaults_to_doc_using_template
from enum import Enum
from django.db.models.expressions import RawSQL
......@@ -186,7 +186,7 @@ class Subtask(BasicCommon):
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
creating = self._state.adding # True on create, False on update
check_doc_against_template(self, 'specifications_doc', 'specifications_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'specifications_doc', 'specifications_template')
if self.state.value == SubtaskState.Choices.SCHEDULED.value and self.__original_state.value == SubtaskState.Choices.SCHEDULING.value:
if self.start_time is None:
......@@ -244,7 +244,7 @@ class SubtaskInput(BasicCommon):
selection_template = ForeignKey('TaskRelationSelectionTemplate', on_delete=PROTECT, help_text='Schema used for selection_doc.')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'selection_doc', 'selection_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'selection_doc', 'selection_template')
super().save(force_insert, force_update, using, update_fields)
......@@ -275,8 +275,8 @@ class Dataproduct(BasicCommon):
feedback_template = ForeignKey('DataproductFeedbackTemplate', on_delete=PROTECT, help_text='Schema used for feedback_doc.')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'specifications_doc', 'specifications_template')
check_doc_against_template(self, 'feedback_doc', 'feedback_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'specifications_doc', 'specifications_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'feedback_doc', 'feedback_template')
super().save(force_insert, force_update, using, update_fields)
......
......@@ -404,23 +404,30 @@ class ProjectQuota(Model):
class ResourceType(NamedCommonPK):
quantity = ForeignKey('Quantity', null=False, on_delete=PROTECT, help_text='The quantity of this resource type.')
def check_doc_against_template(model, document_attr:str, template_attr:str):
def annotate_validate_add_defaults_to_doc_using_template(model: Model, document_attr:str, template_attr:str) -> None:
'''
annotate, validate and add defaults to the JSON document in the model instance using the schema of the given template.
'''
try:
# fetch the actual JSON document and template-model-intstance
document = getattr(model, document_attr)
template = getattr(model, template_attr)
if isinstance(document, str):
document = json.loads(document)
if document is not None and template is not None:
try:
if isinstance(document, str):
document = json.loads(document)
# always annotate the json data document with a $schema URI to the schema that it is based on.
# this enables all users using this document (inside or outside of TMSS) to do their own validation and usage of editors which use the schema as UI template
document['$schema'] = template.schema['$id']
except (KeyError, TypeError) as e:
except (KeyError, TypeError, AttributeError) as e:
raise SchemaValidationException("Cannot set $schema in json_doc to the schema's $id.\nError: %s \njson_doc: %s\nschema: %s" % (str(e), document, template.schema))
# add defaults for missing properies, and validate on the fly
document = add_defaults_to_json_object_for_schema(document, template.schema)
validate_json_against_schema(document, template.schema)
# update the model instance with the updated and validated document
setattr(model, document_attr, document)
except AttributeError:
pass
......@@ -429,6 +436,7 @@ def check_doc_against_template(model, document_attr:str, template_attr:str):
except jsonschema.ValidationError as e:
raise SchemaValidationException(str(e))
class SchedulingSet(NamedCommon):
generator_doc = JSONField(null=True, help_text='Parameters for the generator (NULLable).')
generator_template = ForeignKey('GeneratorTemplate', on_delete=SET_NULL, null=True, help_text='Generator for the scheduling units in this set (NULLable).')
......@@ -436,7 +444,7 @@ class SchedulingSet(NamedCommon):
project = ForeignKey('Project', related_name="scheduling_sets", on_delete=PROTECT, help_text='Project to which this scheduling set belongs.') # protected to avoid accidents
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'generator_doc', 'generator_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'generator_doc', 'generator_template')
super().save(force_insert, force_update, using, update_fields)
......@@ -456,7 +464,7 @@ class SchedulingUnitDraft(NamedCommon):
if self.observation_strategy_template_id and self.observation_strategy_template.template:
validate_json_against_schema(self.observation_strategy_template.template, self.requirements_template.schema)
check_doc_against_template(self, 'requirements_doc', 'requirements_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'requirements_doc', 'requirements_template')
super().save(force_insert, force_update, using, update_fields)
@property
......@@ -493,7 +501,7 @@ class SchedulingUnitBlueprint(NamedCommon):
draft = ForeignKey('SchedulingUnitDraft', related_name='scheduling_unit_blueprints', on_delete=CASCADE, help_text='Scheduling Unit Draft which this run instantiates.')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'requirements_doc', 'requirements_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'requirements_doc', 'requirements_template')
super().save(force_insert, force_update, using, update_fields)
......@@ -555,7 +563,7 @@ class TaskDraft(NamedCommon):
specifications_template = ForeignKey('TaskTemplate', on_delete=CASCADE, help_text='Schema used for requirements_doc.') # todo: 'schema'?
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'specifications_doc', 'specifications_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'specifications_doc', 'specifications_template')
super().save(force_insert, force_update, using, update_fields)
@property
......@@ -669,7 +677,7 @@ class TaskBlueprint(NamedCommon):
scheduling_unit_blueprint = ForeignKey('SchedulingUnitBlueprint', related_name='task_blueprints', on_delete=CASCADE, help_text='Scheduling Unit Blueprint to which this task belongs.')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'specifications_doc', 'specifications_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'specifications_doc', 'specifications_template')
super().save(force_insert, force_update, using, update_fields)
@property
......@@ -769,7 +777,7 @@ class TaskRelationDraft(BasicCommon):
output_role = ForeignKey('TaskConnectorType', related_name='taskrelationdraft_output_roles', on_delete=CASCADE, help_text='Output connector type (what kind of data can be created as output).')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'selection_doc', 'selection_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'selection_doc', 'selection_template')
super().save(force_insert, force_update, using, update_fields)
......@@ -788,7 +796,7 @@ class TaskRelationBlueprint(BasicCommon):
selection_template = ForeignKey('TaskRelationSelectionTemplate', on_delete=CASCADE, help_text='Schema used for selection_doc.') # todo: 'schema'?
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
check_doc_against_template(self, 'selection_doc', 'selection_template')
annotate_validate_add_defaults_to_doc_using_template(self, 'selection_doc', 'selection_template')
super().save(force_insert, force_update, using, update_fields)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment