From 8668df8d4944bad13d037f16e1911e2cc07deb6d Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 8 Jul 2015 20:08:04 +0300 Subject: [PATCH] added loaders for user data --- apier/v1/apier.go | 3 +- cmd/cgr-loader/cgr-loader.go | 3 +- .../mysql/create_tariffplan_tables.sql | 17 ++++++++ .../postgres/create_tariffplan_tables.sql | 17 ++++++++ data/tariffplans/tutorial/User.csv | 4 ++ engine/libtest.go | 3 +- engine/loader_csv_test.go | 29 ++++++++++++- engine/loader_local_test.go | 6 ++- engine/model_helpers.go | 20 +++++++++ engine/models.go | 13 ++++++ engine/storage_csv.go | 40 +++++++++++++++--- engine/storage_interface.go | 5 +++ engine/storage_map.go | 22 ++++++++++ engine/storage_redis.go | 20 +++++++++ engine/storage_sql.go | 41 +++++++++++++++++++ engine/tp_reader.go | 41 +++++++++++++++++++ engine/tpimporter_csv.go | 19 ++++++++- {users => engine}/users.go | 2 +- {users => engine}/users_test.go | 2 +- general_tests/acntacts_test.go | 3 +- general_tests/costs1_test.go | 2 +- general_tests/datachrg1_test.go | 2 +- general_tests/ddazmbl1_test.go | 3 +- general_tests/ddazmbl2_test.go | 3 +- general_tests/ddazmbl3_test.go | 3 +- general_tests/smschrg1_test.go | 2 +- utils/consts.go | 2 + 27 files changed, 306 insertions(+), 21 deletions(-) create mode 100644 data/tariffplans/tutorial/User.csv rename {users => engine}/users.go (99%) rename {users => engine}/users_test.go (99%) diff --git a/apier/v1/apier.go b/apier/v1/apier.go index cf18d59ba..9a1e8e739 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -1015,7 +1015,8 @@ func (self *ApierV1) LoadTariffPlanFromFolder(attrs utils.AttrLoadTpFromFolder, path.Join(attrs.FolderPath, utils.ACTION_TRIGGERS_CSV), path.Join(attrs.FolderPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(attrs.FolderPath, utils.DERIVED_CHARGERS_CSV), - path.Join(attrs.FolderPath, utils.CDR_STATS_CSV)), "") + path.Join(attrs.FolderPath, utils.CDR_STATS_CSV), + path.Join(attrs.FolderPath, utils.USERS_CSV)), "") if err := loader.LoadAll(); err != nil { return utils.NewErrServerError(err) } diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go index 9148301ed..8aa558c7e 100644 --- a/cmd/cgr-loader/cgr-loader.go +++ b/cmd/cgr-loader/cgr-loader.go @@ -154,7 +154,8 @@ func main() { path.Join(*dataPath, utils.ACTION_TRIGGERS_CSV), path.Join(*dataPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(*dataPath, utils.DERIVED_CHARGERS_CSV), - path.Join(*dataPath, utils.CDR_STATS_CSV)) + path.Join(*dataPath, utils.CDR_STATS_CSV), + path.Join(*dataPath, utils.USERS_CSV)) } tpReader := engine.NewTpReader(ratingDb, accountDb, loader, *tpid) err = tpReader.LoadAll() diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 5d515dccd..c458b4832 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -335,3 +335,20 @@ CREATE TABLE tp_cdrstats ( PRIMARY KEY (`id`), KEY `tpid` (`tpid`) ); + + -- +-- Table structure for table `tp_cdrstats` +-- + +DROP TABLE IF EXISTS tp_cdrstats; +CREATE TABLE tp_cdrstats ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `tpid` varchar(64) NOT NULL, + `tenant` varchar(64) NOT NULL, + `user_name` varchar(64) NOT NULL, + `attribute` varchar(64) NOT NULL, + `value` varchar(64) NOT NULL, + `created_at` TIMESTAMP, + PRIMARY KEY (`id`), + KEY `tpid` (`tpid`) +); diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index 83c8880fa..7eea8e7ca 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -330,3 +330,20 @@ CREATE TABLE tp_cdrstats ( ); CREATE INDEX tpcdrstats_tpid_idx ON tp_cdrstats (tpid); CREATE INDEX tpcdrstats_idx ON tp_cdrstats (tpid,tag); + +-- +-- Table structure for table `tp_users` +-- + +DROP TABLE IF EXISTS tp_users; +CREATE TABLE tp_users ( + id SERIAL PRIMARY KEY, + tpid VARCHAR(64) NOT NULL, + tenant VARCHAR(64) NOT NULL, + user_name VARCHAR(64) NOT NULL, + attribute VARCHAR(64) NOT NULL, + `value` VARCHAR(64) NOT NULL, + created_at TIMESTAMP +); +CREATE INDEX tpusers_tpid_idx ON tp_users (tpid); +CREATE INDEX tpusers_idx ON tp_users (tpid,tenant,user_name); diff --git a/data/tariffplans/tutorial/User.csv b/data/tariffplans/tutorial/User.csv new file mode 100644 index 000000000..7ef421bb0 --- /dev/null +++ b/data/tariffplans/tutorial/User.csv @@ -0,0 +1,4 @@ +#Tenant[0],UserName[1],Attribute[2],Value[3] +cgrates.org,1001,test0,val0 +cgrates.org,1001,test1,val1 +cgrates.org,1002,another,value diff --git a/engine/libtest.go b/engine/libtest.go index f7e710a27..73a6f00bd 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -105,7 +105,8 @@ func LoadTariffPlanFromFolder(tpPath string, ratingDb RatingStorage, accountingD path.Join(tpPath, utils.ACTION_TRIGGERS_CSV), path.Join(tpPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(tpPath, utils.DERIVED_CHARGERS_CSV), - path.Join(tpPath, utils.CDR_STATS_CSV)), "") + path.Join(tpPath, utils.CDR_STATS_CSV), + path.Join(tpPath, utils.USERS_CSV)), "") if err := loader.LoadAll(); err != nil { return utils.NewErrServerError(err) } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 37e07fb70..3f126ddbf 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -208,6 +208,12 @@ CDRST1,,,,ACD,,,,,,,,,,,,,,,,,,,,STANDARD_TRIGGER CDRST1,,,,ACC,,,,,,,,,,,,,,,,,,,, CDRST2,10,10m,,ASR,,,,,,,cgrates.org,call,,,,,,,,,,,, CDRST2,,,,ACD,,,,,,,,,,,,,,,,,,,, +` + users = ` +#Tenant[0],UserName[1],Attribute[2],Value[3] +cgrates.org,rif,test0,val0 +cgrates.org,rif,test1,val1 +cgrates.org,dan,another,value ` ) @@ -215,7 +221,7 @@ var csvr *TpReader func init() { csvr = NewTpReader(ratingStorage, accountingStorage, NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats), "") + sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") if err := csvr.LoadDestinations(); err != nil { log.Print("error in LoadDestinations:", err) } @@ -258,6 +264,9 @@ func init() { if err := csvr.LoadCdrStats(); err != nil { log.Print("error in LoadCdrStats:", err) } + if err := csvr.LoadUsers(); err != nil { + log.Print("error in LoadUsers:", err) + } csvr.WriteToDatabase(false, false) ratingStorage.CacheAll() } @@ -1104,3 +1113,21 @@ func TestLoadCdrStats(t *testing.T) { t.Errorf("Unexpected stats %+v", csvr.cdrStats[cdrStats1.Id]) } } + +func TestLoadUsers(t *testing.T) { + if len(csvr.users) != 2 { + t.Error("Failed to load users: ", csvr.users) + } + user1 := &UserProfile{ + Tenant: "cgrates.org", + UserName: "rif", + Profile: map[string]string{ + "test0": "val0", + "test1": "val1", + }, + } + + if !reflect.DeepEqual(csvr.users[user1.GetId()], user1) { + t.Errorf("Unexpected user %+v", csvr.users[user1.GetId()]) + } +} diff --git a/engine/loader_local_test.go b/engine/loader_local_test.go index a87769796..393832d0e 100644 --- a/engine/loader_local_test.go +++ b/engine/loader_local_test.go @@ -130,7 +130,8 @@ func TestLoadFromCSV(t *testing.T) { path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACTION_TRIGGERS_CSV), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACCOUNT_ACTIONS_CSV), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DERIVED_CHARGERS_CSV), - path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.CDR_STATS_CSV)), "") + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.CDR_STATS_CSV), + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.USERS_CSV)), "") if err = loader.LoadDestinations(); err != nil { t.Error("Failed loading destinations: ", err.Error()) @@ -165,6 +166,9 @@ func TestLoadFromCSV(t *testing.T) { if err = loader.LoadDerivedChargers(); err != nil { t.Error("Failed loading derived chargers: ", err.Error()) } + if err = loader.LoadUsers(); err != nil { + t.Error("Failed loading users: ", err.Error()) + } if err := loader.WriteToDatabase(true, false); err != nil { t.Error("Could not write data into ratingDb: ", err.Error()) } diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 823f21185..f3ee84554 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -714,3 +714,23 @@ func ValueOrDefault(val string, deflt string) string { } return val } + +type TpUsers []TpUser + +func (tps TpUsers) GetUsers() (map[string]*UserProfile, error) { + users := make(map[string]*UserProfile) + for _, tp := range tps { + var user *UserProfile + var found bool + if user, found = users[tp.GetId()]; !found { + user = &UserProfile{ + Tenant: tp.Tenant, + UserName: tp.UserName, + Profile: make(map[string]string), + } + users[tp.GetId()] = user + } + user.Profile[tp.Attribute] = tp.Value + } + return users, nil +} diff --git a/engine/models.go b/engine/models.go index 6280db899..1cc0c16dc 100644 --- a/engine/models.go +++ b/engine/models.go @@ -320,6 +320,19 @@ type TpCdrstat struct { CreatedAt time.Time } +type TpUser struct { + Id int64 + Tpid string + Tenant string `index:"0" re:""` + UserName string `index:"1" re:""` + Attribute string `index:"2" re:""` + Value string `index:"3" re:""` +} + +func (tu *TpUser) GetId() string { + return utils.ConcatenatedKey(tu.Tenant, tu.UserName) +} + type TblCdrsPrimary struct { Id int64 Cgrid string diff --git a/engine/storage_csv.go b/engine/storage_csv.go index 371fbf9b7..661110bf9 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -15,26 +15,26 @@ type CSVStorage struct { readerFunc func(string, rune, int) (*csv.Reader, *os.File, error) // file names destinationsFn, ratesFn, destinationratesFn, timingsFn, destinationratetimingsFn, ratingprofilesFn, - sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn string + sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string } func NewFileCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, - actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn string) *CSVStorage { + actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string) *CSVStorage { c := new(CSVStorage) c.sep = sep c.readerFunc = openFileCSVStorage c.destinationsFn, c.timingsFn, c.ratesFn, c.destinationratesFn, c.destinationratetimingsFn, c.ratingprofilesFn, - c.sharedgroupsFn, c.lcrFn, c.actionsFn, c.actiontimingsFn, c.actiontriggersFn, c.accountactionsFn, c.derivedChargersFn, c.cdrStatsFn = destinationsFn, timingsFn, - ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn + c.sharedgroupsFn, c.lcrFn, c.actionsFn, c.actiontimingsFn, c.actiontriggersFn, c.accountactionsFn, c.derivedChargersFn, c.cdrStatsFn, c.usersFn = destinationsFn, timingsFn, + ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn return c } func NewStringCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, - actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn string) *CSVStorage { + actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string) *CSVStorage { c := NewFileCSVStorage(sep, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, - ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn) + ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn) c.readerFunc = openStringCSVStorage return c } @@ -458,6 +458,34 @@ func (csvs *CSVStorage) GetTpCdrStats(tpid, tag string) ([]TpCdrstat, error) { return tpCdrStats, nil } +func (csvs *CSVStorage) GetTpUsers(filter *TpUser) ([]TpUser, error) { + csvReader, fp, err := csvs.readerFunc(csvs.usersFn, csvs.sep, getColumnCount(TpUser{})) + if err != nil { + log.Print("Could not load users file: ", err) + // allow writing of the other values + return nil, nil + } + if fp != nil { + defer fp.Close() + } + var tpUsers []TpUser + for record, err := csvReader.Read(); err != io.EOF; record, err = csvReader.Read() { + if err != nil { + log.Print("bad line in users csv: ", err) + return nil, err + } + if tpUser, err := csvLoad(TpUser{}, record); err != nil { + log.Print("error loading user: ", err) + return nil, err + } else { + u := tpUser.(TpUser) + u.Tpid = filter.Tpid + tpUsers = append(tpUsers, u) + } + } + return tpUsers, nil +} + func (csvs *CSVStorage) GetTpIds() ([]string, error) { return nil, utils.ErrNotImplemented } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 9e7a0a0b1..1e43eca3b 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -71,6 +71,9 @@ type RatingStorage interface { SetAccAlias(string, string) error RemoveAccAliases([]*TenantAccount) error GetAccountAliases(string, string, bool) ([]string, error) + SetUser(*UserProfile) error + GetUser(string) (*UserProfile, error) + RemoveUser(string) error } type AccountingStorage interface { @@ -119,6 +122,7 @@ type LoadReader interface { GetTpRatingProfiles(*TpRatingProfile) ([]TpRatingProfile, error) GetTpSharedGroups(string, string) ([]TpSharedGroup, error) GetTpCdrStats(string, string) ([]TpCdrstat, error) + GetTpUsers(*TpUser) ([]TpUser, error) GetTpDerivedChargers(*TpDerivedCharger) ([]TpDerivedCharger, error) GetTpLCRs(string, string) ([]TpLcrRule, error) GetTpActions(string, string) ([]TpAction, error) @@ -137,6 +141,7 @@ type LoadWriter interface { SetTpRatingProfiles([]TpRatingProfile) error SetTpSharedGroups([]TpSharedGroup) error SetTpCdrStats([]TpCdrstat) error + SetTpUsers([]TpUser) error SetTpDerivedChargers([]TpDerivedCharger) error SetTpLCRs([]TpLcrRule) error SetTpActions([]TpAction) error diff --git a/engine/storage_map.go b/engine/storage_map.go index 61d98e145..339054110 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -584,6 +584,28 @@ func (ms *MapStorage) RemoveSubscriber(key string) (err error) { return } +func (ms *MapStorage) SetUser(up *UserProfile) error { + result, err := ms.ms.Marshal(up) + if err != nil { + return err + } + ms.dict[utils.USERS_PREFIX+up.GetId()] = result + return nil +} +func (ms *MapStorage) GetUser(key string) (up *UserProfile, err error) { + up = &UserProfile{} + if values, ok := ms.dict[utils.USERS_PREFIX+key]; ok { + err = ms.ms.Unmarshal(values, &up) + } else { + return nil, utils.ErrNotFound + } + return +} +func (ms *MapStorage) RemoveUser(key string) error { + delete(ms.dict, utils.USERS_PREFIX+key) + return nil +} + func (ms *MapStorage) GetActionPlans(key string) (ats ActionPlans, err error) { if values, ok := ms.dict[utils.ACTION_TIMING_PREFIX+key]; ok { err = ms.ms.Unmarshal(values, &ats) diff --git a/engine/storage_redis.go b/engine/storage_redis.go index c53a0c679..8f9704d9d 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -707,6 +707,15 @@ func (rs *RedisStorage) GetSubscribers() (result map[string]*SubscriberData, err return } +func (rs *RedisStorage) GetUser(key string) (up *UserProfile, err error) { + var values []byte + if values, err = rs.db.Get(utils.USERS_PREFIX + key); err == nil { + up = &UserProfile{} + err = rs.ms.Unmarshal(values, &up) + } + return +} + func (rs *RedisStorage) SetSubscriber(key string, sub *SubscriberData) (err error) { result, err := rs.ms.Marshal(sub) rs.db.Set(utils.PUBSUB_SUBSCRIBERS_PREFIX+key, result) @@ -718,6 +727,17 @@ func (rs *RedisStorage) RemoveSubscriber(key string) (err error) { return } +func (rs *RedisStorage) SetUser(up *UserProfile) (err error) { + result, err := rs.ms.Marshal(up) + rs.db.Set(utils.USERS_PREFIX+up.GetId(), result) + return +} + +func (rs *RedisStorage) RemoveUser(key string) (err error) { + rs.db.Del(utils.USERS_PREFIX + key) + return +} + func (rs *RedisStorage) GetActionPlans(key string) (ats ActionPlans, err error) { var values []byte if values, err = rs.db.Get(utils.ACTION_TIMING_PREFIX + key); err == nil { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index b422d1238..467df30e8 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -1311,3 +1311,44 @@ func (self *SQLStorage) GetTpCdrStats(tpid, tag string) ([]TpCdrstat, error) { return tpCdrStats, nil } + +func (self *SQLStorage) SetTpUsers(users []TpUser) error { + if len(users) == 0 { + return nil + } + m := make(map[string]bool) + + tx := self.db.Begin() + for _, user := range users { + if found, _ := m[user.GetId()]; !found { + m[user.GetId()] = true + if err := tx.Where(&TpUser{Tpid: user.Tpid, Tenant: user.Tenant, UserName: user.UserName}).Delete(TpUser{}).Error; err != nil { + tx.Rollback() + return err + } + } + save := tx.Save(&user) + if save.Error != nil { + tx.Rollback() + return save.Error + } + } + tx.Commit() + return nil +} + +func (self *SQLStorage) GetTpUsers(filter *TpUser) ([]TpUser, error) { + var tpUsers []TpUser + q := self.db.Where("tpid = ?", filter.Tpid) + if len(filter.Tenant) != 0 { + q = q.Where("tenant = ?", filter.Tenant) + } + if len(filter.UserName) != 0 { + q = q.Where("user_name = ?", filter.UserName) + } + if err := q.Find(&tpUsers).Error; err != nil { + return nil, err + } + + return tpUsers, nil +} diff --git a/engine/tp_reader.go b/engine/tp_reader.go index d20cb7420..7e7fa828c 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -33,6 +33,7 @@ type TpReader struct { lcrs map[string]*LCR derivedChargers map[string]utils.DerivedChargers cdrStats map[string]*CdrStats + users map[string]*UserProfile } func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid string) *TpReader { @@ -56,6 +57,7 @@ func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid str accAliases: make(map[string]string), accountActions: make(map[string]*Account), cdrStats: make(map[string]*CdrStats), + users: make(map[string]*UserProfile), derivedChargers: make(map[string]utils.DerivedChargers), } //add *any and *asap timing tag (in case of no timings file) @@ -1050,6 +1052,30 @@ func (tpr *TpReader) LoadCdrStats() error { return tpr.LoadCdrStatsFiltered("", false) } +func (tpr *TpReader) LoadUsersFiltered(filter *TpUser) (bool, error) { + tpUsers, err := tpr.lr.GetTpUsers(filter) + + user := &UserProfile{ + Tenant: filter.Tenant, + UserName: filter.UserName, + Profile: make(map[string]string), + } + for _, tpUser := range tpUsers { + user.Profile[tpUser.Attribute] = tpUser.Value + } + tpr.ratingStorage.SetUser(user) + return len(tpUsers) > 0, err +} + +func (tpr *TpReader) LoadUsers() error { + tps, err := tpr.lr.GetTpUsers(&TpUser{Tpid: tpr.tpid}) + if err != nil { + return err + } + tpr.users, err = TpUsers(tps).GetUsers() + return err +} + func (tpr *TpReader) LoadAll() error { var err error if err = tpr.LoadDestinations(); err != nil { @@ -1094,6 +1120,9 @@ func (tpr *TpReader) LoadAll() error { if err = tpr.LoadCdrStats(); err != nil { return err } + if err = tpr.LoadUsers(); err != nil { + return err + } return nil } @@ -1273,6 +1302,18 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose bool) (err error) { log.Print("\t", sq.Id) } } + if verbose { + log.Print("Users:") + } + for _, u := range tpr.users { + err = tpr.ratingStorage.SetUser(u) + if err != nil { + return err + } + if verbose { + log.Print("\t", u.GetId()) + } + } return } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 0bc2b3c5f..565681eb0 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.USERS_CSV: (*TPCSVImporter).importUsers, } func (self *TPCSVImporter) Run() error { @@ -71,7 +72,8 @@ func (self *TPCSVImporter) Run() error { path.Join(self.DirPath, utils.ACTION_TRIGGERS_CSV), path.Join(self.DirPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(self.DirPath, utils.DERIVED_CHARGERS_CSV), - path.Join(self.DirPath, utils.CDR_STATS_CSV)) + path.Join(self.DirPath, utils.CDR_STATS_CSV), + path.Join(self.DirPath, utils.USERS_CSV)) files, _ := ioutil.ReadDir(self.DirPath) for _, f := range files { fHandler, hasName := fileHandlers[f.Name()] @@ -295,3 +297,18 @@ func (self *TPCSVImporter) importCdrStats(fn string) error { return self.StorDb.SetTpCdrStats(tps) } + +func (self *TPCSVImporter) importUsers(fn string) error { + if self.Verbose { + log.Printf("Processing file: <%s> ", fn) + } + tps, err := self.csvr.GetTpUsers(nil) + if err != nil { + return err + } + for i := 0; i < len(tps); i++ { + tps[i].Tpid = self.TPid + } + + return self.StorDb.SetTpUsers(tps) +} diff --git a/users/users.go b/engine/users.go similarity index 99% rename from users/users.go rename to engine/users.go index e477418e4..e92969c4f 100644 --- a/users/users.go +++ b/engine/users.go @@ -1,4 +1,4 @@ -package users +package engine import ( "strings" diff --git a/users/users_test.go b/engine/users_test.go similarity index 99% rename from users/users_test.go rename to engine/users_test.go index 09bd6de81..4eb67babc 100644 --- a/users/users_test.go +++ b/engine/users_test.go @@ -1,4 +1,4 @@ -package users +package engine import ( "testing" diff --git a/general_tests/acntacts_test.go b/general_tests/acntacts_test.go index bf4836b42..de7d646c7 100644 --- a/general_tests/acntacts_test.go +++ b/general_tests/acntacts_test.go @@ -52,8 +52,9 @@ ENABLE_ACNT,*enable_account,,,,,,,,,,,,,10` accountActions := `cgrates.org,1,*out,TOPUP10_AT,` derivedCharges := `` cdrStats := `` + users := `` csvr := engine.NewTpReader(ratingDbAcntActs, acntDbAcntActs, engine.NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats), "") + sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") if err := csvr.LoadAll(); err != nil { t.Fatal(err) } diff --git a/general_tests/costs1_test.go b/general_tests/costs1_test.go index b8c8701d3..f3127ad25 100644 --- a/general_tests/costs1_test.go +++ b/general_tests/costs1_test.go @@ -54,7 +54,7 @@ RP_SMS1,DR_SMS_1,ALWAYS,10` *out,cgrates.org,data,*any,2012-01-01T00:00:00Z,RP_DATA1,, *out,cgrates.org,sms,*any,2012-01-01T00:00:00Z,RP_SMS1,,` csvr := engine.NewTpReader(ratingDb, acntDb, engine.NewStringCSVStorage(',', dests, timings, rates, destinationRates, ratingPlans, ratingProfiles, - "", "", "", "", "", "", "", ""), "") + "", "", "", "", "", "", "", "", ""), "") if err := csvr.LoadTimings(); err != nil { t.Fatal(err) diff --git a/general_tests/datachrg1_test.go b/general_tests/datachrg1_test.go index b2ac3a2b0..c200bf661 100644 --- a/general_tests/datachrg1_test.go +++ b/general_tests/datachrg1_test.go @@ -45,7 +45,7 @@ DR_DATA_2,*any,RT_DATA_1c,*up,4,0,` RP_DATA1,DR_DATA_2,TM2,10` ratingProfiles := `*out,cgrates.org,data,*any,2012-01-01T00:00:00Z,RP_DATA1,,` csvr := engine.NewTpReader(ratingDb, acntDb, engine.NewStringCSVStorage(',', "", timings, rates, destinationRates, ratingPlans, ratingProfiles, - "", "", "", "", "", "", "", ""), "") + "", "", "", "", "", "", "", "", ""), "") if err := csvr.LoadTimings(); err != nil { t.Fatal(err) } diff --git a/general_tests/ddazmbl1_test.go b/general_tests/ddazmbl1_test.go index 50c7e3dd4..be8a38562 100644 --- a/general_tests/ddazmbl1_test.go +++ b/general_tests/ddazmbl1_test.go @@ -61,8 +61,9 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` accountActions := `cgrates.org,12344,*out,TOPUP10_AT,` derivedCharges := `` cdrStats := `` + users := `` csvr := engine.NewTpReader(ratingDb, acntDb, engine.NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats), "") + sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") if err := csvr.LoadDestinations(); err != nil { t.Fatal(err) } diff --git a/general_tests/ddazmbl2_test.go b/general_tests/ddazmbl2_test.go index e87dc61ca..29bd6f177 100644 --- a/general_tests/ddazmbl2_test.go +++ b/general_tests/ddazmbl2_test.go @@ -61,8 +61,9 @@ TOPUP10_AT,TOPUP10_AC1,ASAP,10` accountActions := `cgrates.org,12345,*out,TOPUP10_AT,` derivedCharges := `` cdrStats := `` + users := `` csvr := engine.NewTpReader(ratingDb2, acntDb2, engine.NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats), "") + sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") if err := csvr.LoadDestinations(); err != nil { t.Fatal(err) } diff --git a/general_tests/ddazmbl3_test.go b/general_tests/ddazmbl3_test.go index 6fc1f22f4..512176715 100644 --- a/general_tests/ddazmbl3_test.go +++ b/general_tests/ddazmbl3_test.go @@ -59,8 +59,9 @@ RP_UK,DR_UK_Mobile_BIG5,ALWAYS,10` accountActions := `cgrates.org,12346,*out,TOPUP10_AT,` derivedCharges := `` cdrStats := `` + users := `` csvr := engine.NewTpReader(ratingDb3, acntDb3, engine.NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats), "") + sharedGroups, lcrs, actions, actionPlans, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") if err := csvr.LoadDestinations(); err != nil { t.Fatal(err) } diff --git a/general_tests/smschrg1_test.go b/general_tests/smschrg1_test.go index 650f9dc15..e391d8b2e 100644 --- a/general_tests/smschrg1_test.go +++ b/general_tests/smschrg1_test.go @@ -41,7 +41,7 @@ func TestSMSLoadCsvTpSmsChrg1(t *testing.T) { ratingPlans := `RP_SMS1,DR_SMS_1,ALWAYS,10` ratingProfiles := `*out,cgrates.org,sms,*any,2012-01-01T00:00:00Z,RP_SMS1,,` csvr := engine.NewTpReader(ratingDb, acntDb, engine.NewStringCSVStorage(',', "", timings, rates, destinationRates, ratingPlans, ratingProfiles, - "", "", "", "", "", "", "", ""), "") + "", "", "", "", "", "", "", "", ""), "") if err := csvr.LoadTimings(); err != nil { t.Fatal(err) } diff --git a/utils/consts.go b/utils/consts.go index b54bae18e..96b7acbbe 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -77,6 +77,7 @@ const ( ACCOUNT_ACTIONS_CSV = "AccountActions.csv" DERIVED_CHARGERS_CSV = "DerivedChargers.csv" CDR_STATS_CSV = "CdrStats.csv" + USERS_CSV = "Users.csv" ROUNDING_UP = "*up" ROUNDING_MIDDLE = "*middle" ROUNDING_DOWN = "*down" @@ -167,6 +168,7 @@ const ( DERIVEDCHARGERS_PREFIX = "dcs_" CDR_STATS_QUEUE_PREFIX = "csq_" PUBSUB_SUBSCRIBERS_PREFIX = "pss_" + USERS_PREFIX = "usr_" CDR_STATS_PREFIX = "cst_" TEMP_DESTINATION_PREFIX = "tmp_" LOG_CALL_COST_PREFIX = "cco_"