add sets up
This commit is contained in:
parent
583ca2fbac
commit
29b192211d
@ -26,7 +26,20 @@ type Bill struct {
|
|||||||
Total float64 `json:"total" bson:"total" validate:"required"`
|
Total float64 `json:"total" bson:"total" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func DraftBill(order *order.Order, request *tools.APIRequest) (*Bill, error) {
|
func GenerateBill(order *order.Order, request *tools.APIRequest) (*Bill, error) {
|
||||||
|
// hhmmm : should get... the loop.
|
||||||
|
return &Bill{
|
||||||
|
AbstractObject: utils.AbstractObject{
|
||||||
|
Name: "bill_" + request.PeerID + "_" + time.Now().UTC().Format("2006-01-02T15:04:05"),
|
||||||
|
IsDraft: false,
|
||||||
|
},
|
||||||
|
OrderID: order.UUID,
|
||||||
|
Status: enum.PENDING,
|
||||||
|
// SubOrders: peerOrders,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DraftFirstBill(order *order.Order, request *tools.APIRequest) (*Bill, error) {
|
||||||
peers := map[string][]*PeerItemOrder{}
|
peers := map[string][]*PeerItemOrder{}
|
||||||
for _, p := range order.Purchases {
|
for _, p := range order.Purchases {
|
||||||
// TODO : if once
|
// TODO : if once
|
||||||
|
2
models/billing_process.md
Normal file
2
models/billing_process.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Billing process
|
||||||
|
Scheduler process a drafted order + a first bill corresponding to every once buying.
|
@ -12,6 +12,7 @@ type PricedItemITF interface {
|
|||||||
IsPurchasable() bool
|
IsPurchasable() bool
|
||||||
IsBooked() bool
|
IsBooked() bool
|
||||||
GetCreatorID() string
|
GetCreatorID() string
|
||||||
|
SelectPricing() PricingProfileITF
|
||||||
GetLocationStart() *time.Time
|
GetLocationStart() *time.Time
|
||||||
SetLocationStart(start time.Time)
|
SetLocationStart(start time.Time)
|
||||||
SetLocationEnd(end time.Time)
|
SetLocationEnd(end time.Time)
|
||||||
|
@ -5,10 +5,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PricingProfileITF interface {
|
type PricingProfileITF interface {
|
||||||
GetPrice(quantity float64, val float64, start time.Time, end time.Time, params ...string) (float64, error)
|
|
||||||
IsPurchasable() bool
|
|
||||||
IsBooked() bool
|
IsBooked() bool
|
||||||
|
IsPurchasable() bool
|
||||||
|
GetPurchase() BuyingStrategy
|
||||||
GetOverrideStrategyValue() int
|
GetOverrideStrategyValue() int
|
||||||
|
GetPrice(quantity float64, val float64, start time.Time, end time.Time, params ...string) (float64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RefundType int
|
type RefundType int
|
||||||
|
@ -5,6 +5,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/resources/purchase_resource"
|
"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"
|
||||||
@ -17,9 +18,11 @@ import (
|
|||||||
type Order struct {
|
type Order struct {
|
||||||
utils.AbstractObject
|
utils.AbstractObject
|
||||||
ExecutionsID string `json:"executions_id" bson:"executions_id" validate:"required"`
|
ExecutionsID string `json:"executions_id" bson:"executions_id" validate:"required"`
|
||||||
|
Status enum.CompletionStatus `json:"status" bson:"status" default:"0"`
|
||||||
Purchases []*purchase_resource.PurchaseResource `json:"purchases" bson:"purchases"`
|
Purchases []*purchase_resource.PurchaseResource `json:"purchases" bson:"purchases"`
|
||||||
Bookings []*booking.Booking `json:"bookings" bson:"bookings"`
|
Bookings []*booking.Booking `json:"bookings" bson:"bookings"`
|
||||||
Status enum.CompletionStatus `json:"status" bson:"status" default:"0"`
|
|
||||||
|
Billing map[pricing.BillingStrategy][]*booking.Booking `json:"billing" bson:"billing"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Order) StoreDraftDefault() {
|
func (r *Order) StoreDraftDefault() {
|
||||||
|
@ -30,12 +30,11 @@ func (r *ComputeResource) GetType() string {
|
|||||||
return tools.COMPUTE_RESOURCE.String()
|
return tools.COMPUTE_RESOURCE.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abs *ComputeResource) ConvertToPricedResource(
|
func (abs *ComputeResource) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF {
|
||||||
t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF {
|
|
||||||
if t != tools.COMPUTE_RESOURCE {
|
if t != tools.COMPUTE_RESOURCE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request, buyingStrategy, pricingStrategy)
|
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request)
|
||||||
priced := p.(*PricedResource)
|
priced := p.(*PricedResource)
|
||||||
return &PricedComputeResource{
|
return &PricedComputeResource{
|
||||||
PricedResource: *priced,
|
PricedResource: *priced,
|
||||||
@ -84,6 +83,10 @@ func (p *ComputeResourcePricingProfile) IsPurchasable() bool {
|
|||||||
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ComputeResourcePricingProfile) GetPurchase() pricing.BuyingStrategy {
|
||||||
|
return p.Pricing.BuyingStrategy
|
||||||
|
}
|
||||||
|
|
||||||
func (p *ComputeResourcePricingProfile) IsBooked() bool {
|
func (p *ComputeResourcePricingProfile) IsBooked() bool {
|
||||||
if p.Pricing.BuyingStrategy == pricing.PERMANENT {
|
if p.Pricing.BuyingStrategy == pricing.PERMANENT {
|
||||||
p.Pricing.BuyingStrategy = pricing.SUBSCRIPTION
|
p.Pricing.BuyingStrategy = pricing.SUBSCRIPTION
|
||||||
@ -159,11 +162,8 @@ func (r *PricedComputeResource) GetPrice() (float64, error) {
|
|||||||
r.UsageEnd = &add
|
r.UsageEnd = &add
|
||||||
}
|
}
|
||||||
if r.SelectedPricing == nil {
|
if r.SelectedPricing == nil {
|
||||||
if len(r.PricingProfiles) == 0 {
|
|
||||||
return 0, errors.New("pricing profile must be set on Priced Compute" + r.ResourceID)
|
return 0, errors.New("pricing profile must be set on Priced Compute" + r.ResourceID)
|
||||||
}
|
}
|
||||||
r.SelectedPricing = r.PricingProfiles[0]
|
|
||||||
}
|
|
||||||
pricing := r.SelectedPricing
|
pricing := r.SelectedPricing
|
||||||
price := float64(0)
|
price := float64(0)
|
||||||
for _, l := range []map[string]float64{r.CPUsLocated, r.GPUsLocated} {
|
for _, l := range []map[string]float64{r.CPUsLocated, r.GPUsLocated} {
|
||||||
|
@ -37,12 +37,11 @@ func (r *DataResource) GetType() string {
|
|||||||
return tools.DATA_RESOURCE.String()
|
return tools.DATA_RESOURCE.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abs *DataResource) ConvertToPricedResource(
|
func (abs *DataResource) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF {
|
||||||
t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF {
|
|
||||||
if t != tools.DATA_RESOURCE {
|
if t != tools.DATA_RESOURCE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request, buyingStrategy, pricingStrategy)
|
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request)
|
||||||
priced := p.(*PricedResource)
|
priced := p.(*PricedResource)
|
||||||
return &PricedDataResource{
|
return &PricedDataResource{
|
||||||
PricedResource: *priced,
|
PricedResource: *priced,
|
||||||
@ -137,6 +136,10 @@ 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) GetPurchase() pricing.BuyingStrategy {
|
||||||
|
return p.Pricing.BuyingStrategy
|
||||||
|
}
|
||||||
|
|
||||||
func (p *DataResourcePricingProfile) IsPurchasable() bool {
|
func (p *DataResourcePricingProfile) IsPurchasable() bool {
|
||||||
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
||||||
}
|
}
|
||||||
@ -166,11 +169,8 @@ func (r *PricedDataResource) GetPrice() (float64, error) {
|
|||||||
r.UsageEnd = &add
|
r.UsageEnd = &add
|
||||||
}
|
}
|
||||||
if r.SelectedPricing == nil {
|
if r.SelectedPricing == nil {
|
||||||
if len(r.PricingProfiles) == 0 {
|
|
||||||
return 0, errors.New("pricing profile must be set on Priced Data" + r.ResourceID)
|
return 0, errors.New("pricing profile must be set on Priced Data" + r.ResourceID)
|
||||||
}
|
}
|
||||||
r.SelectedPricing = r.PricingProfiles[0]
|
|
||||||
}
|
|
||||||
pricing := r.SelectedPricing
|
pricing := r.SelectedPricing
|
||||||
var err error
|
var err error
|
||||||
amountOfData := float64(1)
|
amountOfData := float64(1)
|
||||||
|
@ -9,9 +9,9 @@ import (
|
|||||||
type ResourceInterface interface {
|
type ResourceInterface interface {
|
||||||
utils.DBObject
|
utils.DBObject
|
||||||
Trim()
|
Trim()
|
||||||
ConvertToPricedResource(t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF
|
ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF
|
||||||
GetType() string
|
GetType() string
|
||||||
GetSelectedInstance() utils.DBObject
|
GetSelectedInstance() ResourceInstanceITF
|
||||||
ClearEnv() utils.DBObject
|
ClearEnv() utils.DBObject
|
||||||
SetAllowedInstances(request *tools.APIRequest)
|
SetAllowedInstances(request *tools.APIRequest)
|
||||||
}
|
}
|
||||||
@ -22,15 +22,15 @@ type ResourceInstanceITF interface {
|
|||||||
GetName() string
|
GetName() string
|
||||||
StoreDraftDefault()
|
StoreDraftDefault()
|
||||||
ClearEnv()
|
ClearEnv()
|
||||||
GetPricingsProfiles(peerID string, groups []string, buyingStrategy int, pricingStrategy int) []pricing.PricingProfileITF
|
GetProfile() pricing.PricingProfileITF
|
||||||
|
GetPricingsProfiles(peerID string, groups []string) []pricing.PricingProfileITF
|
||||||
GetPeerGroups() ([]ResourcePartnerITF, []map[string][]string)
|
GetPeerGroups() ([]ResourcePartnerITF, []map[string][]string)
|
||||||
ClearPeerGroups()
|
ClearPeerGroups()
|
||||||
GetSelectedPartnership() ResourcePartnerITF
|
|
||||||
GetPartnerships(peerID string, groups []string) []ResourcePartnerITF
|
GetPartnerships(peerID string, groups []string) []ResourcePartnerITF
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResourcePartnerITF interface {
|
type ResourcePartnerITF interface {
|
||||||
GetPricingsProfiles(peerID string, groups []string, buyingStrategy int, pricingStrategy int) []pricing.PricingProfileITF
|
GetPricingsProfiles(peerID string, groups []string) []pricing.PricingProfileITF
|
||||||
GetPeerGroups() map[string][]string
|
GetPeerGroups() map[string][]string
|
||||||
ClearPeerGroups()
|
ClearPeerGroups()
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ type PricedResource struct {
|
|||||||
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
||||||
Logo string `json:"logo,omitempty" bson:"logo,omitempty"`
|
Logo string `json:"logo,omitempty" bson:"logo,omitempty"`
|
||||||
InstancesRefs map[string]string `json:"instances_refs,omitempty" bson:"instances_refs,omitempty"`
|
InstancesRefs map[string]string `json:"instances_refs,omitempty" bson:"instances_refs,omitempty"`
|
||||||
PricingProfiles []pricing.PricingProfileITF `json:"pricing_profiles,omitempty" bson:"pricing_profiles,omitempty"`
|
|
||||||
SelectedPricing pricing.PricingProfileITF `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
SelectedPricing pricing.PricingProfileITF `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
||||||
ExplicitBookingDurationS float64 `json:"explicit_location_duration_s,omitempty" bson:"explicit_location_duration_s,omitempty"`
|
ExplicitBookingDurationS float64 `json:"explicit_location_duration_s,omitempty" bson:"explicit_location_duration_s,omitempty"`
|
||||||
UsageStart *time.Time `json:"start,omitempty" bson:"start,omitempty"`
|
UsageStart *time.Time `json:"start,omitempty" bson:"start,omitempty"`
|
||||||
@ -23,6 +22,10 @@ type PricedResource struct {
|
|||||||
ResourceType tools.DataType `json:"resource_type,omitempty" bson:"resource_type,omitempty"`
|
ResourceType tools.DataType `json:"resource_type,omitempty" bson:"resource_type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (abs *PricedResource) SelectPricing() pricing.PricingProfileITF {
|
||||||
|
return abs.SelectedPricing
|
||||||
|
}
|
||||||
|
|
||||||
func (abs *PricedResource) GetID() string {
|
func (abs *PricedResource) GetID() string {
|
||||||
return abs.ResourceID
|
return abs.ResourceID
|
||||||
}
|
}
|
||||||
@ -90,11 +93,8 @@ func (r *PricedResource) GetPrice() (float64, error) {
|
|||||||
r.UsageEnd = &add
|
r.UsageEnd = &add
|
||||||
}
|
}
|
||||||
if r.SelectedPricing == nil {
|
if r.SelectedPricing == nil {
|
||||||
if len(r.PricingProfiles) == 0 {
|
|
||||||
return 0, errors.New("pricing profile must be set on Priced Resource " + r.ResourceID)
|
return 0, errors.New("pricing profile must be set on Priced Resource " + r.ResourceID)
|
||||||
}
|
}
|
||||||
r.SelectedPricing = r.PricingProfiles[0]
|
|
||||||
}
|
|
||||||
pricing := r.SelectedPricing
|
pricing := r.SelectedPricing
|
||||||
return pricing.GetPrice(1, 0, *r.UsageStart, *r.UsageEnd)
|
return pricing.GetPrice(1, 0, *r.UsageStart, *r.UsageEnd)
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,10 @@ func (p *ProcessingResourcePricingProfile) IsBooked() bool {
|
|||||||
return p.Pricing.BuyingStrategy != pricing.PERMANENT
|
return p.Pricing.BuyingStrategy != pricing.PERMANENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProcessingResourcePricingProfile) GetPurchase() pricing.BuyingStrategy {
|
||||||
|
return p.Pricing.BuyingStrategy
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
return p.Pricing.GetPrice(amountOfData, val, start, &end)
|
return p.Pricing.GetPrice(amountOfData, val, start, &end)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ type AbstractResource struct {
|
|||||||
SelectedInstanceIndex *int `json:"selected_instance_index,omitempty" bson:"selected_instance_index,omitempty"` // SelectedInstance is the selected instance
|
SelectedInstanceIndex *int `json:"selected_instance_index,omitempty" bson:"selected_instance_index,omitempty"` // SelectedInstance is the selected instance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AbstractResource) GetSelectedInstance() utils.DBObject {
|
func (r *AbstractResource) GetSelectedInstance() ResourceInstanceITF {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,13 +52,19 @@ 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(
|
func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF {
|
||||||
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 {
|
||||||
instances[instance.GetID()] = instance.GetName()
|
instances[instance.GetID()] = instance.GetName()
|
||||||
profiles = instance.GetPricingsProfiles(request.PeerID, request.Groups, buyingStrategy, pricingStrategy)
|
profiles = instance.GetPricingsProfiles(request.PeerID, request.Groups)
|
||||||
|
}
|
||||||
|
var profile pricing.PricingProfileITF
|
||||||
|
if t := abs.GetSelectedInstance(); t != nil {
|
||||||
|
profile = t.GetProfile()
|
||||||
|
}
|
||||||
|
if profile == nil && len(profiles) > 0 {
|
||||||
|
profile = profiles[0]
|
||||||
}
|
}
|
||||||
return &PricedResource{
|
return &PricedResource{
|
||||||
Name: abs.Name,
|
Name: abs.Name,
|
||||||
@ -66,7 +72,7 @@ func (abs *AbstractInstanciatedResource[T]) ConvertToPricedResource(
|
|||||||
ResourceID: abs.UUID,
|
ResourceID: abs.UUID,
|
||||||
ResourceType: t,
|
ResourceType: t,
|
||||||
InstancesRefs: instances,
|
InstancesRefs: instances,
|
||||||
PricingProfiles: profiles,
|
SelectedPricing: profile,
|
||||||
CreatorID: abs.CreatorID,
|
CreatorID: abs.CreatorID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +84,7 @@ func (abs *AbstractInstanciatedResource[T]) ClearEnv() utils.DBObject {
|
|||||||
return abs
|
return abs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *AbstractInstanciatedResource[T]) GetSelectedInstance() utils.DBObject {
|
func (r *AbstractInstanciatedResource[T]) GetSelectedInstance() ResourceInstanceITF {
|
||||||
if r.SelectedInstanceIndex != nil && len(r.Instances) > *r.SelectedInstanceIndex {
|
if r.SelectedInstanceIndex != nil && len(r.Instances) > *r.SelectedInstanceIndex {
|
||||||
return r.Instances[*r.SelectedInstanceIndex]
|
return r.Instances[*r.SelectedInstanceIndex]
|
||||||
}
|
}
|
||||||
@ -150,26 +156,20 @@ type ResourceInstance[T ResourcePartnerITF] struct {
|
|||||||
Env []models.Param `json:"env,omitempty" bson:"env,omitempty"`
|
Env []models.Param `json:"env,omitempty" bson:"env,omitempty"`
|
||||||
Inputs []models.Param `json:"inputs,omitempty" bson:"inputs,omitempty"`
|
Inputs []models.Param `json:"inputs,omitempty" bson:"inputs,omitempty"`
|
||||||
Outputs []models.Param `json:"outputs,omitempty" bson:"outputs,omitempty"`
|
Outputs []models.Param `json:"outputs,omitempty" bson:"outputs,omitempty"`
|
||||||
SelectedPartnershipIndex *int `json:"selected_partnership_index,omitempty" bson:"selected_partnership_index,omitempty"` // SelectedInstance is the selected instance
|
SelectedPricing pricing.PricingProfileITF `json:"selected_pricing,omitempty" bson:"selected_pricing,omitempty"`
|
||||||
Partnerships []T `json:"partnerships,omitempty" bson:"partnerships,omitempty"`
|
Partnerships []T `json:"partnerships,omitempty" bson:"partnerships,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ResourceInstance[T]) GetSelectedPartnership() ResourcePartnerITF {
|
|
||||||
if r.SelectedPartnershipIndex != nil && len(r.Partnerships) > *r.SelectedPartnershipIndex {
|
|
||||||
return r.Partnerships[*r.SelectedPartnershipIndex]
|
|
||||||
}
|
|
||||||
if len(r.Partnerships) > 0 {
|
|
||||||
return r.Partnerships[0]
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ri *ResourceInstance[T]) ClearEnv() {
|
func (ri *ResourceInstance[T]) ClearEnv() {
|
||||||
ri.Env = []models.Param{}
|
ri.Env = []models.Param{}
|
||||||
ri.Inputs = []models.Param{}
|
ri.Inputs = []models.Param{}
|
||||||
ri.Outputs = []models.Param{}
|
ri.Outputs = []models.Param{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ri *ResourceInstance[T]) GetProfile() pricing.PricingProfileITF {
|
||||||
|
return ri.SelectedPricing
|
||||||
|
}
|
||||||
|
|
||||||
func (ri *ResourceInstance[T]) GetPartnerships(peerID string, groups []string) []ResourcePartnerITF {
|
func (ri *ResourceInstance[T]) GetPartnerships(peerID string, groups []string) []ResourcePartnerITF {
|
||||||
partners := []ResourcePartnerITF{}
|
partners := []ResourcePartnerITF{}
|
||||||
for _, p := range ri.Partnerships {
|
for _, p := range ri.Partnerships {
|
||||||
@ -184,10 +184,10 @@ func (ri *ResourceInstance[T]) GetPartnerships(peerID string, groups []string) [
|
|||||||
return partners
|
return partners
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ri *ResourceInstance[T]) GetPricingsProfiles(peerID string, groups []string, buyingStrategy int, pricingStrategy int) []pricing.PricingProfileITF {
|
func (ri *ResourceInstance[T]) GetPricingsProfiles(peerID string, groups []string) []pricing.PricingProfileITF {
|
||||||
pricings := []pricing.PricingProfileITF{}
|
pricings := []pricing.PricingProfileITF{}
|
||||||
for _, p := range ri.Partnerships {
|
for _, p := range ri.Partnerships {
|
||||||
pricings = append(pricings, p.GetPricingsProfiles(peerID, groups, buyingStrategy, pricingStrategy)...)
|
pricings = append(pricings, p.GetPricingsProfiles(peerID, groups)...)
|
||||||
}
|
}
|
||||||
return pricings
|
return pricings
|
||||||
}
|
}
|
||||||
@ -222,16 +222,16 @@ note : il faut rajouté - une notion de facturation
|
|||||||
Une order est l'ensemble de la commande... un booking une réservation, une purchase un acte d'achat.
|
Une order est l'ensemble de la commande... un booking une réservation, une purchase un acte d'achat.
|
||||||
Une bill (facture) représente alors... l'emission d'une facture à un instant T en but d'être honorée, envoyée ... etc.
|
Une bill (facture) représente alors... l'emission d'une facture à un instant T en but d'être honorée, envoyée ... etc.
|
||||||
*/
|
*/
|
||||||
func (ri *ResourcePartnerShip[T]) GetPricingsProfiles(peerID string, groups []string, buyingStrategy int, pricingStrategy int) []pricing.PricingProfileITF {
|
func (ri *ResourcePartnerShip[T]) GetPricingsProfiles(peerID string, groups []string) []pricing.PricingProfileITF {
|
||||||
profiles := []pricing.PricingProfileITF{}
|
profiles := []pricing.PricingProfileITF{}
|
||||||
if ri.PeerGroups[peerID] == nil {
|
if ri.PeerGroups[peerID] == nil {
|
||||||
return profiles
|
return profiles
|
||||||
}
|
}
|
||||||
for _, p := range ri.PeerGroups[peerID] {
|
for _, p := range ri.PeerGroups[peerID] {
|
||||||
if slices.Contains(groups, p) || slices.Contains(groups, "*") {
|
if slices.Contains(groups, p) || slices.Contains(groups, "*") {
|
||||||
for buyingS, ri := range ri.PricingProfiles {
|
for _, ri := range ri.PricingProfiles {
|
||||||
if _, ok := ri[pricingStrategy]; ok && buyingS == buyingStrategy {
|
for _, i := range ri {
|
||||||
profiles = append(profiles, ri[pricingStrategy])
|
profiles = append(profiles, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return profiles
|
return profiles
|
||||||
|
@ -30,12 +30,11 @@ func (r *StorageResource) GetType() string {
|
|||||||
return tools.STORAGE_RESOURCE.String()
|
return tools.STORAGE_RESOURCE.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abs *StorageResource) ConvertToPricedResource(
|
func (abs *StorageResource) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF {
|
||||||
t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF {
|
|
||||||
if t != tools.STORAGE_RESOURCE {
|
if t != tools.STORAGE_RESOURCE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request, buyingStrategy, pricingStrategy)
|
p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request)
|
||||||
priced := p.(*PricedResource)
|
priced := p.(*PricedResource)
|
||||||
return &PricedStorageResource{
|
return &PricedStorageResource{
|
||||||
PricedResource: *priced,
|
PricedResource: *priced,
|
||||||
@ -153,6 +152,10 @@ 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) GetPurchase() pricing.BuyingStrategy {
|
||||||
|
return p.Pricing.BuyingStrategy
|
||||||
|
}
|
||||||
|
|
||||||
func (p *StorageResourcePricingProfile) IsPurchasable() bool {
|
func (p *StorageResourcePricingProfile) IsPurchasable() bool {
|
||||||
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
return p.Pricing.BuyingStrategy != pricing.UNDEFINED_SUBSCRIPTION
|
||||||
}
|
}
|
||||||
@ -188,11 +191,8 @@ func (r *PricedStorageResource) GetPrice() (float64, error) {
|
|||||||
r.UsageEnd = &add
|
r.UsageEnd = &add
|
||||||
}
|
}
|
||||||
if r.SelectedPricing == nil {
|
if r.SelectedPricing == nil {
|
||||||
if len(r.PricingProfiles) == 0 {
|
|
||||||
return 0, errors.New("pricing profile must be set on Priced Storage" + r.ResourceID)
|
return 0, errors.New("pricing profile must be set on Priced Storage" + r.ResourceID)
|
||||||
}
|
}
|
||||||
r.SelectedPricing = r.PricingProfiles[0]
|
|
||||||
}
|
|
||||||
pricing := r.SelectedPricing
|
pricing := r.SelectedPricing
|
||||||
var err error
|
var err error
|
||||||
amountOfData := float64(1)
|
amountOfData := float64(1)
|
||||||
|
@ -30,7 +30,7 @@ func TestComputeResource_ConvertToPricedResource(t *testing.T) {
|
|||||||
cr := &resources.ComputeResource{}
|
cr := &resources.ComputeResource{}
|
||||||
cr.UUID = "comp123"
|
cr.UUID = "comp123"
|
||||||
cr.AbstractInstanciatedResource.UUID = cr.UUID
|
cr.AbstractInstanciatedResource.UUID = cr.UUID
|
||||||
result := cr.ConvertToPricedResource(tools.COMPUTE_RESOURCE, req, 0, 0)
|
result := cr.ConvertToPricedResource(tools.COMPUTE_RESOURCE, req)
|
||||||
assert.NotNil(t, result)
|
assert.NotNil(t, result)
|
||||||
assert.IsType(t, &resources.PricedComputeResource{}, result)
|
assert.IsType(t, &resources.PricedComputeResource{}, result)
|
||||||
}
|
}
|
||||||
@ -62,20 +62,9 @@ func TestComputeResourcePricingProfile_GetPrice_InvalidParams(t *testing.T) {
|
|||||||
func TestPricedComputeResource_GetPrice(t *testing.T) {
|
func TestPricedComputeResource_GetPrice(t *testing.T) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
end := start.Add(1 * time.Hour)
|
end := start.Add(1 * time.Hour)
|
||||||
profile := &resources.ComputeResourcePricingProfile{
|
|
||||||
CPUsPrices: map[string]float64{"Xeon": 1.0},
|
|
||||||
GPUsPrices: map[string]float64{"Tesla": 2.0},
|
|
||||||
RAMPrice: 0.5,
|
|
||||||
ExploitPricingProfile: pricing.ExploitPricingProfile[pricing.TimePricingStrategy]{
|
|
||||||
AccessPricingProfile: pricing.AccessPricingProfile[pricing.TimePricingStrategy]{
|
|
||||||
Pricing: pricing.PricingStrategy[pricing.TimePricingStrategy]{Price: 1.0},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r := resources.PricedComputeResource{
|
r := resources.PricedComputeResource{
|
||||||
PricedResource: resources.PricedResource{
|
PricedResource: resources.PricedResource{
|
||||||
ResourceID: "comp456",
|
ResourceID: "comp456",
|
||||||
PricingProfiles: []pricing.PricingProfileITF{profile},
|
|
||||||
UsageStart: &start,
|
UsageStart: &start,
|
||||||
UsageEnd: &end,
|
UsageEnd: &end,
|
||||||
ExplicitBookingDurationS: 3600,
|
ExplicitBookingDurationS: 3600,
|
||||||
|
@ -27,10 +27,10 @@ func TestDataResource_GetAccessor(t *testing.T) {
|
|||||||
func TestDataResource_ConvertToPricedResource(t *testing.T) {
|
func TestDataResource_ConvertToPricedResource(t *testing.T) {
|
||||||
d := &resources.DataResource{}
|
d := &resources.DataResource{}
|
||||||
d.UUID = "123"
|
d.UUID = "123"
|
||||||
res := d.ConvertToPricedResource(tools.DATA_RESOURCE, &tools.APIRequest{}, 0, 0)
|
res := d.ConvertToPricedResource(tools.DATA_RESOURCE, &tools.APIRequest{})
|
||||||
assert.IsType(t, &resources.PricedDataResource{}, res)
|
assert.IsType(t, &resources.PricedDataResource{}, res)
|
||||||
|
|
||||||
nilRes := d.ConvertToPricedResource(tools.PROCESSING_RESOURCE, &tools.APIRequest{}, 0, 0)
|
nilRes := d.ConvertToPricedResource(tools.PROCESSING_RESOURCE, &tools.APIRequest{})
|
||||||
assert.Nil(t, nilRes)
|
assert.Nil(t, nilRes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,9 +94,6 @@ func TestPricedDataResource_GetPrice(t *testing.T) {
|
|||||||
PricedResource: resources.PricedResource{
|
PricedResource: resources.PricedResource{
|
||||||
UsageStart: &now,
|
UsageStart: &now,
|
||||||
UsageEnd: &later,
|
UsageEnd: &later,
|
||||||
PricingProfiles: []pricing.PricingProfileITF{
|
|
||||||
pricingProfile,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +101,7 @@ func TestGetPrice(t *testing.T) {
|
|||||||
t.Run("uses first profile if selected is nil", func(t *testing.T) {
|
t.Run("uses first profile if selected is nil", func(t *testing.T) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
end := start.Add(30 * time.Minute)
|
end := start.Add(30 * time.Minute)
|
||||||
mock := &MockPricingProfile{ReturnCost: 42.0}
|
|
||||||
r := &resources.PricedResource{
|
r := &resources.PricedResource{
|
||||||
PricingProfiles: []pricing.PricingProfileITF{mock},
|
|
||||||
UsageStart: &start,
|
UsageStart: &start,
|
||||||
UsageEnd: &end,
|
UsageEnd: &end,
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func (m *MockInstance) GetID() string { return m.ID }
|
|||||||
func (m *MockInstance) GetName() string { return m.Name }
|
func (m *MockInstance) GetName() string { return m.Name }
|
||||||
func (m *MockInstance) ClearEnv() {}
|
func (m *MockInstance) ClearEnv() {}
|
||||||
func (m *MockInstance) ClearPeerGroups() {}
|
func (m *MockInstance) ClearPeerGroups() {}
|
||||||
func (m *MockInstance) GetPricingsProfiles(string, []string, int, int) []pricing.PricingProfileITF {
|
func (m *MockInstance) GetPricingsProfiles(string, []string) []pricing.PricingProfileITF {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (m *MockInstance) GetPeerGroups() ([]resources.ResourcePartnerITF, []map[string][]string) {
|
func (m *MockInstance) GetPeerGroups() ([]resources.ResourcePartnerITF, []map[string][]string) {
|
||||||
@ -37,7 +37,7 @@ func (m *MockPartner) GetPeerGroups() map[string][]string {
|
|||||||
return m.groups
|
return m.groups
|
||||||
}
|
}
|
||||||
func (m *MockPartner) ClearPeerGroups() {}
|
func (m *MockPartner) ClearPeerGroups() {}
|
||||||
func (m *MockPartner) GetPricingsProfiles(string, []string, int, int) []pricing.PricingProfileITF {
|
func (m *MockPartner) GetPricingsProfiles(string, []string) []pricing.PricingProfileITF {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,14 +26,14 @@ func TestStorageResource_ConvertToPricedResource_ValidType(t *testing.T) {
|
|||||||
res := &resources.StorageResource{}
|
res := &resources.StorageResource{}
|
||||||
res.AbstractInstanciatedResource.CreatorID = "creator"
|
res.AbstractInstanciatedResource.CreatorID = "creator"
|
||||||
res.AbstractInstanciatedResource.UUID = "res-id"
|
res.AbstractInstanciatedResource.UUID = "res-id"
|
||||||
priced := res.ConvertToPricedResource(tools.STORAGE_RESOURCE, &tools.APIRequest{}, 0, 0)
|
priced := res.ConvertToPricedResource(tools.STORAGE_RESOURCE, &tools.APIRequest{})
|
||||||
assert.NotNil(t, priced)
|
assert.NotNil(t, priced)
|
||||||
assert.IsType(t, &resources.PricedStorageResource{}, priced)
|
assert.IsType(t, &resources.PricedStorageResource{}, priced)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStorageResource_ConvertToPricedResource_InvalidType(t *testing.T) {
|
func TestStorageResource_ConvertToPricedResource_InvalidType(t *testing.T) {
|
||||||
res := &resources.StorageResource{}
|
res := &resources.StorageResource{}
|
||||||
priced := res.ConvertToPricedResource(tools.COMPUTE_RESOURCE, &tools.APIRequest{}, 0, 0)
|
priced := res.ConvertToPricedResource(tools.COMPUTE_RESOURCE, &tools.APIRequest{})
|
||||||
assert.Nil(t, priced)
|
assert.Nil(t, priced)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ func TestWorkflowResource_ConvertToPricedResource(t *testing.T) {
|
|||||||
Groups: []string{"group1"},
|
Groups: []string{"group1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
pr := w.ConvertToPricedResource(tools.WORKFLOW_RESOURCE, req, 0, 0)
|
pr := w.ConvertToPricedResource(tools.WORKFLOW_RESOURCE, req)
|
||||||
assert.Equal(t, "creator-id", pr.GetCreatorID())
|
assert.Equal(t, "creator-id", pr.GetCreatorID())
|
||||||
assert.Equal(t, tools.WORKFLOW_RESOURCE, pr.GetType())
|
assert.Equal(t, tools.WORKFLOW_RESOURCE, pr.GetType())
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ type WorkflowResource struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *WorkflowResource) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
func (d *WorkflowResource) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
||||||
return NewAccessor[*ComputeResource](tools.WORKFLOW_RESOURCE, request, func() utils.DBObject { return &WorkflowResource{} })
|
return NewAccessor[*WorkflowResource](tools.WORKFLOW_RESOURCE, request, func() utils.DBObject { return &WorkflowResource{} })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WorkflowResource) GetType() string {
|
func (r *WorkflowResource) GetType() string {
|
||||||
@ -34,8 +34,7 @@ func (w *WorkflowResource) SetAllowedInstances(request *tools.APIRequest) {
|
|||||||
/* EMPTY */
|
/* EMPTY */
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WorkflowResource) ConvertToPricedResource(
|
func (w *WorkflowResource) ConvertToPricedResource(t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF {
|
||||||
t tools.DataType, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) pricing.PricedItemITF {
|
|
||||||
return &PricedResource{
|
return &PricedResource{
|
||||||
Name: w.Name,
|
Name: w.Name,
|
||||||
Logo: w.Logo,
|
Logo: w.Logo,
|
||||||
|
@ -55,7 +55,7 @@ func (wf *Graph) IsWorkflow(item GraphItem) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graph) GetAverageTimeRelatedToProcessingActivity(start time.Time, processings []*resources.ProcessingResource, resource resources.ResourceInterface,
|
func (g *Graph) GetAverageTimeRelatedToProcessingActivity(start time.Time, processings []*resources.ProcessingResource, resource resources.ResourceInterface,
|
||||||
f func(GraphItem) resources.ResourceInterface, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) (float64, float64) {
|
f func(GraphItem) resources.ResourceInterface, request *tools.APIRequest) (float64, float64) {
|
||||||
nearestStart := float64(10000000000)
|
nearestStart := float64(10000000000)
|
||||||
oneIsInfinite := false
|
oneIsInfinite := false
|
||||||
longestDuration := float64(0)
|
longestDuration := float64(0)
|
||||||
@ -67,7 +67,7 @@ func (g *Graph) GetAverageTimeRelatedToProcessingActivity(start time.Time, proce
|
|||||||
} else if link.Source.ID == processing.GetID() && f(g.Items[link.Source.ID]) != nil && f(g.Items[link.Source.ID]).GetID() == resource.GetID() { // if the source is the processing and the destination is not a compute
|
} else if link.Source.ID == processing.GetID() && f(g.Items[link.Source.ID]) != nil && f(g.Items[link.Source.ID]).GetID() == resource.GetID() { // if the source is the processing and the destination is not a compute
|
||||||
source = link.Destination.ID
|
source = link.Destination.ID
|
||||||
}
|
}
|
||||||
priced := processing.ConvertToPricedResource(tools.PROCESSING_RESOURCE, request, buyingStrategy, pricingStrategy)
|
priced := processing.ConvertToPricedResource(tools.PROCESSING_RESOURCE, request)
|
||||||
if source != "" {
|
if source != "" {
|
||||||
if priced.GetLocationStart() != nil {
|
if priced.GetLocationStart() != nil {
|
||||||
near := float64(priced.GetLocationStart().Sub(start).Seconds())
|
near := float64(priced.GetLocationStart().Sub(start).Seconds())
|
||||||
@ -96,7 +96,7 @@ func (g *Graph) GetAverageTimeRelatedToProcessingActivity(start time.Time, proce
|
|||||||
/*
|
/*
|
||||||
* GetAverageTimeBeforeStart is a function that returns the average time before the start of a processing
|
* GetAverageTimeBeforeStart is a function that returns the average time before the start of a processing
|
||||||
*/
|
*/
|
||||||
func (g *Graph) GetAverageTimeProcessingBeforeStart(average float64, processingID string, request *tools.APIRequest, buyingStrategy int, pricingStrategy int) float64 {
|
func (g *Graph) GetAverageTimeProcessingBeforeStart(average float64, processingID string, request *tools.APIRequest) float64 {
|
||||||
currents := []float64{} // list of current time
|
currents := []float64{} // list of current time
|
||||||
for _, link := range g.Links { // for each link
|
for _, link := range g.Links { // for each link
|
||||||
var source string // source is the source of the link
|
var source string // source is the source of the link
|
||||||
@ -112,12 +112,12 @@ func (g *Graph) GetAverageTimeProcessingBeforeStart(average float64, processingI
|
|||||||
if r == nil { // if item is nil, continue
|
if r == nil { // if item is nil, continue
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
priced := r.ConvertToPricedResource(dt, request, buyingStrategy, pricingStrategy)
|
priced := r.ConvertToPricedResource(dt, request)
|
||||||
current := priced.GetExplicitDurationInS() // get the explicit duration of the item
|
current := priced.GetExplicitDurationInS() // get the explicit duration of the item
|
||||||
if current < 0 { // if current is negative, its means that duration of a before could be infinite continue
|
if current < 0 { // if current is negative, its means that duration of a before could be infinite continue
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
current += g.GetAverageTimeProcessingBeforeStart(current, source, request, buyingStrategy, pricingStrategy) // get the average time before start of the source
|
current += g.GetAverageTimeProcessingBeforeStart(current, source, request) // get the average time before start of the source
|
||||||
currents = append(currents, current) // append the current to the currents
|
currents = append(currents, current) // append the current to the currents
|
||||||
}
|
}
|
||||||
var max float64 // get the max time to wait dependancies to finish
|
var max float64 // get the max time to wait dependancies to finish
|
||||||
|
@ -83,7 +83,7 @@ func (w *Workflow) GetPricedItem(
|
|||||||
for _, item := range w.Graph.Items {
|
for _, item := range w.Graph.Items {
|
||||||
if f(item) {
|
if f(item) {
|
||||||
dt, res := item.GetResource()
|
dt, res := item.GetResource()
|
||||||
ord := res.ConvertToPricedResource(dt, request, buyingStrategy, pricingStrategy)
|
ord := res.ConvertToPricedResource(dt, request)
|
||||||
list_datas[res.GetID()] = ord
|
list_datas[res.GetID()] = ord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,12 +166,11 @@ func (wfa *Workflow) CheckBooking(caller *tools.HTTPCaller) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
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) (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, wf.Graph.IsProcessing,
|
||||||
buyingStrategy, pricingStrategy, 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)) * 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))
|
||||||
return &s
|
return &s
|
||||||
@ -179,7 +178,7 @@ func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIR
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, priceds, nil, err
|
return 0, priceds, nil, err
|
||||||
}
|
}
|
||||||
if _, priceds, err = plan[resources.ResourceInterface](tools.DATA_RESOURCE, wf, priceds, request, buyingStrategy, pricingStrategy,
|
if _, priceds, err = plan[resources.ResourceInterface](tools.DATA_RESOURCE, wf, priceds, request,
|
||||||
wf.Graph.IsData, func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
wf.Graph.IsData, func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
||||||
return start, 0
|
return start, 0
|
||||||
}, func(started time.Time, duration float64) *time.Time {
|
}, func(started time.Time, duration float64) *time.Time {
|
||||||
@ -188,14 +187,14 @@ func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIR
|
|||||||
return 0, priceds, nil, err
|
return 0, priceds, nil, err
|
||||||
}
|
}
|
||||||
for k, f := range map[tools.DataType]func(graph.GraphItem) bool{tools.STORAGE_RESOURCE: wf.Graph.IsStorage, tools.COMPUTE_RESOURCE: wf.Graph.IsCompute} {
|
for k, f := range map[tools.DataType]func(graph.GraphItem) bool{tools.STORAGE_RESOURCE: wf.Graph.IsStorage, tools.COMPUTE_RESOURCE: wf.Graph.IsCompute} {
|
||||||
if _, priceds, err = plan[resources.ResourceInterface](k, wf, priceds, request, buyingStrategy, pricingStrategy,
|
if _, priceds, err = plan[resources.ResourceInterface](k, wf, priceds, request,
|
||||||
f, func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
f, func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
||||||
nearestStart, longestDuration := wf.Graph.GetAverageTimeRelatedToProcessingActivity(start, ps, res, func(i graph.GraphItem) (r resources.ResourceInterface) {
|
nearestStart, longestDuration := wf.Graph.GetAverageTimeRelatedToProcessingActivity(start, ps, res, func(i graph.GraphItem) (r resources.ResourceInterface) {
|
||||||
if f(i) {
|
if f(i) {
|
||||||
_, r = i.GetResource()
|
_, r = i.GetResource()
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}, request, buyingStrategy, pricingStrategy)
|
}, request)
|
||||||
return start.Add(time.Duration(nearestStart) * time.Second), longestDuration
|
return start.Add(time.Duration(nearestStart) * time.Second), longestDuration
|
||||||
}, 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))
|
||||||
@ -205,8 +204,7 @@ func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
longest := common.GetPlannerLongestTime(end, priceds, request)
|
longest := common.GetPlannerLongestTime(end, priceds, request)
|
||||||
if _, priceds, err = plan[resources.ResourceInterface](tools.WORKFLOW_RESOURCE, wf, priceds, request,
|
if _, priceds, err = plan[resources.ResourceInterface](tools.WORKFLOW_RESOURCE, wf, priceds, request, wf.Graph.IsWorkflow,
|
||||||
buyingStrategy, pricingStrategy, wf.Graph.IsWorkflow,
|
|
||||||
func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
func(res resources.ResourceInterface, priced pricing.PricedItemITF) (time.Time, float64) {
|
||||||
start := start.Add(time.Duration(common.GetPlannerNearestStart(start, priceds, request)) * time.Second)
|
start := start.Add(time.Duration(common.GetPlannerNearestStart(start, priceds, request)) * time.Second)
|
||||||
longest := float64(-1)
|
longest := float64(-1)
|
||||||
@ -214,7 +212,7 @@ func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIR
|
|||||||
if code != 200 || err != nil {
|
if code != 200 || err != nil {
|
||||||
return start, longest
|
return start, longest
|
||||||
}
|
}
|
||||||
if neoLongest, _, _, err := r.(*Workflow).Planify(start, end, request, buyingStrategy, pricingStrategy); err != nil {
|
if neoLongest, _, _, err := r.(*Workflow).Planify(start, end, request); err != nil {
|
||||||
return start, longest
|
return start, longest
|
||||||
} else if neoLongest > longest {
|
} else if neoLongest > longest {
|
||||||
longest = neoLongest
|
longest = neoLongest
|
||||||
@ -231,7 +229,6 @@ func (wf *Workflow) Planify(start time.Time, end *time.Time, request *tools.APIR
|
|||||||
|
|
||||||
func plan[T resources.ResourceInterface](
|
func plan[T resources.ResourceInterface](
|
||||||
dt tools.DataType, wf *Workflow, priceds map[tools.DataType]map[string]pricing.PricedItemITF, request *tools.APIRequest,
|
dt tools.DataType, wf *Workflow, priceds map[tools.DataType]map[string]pricing.PricedItemITF, request *tools.APIRequest,
|
||||||
buyingStrategy int, pricingStrategy int,
|
|
||||||
f func(graph.GraphItem) bool, start func(resources.ResourceInterface, pricing.PricedItemITF) (time.Time, float64), end func(time.Time, float64) *time.Time) ([]T, map[tools.DataType]map[string]pricing.PricedItemITF, error) {
|
f func(graph.GraphItem) bool, start func(resources.ResourceInterface, pricing.PricedItemITF) (time.Time, float64), end func(time.Time, float64) *time.Time) ([]T, map[tools.DataType]map[string]pricing.PricedItemITF, error) {
|
||||||
resources := []T{}
|
resources := []T{}
|
||||||
for _, item := range wf.GetGraphItems(f) {
|
for _, item := range wf.GetGraphItems(f) {
|
||||||
@ -242,7 +239,10 @@ func plan[T resources.ResourceInterface](
|
|||||||
if realItem == nil {
|
if realItem == nil {
|
||||||
return resources, priceds, errors.New("could not load the processing resource")
|
return resources, priceds, errors.New("could not load the processing resource")
|
||||||
}
|
}
|
||||||
priced := realItem.ConvertToPricedResource(dt, request, buyingStrategy, pricingStrategy)
|
priced := realItem.ConvertToPricedResource(dt, request)
|
||||||
|
if priced.SelectPricing() == nil {
|
||||||
|
return resources, priceds, errors.New("no pricings are selected... can't proceed")
|
||||||
|
}
|
||||||
started, duration := start(realItem, priced)
|
started, duration := start(realItem, priced)
|
||||||
priced.SetLocationStart(started)
|
priced.SetLocationStart(started)
|
||||||
if duration >= 0 {
|
if duration >= 0 {
|
||||||
|
@ -37,8 +37,6 @@ 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"`
|
|
||||||
SelectedPricingStrategy int `json:"selected_pricing_strategy"`
|
|
||||||
SelectedBillingStrategy pricing.BillingStrategy `json:"selected_billing_strategy"`
|
SelectedBillingStrategy pricing.BillingStrategy `json:"selected_billing_strategy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +68,7 @@ func (ws *WorkflowSchedule) GetBuyAndBook(wfID string, request *tools.APIRequest
|
|||||||
return false, nil, []*WorkflowExecution{}, []*purchase_resource.PurchaseResource{}, []*booking.Booking{}, errors.New("could not load the workflow with id: " + err.Error())
|
return false, nil, []*WorkflowExecution{}, []*purchase_resource.PurchaseResource{}, []*booking.Booking{}, errors.New("could not load the workflow with id: " + err.Error())
|
||||||
}
|
}
|
||||||
wf := res.(*workflow.Workflow)
|
wf := res.(*workflow.Workflow)
|
||||||
longest, priceds, wf, err := wf.Planify(ws.Start, ws.End, request, int(ws.SelectedBuyingStrategy), ws.SelectedPricingStrategy)
|
longest, priceds, wf, err := wf.Planify(ws.Start, ws.End, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, wf, []*WorkflowExecution{}, []*purchase_resource.PurchaseResource{}, []*booking.Booking{}, err
|
return false, wf, []*WorkflowExecution{}, []*purchase_resource.PurchaseResource{}, []*booking.Booking{}, err
|
||||||
}
|
}
|
||||||
@ -90,10 +88,6 @@ func (ws *WorkflowSchedule) GetBuyAndBook(wfID string, request *tools.APIRequest
|
|||||||
bookings = append(bookings, exec.Book(ws.UUID, wfID, priceds)...)
|
bookings = append(bookings, exec.Book(ws.UUID, wfID, priceds)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ws.GenerateOrder(purchased, bookings, request); err != nil {
|
|
||||||
return false, wf, execs, purchased, bookings, err
|
|
||||||
}
|
|
||||||
|
|
||||||
errCh := make(chan error, len(bookings))
|
errCh := make(chan error, len(bookings))
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
|
|
||||||
@ -107,6 +101,10 @@ func (ws *WorkflowSchedule) GetBuyAndBook(wfID string, request *tools.APIRequest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := ws.GenerateOrder(purchased, bookings, request); err != nil {
|
||||||
|
return false, wf, execs, purchased, bookings, err
|
||||||
|
}
|
||||||
|
|
||||||
return true, wf, execs, purchased, bookings, nil
|
return true, wf, execs, purchased, bookings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +120,7 @@ func (ws *WorkflowSchedule) GenerateOrder(purchases []*purchase_resource.Purchas
|
|||||||
Status: enum.PENDING,
|
Status: enum.PENDING,
|
||||||
}
|
}
|
||||||
if res, _, err := order.NewAccessor(request).StoreOne(newOrder); err == nil {
|
if res, _, err := order.NewAccessor(request).StoreOne(newOrder); err == nil {
|
||||||
if _, err := bill.DraftBill(res.(*order.Order), request); err != nil {
|
if _, err := bill.DraftFirstBill(res.(*order.Order), request); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user