Skip to content
Snippets Groups Projects
scheduling.py 4.87 KiB
Newer Older
"""
This file contains the database models
"""

from django.db.models import Model, CharField, DateTimeField, BooleanField, ForeignKey, CASCADE, IntegerField, SET_NULL, PROTECT, ManyToManyField
from django.contrib.postgres.fields import ArrayField, JSONField
from .specification import AbstractChoice, BasicCommon, Template, NamedCommon, WorkRequestBlueprint
from enum import Enum


#
# I/O
#

class TaskIORole(BasicCommon):
    role = ForeignKey('RoleChoice', null=False, on_delete=CASCADE)
    datatype = ForeignKey('DatatypeChoice', null=False, on_delete=CASCADE)
    dataformats = ManyToManyField('DataformatChoice', blank=True)
    outputs = ManyToManyField('TaskTemplate', related_name='inputs_dataproduct_relation', blank=True) # blank=True required to make ManyToMany optional in Django validation
    inputs = ManyToManyField('TaskTemplate', related_name='input_roles_dataproduct_relation', blank=True)


#
# Choices
#

class TaskStateChoice(AbstractChoice):
    """Defines the model and predefined list of possible TaskStatusChoice's for Task.
    The items in the Choises class below are automagically populated into the database via a data migration."""
    class Choices(Enum):
        CREATING = "creating"
        CREATED = "created"
        SCHEDULING = "scheduling"
        SCHEDULED = "scheduled"
        QUEUEING = "queueing"
        QUEUED = "queued"
        STARTING = "starting"
        STARTED = "started"
        FINISHING = "finishing"
        FINISHED = "finished"
        CANCELLING = "cancelling"
        CANCELLED = "cancelled"
        ERROR = "error"


class TaskTypeChoice(AbstractChoice):
    """Defines the model and predefined list of possible TaskTypeChoice's for Task.
    The items in the Choises class below are automagically populated into the database via a data migration."""
    class Choices(Enum):
        OBSERVATION = "observation"
        PIPELINE = "pipeline"
        COYP = "copy"
        INSPECTION = "inspection"
        DELETION = "deletion"


class StationTypeChoice(AbstractChoice):
        """Defines the model and predefined list of possible StationTypeChoice's for AntennaSet.
        The items in the Choises class below are automagically populated into the database via a data migration."""

        class Choices(Enum):
            CORE = "core"
            REMOTE = "remote"
            INTERNATIONAL = "international"


#
# Templates
#

class TaskTemplate(Template):
    queue = BooleanField(default=False)
    realtime = BooleanField(default=False)

class DefaultTaskTemplate(BasicCommon):
    name = CharField(max_length=30, unique=True)
    template = ForeignKey('TaskTemplate', on_delete=PROTECT)

class DataproductSpecificationTemplate(Template):
    pass

class DefaultDataproductSpecificationTemplate(BasicCommon):
    name = CharField(max_length=30, unique=True)
    template = ForeignKey('DataproductSpecificationTemplate', on_delete=PROTECT)


#
# Instance Objects
#

class Task(BasicCommon):
    type = ForeignKey('TaskTypeChoice', null=False, on_delete=CASCADE)
    start_time = DateTimeField()
    stop_time = DateTimeField()
    state = ForeignKey('TaskStateChoice', null=False, on_delete=PROTECT, related_name='task_states') # set CANCELLED or ERROR instead?
    requested_state = ForeignKey('TaskStateChoice', null=False, on_delete=CASCADE, related_name='task_requested_states') # set CANCELLED or ERROR instead?
    specification = JSONField()
    work_request_blueprint = ForeignKey('WorkRequestBlueprint', null=True, on_delete=SET_NULL)
    template = ForeignKey('TaskTemplate', null=False, on_delete=CASCADE)
    #resource_claim = ForeignKey("ResourceClaim", null=False, on_delete=CASCADE) # todo <-- how is this external reference supposed to work?


class DataproductRelation(BasicCommon):
    task = ForeignKey('Task', null=False, on_delete=CASCADE)
    input = ForeignKey('Dataproduct', related_name='inputs_dataproduct_relation',  null=True, on_delete=SET_NULL)
    output = ForeignKey('Dataproduct', related_name='outputs_dataproduct_relation', null=True, on_delete=SET_NULL)
    input_role = ForeignKey('TaskIORole', related_name='input_roles_dataproduct_relation', null=True, on_delete=SET_NULL)
    output_role = ForeignKey('TaskIORole', related_name='output_roles_dataproduct_relation', null=True, on_delete=SET_NULL)


class Dataproduct(BasicCommon):
    filename = CharField(max_length=128)
    directory = CharField(max_length=1024)
    dataformat = ForeignKey('DataformatChoice', null=False, on_delete=CASCADE)
    deleted_since = DateTimeField(null=True)
    pinned_since = DateTimeField(null=True)
    specification = JSONField()
    specification_template = ForeignKey('DataproductSpecificationTemplate', null=False, on_delete=CASCADE)


class AntennaSet(NamedCommon):
    station_type = ForeignKey('StationTypeChoice', null=False, on_delete=CASCADE)
    rcus = ArrayField(IntegerField(), size=128, blank=False)
    inputs = ArrayField(CharField(max_length=30), size=128, blank=True)