diff --git a/models/workflow/workflow_mongo_accessor.go b/models/workflow/workflow_mongo_accessor.go index b31f6b9..f8d2f50 100644 --- a/models/workflow/workflow_mongo_accessor.go +++ b/models/workflow/workflow_mongo_accessor.go @@ -2,6 +2,7 @@ package oclib import ( "errors" + "time" "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" @@ -10,6 +11,7 @@ import ( "cloud.o-forge.io/core/oc-lib/models/workflow_execution" "cloud.o-forge.io/core/oc-lib/models/workspace" "github.com/vk496/cron" + "go.mongodb.org/mongo-driver/bson/primitive" ) type workflowMongoAccessor struct { @@ -20,6 +22,67 @@ func New() *workflowMongoAccessor { return &workflowMongoAccessor{} } +func (wfa *workflowMongoAccessor) checkBooking(data *Workflow) bool { + accessor := (&workflow_execution.WorkflowExecution{}).GetAccessor() + s := data.Schedule.Start.Add(time.Duration(-10) * time.Second) + e := data.Schedule.Start.Add(time.Duration(10) * time.Second) + sd := primitive.NewDateTimeFromTime(s) + ed := primitive.NewDateTimeFromTime(e) + f := dbs.Filters{ + And: map[string][]dbs.Filter{ + "execution_date": {{Operator: "gte", Value: sd}, {Operator: "lte", Value: ed}}, + }, + } + arr, _, _ := accessor.Search(&f, "") + return len(arr) == 0 +} + +func (wfa *workflowMongoAccessor) getExecutions(id string, data *Workflow) ([]*workflow_execution.WorkflowExecution, error) { + workflows_execution := []*workflow_execution.WorkflowExecution{} + if data.Schedule != nil { + if data.Schedule.Start == nil || data.Schedule.Start.IsZero() { + return workflows_execution, errors.New("should get a start date on the scheduler.") + } + if data.Schedule.End != nil && data.Schedule.End.IsZero() { + data.Schedule.End = nil + } + if len(data.Schedule.Cron) > 0 { + if data.Schedule.End == nil { + return workflows_execution, errors.New("a cron task should got a end date.") + } + c, err := cron.Parse(data.Schedule.Cron) + if err != nil { + return workflows_execution, errors.New("Bad cron message: " + err.Error()) + } + for s := c.Next(*data.Schedule.Start); !s.IsZero() && s.Before(*data.Schedule.End); s = c.Next(s) { + obj := &workflow_execution.WorkflowExecution{ + AbstractObject: utils.AbstractObject{ + Name: data.Schedule.Name, + }, + ExecDate: &s, + EndDate: data.Schedule.End, + State: 1, + WorkflowID: id, + } + workflows_execution = append(workflows_execution, obj) + } + + } else { + obj := &workflow_execution.WorkflowExecution{ + AbstractObject: utils.AbstractObject{ + Name: data.Schedule.Name, + }, + ExecDate: data.Schedule.Start, + EndDate: data.Schedule.End, + State: 1, + WorkflowID: id, + } + workflows_execution = append(workflows_execution, obj) + } + } + return workflows_execution, nil +} + func (wfa *workflowMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { return wfa.GenericDeleteOne(id, wfa) } @@ -33,53 +96,23 @@ func (wfa *workflowMongoAccessor) execution(id string, realData *Workflow, delet if r.Schedule.Start == realData.Schedule.Start && r.Schedule.End == realData.Schedule.End && r.Schedule.Cron == realData.Schedule.Cron { return 200, nil } + if !wfa.checkBooking(realData) { + return 409, errors.New("the booking is already taken.") + } if delete { mongo.MONGOService.DeleteMultiple(map[string]interface{}{ "workflow_id": id, "state": 1, }, utils.WORKFLOW_EXECUTION.String()) } - if realData.Schedule != nil { - accessor := (&workflow_execution.WorkflowExecution{}).GetAccessor() - if realData.Schedule.Start == nil || realData.Schedule.Start.IsZero() { - return 422, errors.New("should get a start date on the scheduler.") - } - if realData.Schedule.End != nil && realData.Schedule.End.IsZero() { - realData.Schedule.End = nil - } - if len(realData.Schedule.Cron) > 0 { - if realData.Schedule.End == nil { - return 422, errors.New("a cron task should got a end date.") - } - c, err := cron.Parse(realData.Schedule.Cron) - if err != nil { - return 422, errors.New("Bad cron message: " + err.Error()) - } - for s := c.Next(*realData.Schedule.Start); !s.IsZero() && s.Before(*realData.Schedule.End); s = c.Next(s) { - obj := &workflow_execution.WorkflowExecution{ - AbstractObject: utils.AbstractObject{ - Name: realData.Schedule.Name, - }, - ExecDate: &s, - EndDate: realData.Schedule.End, - State: 1, - WorkflowID: id, - } - accessor.StoreOne(obj) - } - - } else { - obj := &workflow_execution.WorkflowExecution{ - AbstractObject: utils.AbstractObject{ - Name: realData.Schedule.Name, - }, - ExecDate: realData.Schedule.Start, - EndDate: realData.Schedule.End, - State: 1, - WorkflowID: id, - } + accessor := (&workflow_execution.WorkflowExecution{}).GetAccessor() + execs, err := wfa.getExecutions(id, realData) + if err != nil && len(execs) > 0 { + for _, obj := range execs { accessor.StoreOne(obj) } + } else { + return 422, err } return 200, nil } diff --git a/models/workflow_execution/workflow_execution_mongo_accessor.go b/models/workflow_execution/workflow_execution_mongo_accessor.go index 0c83095..5d905d7 100644 --- a/models/workflow_execution/workflow_execution_mongo_accessor.go +++ b/models/workflow_execution/workflow_execution_mongo_accessor.go @@ -72,7 +72,6 @@ func (wfa *workflowExecutionMongoAccessor) Search(filters *dbs.Filters, search s wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err } - var results []WorkflowExecution if err = res_mongo.All(mongo.MngoCtx, &results); err != nil { return nil, 404, err