diff --git a/migrator/accounts.go b/migrator/accounts.go
index 67000ab71..53e45106b 100644
--- a/migrator/accounts.go
+++ b/migrator/accounts.go
@@ -91,6 +91,38 @@ func (m *Migrator) getV1AccountFromDB(key string) (*v1Account, error) {
}
}
+func (m *Migrator) SetV1onRedis(key string, bl []byte) (err error) {
+ dataDB := m.dataDB.(*engine.RedisStorage)
+ if err = dataDB.Cmd("SET", key, bl).Err; err != nil {
+ return err
+ }
+ return
+}
+
+func (m *Migrator) FlushRedis() (err error) {
+ dataDB := m.dataDB.(*engine.RedisStorage)
+ if err = dataDB.Cmd("FLUSHALL").Err; err != nil {
+ return err
+ }
+ return
+}
+
+func (m *Migrator) FlushMongo() (err error) {
+ dataDB := m.dataDB.(*engine.MongoStorage)
+ mgoDB := dataDB.DB()
+ defer mgoDB.Session.Close()
+ cols, err := mgoDB.CollectionNames()
+ for _, col := range cols {
+ if err := mgoDB.C(col).DropCollection(); err != nil {
+ return err
+ }
+ }
+ if err != nil {
+ return err
+ }
+ return
+}
+
type v1Account struct {
Id string
BalanceMap map[string]v1BalanceChain
diff --git a/migrator/action.go b/migrator/action.go
index e73e88efd..dad5402a1 100644
--- a/migrator/action.go
+++ b/migrator/action.go
@@ -18,8 +18,11 @@ along with this program. If not, see
package migrator
import (
+ "fmt"
+
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
+ "gopkg.in/mgo.v2/bson"
)
type v1Action struct {
@@ -35,8 +38,67 @@ type v1Action struct {
type v1Actions []*v1Action
-func (v1Act v1Action) AsAction() (act engine.Action) {
- act = engine.Action{
+func (m *Migrator) migrateActions() (err error) {
+ var acts engine.Actions
+ var actv1keys []string
+ actv1keys, err = m.tpDB.GetKeysForPrefix(utils.ACTION_PREFIX)
+ if err != nil {
+ return
+ }
+ for _, actv1key := range actv1keys {
+ v1act, err := m.getV1ActionFromDB(actv1key)
+ if err != nil {
+ return err
+ }
+ act := v1act.AsAction()
+ acts = append(acts, act)
+ if err := m.tpDB.SetActions(act.Id, acts, utils.NonTransactional); err != nil {
+ return err
+ }
+ // All done, update version wtih current one
+ vrs := engine.Versions{utils.ACTION_PREFIX: engine.CurrentStorDBVersions()[utils.ACTION_PREFIX]}
+ if err = m.tpDB.SetVersions(vrs); err != nil {
+ return utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ err.Error(),
+ fmt.Sprintf("error: <%s> when updating Accounts version into StorDB", err.Error()))
+ }
+ }
+ return
+}
+
+func (m *Migrator) getV1ActionFromDB(key string) (v1act *v1Action, err error) {
+ switch m.dataDBType {
+ case utils.REDIS:
+ tpDB := m.tpDB.(*engine.RedisStorage)
+ if strVal, err := tpDB.Cmd("GET", key).Bytes(); err != nil {
+ return nil, err
+ } else {
+ v1act := &v1Action{Id: key}
+ if err := m.mrshlr.Unmarshal(strVal, v1act); err != nil {
+ return nil, err
+ }
+ return v1act, nil
+ }
+ case utils.MONGO:
+ tpDB := m.tpDB.(*engine.MongoStorage)
+ mgoDB := tpDB.DB()
+ defer mgoDB.Session.Close()
+ v1act := new(v1Action)
+ if err := mgoDB.C(v1AccountTBL).Find(bson.M{"id": key}).One(v1act); err != nil {
+ return nil, err
+ }
+ return v1act, nil
+ default:
+ return nil, utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ utils.UnsupportedDB,
+ fmt.Sprintf("error: unsupported: <%s> for getV1ActionPlansFromDB method", m.dataDBType))
+ }
+}
+
+func (v1Act v1Action) AsAction() (act *engine.Action) {
+ act = &engine.Action{
Id: v1Act.Id,
ActionType: v1Act.ActionType,
ExtraParameters: v1Act.ExtraParameters,
diff --git a/migrator/action_plan.go b/migrator/action_plan.go
index 0c4e56019..45c5290b4 100644
--- a/migrator/action_plan.go
+++ b/migrator/action_plan.go
@@ -22,10 +22,16 @@ import (
"strings"
"time"
+ "gopkg.in/mgo.v2/bson"
+
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
+// const (
+// v1AccountDBPrefix = "ubl_"
+// )
+
type v1ActionPlan struct {
Uuid string // uniquely identify the timing
Id string // informative purpose only
@@ -46,15 +52,72 @@ func (at *v1ActionPlan) IsASAP() bool {
return at.Timing.Timing.StartTime == utils.ASAP
}
-func (v1AP v1ActionPlan) AsActionPlan() (ap engine.ActionPlan) {
+func (m *Migrator) migrateActionPlans() (err error) {
+ var apsv1keys []string
+ apsv1keys, err = m.tpDB.GetKeysForPrefix(utils.ACTION_PLAN_PREFIX)
+ if err != nil {
+ return
+ }
+ for _, apsv1key := range apsv1keys {
+ v1aps, err := m.getV1ActionPlansFromDB(apsv1key)
+ if err != nil {
+ return err
+ }
+ aps := v1aps.AsActionPlan()
+ if err = m.tpDB.SetActionPlan(aps.Id, aps, true, utils.NonTransactional); err != nil {
+ return err
+ }
+ }
+ // All done, update version wtih current one
+ vrs := engine.Versions{utils.ACTION_PLAN_PREFIX: engine.CurrentStorDBVersions()[utils.ACTION_PLAN_PREFIX]}
+ if err = m.tpDB.SetVersions(vrs); err != nil {
+ return utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ err.Error(),
+ fmt.Sprintf("error: <%s> when updating ActionPlans version into StorDB", err.Error()))
+ }
+ return
+}
+
+func (m *Migrator) getV1ActionPlansFromDB(key string) (v1aps *v1ActionPlan, err error) {
+ switch m.dataDBType {
+ case utils.REDIS:
+ tpDB := m.tpDB.(*engine.RedisStorage)
+ if strVal, err := tpDB.Cmd("GET", key).Bytes(); err != nil {
+ return nil, err
+ } else {
+ v1aps := &v1ActionPlan{Id: key}
+ if err := m.mrshlr.Unmarshal(strVal, v1aps); err != nil {
+ return nil, err
+ }
+ return v1aps, nil
+ }
+ case utils.MONGO:
+ tpDB := m.tpDB.(*engine.MongoStorage)
+ mgoDB := tpDB.DB()
+ defer mgoDB.Session.Close()
+ v1aps := new(v1ActionPlan)
+ if err := mgoDB.C(v1AccountTBL).Find(bson.M{"id": key}).One(v1aps); err != nil {
+ return nil, err
+ }
+ return v1aps, nil
+ default:
+ return nil, utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ utils.UnsupportedDB,
+ fmt.Sprintf("error: unsupported: <%s> for getV1ActionPlansFromDB method", m.dataDBType))
+ }
+}
+
+func (v1AP v1ActionPlan) AsActionPlan() (ap *engine.ActionPlan) {
for idx, actionId := range v1AP.AccountIds {
- idElements := strings.Split(actionId, utils.CONCATENATED_KEY_SEP)
- if len(idElements) != 3 {
+ idElements := strings.Split(actionId, "_")
+ if len(idElements) != 2 {
continue
}
- v1AP.AccountIds[idx] = fmt.Sprintf("%s:%s", idElements[1], idElements[2])
+ v1AP.AccountIds[idx] = idElements[1]
}
- ap = engine.ActionPlan{
+ ap = &engine.ActionPlan{
Id: v1AP.Id,
AccountIDs: make(utils.StringMap),
}
diff --git a/migrator/action_test.go b/migrator/action_test.go
index db29d3db6..f5f28b7c3 100644
--- a/migrator/action_test.go
+++ b/migrator/action_test.go
@@ -28,7 +28,7 @@ func TestV1ActionsAsActions(t *testing.T) {
v1act := &v1Action{Id: "", ActionType: "", BalanceType: "", Direction: "INBOUND", ExtraParameters: "", ExpirationString: "", Balance: &v1Balance{}}
act := &engine.Action{Id: "", ActionType: "", ExtraParameters: "", ExpirationString: "", Weight: 0.00, Balance: &engine.BalanceFilter{}}
newact := v1act.AsAction()
- if !reflect.DeepEqual(*act, newact) {
- t.Errorf("Expecting: %+v, received: %+v", *act, newact)
+ if !reflect.DeepEqual(act, newact) {
+ t.Errorf("Expecting: %+v, received: %+v", act, newact)
}
}
diff --git a/migrator/action_trigger.go b/migrator/action_trigger.go
index 862115352..dc05ec83d 100644
--- a/migrator/action_trigger.go
+++ b/migrator/action_trigger.go
@@ -1,9 +1,12 @@
package migrator
import (
+ "fmt"
"strings"
"time"
+ "gopkg.in/mgo.v2/bson"
+
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
@@ -33,10 +36,73 @@ type v1ActionTrigger struct {
type v1ActionTriggers []*v1ActionTrigger
-func (v1Act v1ActionTrigger) AsActionTrigger() (at engine.ActionTrigger) {
+func (m *Migrator) migrateActionTriggers() (err error) {
+ var atrrs engine.ActionTriggers
+ var v1atrskeys []string
+ v1atrskeys, err = m.tpDB.GetKeysForPrefix(utils.ACTION_TRIGGER_PREFIX)
+ if err != nil {
+ return
+ }
+ for _, v1atrskey := range v1atrskeys {
+ v1atrs, err := m.getV1ActionTriggerFromDB(v1atrskey)
+ if err != nil {
+ return err
+ }
+ v1atr := v1atrs
+ if v1atrs != nil {
+ atr := v1atr.AsActionTrigger()
+ atrrs = append(atrrs, atr)
- at = engine.ActionTrigger{
- UniqueID: v1Act.Id,
+ if err := m.tpDB.SetActionTriggers(atr.ID, atrrs, utils.NonTransactional); err != nil {
+ return err
+ }
+ }
+ }
+ // All done, update version wtih current one
+ vrs := engine.Versions{utils.ACTION_TRIGGER_PREFIX: engine.CurrentStorDBVersions()[utils.ACTION_TRIGGER_PREFIX]}
+ if err = m.tpDB.SetVersions(vrs); err != nil {
+ return utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ err.Error(),
+ fmt.Sprintf("error: <%s> when updating Accounts version into StorDB", err.Error()))
+ }
+ return
+}
+
+func (m *Migrator) getV1ActionTriggerFromDB(key string) (v1Atr *v1ActionTrigger, err error) {
+ switch m.dataDBType {
+ case utils.REDIS:
+ tpDB := m.tpDB.(*engine.RedisStorage)
+ if strVal, err := tpDB.Cmd("GET", key).Bytes(); err != nil {
+ return nil, err
+ } else {
+ v1Atr := &v1ActionTrigger{Id: key}
+ if err := m.mrshlr.Unmarshal(strVal, &v1Atr); err != nil {
+ return nil, err
+ }
+ return v1Atr, nil
+ }
+ case utils.MONGO:
+ tpDB := m.tpDB.(*engine.MongoStorage)
+ mgoDB := tpDB.DB()
+ defer mgoDB.Session.Close()
+ v1Atr := new(v1ActionTrigger)
+ if err := mgoDB.C(v1AccountTBL).Find(bson.M{"id": key}).One(v1Atr); err != nil {
+ return nil, err
+ }
+ return v1Atr, nil
+ default:
+ return nil, utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ utils.UnsupportedDB,
+ fmt.Sprintf("error: unsupported: <%s> for getV1ActionTriggerFromDB method", m.dataDBType))
+ }
+}
+
+func (v1Act v1ActionTrigger) AsActionTrigger() (at *engine.ActionTrigger) {
+ at = &engine.ActionTrigger{
+ ID: v1Act.Id,
+ // UniqueID: utils.GenUUID(),
ThresholdType: v1Act.ThresholdType,
ThresholdValue: v1Act.ThresholdValue,
Recurrent: v1Act.Recurrent,
diff --git a/migrator/action_trigger_test.go b/migrator/action_trigger_test.go
index e9cc646e8..0d77bf1e6 100644
--- a/migrator/action_trigger_test.go
+++ b/migrator/action_trigger_test.go
@@ -26,10 +26,11 @@ import (
"github.com/cgrates/cgrates/utils"
)
-var v1ActionTriggers1 = `{"BalanceType": "*monetary","BalanceDirection": "*out","ThresholdType":"*max_balance", "ThresholdValue" :2, "ActionsId": "TEST_ACTIONS", "Executed": true}`
+var v1ActionTriggers1 = `{"Id" : "Test","BalanceType": "*monetary","BalanceDirection": "*out","ThresholdType":"*max_balance", "ThresholdValue" :2, "ActionsId": "TEST_ACTIONS", "Executed": true}`
func TestV1ActionTriggersAsActionTriggers(t *testing.T) {
atrs := &engine.ActionTrigger{
+ ID: "Test",
Balance: &engine.BalanceFilter{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
@@ -44,7 +45,7 @@ func TestV1ActionTriggersAsActionTriggers(t *testing.T) {
t.Error(err)
}
newatrs := v1actstrgrs.AsActionTrigger()
- if !reflect.DeepEqual(*atrs, newatrs) {
- t.Errorf("Expecting: %+v, received: %+v", *atrs, newatrs)
+ if !reflect.DeepEqual(atrs, newatrs) {
+ t.Errorf("Expecting: %+v, received: %+v", atrs, newatrs)
}
}
diff --git a/migrator/migrator.go b/migrator/migrator.go
index 489a79890..95a9470a4 100644
--- a/migrator/migrator.go
+++ b/migrator/migrator.go
@@ -64,6 +64,15 @@ func (m *Migrator) Migrate(taskID string) (err error) {
err = m.migrateCostDetails()
case utils.MetaAccounts:
err = m.migrateAccounts()
+ case "migrateActionPlans":
+ err = m.migrateActionPlans()
+ case "migrateActionTriggers":
+ err = m.migrateActionTriggers()
+ case "migrateActions":
+ err = m.migrateActions()
+ case "migrateSharedGroups":
+ err = m.migrateSharedGroups()
}
+
return
}
diff --git a/migrator/migrator_it_test.go b/migrator/migrator_it_test.go
new file mode 100644
index 000000000..0a538748d
--- /dev/null
+++ b/migrator/migrator_it_test.go
@@ -0,0 +1,303 @@
+// +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 (
+ "flag"
+ "fmt"
+ "path"
+ "reflect"
+ "testing"
+ "time"
+
+ "github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/utils"
+)
+
+var (
+ rdsITdb *engine.RedisStorage
+ mgoITdb *engine.MongoStorage
+ onStor engine.DataDB
+ onStorCfg string
+ dbtype string
+ mig *Migrator
+ dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
+)
+
+// subtests to be executed for each migrator
+var sTestsOnStorIT = []func(t *testing.T){
+ testOnStorITFlush,
+ testMigratorAccounts,
+ testMigratorActionPlans,
+ testMigratorActionTriggers,
+ testMigratorActions,
+ testMigratorSharedGroups,
+}
+
+func TestOnStorITRedisConnect(t *testing.T) {
+ cfg, _ := config.NewDefaultCGRConfig()
+ rdsITdb, err := engine.NewRedisStorage(fmt.Sprintf("%s:%s", cfg.TpDbHost, cfg.TpDbPort), 4, cfg.TpDbPass, cfg.DBDataEncoding, utils.REDIS_MAX_CONNS, nil, 1)
+ if err != nil {
+ t.Fatal("Could not connect to Redis", err.Error())
+ }
+ onStorCfg = cfg.DataDbName
+ mig = NewMigrator(rdsITdb, rdsITdb, utils.REDIS, utils.JSON, rdsITdb, utils.REDIS)
+}
+
+func TestOnStorITRedis(t *testing.T) {
+ dbtype = utils.REDIS
+ onStor = rdsITdb
+ for _, stest := range sTestsOnStorIT {
+ t.Run("TestOnStorITRedis", stest)
+ }
+}
+
+func TestOnStorITMongoConnect(t *testing.T) {
+ cdrsMongoCfgPath := path.Join(*dataDir, "conf", "samples", "cdrsv2mongo")
+ mgoITCfg, err := config.NewCGRConfigFromFolder(cdrsMongoCfgPath)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if mgoITdb, err = engine.NewMongoStorage(mgoITCfg.StorDBHost, mgoITCfg.StorDBPort, mgoITCfg.StorDBName, mgoITCfg.StorDBUser, mgoITCfg.StorDBPass,
+ utils.StorDB, nil, mgoITCfg.CacheConfig, mgoITCfg.LoadHistorySize); err != nil {
+ t.Fatal(err)
+ }
+ onStorCfg = mgoITCfg.StorDBName
+ mig = NewMigrator(mgoITdb, mgoITdb, utils.MONGO, utils.JSON, mgoITdb, utils.MONGO)
+}
+
+func TestOnStorITMongo(t *testing.T) {
+ dbtype = utils.MONGO
+ onStor = mgoITdb
+ for _, stest := range sTestsOnStorIT {
+ t.Run("TestOnStorITMongo", stest)
+ }
+}
+
+func testOnStorITFlush(t *testing.T) {
+ switch {
+ case dbtype == utils.REDIS:
+ err := mig.FlushRedis()
+ if err != nil {
+ t.Error("Error when flushing redis ", err.Error())
+ }
+ case dbtype == utils.MONGO:
+ err := mig.FlushMongo()
+ if err != nil {
+ t.Error("Error when flushing redis ", err.Error())
+ }
+ }
+}
+
+func testMigratorAccounts(t *testing.T) {
+ v1b := &v1Balance{Value: 10, Weight: 10, DestinationIds: "NAT", ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Local()}
+ v1Acc := &v1Account{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]v1BalanceChain{utils.VOICE: v1BalanceChain{v1b}, utils.MONETARY: v1BalanceChain{&v1Balance{Value: 21, ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Local()}}}}
+ v2 := &engine.Balance{Uuid: "", ID: "", Value: 10, Directions: utils.StringMap{"*OUT": true}, ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Local(), Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "", Categories: utils.NewStringMap(""), SharedGroups: utils.NewStringMap(""), TimingIDs: utils.NewStringMap("")}
+ m2 := &engine.Balance{Uuid: "", ID: "", Value: 21, Directions: utils.StringMap{"*OUT": true}, ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC).Local(), DestinationIDs: utils.NewStringMap(""), RatingSubject: "", Categories: utils.NewStringMap(""), SharedGroups: utils.NewStringMap(""), TimingIDs: utils.NewStringMap("")}
+ testAccount := &engine.Account{ID: "CUSTOMER_1:rif", BalanceMap: map[string]engine.Balances{utils.VOICE: engine.Balances{v2}, utils.MONETARY: engine.Balances{m2}}, UnitCounters: engine.UnitCounters{}, ActionTriggers: engine.ActionTriggers{}}
+ switch {
+ case dbtype == utils.REDIS:
+ bit, err := mig.mrshlr.Marshal(v1Acc)
+ if err != nil {
+ t.Error("Error when marshaling ", err.Error())
+ }
+ err = mig.SetV1onRedis(v1AccountDBPrefix+v1Acc.Id, bit)
+ if err != nil {
+ t.Error("Error when setting v1 acc ", err.Error())
+ }
+
+ err = mig.Migrate(utils.MetaAccounts)
+ if err != nil {
+ t.Error("Error when migrating accounts ", err.Error())
+ }
+ result, err := mig.dataDB.GetAccount(testAccount.ID)
+ if err != nil {
+ t.Error("Error when getting account ", err.Error())
+ }
+ if !reflect.DeepEqual(testAccount, result) {
+ t.Errorf("Expecting: %+v, received: %+v", testAccount, result)
+ }
+ case dbtype == utils.MONGO:
+ t.Errorf("not yet")
+ }
+}
+
+func testMigratorActionPlans(t *testing.T) {
+ v1ap := &v1ActionPlan{Id: "test", AccountIds: []string{"one"}, Timing: &engine.RateInterval{Timing: new(engine.RITiming)}}
+ ap := &engine.ActionPlan{Id: "test", AccountIDs: utils.StringMap{"one": true}, ActionTimings: []*engine.ActionTiming{&engine.ActionTiming{Timing: &engine.RateInterval{Timing: new(engine.RITiming)}}}}
+ switch {
+ case dbtype == utils.REDIS:
+ bit, err := mig.mrshlr.Marshal(v1ap)
+ if err != nil {
+ t.Error("Error when marshaling ", err.Error())
+ }
+ setv1id := utils.ACTION_PLAN_PREFIX + v1ap.Id
+ err = mig.SetV1onRedis(setv1id, bit)
+ if err != nil {
+ t.Error("Error when setting v1 ActionPlan ", err.Error())
+ }
+ err = mig.Migrate("migrateActionPlans")
+ if err != nil {
+ t.Error("Error when migrating ActionPlans ", err.Error())
+ }
+ result, err := mig.tpDB.GetActionPlan(ap.Id, true, utils.NonTransactional)
+ if err != nil {
+ t.Error("Error when getting ActionPlan ", err.Error())
+ }
+ if ap.Id != result.Id || !reflect.DeepEqual(ap.AccountIDs, result.AccountIDs) {
+ t.Errorf("Expecting: %+v, received: %+v", *ap, result)
+ } else if !reflect.DeepEqual(ap.ActionTimings[0].Timing, result.ActionTimings[0].Timing) {
+ t.Errorf("Expecting: %+v, received: %+v", ap.ActionTimings[0].Timing, result.ActionTimings[0].Timing)
+ } else if ap.ActionTimings[0].Weight != result.ActionTimings[0].Weight || ap.ActionTimings[0].ActionsID != result.ActionTimings[0].ActionsID {
+ t.Errorf("Expecting: %+v, received: %+v", ap.ActionTimings[0].Weight, result.ActionTimings[0].Weight)
+ }
+ case dbtype == utils.MONGO:
+ t.Errorf("not yet")
+ }
+}
+
+func testMigratorActionTriggers(t *testing.T) {
+ tim := time.Date(0001, time.January, 1, 0, 0, 0, 0, time.UTC)
+ v1atrs := &v1ActionTrigger{
+ Id: "Test",
+ BalanceType: "*monetary",
+ BalanceDirection: "*out",
+ ThresholdType: "*max_balance",
+ ThresholdValue: 2,
+ ActionsId: "TEST_ACTIONS",
+ Executed: true,
+ }
+
+ atrs := engine.ActionTriggers{
+ &engine.ActionTrigger{
+ ID: "Test",
+ Balance: &engine.BalanceFilter{
+ Type: utils.StringPointer(utils.MONETARY),
+ Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
+ },
+ ExpirationDate: tim,
+ LastExecutionTime: tim,
+ ActivationDate: tim,
+ ThresholdType: utils.TRIGGER_MAX_BALANCE,
+ ThresholdValue: 2,
+ ActionsID: "TEST_ACTIONS",
+ Executed: true,
+ },
+ }
+
+ switch {
+ case dbtype == utils.REDIS:
+ bit, err := mig.mrshlr.Marshal(v1atrs)
+ if err != nil {
+ t.Error("Error when marshaling ", err.Error())
+ }
+ setv1id := utils.ACTION_TRIGGER_PREFIX + v1atrs.Id
+ err = mig.SetV1onRedis(setv1id, bit)
+ if err != nil {
+ t.Error("Error when setting v1 ActionTriggers ", err.Error())
+ }
+ err = mig.Migrate("migrateActionTriggers")
+ if err != nil {
+ t.Error("Error when migrating ActionTriggers ", err.Error())
+ }
+ result, err := mig.tpDB.GetActionTriggers(v1atrs.Id, true, utils.NonTransactional)
+ if err != nil {
+ t.Error("Error when getting ActionTriggers ", err.Error())
+ }
+ if !reflect.DeepEqual(atrs, result) {
+ t.Errorf("Expecting: %+v, received: %+v", atrs, result)
+ }
+ case dbtype == utils.MONGO:
+ t.Errorf("not yet")
+ }
+}
+
+func testMigratorActions(t *testing.T) {
+ v1act := &v1Action{Id: "test", ActionType: "", BalanceType: "", Direction: "INBOUND", ExtraParameters: "", ExpirationString: "", Balance: &v1Balance{}}
+ act := engine.Actions{&engine.Action{Id: "test", ActionType: "", ExtraParameters: "", ExpirationString: "", Weight: 0.00, Balance: &engine.BalanceFilter{}}}
+ switch {
+ case dbtype == utils.REDIS:
+ bit, err := mig.mrshlr.Marshal(v1act)
+ if err != nil {
+ t.Error("Error when marshaling ", err.Error())
+ }
+ setv1id := utils.ACTION_PREFIX + v1act.Id
+ err = mig.SetV1onRedis(setv1id, bit)
+ if err != nil {
+ t.Error("Error when setting v1 Actions ", err.Error())
+ }
+
+ err = mig.Migrate("migrateActions")
+ if err != nil {
+ t.Error("Error when migrating Actions ", err.Error())
+ }
+ result, err := mig.tpDB.GetActions(v1act.Id, true, utils.NonTransactional)
+ if err != nil {
+ t.Error("Error when getting Actions ", err.Error())
+ }
+ if !reflect.DeepEqual(act, result) {
+ t.Errorf("Expecting: %+v, received: %+v", act, result)
+ }
+ case dbtype == utils.MONGO:
+ t.Errorf("not yet")
+ }
+}
+
+func testMigratorSharedGroups(t *testing.T) {
+ v1sg := &v1SharedGroup{
+ Id: "Test",
+ AccountParameters: map[string]*engine.SharingParameters{
+ "test": &engine.SharingParameters{Strategy: "*highest"},
+ },
+ MemberIds: []string{"1", "2", "3"},
+ }
+ sg := &engine.SharedGroup{
+ Id: "Test",
+ AccountParameters: map[string]*engine.SharingParameters{
+ "test": &engine.SharingParameters{Strategy: "*highest"},
+ },
+ MemberIds: utils.NewStringMap("1", "2", "3"),
+ }
+
+ switch {
+ case dbtype == utils.REDIS:
+ bit, err := mig.mrshlr.Marshal(v1sg)
+ if err != nil {
+ t.Error("Error when marshaling ", err.Error())
+ }
+ setv1id := utils.SHARED_GROUP_PREFIX + v1sg.Id
+ err = mig.SetV1onRedis(setv1id, bit)
+ if err != nil {
+ t.Error("Error when setting v1 Actions ", err.Error())
+ }
+
+ err = mig.Migrate("migrateSharedGroups")
+ if err != nil {
+ t.Error("Error when migrating Actions ", err.Error())
+ }
+ result, err := mig.tpDB.GetSharedGroup(v1sg.Id, true, utils.NonTransactional)
+ if err != nil {
+ t.Error("Error when getting Actions ", err.Error())
+ }
+ if !reflect.DeepEqual(sg, result) {
+ t.Errorf("Expecting: %+v, received: %+v", sg, result)
+ }
+ case dbtype == utils.MONGO:
+ t.Errorf("not yet")
+ }
+}
diff --git a/migrator/sharedgroup.go b/migrator/sharedgroup.go
index e728e46db..38663a6aa 100644
--- a/migrator/sharedgroup.go
+++ b/migrator/sharedgroup.go
@@ -18,8 +18,11 @@ along with this program. If not, see
package migrator
import (
+ "fmt"
+
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
+ "gopkg.in/mgo.v2/bson"
)
type v1SharedGroup struct {
@@ -28,8 +31,66 @@ type v1SharedGroup struct {
MemberIds []string
}
-func (v1SG v1SharedGroup) AsSharedGroup() (sg engine.SharedGroup) {
- sg = engine.SharedGroup{
+func (m *Migrator) migrateSharedGroups() (err error) {
+ var sgv1keys []string
+ sgv1keys, err = m.tpDB.GetKeysForPrefix(utils.SHARED_GROUP_PREFIX)
+ if err != nil {
+ return
+ }
+ for _, sgv1key := range sgv1keys {
+ v1sg, err := m.getv1SharedGroupFromDB(sgv1key)
+ if err != nil {
+ return err
+ }
+ sg := v1sg.AsSharedGroup()
+ if err = m.tpDB.SetSharedGroup(sg, utils.NonTransactional); err != nil {
+ return err
+ }
+
+ }
+ // All done, update version wtih current one
+ vrs := engine.Versions{utils.SHARED_GROUP_PREFIX: engine.CurrentStorDBVersions()[utils.SHARED_GROUP_PREFIX]}
+ if err = m.tpDB.SetVersions(vrs); err != nil {
+ return utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ err.Error(),
+ fmt.Sprintf("error: <%s> when updating SharedGroup version into tpDB", err.Error()))
+ }
+ return
+}
+
+func (m *Migrator) getv1SharedGroupFromDB(key string) (*v1SharedGroup, error) {
+ switch m.dataDBType {
+ case utils.REDIS:
+ tpDB := m.tpDB.(*engine.RedisStorage)
+ if strVal, err := tpDB.Cmd("GET", key).Bytes(); err != nil {
+ return nil, err
+ } else {
+ v1SG := &v1SharedGroup{Id: key}
+ if err := m.mrshlr.Unmarshal(strVal, v1SG); err != nil {
+ return nil, err
+ }
+ return v1SG, nil
+ }
+ case utils.MONGO:
+ tpDB := m.tpDB.(*engine.MongoStorage)
+ mgoDB := tpDB.DB()
+ defer mgoDB.Session.Close()
+ v1SG := new(v1SharedGroup)
+ if err := mgoDB.C(v1AccountTBL).Find(bson.M{"id": key}).One(v1SG); err != nil {
+ return nil, err
+ }
+ return v1SG, nil
+ default:
+ return nil, utils.NewCGRError(utils.Migrator,
+ utils.ServerErrorCaps,
+ utils.UnsupportedDB,
+ fmt.Sprintf("error: unsupported: <%s> for getv1SharedGroupFromDB method", m.dataDBType))
+ }
+}
+
+func (v1SG v1SharedGroup) AsSharedGroup() (sg *engine.SharedGroup) {
+ sg = &engine.SharedGroup{
Id: v1SG.Id,
AccountParameters: v1SG.AccountParameters,
MemberIds: make(utils.StringMap),
diff --git a/migrator/sharedgroup_test.go b/migrator/sharedgroup_test.go
index bc7085b16..a13afaa7f 100644
--- a/migrator/sharedgroup_test.go
+++ b/migrator/sharedgroup_test.go
@@ -41,8 +41,8 @@ func TestV1SharedGroupAsSharedGroup(t *testing.T) {
MemberIds: utils.NewStringMap("1", "2", "3"),
}
newsg := v1sg.AsSharedGroup()
- if !reflect.DeepEqual(*sg, newsg) {
- t.Errorf("Expecting: %+v, received: %+v", *sg, newsg)
+ if !reflect.DeepEqual(sg, newsg) {
+ t.Errorf("Expecting: %+v, received: %+v", sg, newsg)
}
}