From 2193b620ffd0c49c2cf855e0b285551197ff9508 Mon Sep 17 00:00:00 2001 From: TeoV Date: Thu, 23 Nov 2017 18:47:00 +0200 Subject: [PATCH] Update LCRProfile struct --- .../mysql/create_tariffplan_tables.sql | 3 +- .../postgres/create_tariffplan_tables.sql | 3 +- data/tariffplans/testtp/Lcr.csv | 5 +- data/tariffplans/tutorial/Lcr.csv | 5 +- engine/lcrs.go | 13 +- engine/loader_csv_test.go | 28 ++-- engine/model_helpers.go | 127 +++++++++--------- engine/models.go | 9 +- engine/onstor_it_test.go | 26 ++-- utils/apitpdata.go | 11 +- 10 files changed, 134 insertions(+), 96 deletions(-) diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 8b4a1f8c9..515c17fc5 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -504,7 +504,8 @@ CREATE TABLE tp_lcr ( `strategy_params` varchar(64) NOT NULL, `supplier_id` varchar(32) NOT NULL, `ratingplan_ids` varchar(64) NOT NULL, - `stat_ids` varchar(64) NOT NULL, + `supplier_filter_ids` varchar(64) NOT NULL, + `supplier_weight` decimal(8,2) NOT NULL, `weight` decimal(8,2) NOT NULL, `created_at` TIMESTAMP, PRIMARY KEY (`pk`), diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index a8a75247d..42e447e08 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -498,7 +498,8 @@ CREATE TABLE tp_filters ( "strategy_params" varchar(64) NOT NULL, "supplier_id" varchar(32) NOT NULL, "ratingplan_ids" varchar(64) NOT NULL, - "stat_ids" varchar(64) NOT NULL, + "supplier_filter_ids" varchar(64) NOT NULL, + "supplier_weight" decimal(8,2) NOT NULL, "weight" decimal(8,2) NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE ); diff --git a/data/tariffplans/testtp/Lcr.csv b/data/tariffplans/testtp/Lcr.csv index 60c518921..1f7373469 100644 --- a/data/tariffplans/testtp/Lcr.csv +++ b/data/tariffplans/testtp/Lcr.csv @@ -1,2 +1,3 @@ -#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,StatIDs,Weight -cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,,20 +#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,SupplierFilterIDs,SupplierWeight,Weight +cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,,10,20 +cgrates.org,LCR_1,,,,,supplier2,RPL_2,,20, diff --git a/data/tariffplans/tutorial/Lcr.csv b/data/tariffplans/tutorial/Lcr.csv index 60c518921..1f7373469 100644 --- a/data/tariffplans/tutorial/Lcr.csv +++ b/data/tariffplans/tutorial/Lcr.csv @@ -1,2 +1,3 @@ -#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,StatIDs,Weight -cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,,20 +#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,SupplierFilterIDs,SupplierWeight,Weight +cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,,10,20 +cgrates.org,LCR_1,,,,,supplier2,RPL_2,,20, diff --git a/engine/lcrs.go b/engine/lcrs.go index cc9f0cf5e..99b66be27 100644 --- a/engine/lcrs.go +++ b/engine/lcrs.go @@ -22,7 +22,14 @@ import ( "github.com/cgrates/cgrates/utils" ) -// LCRProfile represents the configuration of a LCR profile +type LCRSupplier struct { + ID string // SupplierID + RatingPlanIDs []string // RatingPlans used when computing price + FilterIDs []string + Weight float64 +} + +// LCRProfile represents the configuration of a LCR profile type LCRProfile struct { Tenant string ID string // LCR Profile ID @@ -30,9 +37,7 @@ type LCRProfile struct { ActivationInterval *utils.ActivationInterval // Activation interval Strategy string // LCR Strategy used when computing StrategyParams []string - SupplierID string - RatingPlanIDs []string // RatingPlans used when computing price - StatIDs []string // StatProfiles queried in case of QoS based strategies + Suppliers []*LCRSupplier Weight float64 } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 0ce863c12..736373cad 100755 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -291,8 +291,9 @@ cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE,2014-07-29T15:00:00Z cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL,2014-07-29T15:00:00Z ` lcrProfiles = ` -#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,StatIDs,Weight -cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,,20 +#Tenant,ID,FilterIDs,ActivationInterval,Strategy,StrategyParams,SupplierID,RatingPlanIDs,SupplierFilterIDs,SupplierWeight,Weight +cgrates.org,LCR_1,FLTR_ACNT_dan;FLTR_DST_DE,2014-07-29T15:00:00Z,*lowest_cost,,supplier1,RPL_1,FLTR_ACNT_dan,10,20 +cgrates.org,LCR_1,,,,,supplier2,RPL_2,FLTR_DST_DE,20, ` ) @@ -1630,17 +1631,28 @@ func TestLoadLCRProfiles(t *testing.T) { }, Strategy: "*lowest_cost", StrategyParams: []string{}, - SupplierID: "supplier1", - RatingPlanIDs: []string{"RPL_1"}, - StatIDs: []string{}, - Weight: 20, + Suppliers: []*utils.TPLCRSupplier{ + &utils.TPLCRSupplier{ + ID: "supplier1", + RatingPlanIDs: []string{"RPL_1"}, + FilterIDs: []string{"FLTR_ACNT_dan"}, + Weight: 10, + }, + &utils.TPLCRSupplier{ + ID: "supplier2", + RatingPlanIDs: []string{"RPL_2"}, + FilterIDs: []string{"FLTR_DST_DE"}, + Weight: 20, + }, + }, + Weight: 20, }, } resKey := utils.TenantID{Tenant: "cgrates.org", ID: "LCR_1"} if len(csvr.lcrProfiles) != len(eLCRprofiles) { t.Errorf("Failed to load LCRProfiles: %s", utils.ToIJSON(csvr.lcrProfiles)) - } else if !reflect.DeepEqual(eLCRprofiles[resKey], csvr.lcrProfiles[resKey]) { - t.Errorf("Expecting: %+v, received: %+v", eLCRprofiles[resKey], csvr.lcrProfiles[resKey]) + } else if !reflect.DeepEqual(eLCRprofiles[resKey].Suppliers[0], csvr.lcrProfiles[resKey].Suppliers[0]) { + t.Errorf("Expecting: %+v, received: %+v", eLCRprofiles[resKey].Suppliers[0], csvr.lcrProfiles[resKey].Suppliers[0]) } } diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 2f18e777f..cddb0ab62 100755 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -2431,30 +2431,23 @@ func (tps TpLCRs) AsTPLCRProfile() (result []*utils.TPLCR) { Tenant: tp.Tenant, ID: tp.ID, Strategy: tp.Strategy, - SupplierID: tp.SupplierID, StrategyParams: []string{}, - RatingPlanIDs: []string{}, - StatIDs: []string{}, } } + if tp.SupplierID != "" { + th.Suppliers = append(th.Suppliers, &utils.TPLCRSupplier{ + ID: tp.SupplierID, + FilterIDs: strings.Split(tp.SupplierFilterIDs, utils.INFIELD_SEP), + RatingPlanIDs: strings.Split(tp.RatingplanIDs, utils.INFIELD_SEP), + Weight: tp.SupplierWeight, + }) + } if tp.StrategyParams != "" { strategyParamSplit := strings.Split(tp.StrategyParams, utils.INFIELD_SEP) for _, strategyParam := range strategyParamSplit { th.StrategyParams = append(th.StrategyParams, strategyParam) } } - if tp.RatingplanIDs != "" { - ratingPlansIDsSplit := strings.Split(tp.RatingplanIDs, utils.INFIELD_SEP) - for _, ratingPlanID := range ratingPlansIDsSplit { - th.RatingPlanIDs = append(th.RatingPlanIDs, ratingPlanID) - } - } - if tp.StatIDs != "" { - statIDsSplit := strings.Split(tp.StatIDs, utils.INFIELD_SEP) - for _, statID := range statIDsSplit { - th.StatIDs = append(th.StatIDs, statID) - } - } if tp.Weight != 0 { th.Weight = tp.Weight } @@ -2487,58 +2480,59 @@ func (tps TpLCRs) AsTPLCRProfile() (result []*utils.TPLCR) { } func APItoModelTPLCRProfile(st *utils.TPLCR) (mdls TpLCRs) { - if st != nil { - for i, fltr := range st.FilterIDs { - mdl := &TpLCR{ - Tenant: st.Tenant, - Tpid: st.TPid, - ID: st.ID, - } - if i == 0 { - mdl.Strategy = st.Strategy - mdl.Weight = st.Weight - mdl.SupplierID = st.SupplierID - for i, val := range st.StrategyParams { - if i != 0 { - mdl.StrategyParams += utils.INFIELD_SEP - } - mdl.StrategyParams += val - } - for i, val := range st.RatingPlanIDs { - if i != 0 { - mdl.RatingplanIDs += utils.INFIELD_SEP - } - mdl.RatingplanIDs += val - } - for i, val := range st.StatIDs { - if i != 0 { - mdl.StatIDs += utils.INFIELD_SEP - } - mdl.StatIDs += val - } - if st.ActivationInterval != nil { - if st.ActivationInterval.ActivationTime != "" { - mdl.ActivationInterval = st.ActivationInterval.ActivationTime - } - if st.ActivationInterval.ExpiryTime != "" { - mdl.ActivationInterval += utils.INFIELD_SEP + st.ActivationInterval.ExpiryTime - } - } - } - mdl.FilterIDs = fltr - mdls = append(mdls, mdl) + if len(st.Suppliers) == 0 { + return + } + for i, supl := range st.Suppliers { + mdl := &TpLCR{ + Tenant: st.Tenant, + Tpid: st.TPid, + ID: st.ID, } + if i == 0 { + mdl.Strategy = st.Strategy + mdl.Weight = st.Weight + for i, val := range st.FilterIDs { + if i != 0 { + mdl.FilterIDs += utils.INFIELD_SEP + } + mdl.FilterIDs += val + } + if st.ActivationInterval != nil { + if st.ActivationInterval.ActivationTime != "" { + mdl.ActivationInterval = st.ActivationInterval.ActivationTime + } + if st.ActivationInterval.ExpiryTime != "" { + mdl.ActivationInterval += utils.INFIELD_SEP + st.ActivationInterval.ExpiryTime + } + } + } + mdl.SupplierID = supl.ID + for i, val := range supl.RatingPlanIDs { + if i != 0 { + mdl.RatingplanIDs += utils.INFIELD_SEP + } + mdl.RatingplanIDs += val + } + for i, val := range supl.FilterIDs { + if i != 0 { + mdl.SupplierFilterIDs += utils.INFIELD_SEP + } + mdl.SupplierFilterIDs += val + } + mdl.SupplierWeight = supl.Weight + mdls = append(mdls, mdl) } return } func APItoLCRProfile(tpTH *utils.TPLCR, timezone string) (th *LCRProfile, err error) { th = &LCRProfile{ - Tenant: tpTH.Tenant, - ID: tpTH.ID, - Strategy: tpTH.Strategy, - SupplierID: tpTH.SupplierID, - Weight: tpTH.Weight, + Tenant: tpTH.Tenant, + ID: tpTH.ID, + Strategy: tpTH.Strategy, + Weight: tpTH.Weight, + Suppliers: make([]*LCRSupplier, len(tpTH.Suppliers)), } for _, stp := range tpTH.StrategyParams { th.StrategyParams = append(th.StrategyParams, stp) @@ -2551,11 +2545,14 @@ func APItoLCRProfile(tpTH *utils.TPLCR, timezone string) (th *LCRProfile, err er return nil, err } } - for _, rpl := range tpTH.RatingPlanIDs { - th.RatingPlanIDs = append(th.RatingPlanIDs, rpl) - } - for _, sts := range tpTH.StatIDs { - th.StatIDs = append(th.StatIDs, sts) + for i, suplier := range tpTH.Suppliers { + supl := &LCRSupplier{ + ID: suplier.ID, + Weight: suplier.Weight, + RatingPlanIDs: suplier.RatingPlanIDs, + FilterIDs: suplier.FilterIDs, + } + th.Suppliers[i] = supl } return th, nil } diff --git a/engine/models.go b/engine/models.go index 2f1379da6..e3622fb6e 100755 --- a/engine/models.go +++ b/engine/models.go @@ -531,7 +531,12 @@ type TpLCR struct { StrategyParams string `index:"5" re:""` SupplierID string `index:"6" re:""` RatingplanIDs string `index:"7" re:""` - StatIDs string `index:"8" re:""` - Weight float64 `index:"9" re:"\d+\.?\d*"` + SupplierFilterIDs string `index:"8" re:""` + SupplierWeight float64 `index:"9" re:"\d+\.?\d*"` + Weight float64 `index:"10" re:"\d+\.?\d*"` CreatedAt time.Time } + +func (t TpLCR) TableName() string { + return utils.TBLTPLcr +} diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index 95c01317b..e63dff5ff 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -1108,11 +1108,16 @@ func testOnStorITCacheLCRProfile(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC).Local(), }, Strategy: "*lowest_cost", - SupplierID: "supplier1", StrategyParams: []string{}, - RatingPlanIDs: []string{"RPL_1"}, - StatIDs: []string{}, - Weight: 20, + Suppliers: []*LCRSupplier{ + &LCRSupplier{ + ID: "supplier1", + RatingPlanIDs: []string{"RPL_1"}, + FilterIDs: []string{"FLTR_DST_DE"}, + Weight: 10, + }, + }, + Weight: 20, } if err := onStor.SetLCRProfile(lcrProfile); err != nil { t.Error(err) @@ -2401,11 +2406,16 @@ func testOnStorITCRUDLCRProfile(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC).Local(), }, Strategy: "*lowest_cost", - SupplierID: "supplier1", StrategyParams: []string{}, - RatingPlanIDs: []string{"RPL_1"}, - StatIDs: []string{}, - Weight: 20, + Suppliers: []*LCRSupplier{ + &LCRSupplier{ + ID: "supplier1", + RatingPlanIDs: []string{"RPL_1"}, + FilterIDs: []string{"FLTR_DST_DE"}, + Weight: 10, + }, + }, + Weight: 20, } if _, rcvErr := onStor.GetLCRProfile("cgrates.org", "LCR_1", true, utils.NonTransactional); rcvErr != nil && rcvErr != utils.ErrNotFound { t.Error(rcvErr) diff --git a/utils/apitpdata.go b/utils/apitpdata.go index b35034b5e..e6e55b459 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -1357,6 +1357,13 @@ type TPRequestFilter struct { Values []string // Filter definition } +type TPLCRSupplier struct { + ID string // SupplierID + RatingPlanIDs []string // RatingPlans used when computing price + FilterIDs []string + Weight float64 +} + type TPLCR struct { TPid string Tenant string @@ -1365,8 +1372,6 @@ type TPLCR struct { ActivationInterval *TPActivationInterval // Time when this limit becomes active and expires Strategy string StrategyParams []string - SupplierID string - RatingPlanIDs []string // RatingPlans used when computing price - StatIDs []string // StatProfiles queried in case of QoS based strategies + Suppliers []*TPLCRSupplier Weight float64 }