massive draft for payment process (UNCOMPLETE)

This commit is contained in:
mr
2024-12-12 16:25:47 +01:00
parent fbbce7817b
commit 02d1e93c78
55 changed files with 3018 additions and 1177 deletions

View File

@@ -4,8 +4,8 @@ import (
"time"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/models/common"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
"go.mongodb.org/mongo-driver/bson/primitive"
)
@@ -14,49 +14,99 @@ import (
* Booking is a struct that represents a booking
*/
type Booking struct {
workflow_execution.WorkflowExecution // WorkflowExecution contains the workflow execution data
ComputeResourceID string `json:"compute_resource_id,omitempty" bson:"compute_resource_id,omitempty" validate:"required"` // ComputeResourceID is the ID of the compute resource specified in the booking
utils.AbstractObject // AbstractObject contains the basic fields of an object (id, name)
DestPeerID string `json:"dest_peer_id,omitempty"` // DestPeerID is the ID of the destination peer
ExecutionID string `json:"execution_id,omitempty" bson:"execution_id,omitempty" validate:"required"`
State common.ScheduledType `json:"state,omitempty" bson:"state,omitempty" validate:"required"` // State is the state of the booking
ExpectedStartDate time.Time `json:"expected_start_date,omitempty" bson:"expected_start_date,omitempty" validate:"required"` // ExpectedStartDate is the expected start date of the booking
ExpectedEndDate *time.Time `json:"expected_end_date,omitempty" bson:"expected_end_date,omitempty" validate:"required"` // ExpectedEndDate is the expected end date of the booking
RealStartDate *time.Time `json:"real_start_date,omitempty" bson:"real_start_date,omitempty"` // RealStartDate is the real start date of the booking
RealEndDate *time.Time `json:"real_end_date,omitempty" bson:"real_end_date,omitempty"` // RealEndDate is the real end date of the booking
ResourceType tools.DataType `json:"resource_type,omitempty" bson:"resource_type,omitempty" validate:"required"` // ResourceType is the type of the resource
ResourceID string `json:"compute_resource_id,omitempty" bson:"compute_resource_id,omitempty" validate:"required"` // could be a Compute or a Storage
}
// CheckBooking checks if a booking is possible on a specific compute resource
func (wfa *Booking) CheckBooking(id string, start time.Time, end *time.Time) (bool, error) {
func (wfa *Booking) Check(id string, start time.Time, end *time.Time, parrallelAllowed int) (bool, error) {
// check if
if end == nil {
// if no end... then Book like a savage
return true, nil
e := start.Add(time.Hour)
end = &e
}
e := *end
accessor := New(tools.BOOKING, "", "", nil, nil)
accessor := NewAccessor(nil)
res, code, err := accessor.Search(&dbs.Filters{
And: map[string][]dbs.Filter{ // check if there is a booking on the same compute resource by filtering on the compute_resource_id, the state and the execution date
"compute_resource_id": {{Operator: dbs.EQUAL.String(), Value: id}},
"workflowexecution.state": {{Operator: dbs.EQUAL.String(), Value: workflow_execution.SCHEDULED.EnumIndex()}},
"workflowexecution.execution_date": {
{Operator: dbs.LTE.String(), Value: primitive.NewDateTimeFromTime(e)},
"resource_id": {{Operator: dbs.EQUAL.String(), Value: id}},
"state": {{Operator: dbs.EQUAL.String(), Value: common.DRAFT.EnumIndex()}},
"expected_start_date": {
{Operator: dbs.LTE.String(), Value: primitive.NewDateTimeFromTime(*end)},
{Operator: dbs.GTE.String(), Value: primitive.NewDateTimeFromTime(start)},
},
},
}, "")
}, "", wfa.IsDraft)
if code != 200 {
return false, err
}
return len(res) == 0, nil
return len(res) <= parrallelAllowed, nil
}
// tool to convert the argo status to a state
func (wfa *Booking) ArgoStatusToState(status string) *Booking {
wfa.WorkflowExecution.ArgoStatusToState(status)
return wfa
func (d *Booking) GetDelayForLaunch() time.Duration {
return d.RealStartDate.Sub(d.ExpectedStartDate)
}
func (d *Booking) GetDelayForFinishing() time.Duration {
if d.ExpectedEndDate == nil {
return time.Duration(0)
}
return d.RealEndDate.Sub(d.ExpectedStartDate)
}
func (d *Booking) GetUsualDuration() time.Duration {
return d.ExpectedEndDate.Sub(d.ExpectedStartDate)
}
func (d *Booking) GetRealDuration() time.Duration {
if d.RealEndDate == nil || d.RealStartDate == nil {
return time.Duration(0)
}
return d.RealEndDate.Sub(*d.RealStartDate)
}
func (d *Booking) GetDelayOnDuration() time.Duration {
return d.GetRealDuration() - d.GetUsualDuration()
}
func (d *Booking) GetName() string {
return d.UUID + "_" + d.ExecDate.String()
return d.GetID() + "_" + d.ExpectedStartDate.String()
}
func (d *Booking) GetAccessor(username string, peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.BOOKING, username, peerID, groups, caller) // Create a new instance of the accessor
func (d *Booking) GetAccessor(request *tools.APIRequest) utils.Accessor {
return NewAccessor(request) // Create a new instance of the accessor
}
func (d *Booking) VerifyAuth(username string, peerID string, groups []string) bool {
func (d *Booking) VerifyAuth(request *tools.APIRequest) bool {
return true
}
func (r *Booking) StoreDraftDefault() {
r.IsDraft = true
}
func (r *Booking) CanUpdate(set utils.DBObject) (bool, utils.DBObject) {
if !r.IsDraft && r.State != set.(*Booking).State || r.RealStartDate != set.(*Booking).RealStartDate || r.RealEndDate != set.(*Booking).RealEndDate {
return true, &Booking{
State: set.(*Booking).State,
RealStartDate: set.(*Booking).RealStartDate,
RealEndDate: set.(*Booking).RealEndDate,
} // only state can be updated
}
// TODO : HERE WE CAN HANDLE THE CASE WHERE THE BOOKING IS DELAYED OR EXCEEDING OR ending sooner
return r.IsDraft, set
}
func (r *Booking) CanDelete() bool {
return r.IsDraft // only draft bookings can be deleted
}

View File

@@ -5,8 +5,8 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/common"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
)
@@ -15,15 +15,12 @@ type bookingMongoAccessor struct {
}
// New creates a new instance of the bookingMongoAccessor
func New(t tools.DataType, username string, peerID string, groups []string, caller *tools.HTTPCaller) *bookingMongoAccessor {
func NewAccessor(request *tools.APIRequest) *bookingMongoAccessor {
return &bookingMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups,
User: username, // Set the caller
Type: t,
Logger: logs.CreateLogger(tools.BOOKING.String()), // Create a logger with the data type
Request: request,
Type: tools.BOOKING,
},
}
}
@@ -49,26 +46,29 @@ func (a *bookingMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int
func (a *bookingMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
return utils.GenericLoadOne[*Booking](id, func(d utils.DBObject) (utils.DBObject, int, error) {
if d.(*Booking).State == workflow_execution.SCHEDULED && time.Now().UTC().After(*d.(*Booking).ExecDate) {
d.(*Booking).State = workflow_execution.FORGOTTEN
if (d.(*Booking).ExpectedEndDate) == nil {
d.(*Booking).State = common.FORGOTTEN
utils.GenericRawUpdateOne(d, id, a)
} else if d.(*Booking).State == common.SCHEDULED && time.Now().UTC().After(*&d.(*Booking).ExpectedStartDate) {
d.(*Booking).State = common.DELAYED
utils.GenericRawUpdateOne(d, id, a)
}
return d, 200, nil
}, a)
}
func (a *bookingMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
return utils.GenericLoadAll[*Booking](a.getExec(), a)
func (a *bookingMongoAccessor) LoadAll(isDraft bool) ([]utils.ShallowDBObject, int, error) {
return utils.GenericLoadAll[*Booking](a.getExec(), isDraft, a)
}
func (a *bookingMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
return utils.GenericSearch[*Booking](filters, search, (&Booking{}).GetObjectFilters(search), a.getExec(), a)
func (a *bookingMongoAccessor) Search(filters *dbs.Filters, search string, isDraft bool) ([]utils.ShallowDBObject, int, error) {
return utils.GenericSearch[*Booking](filters, search, (&Booking{}).GetObjectFilters(search), a.getExec(), isDraft, a)
}
func (a *bookingMongoAccessor) getExec() func(utils.DBObject) utils.ShallowDBObject {
return func(d utils.DBObject) utils.ShallowDBObject {
if d.(*Booking).State == workflow_execution.SCHEDULED && time.Now().UTC().After(*d.(*Booking).ExecDate) {
d.(*Booking).State = workflow_execution.FORGOTTEN
if d.(*Booking).State == common.SCHEDULED && time.Now().UTC().After(*&d.(*Booking).ExpectedStartDate) {
d.(*Booking).State = common.DELAYED
utils.GenericRawUpdateOne(d, d.GetID(), a)
}
return d