blob: d2bc60df68e686440ed66de8e997eeaa3bb469c0 [file]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Package application holds application-template and deployment entities.
package model
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
// TemplateInputType is the declared type of a template input.
//
// Java stored this as an ORDINAL int (the field carried no @Enumerated annotation),
// which meant reordering the enum silently reinterpreted existing rows. It is stored
// by name here. The JSON representation is unchanged — Jackson already serialised
// these by name — so this is a storage fix, not an API change.
//
// Java: org.apache.airavata.application.model.template.ApplicationTemplateInputType
type TemplateInputType string
const (
TemplateInputTypeString TemplateInputType = "STRING"
TemplateInputTypeInteger TemplateInputType = "INTEGER"
TemplateInputTypeFloat TemplateInputType = "FLOAT"
TemplateInputTypeBoolean TemplateInputType = "BOOLEAN"
TemplateInputTypeFile TemplateInputType = "FILE"
TemplateInputTypeFileList TemplateInputType = "FILE_LIST"
TemplateInputTypeDirectory TemplateInputType = "DIRECTORY"
)
// Valid reports whether t is a recognised TemplateInputType.
func (t TemplateInputType) Valid() bool {
switch t {
case TemplateInputTypeString, TemplateInputTypeInteger, TemplateInputTypeFloat,
TemplateInputTypeBoolean, TemplateInputTypeFile, TemplateInputTypeFileList,
TemplateInputTypeDirectory:
return true
}
return false
}
// TemplateOutputType is the declared type of a template output. Stored by name for
// the same reason as TemplateInputType.
//
// Java: org.apache.airavata.application.model.template.ApplicationTemplateOutputType
type TemplateOutputType string
const (
TemplateOutputTypeFile TemplateOutputType = "FILE"
TemplateOutputTypeFileList TemplateOutputType = "FILE_LIST"
TemplateOutputTypeDirectory TemplateOutputType = "DIRECTORY"
)
// Valid reports whether t is a recognised TemplateOutputType.
func (t TemplateOutputType) Valid() bool {
switch t {
case TemplateOutputTypeFile, TemplateOutputTypeFileList, TemplateOutputTypeDirectory:
return true
}
return false
}
// Template describes an application's input/output contract, independent of where it
// runs.
//
// Inputs and outputs are owned by the template: created, replaced and deleted with
// it. Deployments are not — they outlive individual edits and are managed through
// their own endpoints, so deleting a template that still has deployments is refused
// with a conflict in the service layer.
//
// Java: org.apache.airavata.application.model.template.ApplicationTemplateEntity
type Template struct {
ID string `gorm:"column:template_id;primaryKey;type:varchar(36)" json:"templateId"`
TemplateName *string `gorm:"column:template_name;type:varchar(255)" json:"templateName,omitempty"`
TemplateDescription *string `gorm:"column:template_description;type:varchar(2048)" json:"templateDescription,omitempty"`
Inputs []TemplateInput `gorm:"foreignKey:TemplateID;references:ID;constraint:OnDelete:CASCADE,OnUpdate:CASCADE" json:"inputs,omitempty"`
Outputs []TemplateOutput `gorm:"foreignKey:TemplateID;references:ID;constraint:OnDelete:CASCADE,OnUpdate:CASCADE" json:"outputs,omitempty"`
// The Java entity also mapped a deployments collection. It is omitted here: the
// only thing that reads it is the "refuse to delete a template that still has
// deployments" check, which is a count against the deployments table, and the
// restricting foreign key is already declared on BatchDeployment.Template.
}
// TableName returns the table backing Template.
func (Template) TableName() string { return "application_templates" }
// BeforeCreate assigns a UUID when none was supplied.
func (t *Template) BeforeCreate(*gorm.DB) error {
if t.ID == "" {
t.ID = uuid.NewString()
}
return nil
}
// TemplateInput is one declared input of a Template.
//
// The (template_id, input_name) pair is unique. The Java @UniqueConstraint named the
// column "input_name" while Hibernate's identity naming strategy actually produced
// "inputName", so the constraint referenced a column that did not exist and never
// took effect. Under the normalised snake_case schema the name matches and the
// constraint is live — meaning duplicate input names within a template are now
// rejected, as was always intended.
//
// Java: org.apache.airavata.application.model.template.ApplicationTemplateInputEntity
type TemplateInput struct {
ID string `gorm:"column:input_id;primaryKey;type:varchar(36)" json:"inputId"`
// Owned by Template.Inputs, which declares the cascade; only the key is held here.
TemplateID *string `gorm:"column:template_id;type:varchar(36);uniqueIndex:uk_template_input_name" json:"templateId,omitempty"`
InputName *string `gorm:"column:input_name;type:varchar(255);uniqueIndex:uk_template_input_name" json:"inputName,omitempty"`
DisplayName *string `gorm:"column:display_name;type:varchar(255)" json:"displayName,omitempty"`
InputDescription *string `gorm:"column:input_description;type:varchar(2048)" json:"inputDescription,omitempty"`
InputType *TemplateInputType `gorm:"column:input_type;type:varchar(32)" json:"inputType,omitempty"`
IsRequired bool `gorm:"column:is_required;not null" json:"isRequired"`
// DefaultValue is a JSON document, either {"value": "..."} for a single value or
// {"values": [...]} for a list.
DefaultValue *string `gorm:"column:default_value;type:text" json:"defaultValue,omitempty"`
}
// TableName returns the table backing TemplateInput.
func (TemplateInput) TableName() string { return "application_template_inputs" }
// BeforeCreate assigns a UUID when none was supplied.
func (i *TemplateInput) BeforeCreate(*gorm.DB) error {
if i.ID == "" {
i.ID = uuid.NewString()
}
return nil
}
// TemplateOutput is one declared output of a Template.
//
// Java: org.apache.airavata.application.model.template.ApplicationTemplateOutputEntity
type TemplateOutput struct {
ID string `gorm:"column:output_id;primaryKey;type:varchar(36)" json:"outputId"`
// Owned by Template.Outputs, which declares the cascade; only the key is held here.
TemplateID *string `gorm:"column:template_id;type:varchar(36);index" json:"templateId,omitempty"`
OutputType *TemplateOutputType `gorm:"column:output_type;type:varchar(32)" json:"outputType,omitempty"`
OutputName *string `gorm:"column:output_name;type:varchar(255)" json:"outputName,omitempty"`
DisplayName *string `gorm:"column:display_name;type:varchar(255)" json:"displayName,omitempty"`
OutputDescription *string `gorm:"column:output_description;type:varchar(2048)" json:"outputDescription,omitempty"`
}
// TableName returns the table backing TemplateOutput.
func (TemplateOutput) TableName() string { return "application_template_outputs" }
// BeforeCreate assigns a UUID when none was supplied.
func (o *TemplateOutput) BeforeCreate(*gorm.DB) error {
if o.ID == "" {
o.ID = uuid.NewString()
}
return nil
}