add sets up
This commit is contained in:
		| @@ -15,12 +15,14 @@ import ( | |||||||
| 	"cloud.o-forge.io/core/oc-lib/dbs/mongo" | 	"cloud.o-forge.io/core/oc-lib/dbs/mongo" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/logs" | 	"cloud.o-forge.io/core/oc-lib/logs" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models" | 	"cloud.o-forge.io/core/oc-lib/models" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/booking" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/collaborative_area" | 	"cloud.o-forge.io/core/oc-lib/models/collaborative_area" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule" | 	"cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/compute_units" | 	"cloud.o-forge.io/core/oc-lib/models/compute_units" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/order" | 	"cloud.o-forge.io/core/oc-lib/models/order" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/peer" | 	"cloud.o-forge.io/core/oc-lib/models/peer" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/resources" | 	"cloud.o-forge.io/core/oc-lib/models/resources" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/utils" | 	"cloud.o-forge.io/core/oc-lib/models/utils" | ||||||
| 	w2 "cloud.o-forge.io/core/oc-lib/models/workflow" | 	w2 "cloud.o-forge.io/core/oc-lib/models/workflow" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/workflow_execution" | 	"cloud.o-forge.io/core/oc-lib/models/workflow_execution" | ||||||
| @@ -53,6 +55,7 @@ const ( | |||||||
| 	BOOKING                         = tools.BOOKING | 	BOOKING                         = tools.BOOKING | ||||||
| 	ORDER                           = tools.ORDER | 	ORDER                           = tools.ORDER | ||||||
| 	COMPUTE_UNITS                   = tools.COMPUTE_UNITS | 	COMPUTE_UNITS                   = tools.COMPUTE_UNITS | ||||||
|  | 	PURCHASE_RESOURCE               = tools.PURCHASE_RESOURCE | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // will turn into standards api hostnames | // will turn into standards api hostnames | ||||||
| @@ -585,3 +588,17 @@ func (l *LibData) ToComputeUnits() *compute_units.ComputeUnits { | |||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (l *LibData) ToBookings() *booking.Booking { | ||||||
|  | 	if l.Data.GetAccessor(nil).GetType() == tools.BOOKING { | ||||||
|  | 		return l.Data.(*booking.Booking) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *LibData) ToPurchasedResource() *purchase_resource.PurchaseResource { | ||||||
|  | 	if l.Data.GetAccessor(nil).GetType() == tools.COMPUTE_UNITS { | ||||||
|  | 		return l.Data.(*purchase_resource.PurchaseResource) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								models/bill/bill.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								models/bill/bill.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | package bill | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/utils" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/tools" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | * Bill is a struct that represents when emit billing | ||||||
|  |  */ | ||||||
|  | type Bill struct { | ||||||
|  | 	utils.AbstractObject | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *Bill) StoreDraftDefault() { | ||||||
|  | 	r.IsDraft = true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *Bill) CanDelete() bool { | ||||||
|  | 	return r.IsDraft // only draft ComputeUnits can be deleted | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (d *Bill) GetAccessor(request *tools.APIRequest) utils.Accessor { | ||||||
|  | 	return NewAccessor(request) // Create a new instance of the accessor | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								models/bill/bill_mongo_accessor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								models/bill/bill_mongo_accessor.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | package bill | ||||||
|  |  | ||||||
|  | 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/utils" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/tools" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type billMongoAccessor struct { | ||||||
|  | 	utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // New creates a new instance of the billMongoAccessor | ||||||
|  | func NewAccessor(request *tools.APIRequest) *billMongoAccessor { | ||||||
|  | 	return &billMongoAccessor{ | ||||||
|  | 		AbstractAccessor: utils.AbstractAccessor{ | ||||||
|  | 			Logger:  logs.CreateLogger(tools.COMPUTE_UNITS.String()), // Create a logger with the data type | ||||||
|  | 			Request: request, | ||||||
|  | 			Type:    tools.COMPUTE_UNITS, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | * Nothing special here, just the basic CRUD operations | ||||||
|  |  */ | ||||||
|  | func (a *billMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { | ||||||
|  | 	return utils.GenericDeleteOne(id, a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) { | ||||||
|  | 	// should verify if a source is existing... | ||||||
|  | 	return utils.GenericUpdateOne(set, id, a, &Bill{}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) { | ||||||
|  | 	return utils.GenericStoreOne(data.(*Bill), a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) { | ||||||
|  | 	return utils.GenericStoreOne(data.(*Bill), a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { | ||||||
|  | 	return utils.GenericLoadOne[*Bill](id, func(d utils.DBObject) (utils.DBObject, int, error) { | ||||||
|  | 		return d, 200, nil | ||||||
|  | 	}, a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) LoadAll(isDraft bool) ([]utils.ShallowDBObject, int, error) { | ||||||
|  | 	return utils.GenericLoadAll[*Bill](a.getExec(), isDraft, a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) Search(filters *dbs.Filters, search string, isDraft bool) ([]utils.ShallowDBObject, int, error) { | ||||||
|  | 	return utils.GenericSearch[*Bill](filters, search, (&Bill{}).GetObjectFilters(search), a.getExec(), isDraft, a) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *billMongoAccessor) getExec() func(utils.DBObject) utils.ShallowDBObject { | ||||||
|  | 	return func(d utils.DBObject) utils.ShallowDBObject { | ||||||
|  | 		return d | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -9,7 +9,8 @@ import ( | |||||||
| type PricedItemITF interface { | type PricedItemITF interface { | ||||||
| 	GetID() string | 	GetID() string | ||||||
| 	GetType() tools.DataType | 	GetType() tools.DataType | ||||||
| 	IsPurchased() bool | 	IsPurchasable() bool | ||||||
|  | 	IsBooked() bool | ||||||
| 	GetCreatorID() string | 	GetCreatorID() string | ||||||
| 	GetLocationStart() *time.Time | 	GetLocationStart() *time.Time | ||||||
| 	SetLocationStart(start time.Time) | 	SetLocationStart(start time.Time) | ||||||
|   | |||||||
| @@ -6,7 +6,8 @@ import ( | |||||||
|  |  | ||||||
| type PricingProfileITF interface { | type PricingProfileITF interface { | ||||||
| 	GetPrice(quantity float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) | 	GetPrice(quantity float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) | ||||||
| 	IsPurchased() bool | 	IsPurchasable() bool | ||||||
|  | 	IsBooked() bool | ||||||
| 	GetOverrideStrategyValue() int | 	GetOverrideStrategyValue() int | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,21 +7,65 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | type BillingStrategy int // BAM BAM | ||||||
|  |  | ||||||
|  | // should except... on | ||||||
|  | const ( | ||||||
|  | 	BILL_ONCE BillingStrategy = iota // is a permanent buying ( predictible ) | ||||||
|  | 	BILL_PER_WEEK | ||||||
|  | 	BILL_PER_MONTH | ||||||
|  | 	BILL_PER_YEAR | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func (t BillingStrategy) IsBillingStrategyAllowed(bs int) (BillingStrategy, bool) { | ||||||
|  | 	switch t { | ||||||
|  | 	case BILL_ONCE: | ||||||
|  | 		return BILL_ONCE, bs == 0 | ||||||
|  | 	case BILL_PER_WEEK: | ||||||
|  | 	case BILL_PER_MONTH: | ||||||
|  | 	case BILL_PER_YEAR: | ||||||
|  | 		return t, bs != 0 | ||||||
|  | 	} | ||||||
|  | 	return t, false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (t BillingStrategy) String() string { | ||||||
|  | 	return [...]string{"BILL_ONCE", "BILL_PER_WEEK", "BILL_PER_MONTH", "BILL_PER_YEAR"}[t] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func BillingStrategyList() []BillingStrategy { | ||||||
|  | 	return []BillingStrategy{BILL_ONCE, BILL_PER_WEEK, BILL_PER_MONTH, BILL_PER_YEAR} | ||||||
|  | } | ||||||
|  |  | ||||||
| type BuyingStrategy int | type BuyingStrategy int | ||||||
|  |  | ||||||
| // should except... on | // should except... on | ||||||
| const ( | const ( | ||||||
| 	UNLIMITED BuyingStrategy = iota | 	PERMANENT              BuyingStrategy = iota // is a permanent buying ( predictible ) | ||||||
| 	SUBSCRIPTION | 	UNDEFINED_SUBSCRIPTION                       // a endless subscription ( unpredictible ) | ||||||
| 	PAY_PER_USE | 	SUBSCRIPTION                                 // a defined subscription ( predictible ) | ||||||
|  | 	// PAY_PER_USE                                  // per request. ( unpredictible ) | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (t BuyingStrategy) String() string { | func (t BuyingStrategy) String() string { | ||||||
| 	return [...]string{"UNLIMITED", "SUBSCRIPTION", "PAY PER USE"}[t] | 	return [...]string{"PERMANENT", "UNDEFINED_SUBSCRIPTION", "SUBSCRIPTION"}[t] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (t BuyingStrategy) IsBillingStrategyAllowed(bs BillingStrategy) (BillingStrategy, bool) { | ||||||
|  | 	switch t { | ||||||
|  | 	case PERMANENT: | ||||||
|  | 		return BILL_ONCE, bs == BILL_ONCE | ||||||
|  | 	case UNDEFINED_SUBSCRIPTION: | ||||||
|  | 		return BILL_PER_MONTH, bs != BILL_ONCE | ||||||
|  | 	case SUBSCRIPTION: | ||||||
|  | 		/*case PAY_PER_USE: | ||||||
|  | 		return bs, true*/ | ||||||
|  | 	} | ||||||
|  | 	return bs, false | ||||||
| } | } | ||||||
|  |  | ||||||
| func BuyingStrategyList() []BuyingStrategy { | func BuyingStrategyList() []BuyingStrategy { | ||||||
| 	return []BuyingStrategy{UNLIMITED, SUBSCRIPTION, PAY_PER_USE} | 	return []BuyingStrategy{PERMANENT, UNDEFINED_SUBSCRIPTION, SUBSCRIPTION} | ||||||
| } | } | ||||||
|  |  | ||||||
| type Strategy interface { | type Strategy interface { | ||||||
| @@ -118,7 +162,7 @@ type PricingStrategy[T Strategy] struct { | |||||||
| func (p PricingStrategy[T]) GetPrice(amountOfData float64, bookingTimeDuration float64, start time.Time, end *time.Time) (float64, error) { | func (p PricingStrategy[T]) GetPrice(amountOfData float64, bookingTimeDuration float64, start time.Time, end *time.Time) (float64, error) { | ||||||
| 	if p.BuyingStrategy == SUBSCRIPTION { | 	if p.BuyingStrategy == SUBSCRIPTION { | ||||||
| 		return BookingEstimation(p.GetTimePricingStrategy(), p.Price*float64(amountOfData), bookingTimeDuration, start, end) | 		return BookingEstimation(p.GetTimePricingStrategy(), p.Price*float64(amountOfData), bookingTimeDuration, start, end) | ||||||
| 	} else if p.BuyingStrategy == UNLIMITED { | 	} else if p.BuyingStrategy == PERMANENT { | ||||||
| 		return p.Price, nil | 		return p.Price, nil | ||||||
| 	} | 	} | ||||||
| 	return p.Price * float64(amountOfData), nil | 	return p.Price * float64(amountOfData), nil | ||||||
|   | |||||||
| @@ -15,9 +15,9 @@ func (d DummyStrategy) GetStrategy() string   { return "DUMMY" } | |||||||
| func (d DummyStrategy) GetStrategyValue() int { return int(d) } | func (d DummyStrategy) GetStrategyValue() int { return int(d) } | ||||||
|  |  | ||||||
| func TestBuyingStrategy_String(t *testing.T) { | func TestBuyingStrategy_String(t *testing.T) { | ||||||
| 	assert.Equal(t, "UNLIMITED", pricing.UNLIMITED.String()) | 	assert.Equal(t, "UNLIMITED", pricing.PERMANENT.String()) | ||||||
| 	assert.Equal(t, "SUBSCRIPTION", pricing.SUBSCRIPTION.String()) | 	assert.Equal(t, "SUBSCRIPTION", pricing.SUBSCRIPTION.String()) | ||||||
| 	assert.Equal(t, "PAY PER USE", pricing.PAY_PER_USE.String()) | 	//assert.Equal(t, "PAY PER USE", pricing.PAY_PER_USE.String()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestBuyingStrategyList(t *testing.T) { | func TestBuyingStrategyList(t *testing.T) { | ||||||
| @@ -116,13 +116,13 @@ func TestPricingStrategy_GetPrice(t *testing.T) { | |||||||
| 	assert.True(t, p > 0) | 	assert.True(t, p > 0) | ||||||
|  |  | ||||||
| 	// UNLIMITED case | 	// UNLIMITED case | ||||||
| 	ps.BuyingStrategy = pricing.UNLIMITED | 	ps.BuyingStrategy = pricing.PERMANENT | ||||||
| 	p, err = ps.GetPrice(10, 0, start, &end) | 	p, err = ps.GetPrice(10, 0, start, &end) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, 5.0, p) | 	assert.Equal(t, 5.0, p) | ||||||
|  |  | ||||||
| 	// PAY_PER_USE case | 	// PAY_PER_USE case | ||||||
| 	ps.BuyingStrategy = pricing.PAY_PER_USE | 	//ps.BuyingStrategy = pricing.PAY_PER_USE | ||||||
| 	p, err = ps.GetPrice(3, 0, start, &end) | 	p, err = ps.GetPrice(3, 0, start, &end) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, 15.0, p) | 	assert.Equal(t, 15.0, p) | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"cloud.o-forge.io/core/oc-lib/logs" | 	"cloud.o-forge.io/core/oc-lib/logs" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/bill" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/compute_units" | 	"cloud.o-forge.io/core/oc-lib/models/compute_units" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/order" | 	"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/models/resources/purchase_resource" | ||||||
| @@ -40,6 +41,7 @@ var ModelsCatalog = map[string]func() utils.DBObject{ | |||||||
| 	tools.ORDER.String():               func() utils.DBObject { return &order.Order{} }, | 	tools.ORDER.String():               func() utils.DBObject { return &order.Order{} }, | ||||||
| 	tools.PURCHASE_RESOURCE.String():   func() utils.DBObject { return &purchase_resource.PurchaseResource{} }, | 	tools.PURCHASE_RESOURCE.String():   func() utils.DBObject { return &purchase_resource.PurchaseResource{} }, | ||||||
| 	tools.COMPUTE_UNITS.String():       func() utils.DBObject { return &compute_units.ComputeUnits{} }, | 	tools.COMPUTE_UNITS.String():       func() utils.DBObject { return &compute_units.ComputeUnits{} }, | ||||||
|  | 	tools.BILL.String():                func() utils.DBObject { return &bill.Bill{} }, | ||||||
| } | } | ||||||
|  |  | ||||||
| // Model returns the model object based on the model type | // Model returns the model object based on the model type | ||||||
|   | |||||||
| @@ -265,7 +265,7 @@ func (d *PeerOrder) Pay(request *tools.APIRequest, response chan *PeerOrder, wg | |||||||
| 		d.Status = enum.PAID // TO REMOVE LATER IT'S A MOCK | 		d.Status = enum.PAID // TO REMOVE LATER IT'S A MOCK | ||||||
| 		if d.Status == enum.PAID { | 		if d.Status == enum.PAID { | ||||||
| 			for _, b := range d.Items { | 			for _, b := range d.Items { | ||||||
| 				if !b.Item.IsPurchased() { | 				if !b.Item.IsPurchasable() { | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 				accessor := purchase_resource.NewAccessor(request) | 				accessor := purchase_resource.NewAccessor(request) | ||||||
|   | |||||||
| @@ -80,8 +80,15 @@ type ComputeResourcePricingProfile struct { | |||||||
| 	RAMPrice   float64            `json:"ram_price" bson:"ram_price" default:"-1"`            // RAMPrice is the price of the RAM | 	RAMPrice   float64            `json:"ram_price" bson:"ram_price" default:"-1"`            // RAMPrice is the price of the RAM | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *ComputeResourcePricingProfile) IsPurchased() bool { | func (p *ComputeResourcePricingProfile) IsPurchasable() bool { | ||||||
| 	return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE | 	return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *ComputeResourcePricingProfile) IsBooked() bool { | ||||||
|  | 	if p.Pricing.BuyingStrategy == pricing.PERMANENT { | ||||||
|  | 		p.Pricing.BuyingStrategy = pricing.SUBSCRIPTION | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *ComputeResourcePricingProfile) GetOverrideStrategyValue() int { | func (p *ComputeResourcePricingProfile) GetOverrideStrategyValue() int { | ||||||
|   | |||||||
| @@ -137,8 +137,13 @@ func (p *DataResourcePricingProfile) GetPrice(amountOfData float64, explicitDura | |||||||
| 	return p.Pricing.GetPrice(amountOfData, explicitDuration, start, &end) | 	return p.Pricing.GetPrice(amountOfData, explicitDuration, start, &end) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *DataResourcePricingProfile) IsPurchased() bool { | func (p *DataResourcePricingProfile) IsPurchasable() bool { | ||||||
| 	return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE | 	return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *DataResourcePricingProfile) IsBooked() bool { | ||||||
|  | 	// TODO WHAT ABOUT PAY PER USE... it's a complicate CASE | ||||||
|  | 	return p.Pricing.BuyingStrategy != pricing.PERMANENT | ||||||
| } | } | ||||||
|  |  | ||||||
| type PricedDataResource struct { | type PricedDataResource struct { | ||||||
|   | |||||||
| @@ -35,11 +35,18 @@ func (abs *PricedResource) GetCreatorID() string { | |||||||
| 	return abs.CreatorID | 	return abs.CreatorID | ||||||
| } | } | ||||||
|  |  | ||||||
| func (abs *PricedResource) IsPurchased() bool { | func (abs *PricedResource) IsPurchasable() bool { | ||||||
| 	if abs.SelectedPricing == nil { | 	if abs.SelectedPricing == nil { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 	return (abs.SelectedPricing).IsPurchased() | 	return (abs.SelectedPricing).IsPurchasable() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (abs *PricedResource) IsBooked() bool { | ||||||
|  | 	if abs.SelectedPricing == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	return (abs.SelectedPricing).IsBooked() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (abs *PricedResource) GetLocationEnd() *time.Time { | func (abs *PricedResource) GetLocationEnd() *time.Time { | ||||||
|   | |||||||
| @@ -77,8 +77,12 @@ type ProcessingResourcePricingProfile struct { | |||||||
| 	pricing.AccessPricingProfile[pricing.TimePricingStrategy] // AccessPricingProfile is the pricing profile of a data it means that we can access the data for an amount of time | 	pricing.AccessPricingProfile[pricing.TimePricingStrategy] // AccessPricingProfile is the pricing profile of a data it means that we can access the data for an amount of time | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *ProcessingResourcePricingProfile) IsPurchased() bool { | func (p *ProcessingResourcePricingProfile) IsPurchasable() bool { | ||||||
| 	return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE | 	return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *ProcessingResourcePricingProfile) IsBooked() bool { | ||||||
|  | 	return p.Pricing.BuyingStrategy != pricing.PERMANENT | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *ProcessingResourcePricingProfile) GetPrice(amountOfData float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) { | func (p *ProcessingResourcePricingProfile) GetPrice(amountOfData float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) { | ||||||
|   | |||||||
| @@ -52,7 +52,8 @@ type AbstractInstanciatedResource[T ResourceInstanceITF] struct { | |||||||
| 	Instances        []T `json:"instances,omitempty" bson:"instances,omitempty"` // Bill is the bill of the resource            // Bill is the bill of the resource | 	Instances        []T `json:"instances,omitempty" bson:"instances,omitempty"` // Bill is the bill of the resource            // Bill is the bill of the resource | ||||||
| } | } | ||||||
|  |  | ||||||
| func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF { | func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource( | ||||||
|  | 	t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF { | ||||||
| 	instances := map[string]string{} | 	instances := map[string]string{} | ||||||
| 	profiles := []pricing.PricingProfileITF{} | 	profiles := []pricing.PricingProfileITF{} | ||||||
| 	for _, instance := range abs.Instances { | 	for _, instance := range abs.Instances { | ||||||
|   | |||||||
| @@ -152,8 +152,15 @@ type StorageResourcePricingProfile struct { | |||||||
| 	pricing.ExploitPricingProfile[StorageResourcePricingStrategy] // ExploitPricingProfile is the pricing profile of a storage it means that we exploit the resource for an amount of continuous time | 	pricing.ExploitPricingProfile[StorageResourcePricingStrategy] // ExploitPricingProfile is the pricing profile of a storage it means that we exploit the resource for an amount of continuous time | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *StorageResourcePricingProfile) IsPurchased() bool { | func (p *StorageResourcePricingProfile) IsPurchasable() bool { | ||||||
| 	return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE | 	return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *StorageResourcePricingProfile) IsBooked() bool { | ||||||
|  | 	if p.Pricing.BuyingStrategy == pricing.PERMANENT { | ||||||
|  | 		p.Pricing.BuyingStrategy = pricing.SUBSCRIPTION | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *StorageResourcePricingProfile) GetPrice(amountOfData float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) { | func (p *StorageResourcePricingProfile) GetPrice(amountOfData float64, val float64, start time.Time, end time.Time, params ...string) (float64, error) { | ||||||
|   | |||||||
| @@ -76,11 +76,8 @@ func TestDataResourcePricingStrategy_GetQuantity(t *testing.T) { | |||||||
|  |  | ||||||
| func TestDataResourcePricingProfile_IsPurchased(t *testing.T) { | func TestDataResourcePricingProfile_IsPurchased(t *testing.T) { | ||||||
| 	profile := &resources.DataResourcePricingProfile{} | 	profile := &resources.DataResourcePricingProfile{} | ||||||
| 	profile.Pricing.BuyingStrategy = pricing.PAY_PER_USE |  | ||||||
| 	assert.False(t, profile.IsPurchased()) |  | ||||||
|  |  | ||||||
| 	profile.Pricing.BuyingStrategy = pricing.SUBSCRIPTION | 	profile.Pricing.BuyingStrategy = pricing.SUBSCRIPTION | ||||||
| 	assert.True(t, profile.IsPurchased()) | 	assert.True(t, profile.IsPurchasable()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestPricedDataResource_GetPrice(t *testing.T) { | func TestPricedDataResource_GetPrice(t *testing.T) { | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ type MockPricingProfile struct { | |||||||
| 	ReturnCost float64 | 	ReturnCost float64 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MockPricingProfile) IsPurchased() bool { | func (m *MockPricingProfile) IsPurchasable() bool { | ||||||
| 	return m.Purchased | 	return m.Purchased | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -49,13 +49,13 @@ func TestGetIDAndCreatorAndType(t *testing.T) { | |||||||
| func TestIsPurchased(t *testing.T) { | func TestIsPurchased(t *testing.T) { | ||||||
| 	t.Run("nil selected pricing returns false", func(t *testing.T) { | 	t.Run("nil selected pricing returns false", func(t *testing.T) { | ||||||
| 		r := &resources.PricedResource{} | 		r := &resources.PricedResource{} | ||||||
| 		assert.False(t, r.IsPurchased()) | 		assert.False(t, r.IsPurchasable()) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	t.Run("returns true if pricing profile is purchased", func(t *testing.T) { | 	t.Run("returns true if pricing profile is purchased", func(t *testing.T) { | ||||||
| 		mock := &MockPricingProfile{Purchased: true} | 		mock := &MockPricingProfile{Purchased: true} | ||||||
| 		r := &resources.PricedResource{SelectedPricing: mock} | 		r := &resources.PricedResource{SelectedPricing: mock} | ||||||
| 		assert.True(t, r.IsPurchased()) | 		assert.True(t, r.IsPurchasable()) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -95,21 +95,12 @@ func TestProcessingResourcePricingProfile_GetPrice(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestProcessingResourcePricingProfile_IsPurchased(t *testing.T) { | func TestProcessingResourcePricingProfile_IsPurchased(t *testing.T) { | ||||||
| 	nonPurchased := &ProcessingResourcePricingProfile{ |  | ||||||
| 		AccessPricingProfile: pricing.AccessPricingProfile[pricing.TimePricingStrategy]{ |  | ||||||
| 			Pricing: pricing.PricingStrategy[pricing.TimePricingStrategy]{ |  | ||||||
| 				BuyingStrategy: pricing.PAY_PER_USE, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| 	assert.False(t, nonPurchased.IsPurchased()) |  | ||||||
|  |  | ||||||
| 	purchased := &ProcessingResourcePricingProfile{ | 	purchased := &ProcessingResourcePricingProfile{ | ||||||
| 		AccessPricingProfile: pricing.AccessPricingProfile[pricing.TimePricingStrategy]{ | 		AccessPricingProfile: pricing.AccessPricingProfile[pricing.TimePricingStrategy]{ | ||||||
| 			Pricing: pricing.PricingStrategy[pricing.TimePricingStrategy]{ | 			Pricing: pricing.PricingStrategy[pricing.TimePricingStrategy]{ | ||||||
| 				BuyingStrategy: pricing.UNLIMITED, | 				BuyingStrategy: pricing.PERMANENT, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	assert.True(t, purchased.IsPurchased()) | 	assert.True(t, purchased.IsPurchasable()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,10 +2,8 @@ package resources_test | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/models" | 	"cloud.o-forge.io/core/oc-lib/models/common/models" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" |  | ||||||
| 	"cloud.o-forge.io/core/oc-lib/tools" | 	"cloud.o-forge.io/core/oc-lib/tools" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
|  |  | ||||||
| @@ -107,43 +105,3 @@ func TestPricedStorageResource_GetPrice_NoProfiles(t *testing.T) { | |||||||
| 	_, err := res.GetPrice() | 	_, err := res.GetPrice() | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestPricedStorageResource_GetPrice_WithPricing(t *testing.T) { |  | ||||||
| 	now := time.Now() |  | ||||||
| 	end := now.Add(2 * time.Hour) |  | ||||||
| 	profile := &resources.StorageResourcePricingProfile{ |  | ||||||
| 		ExploitPricingProfile: pricing.ExploitPricingProfile[resources.StorageResourcePricingStrategy]{ |  | ||||||
| 			AccessPricingProfile: pricing.AccessPricingProfile[resources.StorageResourcePricingStrategy]{ |  | ||||||
| 				Pricing: pricing.PricingStrategy[resources.StorageResourcePricingStrategy]{ |  | ||||||
| 					BuyingStrategy: pricing.PAY_PER_USE, |  | ||||||
| 					Price:          42.0, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| 	res := &resources.PricedStorageResource{ |  | ||||||
| 		PricedResource: resources.PricedResource{ |  | ||||||
| 			UsageStart:      &now, |  | ||||||
| 			UsageEnd:        &end, |  | ||||||
| 			PricingProfiles: []pricing.PricingProfileITF{profile}, |  | ||||||
| 		}, |  | ||||||
| 		UsageStorageGB: 1.0, |  | ||||||
| 	} |  | ||||||
| 	price, err := res.GetPrice() |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.Equal(t, 42.0, price) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestStorageResourcePricingProfile_IsPurchased(t *testing.T) { |  | ||||||
| 	p := &resources.StorageResourcePricingProfile{ |  | ||||||
| 		ExploitPricingProfile: pricing.ExploitPricingProfile[resources.StorageResourcePricingStrategy]{ |  | ||||||
| 			AccessPricingProfile: pricing.AccessPricingProfile[resources.StorageResourcePricingStrategy]{ |  | ||||||
| 				Pricing: pricing.PricingStrategy[resources.StorageResourcePricingStrategy]{BuyingStrategy: pricing.PAY_PER_USE}, |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| 	assert.False(t, p.IsPurchased()) |  | ||||||
|  |  | ||||||
| 	p.Pricing.BuyingStrategy = pricing.UNLIMITED |  | ||||||
| 	assert.True(t, p.IsPurchased()) |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -169,8 +169,8 @@ func (wfa *Workflow) CheckBooking(caller *tools.HTTPCaller) (bool, error) { | |||||||
| func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) (float64, map[tools.DataType]map[string]pricing.PricedItemITF, *Workflow, error) { | func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) (float64, map[tools.DataType]map[string]pricing.PricedItemITF, *Workflow, error) { | ||||||
| 	priceds := map[tools.DataType]map[string]pricing.PricedItemITF{} | 	priceds := map[tools.DataType]map[string]pricing.PricedItemITF{} | ||||||
| 	ps, priceds, err := plan[*resources.ProcessingResource](tools.PROCESSING_RESOURCE, wf, priceds, request, | 	ps, priceds, err := plan[*resources.ProcessingResource](tools.PROCESSING_RESOURCE, wf, priceds, request, | ||||||
| 		buyingStrategy, pricingStrategy, | 		buyingStrategy, pricingStrategy, wf.Graph.IsProcessing, | ||||||
| 		wf.Graph.IsProcessing, func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) { | 		func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) { | ||||||
| 			return start.Add(time.Duration(wf.Graph.GetAverageTimeProcessingBeforeStart(0, res.GetID(), request, buyingStrategy, pricingStrategy)) * time.Second), priced.GetExplicitDurationInS() | 			return start.Add(time.Duration(wf.Graph.GetAverageTimeProcessingBeforeStart(0, res.GetID(), request, buyingStrategy, pricingStrategy)) * time.Second), priced.GetExplicitDurationInS() | ||||||
| 		}, func(started time.Time, duration float64) *time.Time { | 		}, func(started time.Time, duration float64) *time.Time { | ||||||
| 			s := started.Add(time.Duration(duration)) | 			s := started.Add(time.Duration(duration)) | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"cloud.o-forge.io/core/oc-lib/models/booking" | 	"cloud.o-forge.io/core/oc-lib/models/booking" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/enum" | 	"cloud.o-forge.io/core/oc-lib/models/common/enum" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" | 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/utils" | 	"cloud.o-forge.io/core/oc-lib/models/utils" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/tools" | 	"cloud.o-forge.io/core/oc-lib/tools" | ||||||
| 	"github.com/google/uuid" | 	"github.com/google/uuid" | ||||||
| @@ -21,6 +22,7 @@ import ( | |||||||
|  */ |  */ | ||||||
| type WorkflowExecution struct { | type WorkflowExecution struct { | ||||||
| 	utils.AbstractObject                                // AbstractObject contains the basic fields of an object (id, name) | 	utils.AbstractObject                                // AbstractObject contains the basic fields of an object (id, name) | ||||||
|  | 	PeerBuyByGraph       map[string]map[string][]string `json:"peer_buy_by_graph,omitempty" bson:"peer_buy_by_graph,omitempty"`   // BookByResource is a map of the resource id and the list of the booking id | ||||||
| 	PeerBookByGraph      map[string]map[string][]string `json:"peer_book_by_graph,omitempty" bson:"peer_book_by_graph,omitempty"` // BookByResource is a map of the resource id and the list of the booking id | 	PeerBookByGraph      map[string]map[string][]string `json:"peer_book_by_graph,omitempty" bson:"peer_book_by_graph,omitempty"` // BookByResource is a map of the resource id and the list of the booking id | ||||||
| 	ExecutionsID         string                         `json:"executions_id,omitempty" bson:"executions_id,omitempty"` | 	ExecutionsID         string                         `json:"executions_id,omitempty" bson:"executions_id,omitempty"` | ||||||
| 	ExecDate             time.Time                      `json:"execution_date,omitempty" bson:"execution_date,omitempty" validate:"required"` // ExecDate is the execution date of the workflow, is required | 	ExecDate             time.Time                      `json:"execution_date,omitempty" bson:"execution_date,omitempty" validate:"required"` // ExecDate is the execution date of the workflow, is required | ||||||
| @@ -110,10 +112,51 @@ func (d *WorkflowExecution) VerifyAuth(request *tools.APIRequest) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| 	booking is an activity reserved for not a long time investment. | booking is an activity reserved for not a long time investment. | ||||||
| 	... purchase is dependant of a one time buying. | ... purchase is dependant of a one time buying. | ||||||
| 	use of a datacenter or storage can't be buy for permanent. | use of a datacenter or storage can't be buy for permanent access. | ||||||
| */ | */ | ||||||
|  | func (d *WorkflowExecution) Buy(bs pricing.BillingStrategy, executionsID string, wfID string, priceds map[tools.DataType]map[string]pricing.PricedItemITF) []*purchase_resource.PurchaseResource { | ||||||
|  | 	purchases := d.buyEach(bs, executionsID, wfID, tools.PROCESSING_RESOURCE, priceds[tools.PROCESSING_RESOURCE]) | ||||||
|  | 	purchases = append(purchases, d.buyEach(bs, executionsID, wfID, tools.DATA_RESOURCE, priceds[tools.DATA_RESOURCE])...) | ||||||
|  | 	return purchases | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (d *WorkflowExecution) buyEach(bs pricing.BillingStrategy, executionsID string, wfID string, dt tools.DataType, priceds map[string]pricing.PricedItemITF) []*purchase_resource.PurchaseResource { | ||||||
|  | 	items := []*purchase_resource.PurchaseResource{} | ||||||
|  | 	for itemID, priced := range priceds { | ||||||
|  | 		if !priced.IsPurchasable() && bs == pricing.BILL_ONCE { // buy only that must be buy | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if d.PeerBuyByGraph == nil { | ||||||
|  | 			d.PeerBuyByGraph = map[string]map[string][]string{} | ||||||
|  | 		} | ||||||
|  | 		if d.PeerBuyByGraph[priced.GetCreatorID()] == nil { | ||||||
|  | 			d.PeerBuyByGraph[priced.GetCreatorID()] = map[string][]string{} | ||||||
|  | 		} | ||||||
|  | 		if d.PeerBuyByGraph[priced.GetCreatorID()][itemID] == nil { | ||||||
|  | 			d.PeerBuyByGraph[priced.GetCreatorID()][itemID] = []string{} | ||||||
|  | 		} | ||||||
|  | 		start := d.ExecDate | ||||||
|  | 		if s := priced.GetLocationStart(); s != nil { | ||||||
|  | 			start = *s | ||||||
|  | 		} | ||||||
|  | 		end := start.Add(time.Duration(priced.GetExplicitDurationInS()) * time.Second) | ||||||
|  | 		bookingItem := &purchase_resource.PurchaseResource{ | ||||||
|  | 			AbstractObject: utils.AbstractObject{ | ||||||
|  | 				UUID: uuid.New().String(), | ||||||
|  | 				Name: d.GetName() + "_" + executionsID + "_" + wfID, | ||||||
|  | 			}, | ||||||
|  | 			ResourceID:   priced.GetID(), | ||||||
|  | 			ResourceType: dt, | ||||||
|  | 			EndDate:      &end, | ||||||
|  | 		} | ||||||
|  | 		items = append(items, bookingItem) | ||||||
|  | 		d.PeerBuyByGraph[priced.GetCreatorID()][itemID] = append( | ||||||
|  | 			d.PeerBuyByGraph[priced.GetCreatorID()][itemID], bookingItem.GetID()) | ||||||
|  | 	} | ||||||
|  | 	return items | ||||||
|  | } | ||||||
|  |  | ||||||
| func (d *WorkflowExecution) Book(executionsID string, wfID string, priceds map[tools.DataType]map[string]pricing.PricedItemITF) []*booking.Booking { | func (d *WorkflowExecution) Book(executionsID string, wfID string, priceds map[tools.DataType]map[string]pricing.PricedItemITF) []*booking.Booking { | ||||||
| 	booking := d.bookEach(executionsID, wfID, tools.STORAGE_RESOURCE, priceds[tools.STORAGE_RESOURCE]) | 	booking := d.bookEach(executionsID, wfID, tools.STORAGE_RESOURCE, priceds[tools.STORAGE_RESOURCE]) | ||||||
| @@ -126,6 +169,9 @@ func (d *WorkflowExecution) Book(executionsID string, wfID string, priceds map[t | |||||||
| func (d *WorkflowExecution) bookEach(executionsID string, wfID string, dt tools.DataType, priceds map[string]pricing.PricedItemITF) []*booking.Booking { | func (d *WorkflowExecution) bookEach(executionsID string, wfID string, dt tools.DataType, priceds map[string]pricing.PricedItemITF) []*booking.Booking { | ||||||
| 	items := []*booking.Booking{} | 	items := []*booking.Booking{} | ||||||
| 	for itemID, priced := range priceds { | 	for itemID, priced := range priceds { | ||||||
|  | 		if !priced.IsBooked() { // book only that must be booked | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
| 		if d.PeerBookByGraph == nil { | 		if d.PeerBookByGraph == nil { | ||||||
| 			d.PeerBookByGraph = map[string]map[string][]string{} | 			d.PeerBookByGraph = map[string]map[string][]string{} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/enum" | 	"cloud.o-forge.io/core/oc-lib/models/common/enum" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" | 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/peer" | 	"cloud.o-forge.io/core/oc-lib/models/peer" | ||||||
|  | 	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/utils" | 	"cloud.o-forge.io/core/oc-lib/models/utils" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/models/workflow" | 	"cloud.o-forge.io/core/oc-lib/models/workflow" | ||||||
| 	"cloud.o-forge.io/core/oc-lib/tools" | 	"cloud.o-forge.io/core/oc-lib/tools" | ||||||
| @@ -34,8 +35,9 @@ type WorkflowSchedule struct { | |||||||
| 	DurationS         float64              `json:"duration_s" default:"-1"`               // End is the end time of the schedule | 	DurationS         float64              `json:"duration_s" default:"-1"`               // End is the end time of the schedule | ||||||
| 	Cron              string               `json:"cron,omitempty"`                        // here the cron format : ss mm hh dd MM dw task | 	Cron              string               `json:"cron,omitempty"`                        // here the cron format : ss mm hh dd MM dw task | ||||||
|  |  | ||||||
| 	SelectedBuyingStrategy  pricing.BuyingStrategy `json:"selected_buying_strategy"` | 	SelectedBuyingStrategy  pricing.BuyingStrategy  `json:"selected_buying_strategy"` | ||||||
| 	SelectedPricingStrategy int                    `json:"selected_pricing_strategy"` | 	SelectedPricingStrategy int                     `json:"selected_pricing_strategy"` | ||||||
|  | 	SelectedBillingStrategy pricing.BillingStrategy `json:"selected_billing_strategy"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewScheduler(start string, end string, durationInS float64, cron string) *WorkflowSchedule { | func NewScheduler(start string, end string, durationInS float64, cron string) *WorkflowSchedule { | ||||||
| @@ -79,8 +81,10 @@ func (ws *WorkflowSchedule) CheckBooking(wfID string, request *tools.APIRequest) | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, wf, []*WorkflowExecution{}, []*booking.Booking{}, err | 		return false, wf, []*WorkflowExecution{}, []*booking.Booking{}, err | ||||||
| 	} | 	} | ||||||
|  | 	purchased := []*purchase_resource.PurchaseResource{} | ||||||
| 	bookings := []*booking.Booking{} | 	bookings := []*booking.Booking{} | ||||||
| 	for _, exec := range execs { | 	for _, exec := range execs { | ||||||
|  | 		purchased = append(purchased, exec.Buy(ws.SelectedBillingStrategy, ws.UUID, wfID, priceds)...) | ||||||
| 		bookings = append(bookings, exec.Book(ws.UUID, wfID, priceds)...) | 		bookings = append(bookings, exec.Book(ws.UUID, wfID, priceds)...) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ const ( | |||||||
| 	ADMIRALTY_KUBECONFIG | 	ADMIRALTY_KUBECONFIG | ||||||
| 	ADMIRALTY_NODES | 	ADMIRALTY_NODES | ||||||
| 	COMPUTE_UNITS | 	COMPUTE_UNITS | ||||||
|  | 	BILL | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var NOAPI = "" | var NOAPI = "" | ||||||
| @@ -67,6 +68,7 @@ var DefaultAPI = [...]string{ | |||||||
| 	ADMIRALTY_KUBECONFIGAPI, | 	ADMIRALTY_KUBECONFIGAPI, | ||||||
| 	ADMIRALTY_NODESAPI, | 	ADMIRALTY_NODESAPI, | ||||||
| 	DATACENTERAPI, | 	DATACENTERAPI, | ||||||
|  | 	NOAPI, | ||||||
| } | } | ||||||
|  |  | ||||||
| // Bind the standard data name to the data type | // Bind the standard data name to the data type | ||||||
| @@ -94,6 +96,7 @@ var Str = [...]string{ | |||||||
| 	"admiralty_kubeconfig", | 	"admiralty_kubeconfig", | ||||||
| 	"admiralty_node", | 	"admiralty_node", | ||||||
| 	"compute_units", | 	"compute_units", | ||||||
|  | 	"bill", | ||||||
| } | } | ||||||
|  |  | ||||||
| func FromInt(i int) string { | func FromInt(i int) string { | ||||||
| @@ -114,5 +117,7 @@ func (d DataType) EnumIndex() int { | |||||||
| } | } | ||||||
|  |  | ||||||
| func DataTypeList() []DataType { | 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, PURCHASE_RESOURCE, ADMIRALTY_SOURCE, ADMIRALTY_TARGET, ADMIRALTY_SECRET, ADMIRALTY_KUBECONFIG, ADMIRALTY_NODES} | 	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, ADMIRALTY_SOURCE, ADMIRALTY_TARGET, ADMIRALTY_SECRET, ADMIRALTY_KUBECONFIG, ADMIRALTY_NODES, COMPUTE_UNITS, BILL} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user