modelling

This commit is contained in:
mr 2024-12-16 12:17:20 +01:00
parent 02d1e93c78
commit 7696f065f8
9 changed files with 383 additions and 74 deletions

View File

@ -7,7 +7,7 @@ abstract Resource{
+icon: string +icon: string
+description: string +description: string
+graphic: GraphicElement +graphic: GraphicElement
+element: DataResource/ProcessingResource/StorageResource/Workflow/DatacenterResource +element: DataResource/ProcessingResource/StorageResource/Workflow/ComputeResource
} }
class DataResource { class DataResource {
@ -31,7 +31,7 @@ class StorageResource {
+capacity: int +capacity: int
} }
class DatacenterResource { class ComputeResource {
+UUID: int +UUID: int
+name: string +name: string
@ -96,7 +96,7 @@ class UserWorkflows {
class DatacenterWorkflows { class DatacenterWorkflows {
+UUID: int +UUID: int
+datacenter: DatacenterResource +compute: ComputeResource
+workflows: Workflow[] +workflows: Workflow[]
} }
@ -159,7 +159,7 @@ DatacenterWorkflows "1" o-- "0..*" Workflow
Resource<|-- DataResource Resource<|-- DataResource
Resource<|-- ProcessingResource Resource<|-- ProcessingResource
Resource<|-- StorageResource Resource<|-- StorageResource
Resource<|-- DatacenterResource Resource<|-- ComputeResource
Resource<|-- Workflow Resource<|-- Workflow
ResourceSet "1" o-- "0..*" Ressource ResourceSet "1" o-- "0..*" Ressource

325
doc/order_model.puml Normal file
View File

@ -0,0 +1,325 @@
@startuml
class AbstractObject {
ID string
Name string
IsDraft bool // is consider as a draft
UpdateDate date
LastPeerWriter string
CreatorID string
AccessMode int // public or private
}
AbstractObject ^-- AbstractResource
AbstractObject ^-- Order
AbstractObject ^-- Booking
AbstractObject ^-- BuyingStatus
AbstractObject ^-- WorkflowExecution
AbstractObject ^-- Workflow
class AbstractResource {
Logo string
Description string
ShortDescription string
Owners []string
UsageRestrictions string
VerifyAuth(request) bool
}
AbstractResource "1 " --* "many " InstanceITF
AbstractCustomizedResource "1 " --* "1 " InstanceITF
AbstractResource ^-- ComputeResource
AbstractResource ^-- DataResource
AbstractResource ^-- ProcessingResource
AbstractResource ^-- StorageResource
AbstractResource ^-- WorkflowResource
class ComputeResource {
Architecture string
Infrastructure string
}
class DataResource {
Type string
Quality string
OpenData bool
Static bool
UpdatePeriod date
PersonalData bool
AnonymizedPersonalData bool
SizeGB float64
Licence string
Example string
}
ProcessingResource "1 " *-- "1 " ProcessingUsage
class ProcessingUsage {
CPUs map[string]CPU
GPUs map[string]GPU
RAM RAM
StorageGB float64
Hypothesis string
ScalingModel string
}
class ProcessingResource {
Infrastructure string
Service bool
Usage ProcessingUsage
OpenSource bool
License string
Maturity string
}
class StorageResource {
Type string
Accronym string
}
WorkflowResource "1 " --* "many " ComputeResource
WorkflowResource "1 " --* "many " DataResource
WorkflowResource "1 " --* "many " ProcessingResource
WorkflowResource "1 " --* "many " StorageResource
class WorkflowResource {
WorkflowID string
}
class ExploitResourceSet {}
AbstractCustomizedResource --^ AbstractResource
AbstractCustomizedResource --* ExploitResourceSet
ExploitResourceSet ^-- CustomizedComputeResource
ExploitResourceSet ^-- CustomizedDataResource
ExploitResourceSet ^-- CustomizedProcessingResource
ExploitResourceSet ^-- CustomizedStorageResource
ExploitResourceSet ^-- CustomizedWorkflowResource
class AbstractCustomizedResource {
// A customized resource is an
// extended abstract resource not use in catalog
ExplicitBookingDurationS float64
UsageStart date
UsageEnd date
SelectedPricing string
}
class CustomizedComputeResource {
CPUsLocated map[string]float64
GPUsLocated map[string]float64
RAMLocated float64
}
class CustomizedDataResource {
StorageGB float64
}
class CustomizedProcessingResource {
Container Container
}
class CustomizedStorageResource {
StorageGB bool
}
class CustomizedWorkflowResource {}
interface InstanceITF {
GetID() string
VerifyPartnership() bool // eval if there is one partnership per peer groups in every instance
GetPeerGroups() []ResourcePartnerITF, []map[string][]string
ClearPeerGroups()
}
InstanceITF -- ResourceInstance
ResourceInstance ^-- ComputeResourceInstance
ResourceInstance ^-- StorageResourceInstance
ResourceInstance "many " --* "1 " ResourcePartnerITF
class ResourceInstance {
ID string
Location Geopoint
Country CountryCode
AccessProtocol string
}
class ComputeResourceInstance {
SecurityLevel string
PowerSource string
CPUs map[string]CPU
GPUs map[string]GPU
RAM RAM
}
class StorageResourceInstance {
Local bool
SecurityLevel string
SizeType string
SizeGB int
Encryption bool
Redundancy string
Throughput string
}
ResourcePartnerITF -- ResourcePartnership
ResourcePartnership ^-- ComputeResourcePartnership
ResourcePartnership ^-- DataResourcePartnership
ResourcePartnership ^-- StorageResourcePartnership
interface ResourcePartnerITF {
GetPricing(id string) PricingProfileITF
GetPeerGroups() []ResourcePartnerITF, []map[string][]string
ClearPeerGroups()
}
ResourcePartnership "many " --* "1 " PricingProfileITF
class ResourcePartnership{
Namespace string
PeerGroups map[string][]string
}
class ComputeResourcePartnership {
MaxAllowedCPUsCores map[string]int
MaxAllowedGPUsMemoryGB map[string]float64
RAMSizeGB float64
}
class DataResourcePartnership {
MaxDownloadableGBAllowed float64
PersonalDataAllowed bool
AnonymizedPersonalDataAllowed bool
}
class StorageResourcePartnership {
MaxSizeGBAllowed float64
OnlyEncryptedAllowed bool
}
RefundType -- AccessPricingProfile
enum RefundType {
REFUND_DEAD_END
REFUND_ON_ERROR
REFUND_ON_EARLY_END
}
PricingProfileITF -- AccessPricingProfile
PricingProfileITF -- ExploitPricingProfile
PricingProfileITF -- WorkflowResourcePricingProfile
AccessPricingProfile ^-- DataResourcePricingProfile
AccessPricingProfile ^-- ProcessingResourcePricingProfile
ExploitPricingProfile ^-- ComputeResourcePricingProfile
ExploitPricingProfile ^-- StorageResourcePricingProfile
interface PricingProfileITF {
GetPrice(quantity float64, val float64, start date, end date, request) float64
IsBuying() bool
}
class AccessPricingProfile {
ID string
Pricing PricingStrategy
DefaultRefundType RefundType
RefundRatio int // percentage of refund on price
}
class DataResourcePricingProfile {}
class ProcessingResourcePricingProfile {}
ExploitPrivilegeStrategy -- ExploitPricingProfile
enum ExploitPrivilegeStrategy {
BASIC
GARANTED_ON_DELAY
GARANTED
}
AccessPricingProfile --* PricingStrategy
AccessPricingProfile ^-- ExploitPricingProfile
class ExploitPricingProfile {
AdditionnalRefundTypes RefundTypeint
PrivilegeStrategy ExploitPrivilegeStrategy
GarantedDelaySecond int
Exceeding bool
ExceedingRatio int // percentage of Exceeding based on price
}
class ComputeResourcePricingProfile {
OverrideCPUsPrices map[string]float64
OverrideGPUsPrices map[string]float64
OverrideRAMPrice float64
}
class StorageResourcePricingProfile {}
WorkflowResourcePricingProfile "1 " --* "many " ExploitResourceSet
class WorkflowResourcePricingProfile {
ID string
}
BuyingStrategy -- PricingStrategy
enum BuyingStrategy {
UNLIMITED
SUBSCRIPTION
PAY_PER_USE
}
Strategy -- TimePricingStrategy
Strategy "0-1 " *-- " " PricingStrategy
interface Strategy {
GetStrategy () string
GetStrategyValue() int
}
enum TimePricingStrategy {
ONCE
PER_SECOND
PER_MINUTE
PER_HOUR
PER_DAY
PER_WEEK
PER_MONTH
}
class PricingStrategy {
Price float64
BuyingStrategy
TimePricingStrategy TimePricingStrategy
OverrideStrategy Strategy
}
PeerOrder "many " *-- "1 " Order
PeerItemOrder "many " *-- "1 " PeerOrder
PricedItemITF "many " *-- "1 " PeerItemOrder
PricedItemITF -- AbstractCustomizedResource
class Order {
OrderBy string
WorkflowExecutionIDs []string
Status string
Total float64
}
class PeerOrder {
PeerID string
Error string
Status string
BillingAddress string
Total float64
}
class PeerItemOrder {
Quantity int
BuyingStatus string
}
class BuyingStatus {}
WorkflowExecution "many " --* "1 " Workflow
Workflow "1 " --* "many " WorkflowScheduler
WorkflowScheduler "1 " --* "many " WorkflowExecution
class WorkflowExecution {
ExecDate date
EndDate date
State string
WorkflowID string
ToBookings() []Booking
}
class WorkflowScheduler* {
Message string
Warning string
Start date
End date
DurationS float64
Cron string
Schedules(workflowID string, request) []WorkflowExecution
}
Workflow "1 " --* "many " ExploitResourceSet
class Workflow {}
interface PricedItemITF {
getPrice(request) float64, error
}
@enduml

View File

@ -3,7 +3,6 @@ package pricing
import ( import (
"time" "time"
"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"
) )
@ -22,33 +21,38 @@ const (
REFUND_ON_EARLY_END REFUND_ON_EARLY_END
) )
type AccessPricingProfile struct { // only use for acces such as : DATA && PROCESSING type AccessPricingProfile[T Strategy] struct { // only use for acces such as : DATA && PROCESSING
utils.DBObject ID string `json:"id,omitempty" bson:"id,omitempty"` // ID is the ID of the pricing
DefaultRefund RefundType `json:"default_refund" bson:"default_refund"` // DefaultRefund is the default refund type of the pricing Pricing PricingStrategy[T] `json:"price,omitempty" bson:"price,omitempty"` // Price is the price of the resource
RefundRatio int32 `json:"refund_ratio" bson:"refund_ratio" default:"0"` // RefundRatio is the refund ratio if missing DefaultRefund RefundType `json:"default_refund" bson:"default_refund"` // DefaultRefund is the default refund type of the pricing
RefundRatio int32 `json:"refund_ratio" bson:"refund_ratio" default:"0"` // RefundRatio is the refund ratio if missing
} }
func (b *AccessPricingProfile) GetOverrideStrategyValue() int { func (b *AccessPricingProfile[T]) GetID() string {
return b.ID
}
func (b *AccessPricingProfile[T]) GetOverrideStrategyValue() int {
return -1 return -1
} }
type ExploitPricingStrategy int type ExploitPrivilegeStrategy int
const ( const (
BASIC ExploitPricingStrategy = iota BASIC ExploitPrivilegeStrategy = iota
GARANTED_ON_DELAY GARANTED_ON_DELAY
GARANTED GARANTED
) )
func (t ExploitPricingStrategy) String() string { func (t ExploitPrivilegeStrategy) String() string {
return [...]string{"BASIC", "GARANTED_ON_DELAY", "GARANTED"}[t] return [...]string{"BASIC", "GARANTED_ON_DELAY", "GARANTED"}[t]
} }
type ExploitPricingProfile struct { // only use for exploit such as : STORAGE, COMPUTE, WORKFLOW type ExploitPricingProfile[T Strategy] struct { // only use for exploit such as : STORAGE, COMPUTE, WORKFLOW
AccessPricingProfile AccessPricingProfile[T]
AdditionnalRefundTypes []RefundType `json:"refund_types" bson:"refund_types"` // RefundTypes is the refund types of the pricing AdditionnalRefundTypes []RefundType `json:"refund_types" bson:"refund_types"` // RefundTypes is the refund types of the pricing
PrivilegeStrategy ExploitPricingStrategy `json:"privilege_strategy,omitempty" bson:"privilege_strategy,omitempty"` // Strategy is the strategy of the pricing PrivilegeStrategy ExploitPrivilegeStrategy `json:"privilege_strategy,omitempty" bson:"privilege_strategy,omitempty"` // Strategy is the strategy of the pricing
GarantedDelaySecond uint GarantedDelaySecond uint
Exceeding bool Exceeding bool

View File

@ -41,24 +41,6 @@ type ComputeResourcePartnership struct {
MaxAllowedRAMSize float64 `json:"allowed_ram,omitempty" bson:"allowed_ram,omitempty"` MaxAllowedRAMSize float64 `json:"allowed_ram,omitempty" bson:"allowed_ram,omitempty"`
} }
func (r *ComputeResourceInstance) VerifyPartnerships() bool {
peersMultiple := map[string]int{}
for _, p := range r.Partnerships {
for k, g := range p.PeerGroups {
for _, v := range g {
if _, ok := peersMultiple[k+"_"+v]; !ok {
peersMultiple[k + "_" + v] = 0
}
peersMultiple[k+"_"+v]++
}
}
for k, p := range peersMultiple {
if p > 1 {
return false
}
}
}
type ComputeResourcePricingProfileOptions struct { type ComputeResourcePricingProfileOptions struct {
CPUCore int `json:"cpu_core" bson:"cpu_core" default:"1"` CPUCore int `json:"cpu_core" bson:"cpu_core" default:"1"`
GPUMemoryGB float64 `json:"gpu_memory_gb" bson:"gpu_memory_gb" default:"1"` GPUMemoryGB float64 `json:"gpu_memory_gb" bson:"gpu_memory_gb" default:"1"`
@ -66,9 +48,8 @@ type ComputeResourcePricingProfileOptions struct {
} }
type ComputeResourcePricingProfile struct { type ComputeResourcePricingProfile struct {
pricing.ExploitPricingProfile pricing.ExploitPricingProfile[pricing.TimePricingStrategy]
Pricing pricing.PricingStrategy[pricing.TimePricingStrategy] `json:"price,omitempty" bson:"price,omitempty"` // Price is the price of the resource Options ComputeResourcePricingProfileOptions `json:"options,omitempty" bson:"options,omitempty"` // Options is the options of the pricing profile
Options ComputeResourcePricingProfileOptions `json:"options,omitempty" bson:"options,omitempty"` // Options is the options of the pricing profile
// ExploitPricingProfile is the pricing profile of a compute it means that we exploit the resource for an amount of continuous time // ExploitPricingProfile is the pricing profile of a compute it means that we exploit the resource for an amount of continuous time
OverrideCPUsPrices map[string]float64 `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs OverrideCPUsPrices map[string]float64 `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs
OverrideGPUsPrices map[string]float64 `json:"gpus_prices,omitempty" bson:"gpus_prices,omitempty"` // GPUsPrices is the prices of the GPUs OverrideGPUsPrices map[string]float64 `json:"gpus_prices,omitempty" bson:"gpus_prices,omitempty"` // GPUsPrices is the prices of the GPUs

View File

@ -91,8 +91,7 @@ func (t DataResourcePricingStrategy) GetQuantity(amountOfDataGB float64) (float6
} }
type DataResourcePricingProfile struct { type DataResourcePricingProfile struct {
Pricing *pricing.PricingStrategy[DataResourcePricingStrategy] `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs pricing.AccessPricingProfile[DataResourcePricingStrategy] // AccessPricingProfile is the pricing profile of a data it means that we can access the data for an amount of time
pricing.AccessPricingProfile // AccessPricingProfile is the pricing profile of a data it means that we can access the data for an amount of time
} }
func (p *DataResourcePricingProfile) GetOverrideStrategyValue() int { func (p *DataResourcePricingProfile) GetOverrideStrategyValue() int {

View File

@ -65,8 +65,7 @@ func (d *ProcessingResource) GetAccessor(request *tools.APIRequest) utils.Access
} }
type ProcessingResourcePricingProfile struct { type ProcessingResourcePricingProfile struct {
Pricing *pricing.PricingStrategy[pricing.TimePricingStrategy] `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs 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 // AccessPricingProfile is the pricing profile of a data it means that we can access the data for an amount of time
} }
func (p *ProcessingResourcePricingProfile) IsBuying() bool { func (p *ProcessingResourcePricingProfile) IsBuying() bool {

View File

@ -85,6 +85,30 @@ func (abs *AbstractResource[T]) GetPartnership(request *tools.APIRequest) Resour
return nil return nil
} }
func (abs *AbstractResource[T]) VerifyPartnerships() bool {
// a peer can be part of only one partnership by instance
// may we need to define partnership in a different DB
for _, instance := range abs.Instances {
if !instance.VerifyPartnerships() {
return false
}
}
return true
}
func (d *AbstractResource[T]) Trim() {
if ok, _ := (&peer.Peer{AbstractObject: utils.AbstractObject{UUID: d.CreatorID}}).IsMySelf(); !ok {
// TODO clean up the peer groups that are not in the allowed peers group
for _, instance := range d.Instances {
instance.ClearPeerGroups()
}
}
}
func (abs *AbstractResource[T]) VerifyAuth(request *tools.APIRequest) bool {
return len(verifyAuthAction[T](abs.Instances, request)) > 0 || abs.AbstractObject.VerifyAuth(request)
}
type AbstractCustomizedResource[T InstanceITF] struct { type AbstractCustomizedResource[T InstanceITF] struct {
abstractResource abstractResource
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"`
@ -179,35 +203,6 @@ func verifyAuthAction[T InstanceITF](baseInstance []T, request *tools.APIRequest
return instances return instances
} }
/*
* VerifyPartnerships is a function that verifies the partnerships of the resource
* an instance can only have one partnership available for a peer
* it returns a boolean
*/
func (abs *AbstractResource[T]) VerifyPartnerships() bool {
// a peer can be part of only one partnership by instance
// may we need to define partnership in a different DB
for _, instance := range abs.Instances {
if !instance.VerifyPartnerships() {
return false
}
}
return true
}
func (d *AbstractResource[T]) Trim() {
if ok, _ := (&peer.Peer{AbstractObject: utils.AbstractObject{UUID: d.CreatorID}}).IsMySelf(); !ok {
// TODO clean up the peer groups that are not in the allowed peers group
for _, instance := range d.Instances {
instance.ClearPeerGroups()
}
}
}
func (abs *AbstractResource[T]) VerifyAuth(request *tools.APIRequest) bool {
return len(verifyAuthAction[T](abs.Instances, request)) > 0 || abs.AbstractObject.VerifyAuth(request)
}
type ResourceInstance[T ResourcePartnerITF] struct { type ResourceInstance[T ResourcePartnerITF] struct {
UUID string `json:"id,omitempty" bson:"id,omitempty"` UUID string `json:"id,omitempty" bson:"id,omitempty"`
Location geopoint.GeoPoint `json:"location,omitempty" bson:"location,omitempty"` Location geopoint.GeoPoint `json:"location,omitempty" bson:"location,omitempty"`

View File

@ -96,8 +96,7 @@ func (t StorageResourcePricingStrategy) GetQuantity(amountOfDataGB float64) (flo
} }
type StorageResourcePricingProfile struct { type StorageResourcePricingProfile struct {
Pricing *pricing.PricingStrategy[StorageResourcePricingStrategy] `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs 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 // ExploitPricingProfile is the pricing profile of a storage it means that we exploit the resource for an amount of continuous time
} }
func (p *StorageResourcePricingProfile) IsBuying() bool { func (p *StorageResourcePricingProfile) IsBuying() bool {

View File

@ -3,7 +3,6 @@ package resources
import ( import (
"time" "time"
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
"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"
) )
@ -36,8 +35,16 @@ func (d *WorkflowResource) GetAccessor(request *tools.APIRequest) utils.Accessor
} }
type WorkflowResourcePricingProfile struct { type WorkflowResourcePricingProfile struct {
ID string `json:"id,omitempty" bson:"id,omitempty"`
ExploitedResourceSet ExploitedResourceSet
pricing.ExploitPricingProfile // ExploitPricingProfile is the pricing profile of a workflow it means that we exploit the resource for an amount of continuous time }
func (p *WorkflowResourcePricingProfile) GetOverrideStrategyValue() int {
return -1
}
func (p *WorkflowResourcePricingProfile) GetID() string {
return p.ID
} }
func (p *WorkflowResourcePricingProfile) IsBuying() bool { func (p *WorkflowResourcePricingProfile) IsBuying() bool {