2023-03-03 14:43:11 +01:00
package controllers
import (
"time"
2024-07-29 18:02:29 +02:00
"cloud.o-forge.io/core/deprecated-oc-catalog/models"
2023-03-03 14:43:11 +01:00
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
"github.com/vk496/cron"
)
type WorkflowController struct {
beego . Controller
}
// @Title Create a new workflow
// @Description Create a name for the new workflow
// @Param workflowName query string true "Name of the workflow"
// @Success 200 {string} Workflow created succeful
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// // @Security jwtAPIToken
// @router / [post]
func ( u * WorkflowController ) CreateWorkflow ( workflowName string ) {
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
// //TODO: Implement as swagger security definition (api key?)
// username, err := GetUsernameFromToken(token)
// if err != nil {
// u.Data["json"] = "No valid token"
// u.Ctx.Output.Status = 403
// u.ServeJSON()
// return
// }
username := "asd"
if err := models . CreateWorkflow ( username , workflowName ) ; err != nil {
u . Data [ "json" ] = err . Error ( )
u . Ctx . Output . Status = 400
u . ServeJSON ( )
return
}
}
// @Title List workflows
// @Description List available workflows
// @Success 200 []string List of workflows
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// // @Security jwtAPIToken
// @router / [get]
func ( u * WorkflowController ) ListWorkflows ( ) {
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
username := "asd"
w := models . GetWorkspace ( username )
if w == nil {
// No username
u . Data [ "json" ] = "Workspace doesn't exist"
u . Ctx . Output . Status = 400
u . ServeJSON ( )
}
u . Data [ "json" ] = w . GetWorkflows ( )
u . ServeJSON ( )
}
// @Title Get Workflow
// @Description Get a workflow by name
// @Param workflowName path string true "Workflow Name"
// @Success 200 {object} models.Workflow
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// // @Security jwtAPIToken
// @router /:workflowName [get]
func ( u * WorkflowController ) GetWorkflow ( workflowName string ) {
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
username := "asd"
proj , err := models . GetWorkflow ( username , workflowName )
if err != nil {
u . SetData ( err . Error ( ) )
u . Ctx . Output . Status = 400
u . ServeJSON ( )
return
}
u . Data [ "json" ] = proj
u . ServeJSON ( )
}
// @Title Add new object to a Workflow
// @Description Create a Rtype object from already added resources to the workspace
// @Param workflowName path string true "workflow Name"
// @Param rID query string true "rID of already existing item in Workspace"
// @Success 200 {string} ID of the new object (rObjID)
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// // @Security jwtAPIToken
// @router /:workflowName/add [post]
func ( u * WorkflowController ) AddElementWorkflow ( workflowName , rID string ) {
username := "asd"
rObjID , err := models . CreateObjectInWorkflow ( username , workflowName , rID )
if err != nil {
logs . Debug ( err . Error ( ) )
u . Data [ "json" ] = err . Error ( )
u . Ctx . Output . Status = 400
u . ServeJSON ( )
return
}
u . Data [ "json" ] = rObjID
u . ServeJSON ( )
return
}
// @Title Parse mxGraph
// @Description If we use this aproach to transofrm mxgraph representation in our representation, we should not use other API calls for modify the project structure or we'll have inconsistencies.
// @Param workflowName path string true "Workflow Name"
// @Param xmlData body string true "Xml representation of the workflow"
// @Success 200 The xmlgraph consumed correctly
// @Success 201 The xmlgraph consumed with issues
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// @router /:workflowName/mxGraphParser [post]
func ( u * WorkflowController ) MxGraphParser ( workflowName , xmlData string ) {
username := "asd"
err , mxissues := models . ParseMxGraph ( username , workflowName , xmlData )
if err != nil {
logs . Debug ( err . Error ( ) )
u . CustomAbort ( 400 , err . Error ( ) )
}
if len ( mxissues ) > 0 {
strErrors := make ( [ ] string , len ( mxissues ) )
for i , err := range mxissues {
strErrors [ i ] = err . Error ( )
}
u . Data [ "json" ] = strErrors
u . Ctx . Output . Status = 201
u . ServeJSON ( )
return
}
}
// @Title Get mxGraph last status
// @Description Obtain the last mxgraph XML status from the workflow
// @Param workflowName path string true "Workflow Name"
// @Success 200 The xmlgraph
// @Success 201 Empty workflow
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// @router /:workflowName/mxGraphParser [get]
func ( u * WorkflowController ) MxGraphParserConsume ( workflowName string ) {
username := "asd"
xmlData , err := models . GetMxGraph ( username , workflowName )
if err != nil {
logs . Debug ( err . Error ( ) )
u . Data [ "json" ] = err . Error ( )
u . Ctx . Output . Status = 400
u . ServeJSON ( )
return
}
if xmlData == nil {
u . Ctx . Output . Status = 201
} else {
u . Ctx . Output . Status = 200
u . Ctx . Output . Body ( [ ] byte ( * xmlData ) )
u . ServeXML ( )
}
return
}
// @Title Create a realtionship between two Robjects
// @Description Create a Rtype object from already added resources to the workspace
// @Param workflowName path string true "Workflow Name"
// @Param rObjIDsource query string true "Robject source. Usually Data"
// @Param isInput query bool true "If the operation is for input (true) linkage or output (false)"
// @Param rObjIDtarger query string true "Robject where will be written the association"
// @Success 200 {string} ID of the new object (rObjID)
// @Failure 403 Authentication issue
// @Failure 400 {string} Other error
// // @Security jwtAPIToken
// @router /:workflowName/link [post]
func ( u * WorkflowController ) LinkElementsWorkflow ( workflowName , rObjIDsource , rObjIDtarger string , isInput bool ) {
username := "asd"
err := models . LinkObjectsInWorkspace ( username , workflowName , rObjIDsource , isInput , rObjIDtarger )
if err != nil {
logs . Debug ( err . Error ( ) )
u . Data [ "json" ] = err . Error ( )
u . Ctx . Output . Status = 400
u . ServeJSON ( )
return
}
}
// @Title Get Schedule
// @Description Obtain the desired schedule of this workflow
// @Param workflowName path string true "Workflow Name"
// @Success 200 {object} models.ScheduleTime
// @Failure 403 Authentication issue
// @Failure 400 Workflow doesn't exist
// @Failure 401 Other error
// @router /:workflowName/schedule [get]
func ( u * WorkflowController ) GetWorkflowSchedule ( workflowName string ) {
username := "asd"
sched , err := models . GetWorkflowSchedule ( username , workflowName )
// Some error
if err != nil {
u . CustomAbort ( 401 , err . Error ( ) )
}
// No workflow
if sched == nil {
u . Ctx . Output . Status = 400
return
}
u . Ctx . Output . Status = 200
u . Data [ "json" ] = sched
u . ServeJSON ( )
}
// @Title Set Schedule
// @Description Set desired schedule by the user. No other effects a part of saving the user input
// @Param workflowName path string true "Workflow Name"
// @Param isService query bool true "True: Service, False: Task"
// @Param startDate query time.Time true "RFC3339 time for startDate"
// @Param stopDate query time.Time true "RFC3339 time for stopDate"
// @Param events query string false "List of events separated by comma"
// @Param cronString query string false "Cron string"
// @Param duration query uint false "Duration in seconds"
// @Success 200 {object} models.ScheduleInfo
// @Failure 403 Authentication issue
// @Failure 400 Workflow doesn't exist
// @Failure 401 Other error
// @Failure 402 Bad user input
// @router /:workflowName/schedule [put]
func ( u * WorkflowController ) SetWorkflowSchedule ( workflowName , cronString , events string , isService bool , startDate , stopDate time . Time , duration uint ) {
username := "asd"
// Check Dates
if startDate . After ( stopDate ) || startDate . Equal ( stopDate ) {
u . CustomAbort ( 402 , "startDate must be before stopDate" )
}
if startDate . Before ( time . Now ( ) . UTC ( ) ) {
u . CustomAbort ( 402 , "Current server time (" + time . Now ( ) . UTC ( ) . String ( ) + ") is after the startDate (" + startDate . String ( ) + ")" )
}
// Tasks must have cron and duration
if ! isService {
if cronString == "" {
u . CustomAbort ( 402 , "Tasks cronString must not be empty" )
}
if duration == 0 {
u . CustomAbort ( 402 , "Tasks duration musn't be 0" )
}
_ , err := cron . Parse ( cronString )
// Check cron
if err != nil {
u . CustomAbort ( 402 , "Bad cron message: " + err . Error ( ) )
}
}
schedInfo , err := models . SetWorkflowSchedule ( username , workflowName , cronString , events , isService , startDate , stopDate , duration )
// Some error
if err != nil {
u . CustomAbort ( 401 , err . Error ( ) )
}
// No workflow
if schedInfo == nil {
u . CustomAbort ( 400 , "" )
}
u . Ctx . Output . Status = 200
u . Data [ "json" ] = schedInfo
u . ServeJSON ( )
}
// @Title Check Schedule
// @Description Check if we can schedule the project in other DCs. Must set a desired schedule first!
// @Param workflowName path string true "Workflow Name"
// @Success 200 {object} []models.DCstatus
// @Failure 403 Authentication issue
// @Failure 401 Other error
// @router /:workflowName/schedule/check [get]
func ( u * WorkflowController ) CheckWorkflowSchedule ( workflowName string ) {
username := "asd"
data , err := models . CheckAndBookWorkflowSchedule ( username , workflowName , false )
if err != nil {
u . CustomAbort ( 401 , err . Error ( ) )
}
u . Ctx . Output . Status = 200
u . Data [ "json" ] = data
u . ServeJSON ( )
return
}
// @Title Book Schedule
// @Description Book a schedule in all DCs of the workflow. Must set a desired schedule first!
// @Param workflowName path string true "Workflow Name"
// @Success 200 {object} []models.DCstatus
// @Failure 403 Authentication issue
// @Failure 401 Other error. Check output
// @router /:workflowName/schedule/book [post]
func ( u * WorkflowController ) BookWorkflowSchedule ( workflowName string ) {
username := "asd"
data , err := models . CheckAndBookWorkflowSchedule ( username , workflowName , true )
if err != nil {
u . CustomAbort ( 401 , err . Error ( ) )
}
u . Ctx . Output . Status = 200
u . Data [ "json" ] = data
u . ServeJSON ( )
return
}