2024-08-12 14:18:13 +02:00
package booking
import (
"time"
"cloud.o-forge.io/core/oc-lib/dbs"
2024-12-12 16:25:47 +01:00
"cloud.o-forge.io/core/oc-lib/models/common"
2024-08-12 14:18:13 +02:00
"cloud.o-forge.io/core/oc-lib/models/utils"
2024-08-12 16:11:25 +02:00
"cloud.o-forge.io/core/oc-lib/tools"
2024-08-12 14:18:13 +02:00
"go.mongodb.org/mongo-driver/bson/primitive"
)
2024-08-30 14:50:48 +02:00
/ *
* Booking is a struct that represents a booking
* /
2024-08-12 14:18:13 +02:00
type Booking struct {
2024-12-12 16:25:47 +01:00
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
2024-08-12 14:18:13 +02:00
}
2024-11-07 11:05:24 +01:00
// CheckBooking checks if a booking is possible on a specific compute resource
2024-12-12 16:25:47 +01:00
func ( wfa * Booking ) Check ( id string , start time . Time , end * time . Time , parrallelAllowed int ) ( bool , error ) {
2024-08-12 14:18:13 +02:00
// check if
if end == nil {
// if no end... then Book like a savage
2024-12-12 16:25:47 +01:00
e := start . Add ( time . Hour )
end = & e
2024-08-12 14:18:13 +02:00
}
2024-12-12 16:25:47 +01:00
accessor := NewAccessor ( nil )
2024-08-12 14:18:13 +02:00
res , code , err := accessor . Search ( & dbs . Filters {
2024-11-07 11:05:24 +01:00
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
2024-12-12 16:25:47 +01:00
"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 ) } ,
2024-08-12 14:18:13 +02:00
{ Operator : dbs . GTE . String ( ) , Value : primitive . NewDateTimeFromTime ( start ) } ,
} ,
} ,
2024-12-12 16:25:47 +01:00
} , "" , wfa . IsDraft )
2024-08-12 14:18:13 +02:00
if code != 200 {
return false , err
}
2024-12-12 16:25:47 +01:00
return len ( res ) <= parrallelAllowed , nil
}
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 )
2024-08-12 14:18:13 +02:00
}
2024-12-12 16:25:47 +01:00
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 ( )
2024-08-12 14:18:13 +02:00
}
func ( d * Booking ) GetName ( ) string {
2024-12-12 16:25:47 +01:00
return d . GetID ( ) + "_" + d . ExpectedStartDate . String ( )
2024-08-12 14:18:13 +02:00
}
2024-12-12 16:25:47 +01:00
func ( d * Booking ) GetAccessor ( request * tools . APIRequest ) utils . Accessor {
return NewAccessor ( request ) // Create a new instance of the accessor
2024-08-12 14:18:13 +02:00
}
2024-12-04 12:14:55 +01:00
2024-12-12 16:25:47 +01:00
func ( d * Booking ) VerifyAuth ( request * tools . APIRequest ) bool {
2024-12-04 12:14:55 +01:00
return true
}
2024-12-12 16:25:47 +01:00
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
}