Compare commits

...

15 Commits

Author SHA1 Message Date
mr
c53e25e69a add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
4aebb48e73 add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
c9690fc1ba add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
cd10104089 add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
f6bc19123c add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
305e5919f9 add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
2ee2320a03 add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
9a4cf686ca add purchase resource in model catalog 2025-02-13 10:32:49 +01:00
mr
5376cf7681 workflow execution evolved 2025-02-13 10:32:49 +01:00
mr
2f0eb9ca35 workflow execution evolved 2025-02-13 10:32:49 +01:00
mr
c1d0932301 workflow execution evolved 2025-02-13 10:32:49 +01:00
mr
82cb2aa76a workflow execution evolved 2025-02-13 10:32:49 +01:00
mr
2cbbb49ce2 workflow execution evolved 2025-02-13 10:32:49 +01:00
mr
3c615fd3bc workflow execution evolved 2025-02-13 10:32:49 +01:00
pb
91d3e5c3cd Added a nil verification to StoreOne and UpdateOne for Graph object 2025-02-13 10:32:49 +01:00
14 changed files with 109 additions and 51 deletions

View File

@ -247,15 +247,17 @@ func ToScheduler(m interface{}) (n *workflow_execution.WorkflowSchedule) {
}
func (r *Request) Schedule(wfID string, scheduler *workflow_execution.WorkflowSchedule) (*workflow_execution.WorkflowSchedule, error) {
if _, _, err := scheduler.Schedules(wfID, &tools.APIRequest{
ws, _, _, err := scheduler.Schedules(wfID, &tools.APIRequest{
Caller: r.caller,
Username: r.user,
PeerID: r.peerID,
Groups: r.groups,
}); err != nil {
})
if err != nil {
return nil, err
}
return scheduler, nil
fmt.Println("BAM", ws)
return ws, nil
}
func (r *Request) CheckBooking(wfID string, start string, end string, durationInS float64, cron string) bool {

View File

@ -46,6 +46,9 @@ 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 == enum.DRAFT && time.Now().UTC().After(d.(*Booking).ExpectedStartDate) {
return utils.GenericDeleteOne(d.GetID(), a)
}
if (d.(*Booking).ExpectedEndDate) == nil {
d.(*Booking).State = enum.FORGOTTEN
utils.GenericRawUpdateOne(d, id, a)
@ -67,6 +70,10 @@ func (a *bookingMongoAccessor) Search(filters *dbs.Filters, search string, isDra
func (a *bookingMongoAccessor) getExec() func(utils.DBObject) utils.ShallowDBObject {
return func(d utils.DBObject) utils.ShallowDBObject {
if d.(*Booking).State == enum.DRAFT && time.Now().UTC().After(d.(*Booking).ExpectedStartDate) {
utils.GenericDeleteOne(d.GetID(), a)
return nil
}
if d.(*Booking).State == enum.SCHEDULED && time.Now().UTC().After(*&d.(*Booking).ExpectedStartDate) {
d.(*Booking).State = enum.DELAYED
utils.GenericRawUpdateOne(d, d.GetID(), a)

View File

@ -3,6 +3,7 @@ package models
import (
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/order"
"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
"cloud.o-forge.io/core/oc-lib/tools"
"cloud.o-forge.io/core/oc-lib/models/booking"
@ -36,6 +37,7 @@ var models = map[string]func() utils.DBObject{
tools.WORKFLOW_HISTORY.String(): func() utils.DBObject { return &w2.WorkflowHistory{} },
tools.WORKSPACE_HISTORY.String(): func() utils.DBObject { return &w3.WorkspaceHistory{} },
tools.ORDER.String(): func() utils.DBObject { return &order.Order{} },
tools.PURCHASE_RESOURCE.String(): func() utils.DBObject { return &purchase_resource.PurchaseResource{} },
}
// Model returns the model object based on the model type

View File

@ -24,6 +24,7 @@ import (
type Order struct {
utils.AbstractObject
OrderBy string `json:"order_by" bson:"order_by" validate:"required"`
WorkflowID string `json:"workflow_id" bson:"workflow_id" validate:"required"`
WorkflowExecutionIDs []string `json:"workflow_execution_ids" bson:"workflow_execution_ids" validate:"required"`
Status enum.CompletionStatus `json:"status" bson:"status" default:"0"`
SubOrders map[string]*PeerOrder `json:"sub_orders" bson:"sub_orders"`
@ -90,12 +91,14 @@ func (o *Order) draftStoreFromModel(scheduler *workflow_execution.WorkflowSchedu
if request == nil {
return errors.New("no request found")
}
if scheduler.Workflow.Graph == nil { // if the workflow has no graph, return an error
fmt.Println("Drafting order", scheduler.Workflow)
if scheduler.Workflow == nil || scheduler.Workflow.Graph == nil { // if the workflow has no graph, return an error
return errors.New("no graph found")
}
o.SetName()
o.WorkflowID = scheduler.Workflow.GetID()
o.IsDraft = true
o.OrderBy = request.Username
o.OrderBy = request.PeerID
o.WorkflowExecutionIDs = []string{} // create an array of ids
for _, exec := range scheduler.WorkflowExecutions {
o.WorkflowExecutionIDs = append(o.WorkflowExecutionIDs, exec.GetID())
@ -124,6 +127,9 @@ func (o *Order) draftStoreFromModel(scheduler *workflow_execution.WorkflowSchedu
for _, resource := range resources {
peerOrder.AddItem(resource, len(resources)) // TODO SPECIALS REF ADDITIONALS NOTES
}
if o.SubOrders == nil {
o.SubOrders = map[string]*PeerOrder{}
}
o.SubOrders[peerOrder.GetID()] = peerOrder
}
// search an order with same user name and same session id
@ -134,7 +140,8 @@ func (o *Order) draftStoreFromModel(scheduler *workflow_execution.WorkflowSchedu
// should store the order
res, code, err := o.GetAccessor(request).Search(&dbs.Filters{
And: map[string][]dbs.Filter{
"order_by": {{Operator: dbs.EQUAL.String(), Value: request.Username}},
"workflow_id": {{Operator: dbs.EQUAL.String(), Value: o.WorkflowID}},
"order_by": {{Operator: dbs.EQUAL.String(), Value: request.PeerID}},
},
}, "", o.IsDraft)
if code != 200 || err != nil {
@ -321,4 +328,5 @@ func (d *PeerItemOrder) GetPrice(request *tools.APIRequest) (float64, error) {
return p * float64(d.Quantity), nil
}
// WTF HOW TO SELECT THE RIGHT PRICE ???
// SHOULD SET A BUYING STATUS WHEN PAYMENT IS VALIDATED

View File

@ -138,11 +138,19 @@ func (r *PricedComputeResource) GetType() tools.DataType {
}
func (r *PricedComputeResource) GetPrice() (float64, error) {
if r.UsageStart == nil || r.UsageEnd == nil {
return 0, errors.New("usage start and end must be set")
now := time.Now()
if r.UsageStart == nil {
r.UsageStart = &now
}
if r.UsageEnd == nil {
add := r.UsageStart.Add(time.Duration(1 * time.Hour))
r.UsageEnd = &add
}
if r.SelectedPricing == nil {
return 0, errors.New("selected pricing must be set")
if len(r.PricingProfiles) == 0 {
return 0, errors.New("pricing profile must be set on Priced Compute" + r.ResourceID)
}
r.SelectedPricing = &r.PricingProfiles[0]
}
pricing := *r.SelectedPricing
price := float64(0)

View File

@ -2,6 +2,7 @@ package resources
import (
"errors"
"fmt"
"time"
"cloud.o-forge.io/core/oc-lib/models/common/models"
@ -150,11 +151,20 @@ func (r *PricedDataResource) GetType() tools.DataType {
}
func (r *PricedDataResource) GetPrice() (float64, error) {
if r.UsageStart == nil || r.UsageEnd == nil {
return 0, errors.New("usage start and end must be set")
fmt.Println("GetPrice", r.UsageStart, r.UsageEnd)
now := time.Now()
if r.UsageStart == nil {
r.UsageStart = &now
}
if r.UsageEnd == nil {
add := r.UsageStart.Add(time.Duration(1 * time.Hour))
r.UsageEnd = &add
}
if r.SelectedPricing == nil {
return 0, errors.New("selected pricing must be set")
if len(r.PricingProfiles) == 0 {
return 0, errors.New("pricing profile must be set on Priced Data" + r.ResourceID)
}
r.SelectedPricing = &r.PricingProfiles[0]
}
pricing := *r.SelectedPricing
var err error

View File

@ -2,6 +2,7 @@ package resources
import (
"errors"
"fmt"
"time"
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
@ -34,18 +35,6 @@ func (abs *PricedResource) GetCreatorID() string {
return abs.CreatorID
}
func (abs *PricedResource) SetStartUsage(start time.Time) {
if abs.UsageStart == nil {
abs.UsageStart = &start
}
}
func (abs *PricedResource) SetEndUsage(end time.Time) {
if abs.UsageEnd == nil {
abs.UsageEnd = &end
}
}
func (abs *PricedResource) IsPurchased() bool {
if abs.SelectedPricing == nil {
return false
@ -71,20 +60,34 @@ func (abs *PricedResource) SetLocationEnd(end time.Time) {
func (abs *PricedResource) GetExplicitDurationInS() float64 {
if abs.ExplicitBookingDurationS == 0 {
if abs.UsageEnd == nil || abs.UsageStart == nil {
if abs.UsageEnd == nil && abs.UsageStart == nil {
return time.Duration(1 * time.Hour).Seconds()
}
if abs.UsageEnd == nil {
add := abs.UsageStart.Add(time.Duration(1 * time.Hour))
abs.UsageEnd = &add
}
return abs.UsageEnd.Sub(*abs.UsageStart).Seconds()
}
return abs.ExplicitBookingDurationS
}
func (r *PricedResource) GetPrice() (float64, error) {
if r.UsageStart == nil || r.UsageEnd == nil {
return 0, errors.New("usage start and end must be set")
fmt.Println("GetPrice", r.UsageStart, r.UsageEnd)
now := time.Now()
if r.UsageStart == nil {
r.UsageStart = &now
}
if r.UsageEnd == nil {
add := r.UsageStart.Add(time.Duration(1 * time.Hour))
r.UsageEnd = &add
}
if r.SelectedPricing == nil {
return 0, errors.New("selected pricing must be set")
if len(r.PricingProfiles) == 0 {
return 0, errors.New("pricing profile must be set on Priced Resource " + r.ResourceID)
}
r.SelectedPricing = &r.PricingProfiles[0]
}
return (*r.SelectedPricing).GetPrice(1, 0, *r.UsageStart, *r.UsageEnd)
pricing := *r.SelectedPricing
return pricing.GetPrice(1, 0, *r.UsageStart, *r.UsageEnd)
}

View File

@ -17,9 +17,9 @@ type purchaseResourceMongoAccessor struct {
func NewAccessor(request *tools.APIRequest) *purchaseResourceMongoAccessor {
return &purchaseResourceMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(tools.BUYING_STATUS.String()), // Create a logger with the data type
Logger: logs.CreateLogger(tools.PURCHASE_RESOURCE.String()), // Create a logger with the data type
Request: request,
Type: tools.BUYING_STATUS,
Type: tools.PURCHASE_RESOURCE,
},
}
}

View File

@ -169,10 +169,19 @@ type ResourcePartnerShip[T pricing.PricingProfileITF] struct {
}
func (ri *ResourcePartnerShip[T]) GetPricingsProfiles(peerID string, groups []string) []pricing.PricingProfileITF {
profiles := []pricing.PricingProfileITF{}
if ri.PeerGroups[peerID] != nil {
for _, ri := range ri.PricingProfiles {
profiles = append(profiles, ri)
}
if slices.Contains(groups, "*") {
for _, ri := range ri.PricingProfiles {
profiles = append(profiles, ri)
}
return profiles
}
for _, p := range ri.PeerGroups[peerID] {
if slices.Contains(groups, p) {
profiles := []pricing.PricingProfileITF{}
for _, ri := range ri.PricingProfiles {
profiles = append(profiles, ri)
}
@ -180,7 +189,7 @@ func (ri *ResourcePartnerShip[T]) GetPricingsProfiles(peerID string, groups []st
}
}
}
return []pricing.PricingProfileITF{}
return profiles
}
func (rp *ResourcePartnerShip[T]) GetPeerGroups() map[string][]string {

View File

@ -2,6 +2,7 @@ package resources
import (
"errors"
"fmt"
"time"
"cloud.o-forge.io/core/oc-lib/models/common/enum"
@ -161,11 +162,20 @@ func (r *PricedStorageResource) GetType() tools.DataType {
}
func (r *PricedStorageResource) GetPrice() (float64, error) {
if r.UsageStart == nil || r.UsageEnd == nil {
return 0, errors.New("usage start and end must be set")
fmt.Println("GetPrice", r.UsageStart, r.UsageEnd)
now := time.Now()
if r.UsageStart == nil {
r.UsageStart = &now
}
if r.UsageEnd == nil {
add := r.UsageStart.Add(time.Duration(1 * time.Hour))
r.UsageEnd = &add
}
if r.SelectedPricing == nil {
return 0, errors.New("selected pricing must be set")
if len(r.PricingProfiles) == 0 {
return 0, errors.New("pricing profile must be set on Priced Storage" + r.ResourceID)
}
r.SelectedPricing = &r.PricingProfiles[0]
}
pricing := *r.SelectedPricing
var err error

View File

@ -92,7 +92,7 @@ func (a *workflowMongoAccessor) share(realData *Workflow, delete bool, caller *t
func (a *workflowMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
// avoid the update if the schedule is the same
set = a.verifyResource(set)
if set.(*Workflow).Graph.Partial {
if set.(*Workflow).Graph != nil && set.(*Workflow).Graph.Partial {
return nil, 403, errors.New("you are not allowed to update a partial workflow")
}
res, code, err := utils.GenericUpdateOne(a.verifyResource(set), id, a, &Workflow{})
@ -109,7 +109,7 @@ func (a *workflowMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.
func (a *workflowMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data = a.verifyResource(data)
d := data.(*Workflow)
if d.Graph.Partial {
if d.Graph != nil && d.Graph.Partial {
return nil, 403, errors.New("you are not allowed to update a partial workflow")
}
res, code, err := utils.GenericStoreOne(d, a)

View File

@ -28,9 +28,8 @@ type WorkflowExecutions struct {
}
func (r *WorkflowExecutions) StoreDraftDefault() {
// r.IsDraft = true
r.IsDraft = false // TODO: TEMPORARY
r.State = enum.SCHEDULED
r.IsDraft = true // TODO: TEMPORARY
r.State = enum.DRAFT
}
func (r *WorkflowExecutions) CanUpdate(set utils.DBObject) (bool, utils.DBObject) {

View File

@ -87,21 +87,21 @@ func (ws *WorkflowSchedule) CheckBooking(wfID string, request *tools.APIRequest)
return true, wf, execs, nil
}
func (ws *WorkflowSchedule) Schedules(wfID string, request *tools.APIRequest) (*workflow.Workflow, []*WorkflowExecutions, error) {
func (ws *WorkflowSchedule) Schedules(wfID string, request *tools.APIRequest) (*WorkflowSchedule, *workflow.Workflow, []*WorkflowExecutions, error) {
if request == nil {
return nil, []*WorkflowExecutions{}, errors.New("no request found")
return ws, nil, []*WorkflowExecutions{}, errors.New("no request found")
}
c := request.Caller
if c == nil || c.URLS == nil || c.URLS[tools.BOOKING] == nil {
return nil, []*WorkflowExecutions{}, errors.New("no caller defined")
return ws, nil, []*WorkflowExecutions{}, errors.New("no caller defined")
}
methods := c.URLS[tools.BOOKING]
if _, ok := methods[tools.GET]; !ok {
return nil, []*WorkflowExecutions{}, errors.New("no path found")
return ws, nil, []*WorkflowExecutions{}, errors.New("no path found")
}
ok, wf, executions, err := ws.CheckBooking(wfID, request)
if !ok || err != nil {
return nil, []*WorkflowExecutions{}, errors.New("could not book the workflow : " + fmt.Sprintf("%v", err))
return ws, nil, []*WorkflowExecutions{}, errors.New("could not book the workflow : " + fmt.Sprintf("%v", err))
}
ws.Workflow = wf
@ -110,14 +110,14 @@ func (ws *WorkflowSchedule) Schedules(wfID string, request *tools.APIRequest) (*
for _, exec := range executions {
err := exec.PurgeDraft(request)
if err != nil {
return nil, []*WorkflowExecutions{}, errors.New("purge draft" + fmt.Sprintf("%v", err))
return ws, nil, []*WorkflowExecutions{}, errors.New("purge draft" + fmt.Sprintf("%v", err))
}
exec.GenerateID()
exec.StoreDraftDefault()
// Should DELETE the previous execution2
utils.GenericStoreOne(exec, NewAccessor(request))
}
return wf, executions, nil
return ws, wf, executions, nil
}
/*

View File

@ -20,7 +20,7 @@ const (
WORKFLOW_HISTORY
WORKSPACE_HISTORY
ORDER
BUYING_STATUS
PURCHASE_RESOURCE
)
var NOAPI = ""
@ -70,7 +70,7 @@ var Str = [...]string{
"workflow_history",
"workspace_history",
"order",
"buying_status",
"purchase_resource",
}
func FromInt(i int) string {
@ -91,5 +91,5 @@ func (d DataType) EnumIndex() int {
}
func DataTypeList() []DataType {
return []DataType{DATA_RESOURCE, PROCESSING_RESOURCE, STORAGE_RESOURCE, COMPUTE_RESOURCE, WORKFLOW_RESOURCE, WORKFLOW, WORKFLOW_EXECUTION, WORKSPACE, PEER, COLLABORATIVE_AREA, RULE, BOOKING, WORKFLOW_HISTORY, WORKSPACE_HISTORY, ORDER, BUYING_STATUS}
return []DataType{DATA_RESOURCE, PROCESSING_RESOURCE, STORAGE_RESOURCE, COMPUTE_RESOURCE, WORKFLOW_RESOURCE, WORKFLOW, WORKFLOW_EXECUTION, WORKSPACE, PEER, COLLABORATIVE_AREA, RULE, BOOKING, WORKFLOW_HISTORY, WORKSPACE_HISTORY, ORDER, PURCHASE_RESOURCE}
}