From 5ddbfbfc514c0b13701c9500cce9fc2f7614853a Mon Sep 17 00:00:00 2001 From: TeoV Date: Wed, 11 Jul 2018 09:02:21 -0400 Subject: [PATCH] Add Charger in migrator and add API for TPCharger --- apier/v1/tpchargers.go | 90 +++++++++++++++++ .../mysql/create_tariffplan_tables.sql | 23 ++++- .../postgres/create_tariffplan_tables.sql | 20 ++++ engine/chargers_test.go | 3 +- engine/loader_csv_test.go | 29 +++++- engine/loader_it_test.go | 23 ++++- engine/storage_mongo_datadb.go | 18 ++-- engine/storage_sql.go | 20 ++-- engine/version.go | 2 + migrator/chargers.go | 81 +++++++++++++++ migrator/chargers_it_test.go | 21 ++++ migrator/migrator.go | 4 + migrator/tp_chargers.go | 90 +++++++++++++++++ utils/consts.go | 99 ++++++++++--------- 14 files changed, 457 insertions(+), 66 deletions(-) create mode 100755 apier/v1/tpchargers.go create mode 100755 migrator/chargers.go create mode 100755 migrator/chargers_it_test.go create mode 100755 migrator/tp_chargers.go diff --git a/apier/v1/tpchargers.go b/apier/v1/tpchargers.go new file mode 100755 index 000000000..5b321776b --- /dev/null +++ b/apier/v1/tpchargers.go @@ -0,0 +1,90 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package v1 + +import ( + "github.com/cgrates/cgrates/utils" +) + +// Creates a new ChargerProfile within a tariff plan +func (self *ApierV1) SetTPCharger(attr utils.TPChargerProfile, reply *string) error { + if missing := utils.MissingStructFields(&attr, []string{"TPid", "Tenant", "ID"}); len(missing) != 0 { + return utils.NewErrMandatoryIeMissing(missing...) + } + if err := self.StorDb.SetTPChargers([]*utils.TPChargerProfile{&attr}); err != nil { + return utils.APIErrorHandler(err) + } + *reply = utils.OK + return nil +} + +type AttrGetTPCharger struct { + TPid string // Tariff plan id + ID string +} + +// Queries specific ChargerProfile on Tariff plan +func (self *ApierV1) GetTPCharger(attr AttrGetTPCharger, reply *utils.TPChargerProfile) error { + if missing := utils.MissingStructFields(&attr, []string{"TPid", "ID"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if rls, err := self.StorDb.GetTPChargers(attr.TPid, attr.ID); err != nil { + if err.Error() != utils.ErrNotFound.Error() { + err = utils.NewErrServerError(err) + } + return err + } else { + *reply = *rls[0] + } + return nil +} + +type AttrGetTPChargerIds struct { + TPid string // Tariff plan id + utils.Paginator +} + +// Queries Resource identities on specific tariff plan. +func (self *ApierV1) GetTPChargerIDs(attrs AttrGetTPChargerIds, 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.TBLTPChargers, utils.TPDistinctIds{"id"}, nil, &attrs.Paginator); err != nil { + if err.Error() != utils.ErrNotFound.Error() { + err = utils.NewErrServerError(err) + } + return err + } else { + *reply = ids + } + return nil +} + +// Removes specific Resource on Tariff plan +func (self *ApierV1) RemTPCharger(attrs AttrGetTPCharger, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "ID"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if err := self.StorDb.RemTpData(utils.TBLTPChargers, attrs.TPid, map[string]string{"id": attrs.ID}); err != nil { + return utils.NewErrServerError(err) + } else { + *reply = utils.OK + } + return nil +} diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 5d4832193..f6e3fc8c4 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -525,7 +525,6 @@ CREATE TABLE tp_suppliers ( -- Table structure for table `tp_attributes` -- - DROP TABLE IF EXISTS tp_attributes; CREATE TABLE tp_attributes ( `pk` int(11) NOT NULL AUTO_INCREMENT, @@ -548,9 +547,29 @@ CREATE TABLE tp_attributes ( ); -- --- Table structure for table `versions` +-- Table structure for table `tp_chargers` -- +DROP TABLE IF EXISTS tp_chargers; +CREATE TABLE tp_chargers ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `tpid` varchar(64) NOT NULL, + `tenant` varchar(64) NOT NULL, + `id` varchar(64) NOT NULL, + `filter_ids` varchar(64) NOT NULL, + `activation_interval` varchar(64) NOT NULL, + `run_id` varchar(64) NOT NULL, + `attribute_ids` varchar(64) NOT NULL, + `created_at` TIMESTAMP, + PRIMARY KEY (`pk`), + KEY `tpid` (`tpid`), + UNIQUE KEY `unique_tp_chargers` (`tpid`,`tenant`, + `id`,`filter_ids`,`run_id`,`attribute_ids`) +); + +-- +-- Table structure for table `versions` +-- DROP TABLE IF EXISTS versions; CREATE TABLE versions ( diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index 269db7171..bcb5f2c04 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -536,6 +536,26 @@ CREATE INDEX tp_suppliers_unique ON tp_suppliers ("tpid", "tenant", "id", CREATE INDEX tp_attributes_unique ON tp_attributes ("tpid", "tenant", "id", "filter_ids","field_name","initial","substitute"); + -- + -- Table structure for table `tp_chargers` + -- + + DROP TABLE IF EXISTS tp_chargers; + CREATE TABLE tp_chargers ( + "pk" SERIAL PRIMARY KEY, + "tpid" varchar(64) NOT NULL, + "tenant"varchar(64) NOT NULL, + "id" varchar(64) NOT NULL, + "filter_ids" varchar(64) NOT NULL, + "activation_interval" varchar(64) NOT NULL, + "run_id" varchar(64) NOT NULL, + "attribute_ids" varchar(64) NOT NULL, + "weight" decimal(8,2) NOT NULL, + "created_at" TIMESTAMP WITH TIME ZONE + ); + CREATE INDEX tp_chargers_ids ON tp_chargers (tpid); + CREATE INDEX tp_chargers_unique ON tp_chargers ("tpid", "tenant", "id", + "filter_ids","run_id","attribute_ids"); -- -- Table structure for table `versions` diff --git a/engine/chargers_test.go b/engine/chargers_test.go index 5134a5385..01c48f758 100755 --- a/engine/chargers_test.go +++ b/engine/chargers_test.go @@ -19,7 +19,7 @@ package engine import ( // "reflect" - // "testing" + "testing" // "time" "github.com/cgrates/cgrates/config" @@ -38,7 +38,6 @@ func TestChargerPopulateChargerService(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - chargerSrv, err = NewChargerService(dmCharger, &FilterS{dm: dmAtr, cfg: defaultCfg}, nil, defaultCfg) if err != nil { diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 125a345af..98e8e8ca7 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -304,7 +304,8 @@ cgrates.org,ALS1,con1,FLTR_1,2014-07-29T15:00:00Z,Field1,Initial1,Sub1,true,20 cgrates.org,ALS1,con2;con3,,,Field2,Initial2,Sub2,false, ` chargerProfiles = ` - +#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight +cgrates.org,Charger1,*string:Account:1001,2014-07-29T15:00:00Z,*rated,ATTR_1001_SIMPLEAUTH,20 ` ) @@ -381,6 +382,9 @@ func init() { if err := csvr.LoadAttributeProfiles(); err != nil { log.Print("error in LoadAttributeProfiles:", err) } + if err := csvr.LoadChargerProfiles(); err != nil { + log.Print("error in LoadChargerProfiles:", err) + } csvr.WriteToDatabase(false, false, false) Cache.Clear(nil) //dm.LoadDataDBCache(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) @@ -1768,6 +1772,29 @@ func TestLoadAttributeProfiles(t *testing.T) { } } +func TestLoadChargerProfiles(t *testing.T) { + eChargerProfiles := map[utils.TenantID]*utils.TPChargerProfile{ + utils.TenantID{Tenant: "cgrates.org", ID: "Charger1"}: &utils.TPChargerProfile{ + TPid: testTPID, + Tenant: "cgrates.org", + ID: "Charger1", + FilterIDs: []string{"*string:Account:1001"}, + ActivationInterval: &utils.TPActivationInterval{ + ActivationTime: "2014-07-29T15:00:00Z", + }, + RunID: "*rated", + AttributeIDs: []string{"ATTR_1001_SIMPLEAUTH"}, + Weight: 20, + }, + } + cppKey := utils.TenantID{Tenant: "cgrates.org", ID: "Charger1"} + if len(csvr.chargerProfiles) != len(eChargerProfiles) { + t.Errorf("Failed to load chargerProfiles: %s", utils.ToIJSON(csvr.chargerProfiles)) + } else if !reflect.DeepEqual(eChargerProfiles[cppKey], csvr.chargerProfiles[cppKey]) { + t.Errorf("Expecting: %+v, received: %+v", eChargerProfiles[cppKey], csvr.chargerProfiles[cppKey]) + } +} + func TestLoadResource(t *testing.T) { eResources := []*utils.TenantID{ &utils.TenantID{ diff --git a/engine/loader_it_test.go b/engine/loader_it_test.go index c0963ce35..ad073fa53 100644 --- a/engine/loader_it_test.go +++ b/engine/loader_it_test.go @@ -110,6 +110,7 @@ func TestLoaderITRemoveLoad(t *testing.T) { path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.FiltersCsv), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.SuppliersCsv), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.AttributesCsv), + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ChargersCsv), ), "", "") if err = loader.LoadDestinations(); err != nil { @@ -172,6 +173,9 @@ func TestLoaderITRemoveLoad(t *testing.T) { if err = loader.LoadAttributeProfiles(); err != nil { t.Error("Failed loading Alias profiles: ", err.Error()) } + if err = loader.LoadChargerProfiles(); err != nil { + t.Error("Failed loading Charger profiles: ", err.Error()) + } if err := loader.WriteToDatabase(true, false, false); err != nil { t.Error("Could not write data into dataDb: ", err.Error()) } @@ -211,6 +215,7 @@ func TestLoaderITLoadFromCSV(t *testing.T) { path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.FiltersCsv), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.SuppliersCsv), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.AttributesCsv), + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ChargersCsv), ), "", "") if err = loader.LoadDestinations(); err != nil { @@ -273,6 +278,9 @@ func TestLoaderITLoadFromCSV(t *testing.T) { if err = loader.LoadAttributeProfiles(); err != nil { t.Error("Failed loading Alias profiles: ", err.Error()) } + if err = loader.LoadChargerProfiles(); err != nil { + t.Error("Failed loading Alias profiles: ", err.Error()) + } if err := loader.WriteToDatabase(true, false, false); err != nil { t.Error("Could not write data into dataDb: ", err.Error()) } @@ -491,6 +499,20 @@ func TestLoaderITWriteToDatabase(t *testing.T) { } } + for tenatid, cpp := range loader.chargerProfiles { + rcv, err := loader.dm.GetChargerProfile(tenatid.Tenant, tenatid.ID, true, utils.NonTransactional) + if err != nil { + t.Errorf("Failed GetChargerProfile, tenant: %s, id: %s, error: %s ", cpp.Tenant, cpp.ID, err.Error()) + } + cp, err := APItoChargerProfile(cpp, "UTC") + if err != nil { + t.Error(err) + } + if !reflect.DeepEqual(cp, rcv) { + t.Errorf("Expecting: %v, received: %v", cp, rcv) + } + } + } // Imports data from csv files in tpScenario to storDb @@ -514,7 +536,6 @@ func TestLoaderITImportToStorDb(t *testing.T) { // Loads data from storDb into dataDb func TestLoaderITLoadFromStorDb(t *testing.T) { - loader := NewTpReader(dataDbStor.DataDB(), storDb, utils.TEST_SQL, "") if err := loader.LoadDestinations(); err != nil && err.Error() != utils.NotFoundCaps { t.Error("Failed loading destinations: ", err.Error()) diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 1d005d410..1de46383a 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -160,7 +160,8 @@ func (ms *MongoStorage) EnsureIndexes() (err error) { Background: false, // Build index in background and return immediately Sparse: false, // Only index documents containing the Key fields } - for _, col := range []string{colAct, colApl, colAAp, colAtr, colDcs, colRpl, colLcr, colDst, colRds, colAls, colUsr, colLht} { + for _, col := range []string{colAct, colApl, colAAp, colAtr, + colDcs, colRpl, colLcr, colDst, colRds, colAls, colUsr, colLht} { if err = db.C(col).EnsureIndex(idx); err != nil { return @@ -173,7 +174,8 @@ func (ms *MongoStorage) EnsureIndexes() (err error) { Background: false, Sparse: false, } - for _, col := range []string{colRsP, colRes, colSqs, colSqp, colTps, colThs, colSpp, colAttr, colFlt} { + for _, col := range []string{colRsP, colRes, colSqs, colSqp, + colTps, colThs, colSpp, colAttr, colFlt, colCpp} { if err = db.C(col).EnsureIndex(idx); err != nil { return } @@ -199,8 +201,10 @@ func (ms *MongoStorage) EnsureIndexes() (err error) { Background: false, Sparse: false, } - for _, col := range []string{utils.TBLTPTimings, utils.TBLTPDestinations, utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, - utils.TBLTPSharedGroups, utils.TBLTPCdrStats, utils.TBLTPActions, utils.TBLTPActionPlans, utils.TBLTPActionTriggers, + for _, col := range []string{utils.TBLTPTimings, utils.TBLTPDestinations, + utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, + utils.TBLTPSharedGroups, utils.TBLTPCdrStats, utils.TBLTPActions, + utils.TBLTPActionPlans, utils.TBLTPActionTriggers, utils.TBLTPStats, utils.TBLTPResources} { if err = db.C(col).EnsureIndex(idx); err != nil { return @@ -385,7 +389,8 @@ func (ms *MongoStorage) SelectDatabase(dbName string) (err error) { } func (ms *MongoStorage) RebuildReverseForPrefix(prefix string) (err error) { - if !utils.IsSliceMember([]string{utils.REVERSE_DESTINATION_PREFIX, utils.REVERSE_ALIASES_PREFIX, utils.AccountActionPlansPrefix}, prefix) { + if !utils.IsSliceMember([]string{utils.REVERSE_DESTINATION_PREFIX, + utils.REVERSE_ALIASES_PREFIX, utils.AccountActionPlansPrefix}, prefix) { return utils.ErrInvalidKey } colName, ok := ms.getColNameForPrefix(prefix) @@ -445,7 +450,8 @@ func (ms *MongoStorage) RebuildReverseForPrefix(prefix string) (err error) { } func (ms *MongoStorage) RemoveReverseForPrefix(prefix string) (err error) { - if !utils.IsSliceMember([]string{utils.REVERSE_DESTINATION_PREFIX, utils.REVERSE_ALIASES_PREFIX, utils.AccountActionPlansPrefix}, prefix) { + if !utils.IsSliceMember([]string{utils.REVERSE_DESTINATION_PREFIX, + utils.REVERSE_ALIASES_PREFIX, utils.AccountActionPlansPrefix}, prefix) { return utils.ErrInvalidKey } colName, ok := ms.getColNameForPrefix(prefix) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index b4eb15d29..1e5c630a5 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -108,7 +108,7 @@ func (self *SQLStorage) IsDBEmpty() (resp bool, err error) { utils.TBLTPActionTriggers, utils.TBLTPAccountActions, utils.TBLTPDerivedChargers, utils.TBLTPUsers, utils.TBLTPAliases, utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPThresholds, utils.TBLTPFilters, utils.SessionsCostsTBL, utils.CDRsTBL, utils.TBLTPActionPlans, - utils.TBLVersions, utils.TBLTPSuppliers, utils.TBLTPAttributes, + utils.TBLVersions, utils.TBLTPSuppliers, utils.TBLTPAttributes, utils.TBLTPChargers, } for _, tbl := range tbls { if self.db.HasTable(tbl) { @@ -127,7 +127,7 @@ func (self *SQLStorage) GetTpIds(colName string) ([]string, error) { qryStr := fmt.Sprintf(" (SELECT tpid FROM %s)", colName) if colName == "" { qryStr = fmt.Sprintf( - "(SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s)", + "(SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s)", utils.TBLTPTimings, utils.TBLTPDestinations, utils.TBLTPRates, @@ -149,7 +149,8 @@ func (self *SQLStorage) GetTpIds(colName string) ([]string, error) { utils.TBLTPFilters, utils.TBLTPActionPlans, utils.TBLTPSuppliers, - utils.TBLTPAttributes) + utils.TBLTPAttributes, + utils.TBLTPChargers) } rows, err = self.Db.Query(qryStr) if err != nil { @@ -174,8 +175,8 @@ func (self *SQLStorage) GetTpIds(colName string) ([]string, error) { } // ToDo: TEST -func (self *SQLStorage) GetTpTableIds(tpid, table string, distinct utils.TPDistinctIds, filters map[string]string, pagination *utils.Paginator) ([]string, error) { - +func (self *SQLStorage) GetTpTableIds(tpid, table string, distinct utils.TPDistinctIds, + filters map[string]string, pagination *utils.Paginator) ([]string, error) { qry := fmt.Sprintf("SELECT DISTINCT %s FROM %s where tpid='%s'", distinct, table, tpid) for key, value := range filters { if key != "" && value != "" { @@ -236,10 +237,11 @@ func (self *SQLStorage) RemTpData(table, tpid string, args map[string]string) er if len(table) == 0 { // Remove tpid out of all tables for _, tblName := range []string{utils.TBLTPTimings, utils.TBLTPDestinations, utils.TBLTPRates, - utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, utils.TBLTPRateProfiles, utils.TBLTPSharedGroups, - utils.TBLTPCdrStats, utils.TBLTPLcrs, utils.TBLTPActions, utils.TBLTPActionPlans, utils.TBLTPActionTriggers, - utils.TBLTPAccountActions, utils.TBLTPDerivedChargers, utils.TBLTPAliases, utils.TBLTPUsers, - utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPFilters, utils.TBLTPSuppliers, utils.TBLTPAttributes} { + utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, utils.TBLTPRateProfiles, + utils.TBLTPSharedGroups, utils.TBLTPCdrStats, utils.TBLTPLcrs, utils.TBLTPActions, + utils.TBLTPActionPlans, utils.TBLTPActionTriggers, utils.TBLTPAccountActions, + utils.TBLTPDerivedChargers, utils.TBLTPAliases, utils.TBLTPUsers, utils.TBLTPResources, + utils.TBLTPStats, utils.TBLTPFilters, utils.TBLTPSuppliers, utils.TBLTPAttributes, utils.TBLTPChargers} { if err := tx.Table(tblName).Where("tpid = ?", tpid).Delete(nil).Error; err != nil { tx.Rollback() return err diff --git a/engine/version.go b/engine/version.go index 1b1e70f7c..cfe963bbf 100644 --- a/engine/version.go +++ b/engine/version.go @@ -140,6 +140,7 @@ func CurrentDataDBVersions() Versions { utils.LCR: 1, utils.RatingPlan: 1, utils.RatingProfile: 1, + utils.Chargers: 1, } } @@ -172,6 +173,7 @@ func CurrentStorDBVersions() Versions { utils.TpDestinations: 1, utils.TpRatingPlan: 1, utils.TpRatingProfile: 1, + utils.TpChargers: 1, } } diff --git a/migrator/chargers.go b/migrator/chargers.go new file mode 100755 index 000000000..7cb276727 --- /dev/null +++ b/migrator/chargers.go @@ -0,0 +1,81 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package migrator + +import ( + "fmt" + "strings" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func (m *Migrator) migrateCurrentCharger() (err error) { + var ids []string + tenant := config.CgrConfig().DefaultTenant + ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.ChargerProfilePrefix) + if err != nil { + return err + } + for _, id := range ids { + idg := strings.TrimPrefix(id, utils.ChargerProfilePrefix+tenant+":") + cpp, err := m.dmIN.DataManager().GetChargerProfile(tenant, idg, true, utils.NonTransactional) + if err != nil { + return err + } + if cpp != nil { + if m.dryRun != true { + if err := m.dmOut.DataManager().SetChargerProfile(cpp, true); err != nil { + return err + } + m.stats[utils.Chargers] += 1 + } + } + } + return +} + +func (m *Migrator) migrateChargers() (err error) { + var vrs engine.Versions + current := engine.CurrentDataDBVersions() + vrs, err = m.dmOut.DataManager().DataDB().GetVersions("") + if err != nil { + return utils.NewCGRError(utils.Migrator, + utils.ServerErrorCaps, + err.Error(), + fmt.Sprintf("error: <%s> when querying oldDataDB for versions", err.Error())) + } else if len(vrs) == 0 { + return utils.NewCGRError(utils.Migrator, + utils.MandatoryIEMissingCaps, + utils.UndefinedVersion, + "version number is not defined for ChargerProfile model") + } + switch vrs[utils.Chargers] { + case current[utils.Chargers]: + if m.sameDataDB { + return + } + if err := m.migrateCurrentCharger(); err != nil { + return err + } + return + } + return +} diff --git a/migrator/chargers_it_test.go b/migrator/chargers_it_test.go new file mode 100755 index 000000000..b27cf33cc --- /dev/null +++ b/migrator/chargers_it_test.go @@ -0,0 +1,21 @@ +// +build integration + +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package migrator diff --git a/migrator/migrator.go b/migrator/migrator.go index 18addea64..e21aa6e89 100755 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -140,6 +140,8 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) { err = m.migrateDerivedChargers() case utils.MetaSuppliers: err = m.migrateSupplierProfiles() + case utils.MetaChargers: + err = m.migrateChargers() //TPs case utils.MetaTpRatingPlans: err = m.migrateTPratingplans() @@ -181,6 +183,8 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) { err = m.migrateTPcdrstats() case utils.MetaTpDestinations: err = m.migrateTPDestinations() + case utils.MetaTpChargers: + err = m.migrateTPChargers() //DATADB ALL case utils.MetaDataDB: if err := m.migrateAccounts(); err != nil { diff --git a/migrator/tp_chargers.go b/migrator/tp_chargers.go new file mode 100755 index 000000000..bcab412ab --- /dev/null +++ b/migrator/tp_chargers.go @@ -0,0 +1,90 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package migrator + +import ( + "fmt" + + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func (m *Migrator) migrateCurrentTPChargers() (err error) { + tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPChargers) + if err != nil { + return err + } + + for _, tpid := range tpids { + ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPChargers, + utils.TPDistinctIds{"id"}, map[string]string{}, nil) + if err != nil { + return err + } + for _, id := range ids { + chargers, err := m.storDBIn.StorDB().GetTPChargers(tpid, id) + if err != nil { + return err + } + if chargers != nil { + if m.dryRun != true { + if err := m.storDBOut.StorDB().SetTPChargers(chargers); err != nil { + return err + } + for _, charger := range chargers { + if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPChargers, charger.TPid, + map[string]string{"id": charger.ID}); err != nil { + return err + } + } + m.stats[utils.TpChargers] += 1 + } + } + } + } + return +} + +func (m *Migrator) migrateTPChargers() (err error) { + var vrs engine.Versions + current := engine.CurrentStorDBVersions() + vrs, err = m.storDBOut.StorDB().GetVersions("") + if err != nil { + return utils.NewCGRError(utils.Migrator, + utils.ServerErrorCaps, + err.Error(), + fmt.Sprintf("error: <%s> when querying oldDataDB for versions", err.Error())) + } else if len(vrs) == 0 { + return utils.NewCGRError(utils.Migrator, + utils.MandatoryIEMissingCaps, + utils.UndefinedVersion, + "version number is not defined for TPChargers model") + } + switch vrs[utils.TpChargers] { + case current[utils.TpChargers]: + if m.sameStorDB { + return + } + if err := m.migrateCurrentTPChargers(); err != nil { + return err + } + return + } + return +} diff --git a/utils/consts.go b/utils/consts.go index e402f918a..d53647c86 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -282,22 +282,7 @@ const ( NANO_MULTIPLIER = 1000000000 CGR_AUTHORIZE = "CGR_AUTHORIZE" CONFIG_DIR = "/etc/cgrates/" - CGR_ACCOUNT = "cgr_account" - CGR_SUPPLIER = "cgr_supplier" - CGR_DESTINATION = "cgr_destination" - CGR_SUBJECT = "cgr_subject" - CGR_CATEGORY = "cgr_category" - CGR_REQTYPE = "cgr_reqtype" - CGR_TENANT = "cgr_tenant" - CGR_TOR = "cgr_tor" - CGR_OriginID = "cgr_originid" - CGR_HOST = "cgr_host" - CGR_PDD = "cgr_pdd" DISCONNECT_CAUSE = "DisconnectCause" - CGR_DISCONNECT_CAUSE = "cgr_disconnectcause" - CGR_COMPUTELCR = "cgr_computelcr" - CGR_SUPPLIERS = "cgr_suppliers" - CGRFlags = "cgr_flags" KAM_FLATSTORE = "kamailio_flatstore" OSIPS_FLATSTORE = "opensips_flatstore" MAX_DEBIT_CACHE_PREFIX = "MAX_DEBIT_" @@ -339,7 +324,6 @@ const ( NegativePrefix = "!" MatchStartPrefix = "^" MatchEndPrefix = "$" - SMG = "SMG" MetaGrouped = "*grouped" MetaRaw = "*raw" CreatedAt = "CreatedAt" @@ -432,6 +416,7 @@ const ( Thresholds = "Thresholds" Suppliers = "Suppliers" Attributes = "Attributes" + Chargers = "Chargers" StatS = "Stats" RALService = "RALs" CostSource = "CostSource" @@ -463,30 +448,6 @@ const ( MetaNow = "*now" SessionsCosts = "SessionsCosts" SessionSCosts = "SessionSCosts" - TpRatingPlans = "TpRatingPlans" - TpFilters = "TpFilters" - TpDestinationRates = "TpDestinationRates" - TpActionTriggers = "TpActionTriggers" - TpAccountActionsV = "TpAccountActions" - TpActionPlans = "TpActionPlans" - TpActions = "TpActions" - TpDerivedCharges = "TpDerivedCharges" - TpThresholds = "TpThresholds" - TpSuppliers = "TpSuppliers" - TpStats = "TpStats" - TpSharedGroups = "TpSharedGroups" - TpRatingProfiles = "TpRatingProfiles" - TpResources = "TpResources" - TpRates = "TpRates" - TpTiming = "TpTiming" - TpResource = "TpResource" - TpAliases = "TpAliases" - TpUsers = "TpUsers" - TpDerivedChargersV = "TpDerivedChargers" - TpCdrStats = "TpCdrStats" - TpDestinations = "TpDestinations" - TpRatingPlan = "TpRatingPlan" - TpRatingProfile = "TpRatingProfile" Timing = "Timing" RQF = "RQF" Resource = "Resource" @@ -527,7 +488,6 @@ const ( Error = "Error" MetaCGRRequest = "*cgrRequest" MetaCGRReply = "*cgrReply" - CacheS = "CacheS" CGR_ACD = "cgr_acd" FilterIDs = "FilterIDs" FieldName = "FieldName" @@ -593,6 +553,7 @@ const ( DispatcherS = "DispatcherS" LoaderS = "LoaderS" ChargerS = "ChargerS" + CacheS = "CacheS" ) // Lower service names @@ -635,6 +596,7 @@ const ( MetaTpDestinations = "*tp_destinations" MetaTpRatingPlan = "*tp_rating_plan" MetaTpRatingProfile = "*tp_rating_profile" + MetaTpChargers = "*tp_chargers" MetaDurationSeconds = "*duration_seconds" MetaDurationNanoseconds = "*duration_nanoseconds" CapAttributes = "Attributes" @@ -646,6 +608,34 @@ const ( CapStatQueues = "StatQueues" ) +const ( + TpRatingPlans = "TpRatingPlans" + TpFilters = "TpFilters" + TpDestinationRates = "TpDestinationRates" + TpActionTriggers = "TpActionTriggers" + TpAccountActionsV = "TpAccountActions" + TpActionPlans = "TpActionPlans" + TpActions = "TpActions" + TpDerivedCharges = "TpDerivedCharges" + TpThresholds = "TpThresholds" + TpSuppliers = "TpSuppliers" + TpStats = "TpStats" + TpSharedGroups = "TpSharedGroups" + TpRatingProfiles = "TpRatingProfiles" + TpResources = "TpResources" + TpRates = "TpRates" + TpTiming = "TpTiming" + TpResource = "TpResource" + TpAliases = "TpAliases" + TpUsers = "TpUsers" + TpDerivedChargersV = "TpDerivedChargers" + TpCdrStats = "TpCdrStats" + TpDestinations = "TpDestinations" + TpRatingPlan = "TpRatingPlan" + TpRatingProfile = "TpRatingProfile" + TpChargers = "TpChargers" +) + // Dispatcher Const const ( MetaFirst = "*first" @@ -664,7 +654,7 @@ const ( NestingSep = "." ) -// MetaFilterIndexesAPIs +// ApierV1 APIs const ( ApierV1ComputeFilterIndexes = "ApierV1.ComputeFilterIndexes" ApierV1ReloadCache = "ApierV1.ReloadCache" @@ -676,12 +666,12 @@ const ( ApierV2LoadTariffPlanFromFolder = "ApierV2.LoadTariffPlanFromFolder" ) -// MetaUsersAPIs +// UserS APIs const ( UsersV1ReloadUsers = "UsersV1.ReloadUsers" ) -// MetaSupplierAPIs +// SupplierS APIs const ( SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers" SupplierSv1Ping = "SupplierSv1.Ping" @@ -760,7 +750,7 @@ const ( LoaderSv1Ping = "LoaderSv1.Ping" ) -// Cache +// CacheS APIs const ( CacheSv1GetCacheStats = "CacheSv1.GetCacheStats" CacheSv1GetItemIDs = "CacheSv1.GetItemIDs" @@ -784,6 +774,25 @@ const ( CdrcPing = "Cdrc.Ping" ) +//cgr_ variables +const ( + CGR_ACCOUNT = "cgr_account" + CGR_SUPPLIER = "cgr_supplier" + CGR_DESTINATION = "cgr_destination" + CGR_SUBJECT = "cgr_subject" + CGR_CATEGORY = "cgr_category" + CGR_REQTYPE = "cgr_reqtype" + CGR_TENANT = "cgr_tenant" + CGR_TOR = "cgr_tor" + CGR_OriginID = "cgr_originid" + CGR_HOST = "cgr_host" + CGR_PDD = "cgr_pdd" + CGR_DISCONNECT_CAUSE = "cgr_disconnectcause" + CGR_COMPUTELCR = "cgr_computelcr" + CGR_SUPPLIERS = "cgr_suppliers" + CGRFlags = "cgr_flags" +) + //CSV file name const ( TIMINGS_CSV = "Timings.csv"