package resources import ( "errors" "time" "cloud.o-forge.io/core/oc-lib/models/common/models" "cloud.o-forge.io/core/oc-lib/models/common/pricing" "cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/tools" ) /* * DataResource is a struct that represents a data resource * it defines the resource data */ type DataResource struct { AbstractIntanciatedResource[*DataInstance] Type string `bson:"type,omitempty" json:"type,omitempty"` Quality string `bson:"quality,omitempty" json:"quality,omitempty"` OpenData bool `bson:"open_data" json:"open_data" default:"false"` // Type is the type of the storage Static bool `bson:"static" json:"static" default:"false"` UpdatePeriod *time.Time `bson:"update_period,omitempty" json:"update_period,omitempty"` PersonalData bool `bson:"personal_data,omitempty" json:"personal_data,omitempty"` AnonymizedPersonalData bool `bson:"anonymized_personal_data,omitempty" json:"anonymized_personal_data,omitempty"` SizeGB float64 `json:"size,omitempty" bson:"size,omitempty"` // SizeGB is the size of the data License DataLicense `json:"license" bson:"license" description:"license of the data" default:"0"` // License is the license of the data // ? Interest DataLicense `json:"interest" bson:"interest" description:"interest of the data" default:"0"` // Interest is the interest of the data Example string `json:"example,omitempty" bson:"example,omitempty" description:"base64 encoded data"` // Example is an example of the data } func (d *DataResource) GetAccessor(request *tools.APIRequest) utils.Accessor { return NewAccessor[*DataResource](tools.DATA_RESOURCE, request, func() utils.DBObject { return &DataResource{} }) // Create a new instance of the accessor } func (r *DataResource) GetType() string { return tools.DATA_RESOURCE.String() } func (abs *DataResource) ConvertToPricedResource( t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF { if t != tools.DATA_RESOURCE { return nil } p := abs.AbstractIntanciatedResource.ConvertToPricedResource(t, request) priced := p.(*PricedResource) return &PricedDataResource{ PricedResource: *priced, } } type DataInstance struct { ResourceInstance[*DataResourcePartnership] Source string `json:"source" bson:"source"` // Source is the source of the data } func (ri *DataInstance) StoreDraftDefault() { found := false for _, p := range ri.ResourceInstance.Env { if p.Attr == "source" { found = true break } } if !found { ri.ResourceInstance.Env = append(ri.ResourceInstance.Env, models.Param{ Attr: "source", Value: ri.Source, Readonly: true, }) } ri.ResourceInstance.StoreDraftDefault() } type DataResourcePartnership struct { ResourcePartnerShip[*DataResourcePricingProfile] MaxDownloadableGbAllowed float64 `json:"allowed_gb,omitempty" bson:"allowed_gb,omitempty"` PersonalDataAllowed bool `json:"personal_data_allowed,omitempty" bson:"personal_data_allowed,omitempty"` AnonymizedPersonalDataAllowed bool `json:"anonymized_personal_data_allowed,omitempty" bson:"anonymized_personal_data_allowed,omitempty"` } type DataResourcePricingStrategy int const ( PER_DOWNLOAD DataResourcePricingStrategy = iota PER_TB_DOWNLOADED PER_GB_DOWNLOADED PER_MB_DOWNLOADED PER_KB_DOWNLOADED ) func (t DataResourcePricingStrategy) String() string { return [...]string{"PER DOWNLOAD", "PER TB DOWNLOADED", "PER GB DOWNLOADED", "PER MB DOWNLOADED", "PER KB DOWNLOADED"}[t] } func DataResourcePricingStrategyList() []DataResourcePricingStrategy { return []DataResourcePricingStrategy{PER_DOWNLOAD, PER_TB_DOWNLOADED, PER_GB_DOWNLOADED, PER_MB_DOWNLOADED, PER_KB_DOWNLOADED} } func ToDataResourcePricingStrategy(i int) DataResourcePricingStrategy { return DataResourcePricingStrategy(i) } func (t DataResourcePricingStrategy) GetStrategy() string { return [...]string{"PER_DOWNLOAD", "PER_GB", "PER_MB", "PER_KB"}[t] } func (t DataResourcePricingStrategy) GetStrategyValue() int { return int(t) } func (t DataResourcePricingStrategy) GetQuantity(amountOfDataGB float64) (float64, error) { switch t { case PER_DOWNLOAD: return 1, nil case PER_TB_DOWNLOADED: return amountOfDataGB * 1000, nil case PER_GB_DOWNLOADED: return amountOfDataGB, nil case PER_MB_DOWNLOADED: return amountOfDataGB / 1000, nil case PER_KB_DOWNLOADED: return amountOfDataGB / 1000000, nil } return 0, errors.New("pricing strategy not found") } type DataResourcePricingProfile struct { pricing.AccessPricingProfile[DataResourcePricingStrategy] // 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 { return p.Pricing.OverrideStrategy.GetStrategyValue() } func (p *DataResourcePricingProfile) GetPrice(amountOfData float64, explicitDuration float64, start time.Time, end time.Time, params ...string) (float64, error) { return p.Pricing.GetPrice(amountOfData, explicitDuration, start, &end) } func (p *DataResourcePricingProfile) IsPurchased() bool { return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE } type PricedDataResource struct { PricedResource UsageStorageGB float64 `json:"storage_gb,omitempty" bson:"storage_gb,omitempty"` } func (r *PricedDataResource) GetType() tools.DataType { return tools.DATA_RESOURCE } func (r *PricedDataResource) GetPrice() (float64, error) { if r.UsageStart == nil || r.UsageEnd == nil { return 0, errors.New("usage start and end must be set") } if r.SelectedPricing == nil { return 0, errors.New("selected pricing must be set") } pricing := *r.SelectedPricing var err error amountOfData := float64(1) if pricing.GetOverrideStrategyValue() >= 0 { amountOfData, err = ToDataResourcePricingStrategy(pricing.GetOverrideStrategyValue()).GetQuantity(r.UsageStorageGB) if err != nil { return 0, err } } return pricing.GetPrice(amountOfData, r.ExplicitBookingDurationS, *r.UsageStart, *r.UsageEnd) }