diff --git a/apier/v1/tpaliases.go b/apier/v1/tpaliases.go index bc343d42f..d62f5cc42 100644 --- a/apier/v1/tpaliases.go +++ b/apier/v1/tpaliases.go @@ -37,29 +37,17 @@ func (self *ApierV1) SetTPAlias(attrs utils.TPAliases, reply *string) error { } type AttrGetTPAlias struct { - TPid string // Tariff plan id - Direction string - Tenant string - Category string - Account string - Subject string - Group string + TPid string // Tariff plan id + AliasId string } // Queries specific Alias on Tariff plan -func (self *ApierV1) GetTPAliases(attr AttrGetTPAlias, reply *utils.TPAliases) error { +func (self *ApierV1) GetTPAlias(attr AttrGetTPAlias, reply *utils.TPAliases) error { if missing := utils.MissingStructFields(&attr, []string{"TPid"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - al := &engine.TpAlias{ - Tpid: attr.TPid, - Direction: attr.Direction, - Tenant: attr.Tenant, - Category: attr.Category, - Account: attr.Account, - Subject: attr.Subject, - Group: attr.Group, - } + al := &engine.TpAlias{Tpid: attr.TPid} + al.SetId(attr.AliasId) if tms, err := self.StorDb.GetTpAliases(al); err != nil { return utils.NewErrServerError(err) } else if len(tms) == 0 { @@ -84,7 +72,7 @@ func (self *ApierV1) GetTPAliasIds(attrs AttrGetTPAliasIds, reply *[]string) err if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_ALIASES, utils.TPDistinctIds{"tag"}, nil, &attrs.Paginator); err != nil { + if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_ALIASES, utils.TPDistinctIds{"`direction`", "`tenant`", "`category`", "`account`", "`subject`", "`group`"}, nil, &attrs.Paginator); err != nil { return utils.NewErrServerError(err) } else if ids == nil { return utils.ErrNotFound diff --git a/apier/v1/tplcrrules.go b/apier/v1/tplcrrules.go index b947c097d..5ab708619 100644 --- a/apier/v1/tplcrrules.go +++ b/apier/v1/tplcrrules.go @@ -24,7 +24,7 @@ import ( ) // Creates a new LcrRules profile within a tariff plan -func (self *ApierV1) SetTPLcrRules(attrs utils.TPLcrRules, reply *string) error { +func (self *ApierV1) SetTPLcrRule(attrs utils.TPLcrRules, reply *string) error { if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LcrRulesId", "Identifier", "Weight"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } @@ -37,16 +37,20 @@ func (self *ApierV1) SetTPLcrRules(attrs utils.TPLcrRules, reply *string) error } type AttrGetTPLcrRules struct { - TPid string // Tariff plan id - LcrId string // Lcr id + TPid string // Tariff plan id + LcrRuleId string // Lcr id } // Queries specific LcrRules profile on tariff plan -func (self *ApierV1) GetTPLcrRules(attrs AttrGetTPLcrRules, reply *utils.TPLcrRules) error { - if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LcrId"}); len(missing) != 0 { //Params missing +func (self *ApierV1) GetTPLcrRule(attr AttrGetTPLcrRules, reply *utils.TPLcrRules) error { + if missing := utils.MissingStructFields(&attr, []string{"TPid", "LcrRuleId"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if lcrs, err := self.StorDb.GetTpLCRs(attrs.TPid, attrs.LcrId); err != nil { + lcr := &engine.TpLcrRule{ + Tpid: attr.TPid, + } + lcr.SetLcrRuleId(attr.LcrRuleId) + if lcrs, err := self.StorDb.GetTpLCRs(lcr); err != nil { return utils.NewErrServerError(err) } else if len(lcrs) == 0 { return utils.ErrNotFound @@ -55,22 +59,22 @@ func (self *ApierV1) GetTPLcrRules(attrs AttrGetTPLcrRules, reply *utils.TPLcrRu if err != nil { return err } - *reply = *tmMap[attrs.LcrId] + *reply = *tmMap[attr.LcrRuleId] } return nil } -type AttrGetTPLcrActionIds struct { +type AttrGetTPLcrIds struct { TPid string // Tariff plan id utils.Paginator } // Queries LcrRules identities on specific tariff plan. -func (self *ApierV1) GetTPLcrActionIds(attrs AttrGetTPLcrActionIds, reply *[]string) error { +func (self *ApierV1) GetTPLcrRuleIds(attrs AttrGetTPLcrIds, reply *[]string) error { if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_LCRS, utils.TPDistinctIds{"tag"}, nil, &attrs.Paginator); err != nil { + if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_LCRS, utils.TPDistinctIds{"direction", "tenant", "category", "account", "subject"}, nil, &attrs.Paginator); err != nil { return utils.NewErrServerError(err) } else if ids == nil { return utils.ErrNotFound @@ -81,11 +85,11 @@ func (self *ApierV1) GetTPLcrActionIds(attrs AttrGetTPLcrActionIds, reply *[]str } // Removes specific LcrRules on Tariff plan -func (self *ApierV1) RemTPLcrRules(attrs AttrGetTPLcrRules, reply *string) error { +func (self *ApierV1) RemTPLcrRule(attrs AttrGetTPLcrRules, reply *string) error { if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LcrRulesId"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if err := self.StorDb.RemTpData(utils.TBL_TP_LCRS, attrs.TPid, attrs.LcrId); err != nil { + if err := self.StorDb.RemTpData(utils.TBL_TP_LCRS, attrs.TPid, attrs.LcrRuleId); err != nil { return utils.NewErrServerError(err) } else { *reply = "OK" diff --git a/apier/v1/tpusers.go b/apier/v1/tpusers.go index 8d84b8dd9..d150a04ea 100644 --- a/apier/v1/tpusers.go +++ b/apier/v1/tpusers.go @@ -37,9 +37,8 @@ func (self *ApierV1) SetTPUser(attrs utils.TPUsers, reply *string) error { } type AttrGetTPUser struct { - TPid string // Tariff plan id - Tenant string - UserName string + TPid string // Tariff plan id + UserId string } // Queries specific User on Tariff plan @@ -48,10 +47,9 @@ func (self *ApierV1) GetTPUser(attr AttrGetTPUser, reply *utils.TPUsers) error { return utils.NewErrMandatoryIeMissing(missing...) } usr := &engine.TpUser{ - Tpid: attr.TPid, - Tenant: attr.Tenant, - UserName: attr.UserName, + Tpid: attr.TPid, } + usr.SetId(attr.UserId) if tms, err := self.StorDb.GetTpUsers(usr); err != nil { return utils.NewErrServerError(err) } else if len(tms) == 0 { @@ -76,7 +74,7 @@ func (self *ApierV1) GetTPUserIds(attrs AttrGetTPUserIds, reply *[]string) error if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_USERS, utils.TPDistinctIds{"tag"}, nil, &attrs.Paginator); err != nil { + if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_USERS, utils.TPDistinctIds{"tenant", "user_name"}, nil, &attrs.Paginator); err != nil { return utils.NewErrServerError(err) } else if ids == nil { return utils.ErrNotFound diff --git a/data/docker/devel/Dockerfile b/data/docker/devel/Dockerfile index 33528e230..c9dbb3e1a 100644 --- a/data/docker/devel/Dockerfile +++ b/data/docker/devel/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get -y update && apt-get -y install git bzr mercurial redis-server mysql RUN useradd -c CGRateS -d /var/run/cgrates -s /bin/false -r cgrates # install golang -RUN wget -qO- https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz | tar xzf - -C /root/ +RUN wget -qO- https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz | tar xzf - -C /root/ #install oh-my-zsh RUN sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"; exit 0 diff --git a/engine/model_converters.go b/engine/model_converters.go index c91bd160b..c1f0a0f5e 100644 --- a/engine/model_converters.go +++ b/engine/model_converters.go @@ -138,14 +138,14 @@ func APItoModelRatingProfile(rpf *utils.TPRatingProfile) (result []TpRatingProfi } func APItoModelLcrRule(lcrs *utils.TPLcrRules) (result []TpLcrRule) { - for _, lcr := range lcrs.LcrRules { + for _, lcr := range lcrs.Rules { result = append(result, TpLcrRule{ Tpid: lcrs.TPid, - Direction: lcr.Direction, - Tenant: lcr.Tenant, - Category: lcr.Category, - Account: lcr.Account, - Subject: lcr.Subject, + Direction: lcrs.Direction, + Tenant: lcrs.Tenant, + Category: lcrs.Category, + Account: lcrs.Account, + Subject: lcrs.Subject, DestinationTag: lcr.DestinationId, RpCategory: lcr.RpCategory, Strategy: lcr.Strategy, @@ -154,7 +154,7 @@ func APItoModelLcrRule(lcrs *utils.TPLcrRules) (result []TpLcrRule) { Weight: lcr.Weight, }) } - if len(lcrs.LcrRules) == 0 { + if len(lcrs.Rules) == 0 { result = append(result, TpLcrRule{ Tpid: lcrs.TPid, }) diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 4796bb17f..87d44a0ee 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -774,16 +774,15 @@ func (tps TpLcrRules) GetLcrRules() (map[string]*utils.TPLcrRules, error) { var found bool if lcr, found = lcrs[tp.GetLcrRuleId()]; !found { lcr = &utils.TPLcrRules{ - LcrRulesId: tp.GetLcrRuleId(), + Direction: tp.Direction, + Tenant: tp.Tenant, + Category: tp.Category, + Account: tp.Account, + Subject: tp.Subject, } lcrs[tp.GetLcrRuleId()] = lcr } - lcr.LcrRules = append(lcr.LcrRules, &utils.TPLcrRule{ - Direction: tp.Direction, - Tenant: tp.Tenant, - Category: tp.Category, - Account: tp.Account, - Subject: tp.Subject, + lcr.Rules = append(lcr.Rules, &utils.TPLcrRule{ DestinationId: tp.DestinationTag, RpCategory: tp.RpCategory, Strategy: tp.Strategy, diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index bea90683f..3734958a4 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -322,28 +322,22 @@ func TestTPSharedGroupsAsExportSlice(t *testing.T) { //*in,cgrates.org,*any,EU_LANDLINE,LCR_STANDARD,*static,ivo;dan;rif,2012-01-01T00:00:00Z,10 func TestTPLcrRulesAsExportSlice(t *testing.T) { lcr := &utils.TPLcrRules{ - TPid: "TEST_TPID", - LcrRulesId: "TEST_LCR", - LcrRules: []*utils.TPLcrRule{ + TPid: "TEST_TPID", + Direction: "*in", + Tenant: "cgrates.org", + Category: "LCR_STANDARD", + Account: "*any", + Subject: "*any", + Rules: []*utils.TPLcrRule{ &utils.TPLcrRule{ - Direction: "*in", - Tenant: "cgrates.org", - Account: "*any", - Subject: "*any", DestinationId: "EU_LANDLINE", - Category: "LCR_STANDARD", Strategy: "*static", StrategyParams: "ivo;dan;rif", ActivationTime: "2012-01-01T00:00:00Z", Weight: 20.0}, //*in,cgrates.org,*any,*any,LCR_STANDARD,*lowest_cost,,2012-01-01T00:00:00Z,20 &utils.TPLcrRule{ - Direction: "*in", - Tenant: "cgrates.org", - Account: "*any", - Subject: "*any", DestinationId: "*any", - Category: "LCR_STANDARD", Strategy: "*lowest_cost", StrategyParams: "", ActivationTime: "2012-01-01T00:00:00Z", diff --git a/engine/models.go b/engine/models.go index 483a785a3..46b088798 100644 --- a/engine/models.go +++ b/engine/models.go @@ -139,10 +139,10 @@ func (lcr *TpLcrRule) SetLcrRuleId(id string) error { return fmt.Errorf("wrong LcrRule Id: %s", id) } lcr.Direction = ids[0] - lcr.Tenant = ids[2] - lcr.Category = ids[3] + lcr.Tenant = ids[1] + lcr.Category = ids[2] lcr.Account = ids[3] - lcr.Subject = ids[5] + lcr.Subject = ids[4] return nil } @@ -337,6 +337,16 @@ func (tu *TpUser) GetId() string { return utils.ConcatenatedKey(tu.Tenant, tu.UserName) } +func (tu *TpUser) SetId(id string) error { + vals := strings.Split(id, utils.CONCATENATED_KEY_SEP) + if len(vals) != 2 { + return utils.ErrInvalidKey + } + tu.Tenant = vals[0] + tu.UserName = vals[1] + return nil +} + type TpAlias struct { Id int64 Tpid string @@ -355,6 +365,20 @@ func (ta *TpAlias) TableName() string { return "tp_aliases" } +func (ta *TpAlias) SetId(id string) error { + vals := strings.Split(id, utils.CONCATENATED_KEY_SEP) + if len(vals) != 6 { + return utils.ErrInvalidKey + } + ta.Direction = vals[0] + ta.Tenant = vals[1] + ta.Category = vals[2] + ta.Account = vals[3] + ta.Subject = vals[4] + ta.Group = vals[5] + return nil +} + func (ta *TpAlias) GetId() string { return utils.ConcatenatedKey(ta.Direction, ta.Tenant, ta.Category, ta.Account, ta.Subject, ta.Group) } diff --git a/engine/storage_csv.go b/engine/storage_csv.go index 831afbb95..5d9e65ff6 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -261,7 +261,7 @@ func (csvs *CSVStorage) GetTpSharedGroups(tpid, tag string) ([]TpSharedGroup, er return tpSharedGroups, nil } -func (csvs *CSVStorage) GetTpLCRs(tpid, tag string) ([]TpLcrRule, error) { +func (csvs *CSVStorage) GetTpLCRs(filter *TpLcrRule) ([]TpLcrRule, error) { csvReader, fp, err := csvs.readerFunc(csvs.lcrFn, csvs.sep, getColumnCount(TpLcrRule{})) if err != nil { log.Print("Could not load LCR rules file: ", err) @@ -281,7 +281,9 @@ func (csvs *CSVStorage) GetTpLCRs(tpid, tag string) ([]TpLcrRule, error) { return nil, err } else { lcr := tpRate.(TpLcrRule) - lcr.Tpid = tpid + if filter != nil { + lcr.Tpid = filter.Tpid + } tpLCRs = append(tpLCRs, lcr) } } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 1afa47e72..320e441a7 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -125,10 +125,10 @@ type LoadReader interface { GetTpRatingProfiles(*TpRatingProfile) ([]TpRatingProfile, error) GetTpSharedGroups(string, string) ([]TpSharedGroup, error) GetTpCdrStats(string, string) ([]TpCdrstat, error) + GetTpLCRs(*TpLcrRule) ([]TpLcrRule, error) GetTpUsers(*TpUser) ([]TpUser, error) GetTpAliases(*TpAlias) ([]TpAlias, error) GetTpDerivedChargers(*TpDerivedCharger) ([]TpDerivedCharger, error) - GetTpLCRs(string, string) ([]TpLcrRule, error) GetTpActions(string, string) ([]TpAction, error) GetTpActionPlans(string, string) ([]TpActionPlan, error) GetTpActionTriggers(string, string) ([]TpActionTrigger, error) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 38d416dae..1571ebc83 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -426,23 +426,25 @@ func (self *SQLStorage) SetTpDerivedChargers(sgs []TpDerivedCharger) error { return nil } -func (self *SQLStorage) SetTpLCRs(sgs []TpLcrRule) error { - if len(sgs) == 0 { +func (self *SQLStorage) SetTpLCRs(lcrs []TpLcrRule) error { + if len(lcrs) == 0 { return nil //Nothing to set } m := make(map[string]bool) tx := self.db.Begin() - for _, lcr := range sgs { + for _, lcr := range lcrs { if found, _ := m[lcr.GetLcrRuleId()]; !found { m[lcr.GetLcrRuleId()] = true - tmpDc := &TpLcrRule{} - if err := tmpDc.SetLcrRuleId(lcr.GetLcrRuleId()); err != nil { - tx.Rollback() - return err - } - if err := tx.Where(tmpDc).Delete(TpLcrRule{}).Error; err != nil { + if err := tx.Where(&TpLcrRule{ + Tpid: lcr.Tpid, + Direction: lcr.Direction, + Tenant: lcr.Tenant, + Category: lcr.Category, + Account: lcr.Account, + Subject: lcr.Subject, + }).Delete(TpLcrRule{}).Error; err != nil { tx.Rollback() return err } @@ -1198,12 +1200,25 @@ func (self *SQLStorage) GetTpSharedGroups(tpid, tag string) ([]TpSharedGroup, er } -func (self *SQLStorage) GetTpLCRs(tpid, tag string) ([]TpLcrRule, error) { +func (self *SQLStorage) GetTpLCRs(filter *TpLcrRule) ([]TpLcrRule, error) { var tpLcrRule []TpLcrRule - q := self.db.Where("tpid = ?", tpid) - if len(tag) != 0 { - q = q.Where("tag = ?", tag) + q := self.db.Where("`tpid` = ?", filter.Tpid) + if len(filter.Direction) != 0 { + q = q.Where("`direction` = ?", filter.Direction) } + if len(filter.Tenant) != 0 { + q = q.Where("`tenant` = ?", filter.Tenant) + } + if len(filter.Category) != 0 { + q = q.Where("`category` = ?", filter.Category) + } + if len(filter.Account) != 0 { + q = q.Where("`account` = ?", filter.Account) + } + if len(filter.Subject) != 0 { + q = q.Where("`subject` = ?", filter.Subject) + } + if err := q.Find(&tpLcrRule).Error; err != nil { return nil, err } diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 68906bd04..5a5036591 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -412,7 +412,7 @@ func (tpr *TpReader) LoadSharedGroups() error { } func (tpr *TpReader) LoadLCRs() (err error) { - tps, err := tpr.lr.GetTpLCRs(tpr.tpid, "") + tps, err := tpr.lr.GetTpLCRs(&TpLcrRule{Tpid: tpr.tpid}) if err != nil { return err } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 395a6cdbf..390cc4f95 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -54,6 +54,7 @@ var fileHandlers = map[string]func(*TPCSVImporter, string) error{ utils.ACCOUNT_ACTIONS_CSV: (*TPCSVImporter).importAccountActions, utils.DERIVED_CHARGERS_CSV: (*TPCSVImporter).importDerivedChargers, utils.CDR_STATS_CSV: (*TPCSVImporter).importCdrStats, + utils.LCRS_CSV: (*TPCSVImporter).importLcrs, utils.USERS_CSV: (*TPCSVImporter).importUsers, utils.ALIASES_CSV: (*TPCSVImporter).importAliases, } @@ -301,6 +302,21 @@ func (self *TPCSVImporter) importCdrStats(fn string) error { return self.StorDb.SetTpCdrStats(tps) } +func (self *TPCSVImporter) importLcrs(fn string) error { + if self.Verbose { + log.Printf("Processing file: <%s> ", fn) + } + tps, err := self.csvr.GetTpLCRs(nil) + if err != nil { + return err + } + for i := 0; i < len(tps); i++ { + tps[i].Tpid = self.TPid + } + + return self.StorDb.SetTpLCRs(tps) +} + func (self *TPCSVImporter) importUsers(fn string) error { if self.Verbose { log.Printf("Processing file: <%s> ", fn) diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 6f36a3bb7..8351c99fa 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -302,17 +302,16 @@ type TPSharedGroup struct { } type TPLcrRules struct { - TPid string - LcrRulesId string - LcrRules []*TPLcrRule + TPid string + Direction string + Tenant string + Category string + Account string + Subject string + Rules []*TPLcrRule } type TPLcrRule struct { - Direction string - Tenant string - Category string - Account string - Subject string DestinationId string RpCategory string Strategy string