PricedItem evolved
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||
"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/order"
|
||||
"cloud.o-forge.io/core/oc-lib/models/peer"
|
||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
||||
@@ -48,6 +49,7 @@ func DraftFirstBill(order *order.Order, request *tools.APIRequest) (*Bill, error
|
||||
peers[p.DestPeerID] = []*PeerItemOrder{}
|
||||
}
|
||||
peers[p.DestPeerID] = append(peers[p.DestPeerID], &PeerItemOrder{
|
||||
ResourceType: p.ResourceType,
|
||||
Purchase: p,
|
||||
Item: p.PricedItem,
|
||||
Quantity: 1,
|
||||
@@ -69,6 +71,8 @@ func DraftFirstBill(order *order.Order, request *tools.APIRequest) (*Bill, error
|
||||
peers[b.DestPeerID] = []*PeerItemOrder{}
|
||||
}
|
||||
peers[b.DestPeerID] = append(peers[b.DestPeerID], &PeerItemOrder{
|
||||
ResourceType: b.ResourceType,
|
||||
Quantity: 1,
|
||||
Item: b.PricedItem,
|
||||
})
|
||||
}
|
||||
@@ -135,6 +139,22 @@ type PeerOrder struct {
|
||||
Total float64 `json:"total,omitempty" bson:"total,omitempty"`
|
||||
}
|
||||
|
||||
func PricedByType(dt tools.DataType) pricing.PricedItemITF {
|
||||
switch dt {
|
||||
case tools.PROCESSING_RESOURCE:
|
||||
return &resources.PricedProcessingResource{}
|
||||
case tools.STORAGE_RESOURCE:
|
||||
return &resources.PricedStorageResource{}
|
||||
case tools.DATA_RESOURCE:
|
||||
return &resources.PricedDataResource{}
|
||||
case tools.COMPUTE_RESOURCE:
|
||||
return &resources.PricedComputeResource{}
|
||||
case tools.WORKFLOW_RESOURCE:
|
||||
return &resources.PricedResource[*pricing.ExploitPricingProfile[pricing.TimePricingStrategy]]{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *PeerOrder) Pay(request *tools.APIRequest, response chan *PeerOrder, wg *sync.WaitGroup) {
|
||||
|
||||
d.Status = enum.PENDING
|
||||
@@ -144,7 +164,7 @@ func (d *PeerOrder) Pay(request *tools.APIRequest, response chan *PeerOrder, wg
|
||||
d.Status = enum.PAID // TO REMOVE LATER IT'S A MOCK
|
||||
if d.Status == enum.PAID {
|
||||
for _, b := range d.Items {
|
||||
var priced *resources.PricedResource
|
||||
priced := PricedByType(b.ResourceType)
|
||||
bb, _ := json.Marshal(b.Item)
|
||||
json.Unmarshal(bb, priced)
|
||||
if !priced.IsPurchasable() {
|
||||
@@ -178,6 +198,7 @@ func (d *PeerOrder) SumUpBill(request *tools.APIRequest) error {
|
||||
}
|
||||
|
||||
type PeerItemOrder struct {
|
||||
ResourceType tools.DataType `json:"datatype,omitempty" bson:"datatype,omitempty"`
|
||||
Quantity int `json:"quantity,omitempty" bson:"quantity,omitempty"`
|
||||
Purchase *purchase_resource.PurchaseResource `json:"purchase,omitempty" bson:"purchase,omitempty"`
|
||||
Item map[string]interface{} `json:"item,omitempty" bson:"item,omitempty"`
|
||||
@@ -189,7 +210,7 @@ func (d *PeerItemOrder) GetPriceHT(request *tools.APIRequest) (float64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
///////////
|
||||
var priced *resources.PricedResource
|
||||
priced := PricedByType(d.ResourceType)
|
||||
b, _ := json.Marshal(d.Item)
|
||||
err := json.Unmarshal(b, priced)
|
||||
if err != nil {
|
||||
|
||||
@@ -36,11 +36,11 @@ func (abs *ComputeResource) ConvertToPricedResource(t tools.DataType, selectedIn
|
||||
if t != tools.COMPUTE_RESOURCE {
|
||||
return nil, errors.New("not the proper type expected : cannot convert to priced resource : have " + t.String() + " wait Compute")
|
||||
}
|
||||
p, err := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, request)
|
||||
p, err := ConvertToPricedResource[*ComputeResourcePricingProfile](t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, abs, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priced := p.(*PricedResource)
|
||||
priced := p.(*PricedResource[*ComputeResourcePricingProfile])
|
||||
return &PricedComputeResource{
|
||||
PricedResource: *priced,
|
||||
}, nil
|
||||
@@ -122,7 +122,10 @@ func (p *ComputeResourcePricingProfile) GetPriceHT(amountOfData float64, explici
|
||||
return 0, errors.New("params must be set")
|
||||
}
|
||||
pp := float64(0)
|
||||
model := params[1]
|
||||
model := ""
|
||||
if len(params) > 1 {
|
||||
model = params[1]
|
||||
}
|
||||
if strings.Contains(params[0], "cpus") && len(params) > 1 {
|
||||
if _, ok := p.CPUsPrices[model]; ok {
|
||||
p.Pricing.Price = p.CPUsPrices[model]
|
||||
@@ -158,7 +161,7 @@ func (p *ComputeResourcePricingProfile) GetPriceHT(amountOfData float64, explici
|
||||
}
|
||||
|
||||
type PricedComputeResource struct {
|
||||
PricedResource
|
||||
PricedResource[*ComputeResourcePricingProfile]
|
||||
|
||||
CPUsLocated map[string]float64 `json:"cpus_in_use" bson:"cpus_in_use"` // CPUsInUse is the list of CPUs in use
|
||||
GPUsLocated map[string]float64 `json:"gpus_in_use" bson:"gpus_in_use"` // GPUsInUse is the list of GPUs in use
|
||||
|
||||
@@ -41,11 +41,11 @@ func (abs *DataResource) ConvertToPricedResource(t tools.DataType, selectedInsta
|
||||
if t != tools.DATA_RESOURCE {
|
||||
return nil, errors.New("not the proper type expected : cannot convert to priced resource : have " + t.String() + " wait Data")
|
||||
}
|
||||
p, err := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, request)
|
||||
p, err := ConvertToPricedResource[*DataResourcePricingProfile](t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, abs, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priced := p.(*PricedResource)
|
||||
priced := p.(*PricedResource[*DataResourcePricingProfile])
|
||||
return &PricedDataResource{
|
||||
PricedResource: *priced,
|
||||
}, nil
|
||||
@@ -160,7 +160,7 @@ func (p *DataResourcePricingProfile) IsBooked() bool {
|
||||
}
|
||||
|
||||
type PricedDataResource struct {
|
||||
PricedResource
|
||||
PricedResource[*DataResourcePricingProfile]
|
||||
UsageStorageGB float64 `json:"storage_gb,omitempty" bson:"storage_gb,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ import (
|
||||
"cloud.o-forge.io/core/oc-lib/tools"
|
||||
)
|
||||
|
||||
type PricedResourceITF interface {
|
||||
pricing.PricedItemITF
|
||||
}
|
||||
|
||||
type ResourceInterface interface {
|
||||
utils.DBObject
|
||||
FilterPeer(peerID string) *dbs.Filters
|
||||
@@ -15,7 +19,7 @@ type ResourceInterface interface {
|
||||
ConvertToPricedResource(t tools.DataType, a *int, selectedPartnership *int, selectedBuyingStrategy *int, selectedStrategy *int, b *int, request *tools.APIRequest) (pricing.PricedItemITF, error)
|
||||
GetType() string
|
||||
ClearEnv() utils.DBObject
|
||||
SetAllowedInstances(request *tools.APIRequest, instance_id ...string)
|
||||
SetAllowedInstances(request *tools.APIRequest, instance_id ...string) []ResourceInstanceITF
|
||||
AddInstances(instance ResourceInstanceITF)
|
||||
GetSelectedInstance(index *int) ResourceInstanceITF
|
||||
}
|
||||
|
||||
@@ -37,12 +37,13 @@ func (d *NativeTool) ClearEnv() utils.DBObject {
|
||||
return d
|
||||
}
|
||||
|
||||
func (w *NativeTool) SetAllowedInstances(request *tools.APIRequest, ids ...string) {
|
||||
func (w *NativeTool) SetAllowedInstances(request *tools.APIRequest, ids ...string) []ResourceInstanceITF {
|
||||
/* EMPTY */
|
||||
return []ResourceInstanceITF{}
|
||||
}
|
||||
|
||||
func (w *NativeTool) ConvertToPricedResource(t tools.DataType, selectedInstance *int, selectedPartnership *int, selectedBuyingStrategy *int, selectedStrategy *int, selectedBookingModeIndex *int, request *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
return &PricedResource{
|
||||
return &PricedResource[*pricing.ExploitPricingProfile[pricing.TimePricingStrategy]]{
|
||||
Name: w.Name,
|
||||
Logo: w.Logo,
|
||||
ResourceID: w.UUID,
|
||||
|
||||
@@ -16,11 +16,11 @@ type BookingConfiguration struct {
|
||||
Mode booking.BookingMode `json:"mode,omitempty" bson:"mode,omitempty"`
|
||||
}
|
||||
|
||||
type PricedResource struct {
|
||||
type PricedResource[T pricing.PricingProfileITF] struct {
|
||||
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
||||
Logo string `json:"logo,omitempty" bson:"logo,omitempty"`
|
||||
InstancesRefs map[string]string `json:"instances_refs,omitempty" bson:"instances_refs,omitempty"`
|
||||
SelectedPricing pricing.PricingProfileITF `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
||||
SelectedPricing T `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
||||
Quantity int `json:"quantity,omitempty" bson:"quantity,omitempty"`
|
||||
BookingConfiguration *BookingConfiguration `json:"booking_configuration,omitempty" bson:"booking_configuration,omitempty"`
|
||||
Variations []*pricing.PricingVariation `json:"pricing_variations" bson:"pricing_variations"`
|
||||
@@ -31,56 +31,56 @@ type PricedResource struct {
|
||||
ResourceType tools.DataType `json:"resource_type,omitempty" bson:"resource_type,omitempty"`
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetQuantity() int {
|
||||
func (abs *PricedResource[T]) GetQuantity() int {
|
||||
return abs.Quantity
|
||||
}
|
||||
|
||||
func (abs *PricedResource) AddQuantity(amount int) {
|
||||
func (abs *PricedResource[T]) AddQuantity(amount int) {
|
||||
abs.Quantity += amount
|
||||
}
|
||||
|
||||
func (abs *PricedResource) SelectPricing() pricing.PricingProfileITF {
|
||||
func (abs *PricedResource[T]) SelectPricing() pricing.PricingProfileITF {
|
||||
return abs.SelectedPricing
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetID() string {
|
||||
func (abs *PricedResource[T]) GetID() string {
|
||||
return abs.ResourceID
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetInstanceID() string {
|
||||
func (abs *PricedResource[T]) GetInstanceID() string {
|
||||
return abs.InstanceID
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetType() tools.DataType {
|
||||
func (abs *PricedResource[T]) GetType() tools.DataType {
|
||||
return abs.ResourceType
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetCreatorID() string {
|
||||
func (abs *PricedResource[T]) GetCreatorID() string {
|
||||
return abs.CreatorID
|
||||
}
|
||||
|
||||
func (abs *PricedResource) IsPurchasable() bool {
|
||||
if abs.SelectedPricing == nil {
|
||||
func (abs *PricedResource[T]) IsPurchasable() bool {
|
||||
if any(abs.SelectedPricing) == nil {
|
||||
return false
|
||||
}
|
||||
return (abs.SelectedPricing).IsPurchasable()
|
||||
return abs.SelectedPricing.IsPurchasable()
|
||||
}
|
||||
|
||||
func (abs *PricedResource) IsBooked() bool {
|
||||
if abs.SelectedPricing == nil {
|
||||
func (abs *PricedResource[T]) IsBooked() bool {
|
||||
if any(abs.SelectedPricing) == nil {
|
||||
return false
|
||||
}
|
||||
return (abs.SelectedPricing).IsBooked()
|
||||
return abs.SelectedPricing.IsBooked()
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetLocationEnd() *time.Time {
|
||||
func (abs *PricedResource[T]) GetLocationEnd() *time.Time {
|
||||
if abs.BookingConfiguration == nil {
|
||||
return nil
|
||||
}
|
||||
return abs.BookingConfiguration.UsageEnd
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetLocationStart() *time.Time {
|
||||
func (abs *PricedResource[T]) GetLocationStart() *time.Time {
|
||||
if abs.BookingConfiguration == nil {
|
||||
now := time.Now().Add(2 * time.Minute)
|
||||
return &now
|
||||
@@ -88,34 +88,34 @@ func (abs *PricedResource) GetLocationStart() *time.Time {
|
||||
return abs.BookingConfiguration.UsageStart
|
||||
}
|
||||
|
||||
func (abs *PricedResource) SetLocationStart(start time.Time) {
|
||||
func (abs *PricedResource[T]) SetLocationStart(start time.Time) {
|
||||
if abs.BookingConfiguration == nil {
|
||||
abs.BookingConfiguration = &BookingConfiguration{}
|
||||
}
|
||||
abs.BookingConfiguration.UsageStart = &start
|
||||
}
|
||||
|
||||
func (abs *PricedResource) SetLocationEnd(end time.Time) {
|
||||
func (abs *PricedResource[T]) SetLocationEnd(end time.Time) {
|
||||
if abs.BookingConfiguration == nil {
|
||||
abs.BookingConfiguration = &BookingConfiguration{}
|
||||
}
|
||||
abs.BookingConfiguration.UsageEnd = &end
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetBookingMode() booking.BookingMode {
|
||||
func (abs *PricedResource[T]) GetBookingMode() booking.BookingMode {
|
||||
if abs.BookingConfiguration == nil {
|
||||
return booking.WHEN_POSSIBLE
|
||||
}
|
||||
return abs.BookingConfiguration.Mode
|
||||
}
|
||||
|
||||
func (abs *PricedResource) GetExplicitDurationInS() float64 {
|
||||
func (abs *PricedResource[T]) GetExplicitDurationInS() float64 {
|
||||
if abs.BookingConfiguration == nil {
|
||||
abs.BookingConfiguration = &BookingConfiguration{}
|
||||
}
|
||||
if abs.BookingConfiguration.ExplicitBookingDurationS == 0 {
|
||||
if abs.BookingConfiguration.UsageEnd == nil && abs.BookingConfiguration.UsageStart == nil {
|
||||
return (5 * time.Minute).Seconds()
|
||||
return (1 * time.Hour).Seconds()
|
||||
}
|
||||
if abs.BookingConfiguration.UsageEnd == nil {
|
||||
add := abs.BookingConfiguration.UsageStart.Add(5 * time.Minute)
|
||||
@@ -126,7 +126,7 @@ func (abs *PricedResource) GetExplicitDurationInS() float64 {
|
||||
return abs.BookingConfiguration.ExplicitBookingDurationS
|
||||
}
|
||||
|
||||
func (r *PricedResource) GetPriceHT() (float64, error) {
|
||||
func (r *PricedResource[T]) GetPriceHT() (float64, error) {
|
||||
now := time.Now()
|
||||
if r.BookingConfiguration == nil {
|
||||
r.BookingConfiguration = &BookingConfiguration{}
|
||||
@@ -138,8 +138,8 @@ func (r *PricedResource) GetPriceHT() (float64, error) {
|
||||
add := r.BookingConfiguration.UsageStart.Add(time.Duration(1 * time.Hour))
|
||||
r.BookingConfiguration.UsageEnd = &add
|
||||
}
|
||||
if r.SelectedPricing == nil {
|
||||
return 0, errors.New("pricing profile must be set on Priced Resource " + r.ResourceID)
|
||||
if any(r.SelectedPricing) == nil {
|
||||
return 0, errors.New("pricing profile must be set for resource " + r.ResourceID)
|
||||
}
|
||||
pricing := r.SelectedPricing
|
||||
return pricing.GetPriceHT(1, 0, *r.BookingConfiguration.UsageStart, *r.BookingConfiguration.UsageEnd, r.Variations)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||
@@ -65,7 +66,7 @@ type ProcessingResourcePartnership struct {
|
||||
}
|
||||
|
||||
type PricedProcessingResource struct {
|
||||
PricedResource
|
||||
PricedResource[*ProcessingResourcePricingProfile]
|
||||
IsService bool
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ func (a *PricedProcessingResource) GetExplicitDurationInS() float64 {
|
||||
if a.IsService {
|
||||
return -1
|
||||
}
|
||||
return (5 * time.Minute).Seconds()
|
||||
return (1 * time.Hour).Seconds()
|
||||
}
|
||||
return a.BookingConfiguration.UsageEnd.Sub(*a.BookingConfiguration.UsageStart).Seconds()
|
||||
}
|
||||
@@ -93,6 +94,20 @@ func (d *ProcessingResource) GetAccessor(request *tools.APIRequest) utils.Access
|
||||
return NewAccessor[*ProcessingResource](tools.PROCESSING_RESOURCE, request, func() utils.DBObject { return &ProcessingResource{} }) // Create a new instance of the accessor
|
||||
}
|
||||
|
||||
func (abs *ProcessingResource) ConvertToPricedResource(t tools.DataType, selectedInstance *int, selectedPartnership *int, selectedBuyingStrategy *int, selectedStrategy *int, selectedBookingModeIndex *int, request *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
if t != tools.PROCESSING_RESOURCE {
|
||||
return nil, errors.New("not the proper type expected : cannot convert to priced resource : have " + t.String() + " wait Data")
|
||||
}
|
||||
p, err := ConvertToPricedResource[*DataResourcePricingProfile](t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, abs, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priced := p.(*PricedResource[*DataResourcePricingProfile])
|
||||
return &PricedDataResource{
|
||||
PricedResource: *priced,
|
||||
}, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ func (abs *AbstractInstanciatedResource[T]) AddInstances(instance ResourceInstan
|
||||
abs.Instances = append(abs.Instances, instance.(T))
|
||||
}
|
||||
|
||||
func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.DataType,
|
||||
func ConvertToPricedResource[T pricing.PricingProfileITF](t tools.DataType,
|
||||
selectedInstance *int, selectedPartnership *int, selectedBuyingStrategy *int, selectedStrategy *int,
|
||||
selectedBookingModeIndex *int, request *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
selectedBookingModeIndex *int, abs ResourceInterface, request *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
instances := map[string]string{}
|
||||
var profile pricing.PricingProfileITF
|
||||
var inst ResourceInstanceITF
|
||||
@@ -84,7 +84,7 @@ func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.Data
|
||||
instances[t.GetID()] = t.GetName()
|
||||
profile = t.GetProfile(request.PeerID, selectedPartnership, selectedBuyingStrategy, selectedStrategy)
|
||||
} else {
|
||||
for i, instance := range abs.Instances { // TODO why it crush before ?
|
||||
for i, instance := range abs.SetAllowedInstances(request) { // TODO why it crush before ?
|
||||
if i == 0 {
|
||||
inst = instance
|
||||
}
|
||||
@@ -106,8 +106,8 @@ func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.Data
|
||||
}*/
|
||||
}
|
||||
variations := []*pricing.PricingVariation{}
|
||||
if selectedBookingModeIndex != nil && abs.AllowedBookingModes[booking.BookingMode(*selectedBookingModeIndex)] != nil {
|
||||
variations = append(variations, abs.AllowedBookingModes[booking.BookingMode(*selectedBookingModeIndex)])
|
||||
if selectedBookingModeIndex != nil && abs.GetBookingModes()[booking.BookingMode(*selectedBookingModeIndex)] != nil {
|
||||
variations = append(variations, abs.GetBookingModes()[booking.BookingMode(*selectedBookingModeIndex)])
|
||||
}
|
||||
// Seed the booking configuration with the instance's historical average duration
|
||||
// so GetExplicitDurationInS() returns a realistic default out of the box.
|
||||
@@ -117,17 +117,21 @@ func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.Data
|
||||
bc = &BookingConfiguration{ExplicitBookingDurationS: avg}
|
||||
}
|
||||
}
|
||||
return &PricedResource{
|
||||
Name: abs.Name,
|
||||
Logo: abs.Logo,
|
||||
ResourceID: abs.UUID,
|
||||
InstanceID: inst.GetID(),
|
||||
instanceID := ""
|
||||
if inst != nil {
|
||||
instanceID = inst.GetID()
|
||||
}
|
||||
selectedPricing, _ := profile.(T)
|
||||
return &PricedResource[T]{
|
||||
Name: abs.GetName(),
|
||||
ResourceID: abs.GetID(),
|
||||
InstanceID: instanceID,
|
||||
ResourceType: t,
|
||||
Quantity: 1,
|
||||
InstancesRefs: instances,
|
||||
SelectedPricing: profile,
|
||||
SelectedPricing: selectedPricing,
|
||||
Variations: variations,
|
||||
CreatorID: abs.CreatorID,
|
||||
CreatorID: abs.GetCreatorID(),
|
||||
BookingConfiguration: bc,
|
||||
}, nil
|
||||
}
|
||||
@@ -149,11 +153,16 @@ func (r *AbstractInstanciatedResource[T]) GetSelectedInstance(selected *int) Res
|
||||
return nil
|
||||
}
|
||||
|
||||
func (abs *AbstractInstanciatedResource[T]) SetAllowedInstances(request *tools.APIRequest, instanceID ...string) {
|
||||
if (request != nil && request.PeerID == abs.CreatorID && request.PeerID != "") || request.Admin {
|
||||
return
|
||||
}
|
||||
func (abs *AbstractInstanciatedResource[T]) SetAllowedInstances(request *tools.APIRequest, instanceID ...string) []ResourceInstanceITF {
|
||||
if !((request != nil && request.PeerID == abs.CreatorID && request.PeerID != "") || request.Admin) {
|
||||
abs.Instances = VerifyAuthAction(abs.Instances, request, instanceID...)
|
||||
}
|
||||
inst := []ResourceInstanceITF{}
|
||||
for _, i := range abs.Instances {
|
||||
inst = append(inst, i)
|
||||
}
|
||||
|
||||
return inst
|
||||
}
|
||||
|
||||
func (abs *AbstractInstanciatedResource[T]) VerifyAuth(callName string, request *tools.APIRequest) bool {
|
||||
|
||||
@@ -35,11 +35,11 @@ func (abs *StorageResource) ConvertToPricedResource(t tools.DataType, selectedIn
|
||||
if t != tools.STORAGE_RESOURCE {
|
||||
return nil, errors.New("not the proper type expected : cannot convert to priced resource : have " + t.String() + " wait Storage")
|
||||
}
|
||||
p, err := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, request)
|
||||
p, err := ConvertToPricedResource[*StorageResourcePricingProfile](t, selectedInstance, selectedPartnership, selectedBuyingStrategy, selectedStrategy, selectedBookingModeIndex, abs, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priced := p.(*PricedResource)
|
||||
priced := p.(*PricedResource[*StorageResourcePricingProfile])
|
||||
return &PricedStorageResource{
|
||||
PricedResource: *priced,
|
||||
}, nil
|
||||
@@ -181,7 +181,7 @@ func (p *StorageResourcePricingProfile) IsBooked() bool {
|
||||
}
|
||||
|
||||
type PricedStorageResource struct {
|
||||
PricedResource
|
||||
PricedResource[*StorageResourcePricingProfile]
|
||||
UsageStorageGB float64 `json:"storage_gb,omitempty" bson:"storage_gb,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,16 @@ func TestPricedComputeResource_GetPriceHT(t *testing.T) {
|
||||
start := time.Now()
|
||||
end := start.Add(1 * time.Hour)
|
||||
r := resources.PricedComputeResource{
|
||||
PricedResource: resources.PricedResource{
|
||||
PricedResource: resources.PricedResource[*resources.ComputeResourcePricingProfile]{
|
||||
ResourceID: "comp456",
|
||||
SelectedPricing: &MockPricingProfile{ReturnCost: 1.0},
|
||||
SelectedPricing: &resources.ComputeResourcePricingProfile{
|
||||
CPUsPrices: map[string]float64{"Xeon": 2.0},
|
||||
ExploitPricingProfile: pricing.ExploitPricingProfile[pricing.TimePricingStrategy]{
|
||||
AccessPricingProfile: pricing.AccessPricingProfile[pricing.TimePricingStrategy]{
|
||||
Pricing: pricing.PricingStrategy[pricing.TimePricingStrategy]{Price: 1.0},
|
||||
},
|
||||
},
|
||||
},
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &start,
|
||||
UsageEnd: &end,
|
||||
@@ -73,8 +80,8 @@ func TestPricedComputeResource_GetPriceHT(t *testing.T) {
|
||||
},
|
||||
},
|
||||
CPUsLocated: map[string]float64{"Xeon": 2},
|
||||
GPUsLocated: map[string]float64{"Tesla": 1},
|
||||
RAMLocated: 4,
|
||||
GPUsLocated: map[string]float64{},
|
||||
RAMLocated: 0,
|
||||
}
|
||||
|
||||
price, err := r.GetPriceHT()
|
||||
@@ -84,7 +91,7 @@ func TestPricedComputeResource_GetPriceHT(t *testing.T) {
|
||||
|
||||
func TestPricedComputeResource_GetPriceHT_MissingProfile(t *testing.T) {
|
||||
r := resources.PricedComputeResource{
|
||||
PricedResource: resources.PricedResource{
|
||||
PricedResource: resources.PricedResource[*resources.ComputeResourcePricingProfile]{
|
||||
ResourceID: "comp789",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestDataResourcePricingStrategy_GetQuantity(t *testing.T) {
|
||||
|
||||
func TestDataResourcePricingProfile_IsPurchased(t *testing.T) {
|
||||
profile := &resources.DataResourcePricingProfile{}
|
||||
profile.Pricing.BuyingStrategy = pricing.SUBSCRIPTION
|
||||
profile.Pricing.BuyingStrategy = pricing.PERMANENT
|
||||
assert.True(t, profile.IsPurchasable())
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestPricedDataResource_GetPriceHT(t *testing.T) {
|
||||
pricingProfile.Pricing.OverrideStrategy = resources.PER_GB_DOWNLOADED
|
||||
|
||||
r := &resources.PricedDataResource{
|
||||
PricedResource: resources.PricedResource{
|
||||
PricedResource: resources.PricedResource[*resources.DataResourcePricingProfile]{
|
||||
SelectedPricing: pricingProfile,
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &now,
|
||||
@@ -107,7 +107,7 @@ func TestPricedDataResource_GetPriceHT(t *testing.T) {
|
||||
|
||||
func TestPricedDataResource_GetPriceHT_NoProfiles(t *testing.T) {
|
||||
r := &resources.PricedDataResource{
|
||||
PricedResource: resources.PricedResource{
|
||||
PricedResource: resources.PricedResource[*resources.DataResourcePricingProfile]{
|
||||
ResourceID: "test-resource",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (m *MockPricingProfile) GetPriceHT(amount float64, explicitDuration float64
|
||||
// ---- Tests ----
|
||||
|
||||
func TestGetIDAndCreatorAndType(t *testing.T) {
|
||||
r := resources.PricedResource{
|
||||
r := resources.PricedResource[pricing.PricingProfileITF]{
|
||||
ResourceID: "res-123",
|
||||
CreatorID: "user-abc",
|
||||
ResourceType: tools.DATA_RESOURCE,
|
||||
@@ -48,19 +48,19 @@ func TestGetIDAndCreatorAndType(t *testing.T) {
|
||||
|
||||
func TestIsPurchased(t *testing.T) {
|
||||
t.Run("nil selected pricing returns false", func(t *testing.T) {
|
||||
r := &resources.PricedResource{}
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{}
|
||||
assert.False(t, r.IsPurchasable())
|
||||
})
|
||||
|
||||
t.Run("returns true if pricing profile is purchased", func(t *testing.T) {
|
||||
mock := &MockPricingProfile{Purchased: true}
|
||||
r := &resources.PricedResource{SelectedPricing: mock}
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{SelectedPricing: mock}
|
||||
assert.True(t, r.IsPurchasable())
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetAndSetLocationStartEnd(t *testing.T) {
|
||||
r := &resources.PricedResource{}
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{}
|
||||
|
||||
now := time.Now()
|
||||
r.SetLocationStart(now)
|
||||
@@ -72,7 +72,7 @@ func TestGetAndSetLocationStartEnd(t *testing.T) {
|
||||
|
||||
func TestGetExplicitDurationInS(t *testing.T) {
|
||||
t.Run("uses explicit duration if set", func(t *testing.T) {
|
||||
r := &resources.PricedResource{BookingConfiguration: &resources.BookingConfiguration{
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{BookingConfiguration: &resources.BookingConfiguration{
|
||||
ExplicitBookingDurationS: 3600,
|
||||
},
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func TestGetExplicitDurationInS(t *testing.T) {
|
||||
t.Run("computes duration from start and end", func(t *testing.T) {
|
||||
start := time.Now()
|
||||
end := start.Add(2 * time.Hour)
|
||||
r := &resources.PricedResource{
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &start, UsageEnd: &end,
|
||||
},
|
||||
@@ -91,14 +91,14 @@ func TestGetExplicitDurationInS(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("defaults to 1 hour when times not set", func(t *testing.T) {
|
||||
r := &resources.PricedResource{}
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{}
|
||||
assert.InDelta(t, 3600.0, r.GetExplicitDurationInS(), 0.1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetPriceHT(t *testing.T) {
|
||||
t.Run("returns error if no pricing profile", func(t *testing.T) {
|
||||
r := &resources.PricedResource{ResourceID: "no-profile"}
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{ResourceID: "no-profile"}
|
||||
price, err := r.GetPriceHT()
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "pricing profile must be set")
|
||||
@@ -107,7 +107,7 @@ func TestGetPriceHT(t *testing.T) {
|
||||
|
||||
t.Run("defaults BookingConfiguration when nil", func(t *testing.T) {
|
||||
mock := &MockPricingProfile{ReturnCost: 42.0}
|
||||
r := &resources.PricedResource{
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{
|
||||
SelectedPricing: mock,
|
||||
}
|
||||
price, err := r.GetPriceHT()
|
||||
@@ -119,7 +119,7 @@ func TestGetPriceHT(t *testing.T) {
|
||||
start := time.Now()
|
||||
end := start.Add(1 * time.Hour)
|
||||
mock := &MockPricingProfile{ReturnErr: true}
|
||||
r := &resources.PricedResource{
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{
|
||||
SelectedPricing: mock,
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &start,
|
||||
@@ -135,7 +135,7 @@ func TestGetPriceHT(t *testing.T) {
|
||||
start := time.Now()
|
||||
end := start.Add(1 * time.Hour)
|
||||
mock := &MockPricingProfile{ReturnCost: 10.0}
|
||||
r := &resources.PricedResource{
|
||||
r := &resources.PricedResource[pricing.PricingProfileITF]{
|
||||
SelectedPricing: mock,
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &start,
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestPricedProcessingResource_GetExplicitDurationInS(t *testing.T) {
|
||||
{
|
||||
name: "Nil start time, non-service",
|
||||
input: PricedProcessingResource{
|
||||
PricedResource: PricedResource{
|
||||
PricedResource: PricedResource[*ProcessingResourcePricingProfile]{
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: nil,
|
||||
},
|
||||
@@ -51,7 +51,7 @@ func TestPricedProcessingResource_GetExplicitDurationInS(t *testing.T) {
|
||||
{
|
||||
name: "Duration computed from start and end",
|
||||
input: PricedProcessingResource{
|
||||
PricedResource: PricedResource{
|
||||
PricedResource: PricedResource[*ProcessingResourcePricingProfile]{
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
UsageStart: &now,
|
||||
UsageEnd: &after,
|
||||
@@ -63,7 +63,7 @@ func TestPricedProcessingResource_GetExplicitDurationInS(t *testing.T) {
|
||||
{
|
||||
name: "Explicit duration takes precedence",
|
||||
input: PricedProcessingResource{
|
||||
PricedResource: PricedResource{
|
||||
PricedResource: PricedResource[*ProcessingResourcePricingProfile]{
|
||||
BookingConfiguration: &resources.BookingConfiguration{
|
||||
ExplicitBookingDurationS: 1337,
|
||||
},
|
||||
@@ -96,7 +96,7 @@ func TestProcessingResourcePricingProfile_GetPriceHT(t *testing.T) {
|
||||
},
|
||||
}
|
||||
profile := &ProcessingResourcePricingProfile{AccessPricingProfile: mockPricing}
|
||||
price, err := profile.GetPriceHT(0, 0, start, end, []*pricing.PricingVariation{})
|
||||
price, err := profile.GetPriceHT(1, 0, start, end, []*pricing.PricingVariation{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 100.0, price)
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ func TestGetSelectedInstance_NoIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCanUpdate_WhenOnlyStateDiffers(t *testing.T) {
|
||||
resource := &resources.AbstractResource{AbstractObject: utils.AbstractObject{IsDraft: false}}
|
||||
set := &MockDBObject{isDraft: true}
|
||||
resource := &resources.AbstractResource{AbstractObject: utils.AbstractObject{IsDraft: true}}
|
||||
set := &MockDBObject{isDraft: false}
|
||||
canUpdate, updated := resource.CanUpdate(set)
|
||||
assert.True(t, canUpdate)
|
||||
assert.Equal(t, set, updated)
|
||||
@@ -105,7 +105,12 @@ type FakeResource struct {
|
||||
resources.AbstractInstanciatedResource[*MockInstance]
|
||||
}
|
||||
|
||||
func (f *FakeResource) SetAllowedInstances(*tools.APIRequest, ...string) {}
|
||||
func (f *FakeResource) SetAllowedInstances(req *tools.APIRequest, instance_id ...string) []resources.ResourceInstanceITF {
|
||||
return nil
|
||||
}
|
||||
func (f *FakeResource) ConvertToPricedResource(t tools.DataType, a *int, b *int, c *int, d *int, e *int, req *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *FakeResource) VerifyAuth(string, *tools.APIRequest) bool { return true }
|
||||
|
||||
func TestNewAccessor_ReturnsValid(t *testing.T) {
|
||||
|
||||
@@ -96,7 +96,7 @@ func TestStorageResourcePricingStrategy_GetQuantity_Invalid(t *testing.T) {
|
||||
|
||||
func TestPricedStorageResource_GetPriceHT_NoProfiles(t *testing.T) {
|
||||
res := &resources.PricedStorageResource{
|
||||
PricedResource: resources.PricedResource{
|
||||
PricedResource: resources.PricedResource[*resources.StorageResourcePricingProfile]{
|
||||
ResourceID: "res-id",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ func (d *WorkflowResource) ClearEnv() utils.DBObject {
|
||||
return d
|
||||
}
|
||||
|
||||
func (w *WorkflowResource) SetAllowedInstances(request *tools.APIRequest, ids ...string) {
|
||||
func (w *WorkflowResource) SetAllowedInstances(request *tools.APIRequest, ids ...string) []ResourceInstanceITF {
|
||||
/* EMPTY */
|
||||
return []ResourceInstanceITF{}
|
||||
}
|
||||
|
||||
func (r *WorkflowResource) GetSelectedInstance(selected *int) ResourceInstanceITF {
|
||||
@@ -39,7 +40,7 @@ func (r *WorkflowResource) GetSelectedInstance(selected *int) ResourceInstanceIT
|
||||
}
|
||||
|
||||
func (w *WorkflowResource) ConvertToPricedResource(t tools.DataType, selectedInstance *int, selectedPartnership *int, selectedBuyingStrategy *int, selectedStrategy *int, selectedBookingModeIndex *int, request *tools.APIRequest) (pricing.PricedItemITF, error) {
|
||||
return &PricedResource{
|
||||
return &PricedResource[*pricing.ExploitPricingProfile[pricing.TimePricingStrategy]]{
|
||||
Name: w.Name,
|
||||
Logo: w.Logo,
|
||||
ResourceID: w.UUID,
|
||||
|
||||
Reference in New Issue
Block a user