diff --git a/cmd/cgr-migrator/cgr-migrator.go b/cmd/cgr-migrator/cgr-migrator.go index 5de8c6936..0380b8a5e 100755 --- a/cmd/cgr-migrator/cgr-migrator.go +++ b/cmd/cgr-migrator/cgr-migrator.go @@ -194,6 +194,30 @@ func main() { mgrCfg.MigratorCgrConfig.OutDataDBEncoding = *outDBDataEncoding } + sameDataDB = mgrCfg.MigratorCgrConfig.OutDataDBType == mgrCfg.DataDbType && + mgrCfg.MigratorCgrConfig.OutDataDBHost == mgrCfg.DataDbHost && + mgrCfg.MigratorCgrConfig.OutDataDBPort == mgrCfg.DataDbPort && + mgrCfg.MigratorCgrConfig.OutDataDBName == mgrCfg.DataDbName && + mgrCfg.MigratorCgrConfig.OutDataDBEncoding == mgrCfg.DBDataEncoding + + if dmIN, err = migrator.NewMigratorDataDB(mgrCfg.DataDbType, + mgrCfg.DataDbHost, mgrCfg.DataDbPort, + mgrCfg.DataDbName, mgrCfg.DataDbUser, + mgrCfg.DataDbPass, mgrCfg.DBDataEncoding, + mgrCfg.CacheCfg(), 0); err != nil { + log.Fatal(err) + } + + if sameDataDB { + dmOUT = dmIN + } else if dmOUT, err = migrator.NewMigratorDataDB(mgrCfg.MigratorCgrConfig.OutDataDBType, + mgrCfg.MigratorCgrConfig.OutDataDBHost, mgrCfg.MigratorCgrConfig.OutDataDBPort, + mgrCfg.MigratorCgrConfig.OutDataDBName, mgrCfg.MigratorCgrConfig.OutDataDBUser, + mgrCfg.MigratorCgrConfig.OutDataDBPassword, mgrCfg.MigratorCgrConfig.OutDataDBEncoding, + mgrCfg.CacheCfg(), 0); err != nil { + log.Fatal(err) + } + // inStorDB if *inStorDBType != dfltCfg.StorDBType { mgrCfg.StorDBType = strings.TrimPrefix(*inStorDBType, "*") @@ -230,7 +254,9 @@ func main() { mgrCfg.MigratorCgrConfig.OutStorDBHost = *outStorDBHost } if *outStorDBPort == utils.MetaStorDB { - mgrCfg.MigratorCgrConfig.OutStorDBPort = mgrCfg.StorDBPort + if dfltCfg.MigratorCgrConfig.OutStorDBPort == mgrCfg.MigratorCgrConfig.OutStorDBPort { + mgrCfg.MigratorCgrConfig.OutStorDBPort = mgrCfg.StorDBPort + } } else { mgrCfg.MigratorCgrConfig.OutStorDBPort = *outStorDBPort } @@ -256,30 +282,6 @@ func main() { mgrCfg.MigratorCgrConfig.OutStorDBPassword = *outStorDBPass } - sameDataDB = mgrCfg.MigratorCgrConfig.OutDataDBType == mgrCfg.DataDbType && - mgrCfg.MigratorCgrConfig.OutDataDBHost == mgrCfg.DataDbHost && - mgrCfg.MigratorCgrConfig.OutDataDBPort == mgrCfg.DataDbPort && - mgrCfg.MigratorCgrConfig.OutDataDBName == mgrCfg.DataDbName && - mgrCfg.MigratorCgrConfig.OutDataDBEncoding == mgrCfg.DBDataEncoding - - if dmIN, err = migrator.NewMigratorDataDB(mgrCfg.DataDbType, - mgrCfg.DataDbHost, mgrCfg.DataDbPort, - mgrCfg.DataDbName, mgrCfg.DataDbUser, - mgrCfg.DataDbPass, mgrCfg.DBDataEncoding, - mgrCfg.CacheCfg(), 0); err != nil { - log.Fatal(err) - } - - if sameDataDB { - dmOUT = dmIN - } else if dmOUT, err = migrator.NewMigratorDataDB(mgrCfg.MigratorCgrConfig.OutDataDBType, - mgrCfg.MigratorCgrConfig.OutDataDBHost, mgrCfg.MigratorCgrConfig.OutDataDBPort, - mgrCfg.MigratorCgrConfig.OutDataDBName, mgrCfg.MigratorCgrConfig.OutDataDBUser, - mgrCfg.MigratorCgrConfig.OutDataDBPassword, mgrCfg.MigratorCgrConfig.OutDataDBEncoding, - mgrCfg.CacheCfg(), 0); err != nil { - log.Fatal(err) - } - sameStorDB = mgrCfg.MigratorCgrConfig.OutStorDBType == mgrCfg.StorDBType && mgrCfg.MigratorCgrConfig.OutStorDBHost == mgrCfg.StorDBHost && mgrCfg.MigratorCgrConfig.OutStorDBPort == mgrCfg.StorDBPort && diff --git a/config/config.go b/config/config.go index 27a408eb2..a111c9a1b 100755 --- a/config/config.go +++ b/config/config.go @@ -74,6 +74,11 @@ func NewDbDefaults() DbDefaults { "DbPort": "6379", "DbPass": "", }, + utils.INTERNAL: map[string]string{ + "DbName": "internal", + "DbPort": "internal", + "DbPass": "internal", + }, } return deflt } diff --git a/config/config_defaults.go b/config/config_defaults.go index f46ecfb81..9d59bb844 100755 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -54,7 +54,7 @@ const CGRATES_CFG_JSON = ` "data_db": { // database used to store runtime data (eg: accounts, cdr stats) - "db_type": "redis", // data_db type: + "db_type": "redis", // data_db type: "db_host": "127.0.0.1", // data_db host address "db_port": 6379, // data_db port to reach the database "db_name": "10", // data_db database name to connect to @@ -65,7 +65,7 @@ const CGRATES_CFG_JSON = ` "stor_db": { // database used to store offline tariff plans and CDRs - "db_type": "mysql", // stor database type to use: + "db_type": "mysql", // stor database type to use: "db_host": "127.0.0.1", // the host to connect to "db_port": 3306, // the port to reach the stordb "db_name": "cgrates", // stor database name diff --git a/config/config_test.go b/config/config_test.go index 3f07e2ba7..d9fd1ec16 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -80,6 +80,20 @@ func TestCgrCfgDataDBPortWithoutDynamic(t *testing.T) { } else if cgrCfg.DataDbPort != "6379" { t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbPort, "6379") } + JSN_CFG = ` +{ +"data_db": { + "db_type": "internal", + } +}` + + if cgrCfg, err := NewCGRConfigFromJsonStringWithDefaults(JSN_CFG); err != nil { + t.Error(err) + } else if cgrCfg.DataDbType != utils.INTERNAL { + t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbType, utils.INTERNAL) + } else if cgrCfg.DataDbPort != "6379" { + t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbPort, "6379") + } } func TestCgrCfgDataDBPortWithDymanic(t *testing.T) { @@ -98,6 +112,21 @@ func TestCgrCfgDataDBPortWithDymanic(t *testing.T) { } else if cgrCfg.DataDbPort != "27017" { t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbPort, "27017") } + JSN_CFG = ` +{ +"data_db": { + "db_type": "internal", + "db_port": -1, + } +}` + + if cgrCfg, err := NewCGRConfigFromJsonString(JSN_CFG); err != nil { + t.Error(err) + } else if cgrCfg.DataDbType != utils.INTERNAL { + t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbType, utils.INTERNAL) + } else if cgrCfg.DataDbPort != "internal" { + t.Errorf("Expected: %+v, received: %+v", cgrCfg.DataDbPort, "internal") + } } func TestCgrCfgStorDBPortWithoutDynamic(t *testing.T) { @@ -1055,7 +1084,7 @@ func TestRadiusAgentCfg(t *testing.T) { func TestDbDefaults(t *testing.T) { dbdf := NewDbDefaults() flagInput := utils.MetaDynamic - dbs := []string{utils.MONGO, utils.REDIS, utils.MYSQL} + dbs := []string{utils.MONGO, utils.REDIS, utils.MYSQL, utils.INTERNAL} for _, dbtype := range dbs { host := dbdf.DBHost(dbtype, flagInput) if host != utils.LOCALHOST { diff --git a/data/conf/samples/dbinternal/cgrates.json b/data/conf/samples/dbinternal/cgrates.json index 0619bdb01..f570894b1 100755 --- a/data/conf/samples/dbinternal/cgrates.json +++ b/data/conf/samples/dbinternal/cgrates.json @@ -16,32 +16,19 @@ "data_db": { - "db_type": "*internal", + "db_type": "internal", }, "stor_db": { - "db_type": "*internal", + "db_type": "internal", }, - "rals": { "enabled": true, "thresholds_conns": [ {"address": "*internal"} ], - "cdrstats_conns": [ - {"address": "*internal"} - ], - "pubsubs_conns": [ - {"address": "*internal"} - ], - "users_conns": [ - {"address": "*internal"} - ], - "aliases_conns": [ - {"address": "*internal"} - ], }, @@ -52,45 +39,6 @@ "cdrs": { "enabled": true, - "cdrstats_conns": [ - {"address": "*internal"} - ], -}, - - -"cdre": { - "TestTutITExportCDR": { - "content_fields": [ - {"id": "CGRID", "type": "*composed", "value": "~CGRID"}, - {"id": "RunID", "type": "*composed", "value": "~RunID"}, - {"id":"OriginID", "type": "*composed", "value": "~OriginID"}, - {"id":"RequestType", "type": "*composed", "value": "~RequestType"}, - {"id":"Tenant", "type": "*composed", "value": "~Tenant"}, - {"id":"Category", "type": "*composed", "value": "~Category"}, - {"id":"Account", "type": "*composed", "value": "~Account"}, - {"id":"Destination", "type": "*composed", "value": "~Destination"}, - {"id":"AnswerTime", "type": "*composed", "value": "~AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"}, - {"id":"Usage", "type": "*composed", "value": "~Usage"}, - {"id":"Cost", "type": "*composed", "value": "~Cost", "rounding_decimals": 4}, - {"id":"MatchedDestinationID", "type": "*composed", "value": "~CostDetails:s/\"MatchedDestId\":.*_(\\w{4})/${1}/:s/\"MatchedDestId\":\"INTERNAL\"/ON010/"}, - ], - }, -}, - - -"cdrstats": { - "enabled": true, -}, - - -"pubsubs": { - "enabled": true, -}, - - -"users": { - "enabled": true, - "indexes": ["Uuid"], }, @@ -128,13 +76,14 @@ }, -"aliases": { - "enabled": true, -}, - - "sessions": { "enabled": true, }, + +"migrator": { + "out_datadb_type": "internal", + "out_stordb_type": "internal", +}, + } diff --git a/data/conf/samples/migratortest/cgrates.json b/data/conf/samples/migratortest/cgrates.json deleted file mode 100755 index 19d47df05..000000000 --- a/data/conf/samples/migratortest/cgrates.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - -"data_db": { // database used to store runtime data (eg: accounts, cdr stats) - "db_type": "redis", // data_db type: - "db_port": 9999, // data_db port to reach the database - "db_name": "9999", // data_db database name to connect to -}, - -"stor_db": { // database used to store offline tariff plans and CDRs -"db_host": "*internal", -}, - -"migrator": { -"out_datadb_type": "mongo", -"out_datadb_host": "127.0.0.1", -"out_datadb_port": "27017", -"out_datadb_name": "data_backup", -"out_datadb_user": "", -"out_datadb_password":"", -"out_stordb_type": "mongo", -"out_datadb_host": "127.0.0.1", -"out_stordb_port": "27017", -"out_stordb_name": "store-backup", -"out_stordb_user": "", -"out_stordb_password": "", -}, - -} \ No newline at end of file diff --git a/data/conf/samples/migwithinternal/cgrates.json b/data/conf/samples/migwithinternal/cgrates.json new file mode 100755 index 000000000..b3c0320e1 --- /dev/null +++ b/data/conf/samples/migwithinternal/cgrates.json @@ -0,0 +1,24 @@ +{ +// CGRateS Configuration file +// + +"general": { + "log_level": 7, +}, + + +"data_db": { // database used to store runtime data (eg: accounts, cdr stats) + "db_type": "redis", // data_db type: + "db_port": 6379, // data_db port to reach the database + "db_name": "10", // data_db database name to connect to +}, + +"stor_db": { + "db_type": "internal", +}, + +"migrator":{ + "out_stordb_type": "internal", +}, + +} \ No newline at end of file diff --git a/engine/storage_map_datadb.go b/engine/storage_map_datadb.go index 8ae2b2f8f..4a6ef7fe0 100644 --- a/engine/storage_map_datadb.go +++ b/engine/storage_map_datadb.go @@ -1635,7 +1635,7 @@ func (ms *MapStorage) RemoveChargerProfileDrv(tenant, id string) (err error) { func (ms *MapStorage) GetVersions(itm string) (vrs Versions, err error) { ms.mu.Lock() defer ms.mu.Unlock() - values, ok := ms.dict[itm] + values, ok := ms.dict[utils.TBLVersions] if !ok { return nil, utils.ErrNotFound } @@ -1643,38 +1643,23 @@ func (ms *MapStorage) GetVersions(itm string) (vrs Versions, err error) { if err != nil { return nil, err } - return + if itm != "" { + return Versions{itm: vrs[itm]}, nil + } + return vrs, nil } func (ms *MapStorage) SetVersions(vrs Versions, overwrite bool) (err error) { var result []byte - var x Versions - if !overwrite { - x, err = ms.GetVersions("") - if err != nil { + if overwrite { + if ms.RemoveVersions(nil); err != nil { return err } - for key := range vrs { - if x[key] != vrs[key] { - x[key] = vrs[key] - } - } - result, err = ms.ms.Marshal(x) - if err != nil { - return err - } - ms.mu.Lock() - ms.dict[utils.TBLVersions] = result - ms.mu.Unlock() - return } result, err = ms.ms.Marshal(vrs) if err != nil { return err } - if ms.RemoveVersions(vrs); err != nil { - return err - } ms.mu.Lock() ms.dict[utils.TBLVersions] = result ms.mu.Unlock() @@ -1684,8 +1669,28 @@ func (ms *MapStorage) SetVersions(vrs Versions, overwrite bool) (err error) { func (ms *MapStorage) RemoveVersions(vrs Versions) (err error) { ms.mu.Lock() defer ms.mu.Unlock() + if len(vrs) != 0 { + var internalVersions Versions + values, ok := ms.dict[utils.TBLVersions] + if !ok { + return utils.ErrNotFound + } + err = ms.ms.Unmarshal(values, &internalVersions) + if err != nil { + return + } + for key, _ := range vrs { + delete(internalVersions, key) + } + result, err := ms.ms.Marshal(internalVersions) + if err != nil { + return err + } + ms.dict[utils.TBLVersions] = result + return nil + } delete(ms.dict, utils.TBLVersions) - return + return nil } func (ms *MapStorage) GetStorageType() string { diff --git a/engine/version.go b/engine/version.go index cfe963bbf..92fb8fe59 100644 --- a/engine/version.go +++ b/engine/version.go @@ -86,15 +86,14 @@ func CheckVersions(storage Storage) error { return nil } -func SetDBVersions(storage Storage) error { +func SetDBVersions(storage Storage) (err error) { storType := storage.GetStorageType() x := CurrentDBVersions(storType) // no data, write version - if err := storage.SetVersions(x, false); err != nil { + if err = storage.SetVersions(x, false); err != nil { utils.Logger.Warning(fmt.Sprintf("Could not write current version to db: %v", err)) } - return nil - + return } func (vers Versions) Compare(curent Versions, storType string) string { diff --git a/migrator/accounts2_it_test.go b/migrator/accounts2_it_test.go new file mode 100755 index 000000000..1ef6ab51e --- /dev/null +++ b/migrator/accounts2_it_test.go @@ -0,0 +1,244 @@ +// +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 + +import ( + "log" + "path" + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + acc2PathIn string + acc2PathOut string + acc2CfgIn *config.CGRConfig + acc2CfgOut *config.CGRConfig + acc2Migrator *Migrator +) + +var sTestsAcc2IT = []func(t *testing.T){ + testAcc2ITConnect, + testAcc2ITFlush, + testAcc2ITMigrate, +} + +func TestAccMigrateWithInternal(t *testing.T) { + var err error + acc2PathIn = path.Join(*dataDir, "conf", "samples", "migwithinternal") + acc2CfgIn, err = config.NewCGRConfigFromFolder(acc2PathIn) + if err != nil { + t.Fatal(err) + } + acc2CfgOut, err = config.NewCGRConfigFromFolder(acc2PathIn) + if err != nil { + t.Fatal(err) + } + for _, stest := range sTestsAcc2IT { + t.Run("TestAccMigrateWithInternal", stest) + } +} + +func testAcc2ITConnect(t *testing.T) { + dataDBIn, err := NewMigratorDataDB(acc2CfgIn.DataDbType, + acc2CfgIn.DataDbHost, acc2CfgIn.DataDbPort, acc2CfgIn.DataDbName, + acc2CfgIn.DataDbUser, acc2CfgIn.DataDbPass, acc2CfgIn.DBDataEncoding, + config.CgrConfig().CacheCfg(), *loadHistorySize) + if err != nil { + t.Error(err) + } + dataDBOut, err := NewMigratorDataDB(acc2CfgOut.DataDbType, + acc2CfgOut.DataDbHost, acc2CfgOut.DataDbPort, acc2CfgOut.DataDbName, + acc2CfgOut.DataDbUser, acc2CfgOut.DataDbPass, acc2CfgOut.DBDataEncoding, + config.CgrConfig().CacheCfg(), *loadHistorySize) + if err != nil { + t.Error(err) + } + + storDBIn, err := NewMigratorStorDB(acc2CfgIn.StorDBType, + acc2CfgIn.StorDBHost, acc2CfgIn.StorDBPort, acc2CfgIn.StorDBName, + acc2CfgIn.StorDBUser, acc2CfgIn.StorDBPass, acc2CfgIn.StorDBMaxOpenConns, + acc2CfgIn.StorDBMaxIdleConns, acc2CfgIn.StorDBConnMaxLifetime, acc2CfgIn.StorDBCDRSIndexes) + if err != nil { + t.Error(err) + } + storDBOut, err := NewMigratorStorDB(acc2CfgOut.StorDBType, + acc2CfgOut.StorDBHost, acc2CfgOut.StorDBPort, acc2CfgOut.StorDBName, + acc2CfgOut.StorDBUser, acc2CfgOut.StorDBPass, acc2CfgOut.StorDBMaxOpenConns, + acc2CfgOut.StorDBMaxIdleConns, acc2CfgOut.StorDBConnMaxLifetime, acc2CfgOut.StorDBCDRSIndexes) + if err != nil { + t.Error(err) + } + acc2Migrator, err = NewMigrator(dataDBIn, dataDBOut, + storDBIn, storDBOut, + false, false, false) + if err != nil { + log.Fatal(err) + } +} + +func testAcc2ITFlush(t *testing.T) { + acc2Migrator.dmOut.DataManager().DataDB().Flush("") + if err := engine.SetDBVersions(acc2Migrator.dmOut.DataManager().DataDB()); err != nil { + t.Error("Error ", err.Error()) + } + acc2Migrator.dmIN.DataManager().DataDB().Flush("") + if err := engine.SetDBVersions(acc2Migrator.dmIN.DataManager().DataDB()); err != nil { + t.Error("Error ", err.Error()) + } + if acc2Migrator.dmOut.DataManager().DataDB().GetStorageType() != utils.REDIS { + t.Errorf("Unexpected datadb type : %+v", acc2Migrator.dmOut.DataManager().DataDB().GetStorageType()) + } + if acc2Migrator.storDBIn.StorDB().GetStorageType() != utils.MAPSTOR { + t.Errorf("Unexpected datadb type : %+v", acc2Migrator.storDBIn.StorDB().GetStorageType()) + } + if acc2Migrator.storDBOut.StorDB().GetStorageType() != utils.MAPSTOR { + t.Errorf("Unexpected datadb type : %+v", acc2Migrator.storDBOut.StorDB().GetStorageType()) + } +} + +func testAcc2ITMigrate(t *testing.T) { + timingSlice := []*engine.RITiming{ + &engine.RITiming{ + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + }, + } + v1b := &v1Balance{ + Value: 100000, + Weight: 10, + DestinationIds: "NAT", + ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + Timings: timingSlice, + } + v1Acc := &v1Account{ + Id: "*OUT:CUSTOMER_1:rif", + BalanceMap: map[string]v1BalanceChain{ + utils.DATA: v1BalanceChain{v1b}, + utils.VOICE: v1BalanceChain{v1b}, + utils.MONETARY: v1BalanceChain{ + &v1Balance{Value: 21, + ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + Timings: timingSlice}}}} + + v2d := &engine.Balance{ + Uuid: "", ID: "", + Value: 100000, + Directions: utils.StringMap{"*OUT": true}, + ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + Weight: 10, + DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "", + Categories: utils.NewStringMap(), + SharedGroups: utils.NewStringMap(), + Timings: timingSlice, + TimingIDs: utils.NewStringMap(""), + Factor: engine.ValueFactor{}} + v2b := &engine.Balance{ + Uuid: "", ID: "", + Value: 0.0001, + Directions: utils.StringMap{"*OUT": true}, + ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + Weight: 10, + DestinationIDs: utils.StringMap{"NAT": true}, + RatingSubject: "", + Categories: utils.NewStringMap(), + SharedGroups: utils.NewStringMap(), + Timings: timingSlice, + TimingIDs: utils.NewStringMap(""), + Factor: engine.ValueFactor{}} + m2 := &engine.Balance{ + Uuid: "", + ID: "", + Value: 21, + Directions: utils.StringMap{"*OUT": true}, + ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), + DestinationIDs: utils.NewStringMap(""), + RatingSubject: "", + Categories: utils.NewStringMap(), + SharedGroups: utils.NewStringMap(), + Timings: timingSlice, + TimingIDs: utils.NewStringMap(""), + Factor: engine.ValueFactor{}} + testAccount := &engine.Account{ + ID: "CUSTOMER_1:rif", + BalanceMap: map[string]engine.Balances{ + utils.DATA: engine.Balances{v2d}, + utils.VOICE: engine.Balances{v2b}, + utils.MONETARY: engine.Balances{m2}}, + UnitCounters: engine.UnitCounters{}, + ActionTriggers: engine.ActionTriggers{}, + } + // set v1Account + err := acc2Migrator.dmIN.setV1Account(v1Acc) + if err != nil { + t.Error("Error when setting v1 Accounts ", err.Error()) + } + //set version for account : 1 + currentVersion := engine.Versions{ + utils.StatS: 2, + utils.Thresholds: 2, + utils.Accounts: 1, + utils.Actions: 2, + utils.ActionTriggers: 2, + utils.ActionPlans: 2, + utils.SharedGroups: 2} + err = acc2Migrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false) + if err != nil { + t.Error("Error when setting version for Accounts ", err.Error()) + } + //check if version was set correctly + if vrs, err := acc2Migrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.Accounts] != 1 { + t.Errorf("Unexpected version returned: %d", vrs[utils.Accounts]) + } + //migrate account + err, _ = acc2Migrator.Migrate([]string{utils.MetaAccounts}) + if err != nil { + t.Error("Error when migrating Accounts ", err.Error()) + } + //check if version was updated + if vrs, err := acc2Migrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.Accounts] != 3 { + t.Errorf("Unexpected version returned: %d", vrs[utils.Accounts]) + } + //check if account was migrate correctly + result, err := acc2Migrator.dmOut.DataManager().DataDB().GetAccount(testAccount.ID) + if err != nil { + t.Error("Error when getting Accounts ", err.Error()) + } + if !reflect.DeepEqual(testAccount, result) { + t.Errorf("Expecting: %+v, received: %+v", testAccount, result) + } + //check if old account was deleted + if _, err = acc2Migrator.dmIN.getv1Account(); err != utils.ErrNoMoreData { + t.Error("Error should be not found : ", err) + } +} diff --git a/migrator/migrator.go b/migrator/migrator.go index e21aa6e89..530603cb1 100755 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -83,7 +83,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) { err.Error(), fmt.Sprintf("error: <%s> when updating CostDetails version into StorDB", err.Error())), nil } - } else { log.Print("Cannot dryRun SetVersions!") } diff --git a/migrator/migrator_utils.go b/migrator/migrator_utils.go index 37cdfe46b..8e9b86cf1 100644 --- a/migrator/migrator_utils.go +++ b/migrator/migrator_utils.go @@ -43,7 +43,8 @@ func NewMigratorDataDB(db_type, host, port, name, user, pass, marshaler string, d = newMongoMigrator(dm) db = d.(MigratorDataDB) case utils.INTERNAL: - //do nothing for the moment + d = newMapMigrator(dm) + db = d.(MigratorDataDB) default: err = errors.New(fmt.Sprintf("Unknown db '%s' valid options are '%s' or '%s or '%s'", db_type, utils.REDIS, utils.MONGO, utils.INTERNAL)) @@ -70,7 +71,8 @@ func NewMigratorStorDB(db_type, host, port, name, user, pass string, d = newMigratorSQL(storDb) db = d.(MigratorStorDB) case utils.INTERNAL: - //for the momen do nothing + d = newMapStorDBMigrator(storDb) + db = d.(MigratorStorDB) default: err = errors.New(fmt.Sprintf("Unknown db '%s' valid options are [%s, %s, %s, %s]", db_type, utils.MYSQL, utils.MONGO, utils.POSTGRES, utils.INTERNAL)) diff --git a/migrator/storage_map_datadb.go b/migrator/storage_map_datadb.go new file mode 100755 index 000000000..2a7791de1 --- /dev/null +++ b/migrator/storage_map_datadb.go @@ -0,0 +1,168 @@ +/* +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 ( + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +type mapMigrator struct { + dm *engine.DataManager + mp *engine.MapStorage + dataKeys []string + qryIdx *int +} + +func newMapMigrator(dm *engine.DataManager) (mM *mapMigrator) { + return &mapMigrator{ + dm: dm, + mp: dm.DataDB().(*engine.MapStorage), + } +} + +func (mM *mapMigrator) DataManager() *engine.DataManager { + return mM.dm +} + +//Account methods +//V1 +//get +func (mM *mapMigrator) getv1Account() (v1Acnt *v1Account, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1Account(x *v1Account) (err error) { + return utils.ErrNotImplemented +} + +//rem +func (mM *mapMigrator) remV1Account(id string) (err error) { + return utils.ErrNotImplemented +} + +//V2 +//get +func (mM *mapMigrator) getv2Account() (v2Acnt *v2Account, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV2Account(x *v2Account) (err error) { + return utils.ErrNotImplemented +} + +//rem +func (mM *mapMigrator) remV2Account(id string) (err error) { + return utils.ErrNotImplemented +} + +//ActionPlans methods +//get +func (mM *mapMigrator) getV1ActionPlans() (v1aps *v1ActionPlans, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1ActionPlans(x *v1ActionPlans) (err error) { + return utils.ErrNotImplemented +} + +//Actions methods +//get +func (mM *mapMigrator) getV1Actions() (v1acs *v1Actions, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1Actions(x *v1Actions) (err error) { + return utils.ErrNotImplemented +} + +//ActionTriggers methods +//get +func (mM *mapMigrator) getV1ActionTriggers() (v1acts *v1ActionTriggers, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1ActionTriggers(x *v1ActionTriggers) (err error) { + return utils.ErrNotImplemented +} + +//SharedGroup methods +//get +func (mM *mapMigrator) getV1SharedGroup() (v1sg *v1SharedGroup, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1SharedGroup(x *v1SharedGroup) (err error) { + return utils.ErrNotImplemented +} + +//Stats methods +//get +func (mM *mapMigrator) getV1Stats() (v1st *v1Stat, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1Stats(x *v1Stat) (err error) { + return utils.ErrNotImplemented +} + +//Action methods +//get +func (mM *mapMigrator) getV2ActionTrigger() (v2at *v2ActionTrigger, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV2ActionTrigger(x *v2ActionTrigger) (err error) { + return utils.ErrNotImplemented +} + +//AttributeProfile methods +//get +func (mM *mapMigrator) getV1AttributeProfile() (v1attrPrf *v1AttributeProfile, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV1AttributeProfile(x *v1AttributeProfile) (err error) { + return utils.ErrNotImplemented +} + +//ThresholdProfile methods +//get +func (mM *mapMigrator) getV2ThresholdProfile() (v2T *v2Threshold, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mM *mapMigrator) setV2ThresholdProfile(x *v2Threshold) (err error) { + return utils.ErrNotImplemented +} + +//rem +func (mM *mapMigrator) remV2ThresholdProfile(tenant, id string) (err error) { + return utils.ErrNotImplemented +} diff --git a/migrator/storage_map_stordb.go b/migrator/storage_map_stordb.go new file mode 100755 index 000000000..f866b47c2 --- /dev/null +++ b/migrator/storage_map_stordb.go @@ -0,0 +1,78 @@ +/* +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 ( + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func newMapStorDBMigrator(stor engine.StorDB) (mpMig *mapStorDBMigrator) { + return &mapStorDBMigrator{ + storDB: &stor, + mp: stor.(*engine.MapStorage), + } +} + +type mapStorDBMigrator struct { + storDB *engine.StorDB + mp *engine.MapStorage + dataKeys []string + qryIdx *int +} + +func (mpMig *mapStorDBMigrator) StorDB() engine.StorDB { + return *mpMig.storDB +} + +//CDR methods +//get +func (mpMig *mapStorDBMigrator) getV1CDR() (v1Cdr *v1Cdrs, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mpMig *mapStorDBMigrator) setV1CDR(v1Cdr *v1Cdrs) (err error) { + return utils.ErrNotImplemented +} + +//SMCost methods +//rename +func (mpMig *mapStorDBMigrator) renameV1SMCosts() (err error) { + return utils.ErrNotImplemented +} + +func (mpMig *mapStorDBMigrator) createV1SMCosts() (err error) { + return utils.ErrNotImplemented +} + +//get +func (mpMig *mapStorDBMigrator) getV2SMCost() (v2Cost *v2SessionsCost, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (mpMig *mapStorDBMigrator) setV2SMCost(v2Cost *v2SessionsCost) (err error) { + return utils.ErrNotImplemented +} + +//remove +func (mpMig *mapStorDBMigrator) remV2SMCost(v2Cost *v2SessionsCost) (err error) { + return utils.ErrNotImplemented +}