package controllers import ( "time" "cloud.o-forge.io/core/oc-catalog/models" "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 }