mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Fixes #1186
This commit is contained in:
committed by
Dan Christian Bogos
parent
739edadea8
commit
3a6ebb88ad
@@ -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 &&
|
||||
|
||||
@@ -74,6 +74,11 @@ func NewDbDefaults() DbDefaults {
|
||||
"DbPort": "6379",
|
||||
"DbPass": "",
|
||||
},
|
||||
utils.INTERNAL: map[string]string{
|
||||
"DbName": "internal",
|
||||
"DbPort": "internal",
|
||||
"DbPass": "internal",
|
||||
},
|
||||
}
|
||||
return deflt
|
||||
}
|
||||
|
||||
@@ -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: <redis|mongo>
|
||||
"db_type": "redis", // data_db type: <redis|mongo|internal>
|
||||
"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: <mongo|mysql|postgres>
|
||||
"db_type": "mysql", // stor database type to use: <mongo|mysql|postgres|internal>
|
||||
"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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
|
||||
"data_db": { // database used to store runtime data (eg: accounts, cdr stats)
|
||||
"db_type": "redis", // data_db type: <redis|mongo>
|
||||
"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": "",
|
||||
},
|
||||
|
||||
}
|
||||
24
data/conf/samples/migwithinternal/cgrates.json
Executable file
24
data/conf/samples/migwithinternal/cgrates.json
Executable file
@@ -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: <redis|mongo>
|
||||
"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",
|
||||
},
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
244
migrator/accounts2_it_test.go
Executable file
244
migrator/accounts2_it_test.go
Executable file
@@ -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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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!")
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
168
migrator/storage_map_datadb.go
Executable file
168
migrator/storage_map_datadb.go
Executable file
@@ -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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
78
migrator/storage_map_stordb.go
Executable file
78
migrator/storage_map_stordb.go
Executable file
@@ -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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user