diff --git a/migrator/migrator.go b/migrator/migrator.go
index 148be694c..45a3f3f2e 100755
--- a/migrator/migrator.go
+++ b/migrator/migrator.go
@@ -183,6 +183,8 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
err = m.migrateTPsharedgroups()
case utils.MetaTpRatingProfiles:
err = m.migrateTPratingprofiles()
+ case utils.MetaTpActionProfiles:
+ err = m.migrateTPActionProfiles()
case utils.MetaTpResources:
err = m.migrateTPresources()
case utils.MetaTpRates:
diff --git a/migrator/tp_action_profile.go b/migrator/tp_action_profile.go
new file mode 100644
index 000000000..3be9fd46b
--- /dev/null
+++ b/migrator/tp_action_profile.go
@@ -0,0 +1,79 @@
+/*
+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 (m *Migrator) migrateCurrentTPActionProfiles() (err error) {
+ tpIds, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPActionProfiles)
+ if err != nil {
+ return err
+ }
+
+ for _, tpid := range tpIds {
+ ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPActionProfiles,
+ utils.TPDistinctIds{"id"}, map[string]string{}, nil)
+ if err != nil {
+ return err
+ }
+
+ for _, id := range ids {
+ actionProfiles, err := m.storDBIn.StorDB().GetTPActionProfiles(tpid, utils.EmptyString, id)
+ if err != nil {
+ return err
+ }
+ if actionProfiles == nil || m.dryRun {
+ continue
+ }
+ if err := m.storDBOut.StorDB().SetTPActionProfiles(actionProfiles); err != nil {
+ return err
+ }
+ for _, actionProfile := range actionProfiles {
+ if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPActionProfiles, actionProfile.TPid,
+ map[string]string{"id": actionProfile.ID}); err != nil {
+ return err
+ }
+ }
+ m.stats[utils.TpActionProfiles]++
+ }
+ }
+ return
+}
+
+func (m *Migrator) migrateTPActionProfiles() (err error) {
+ var vrs engine.Versions
+ current := engine.CurrentStorDBVersions()
+ if vrs, err = m.getVersions(utils.TpActionProfiles); err != nil {
+ return
+ }
+ switch vrs[utils.TpActionProfiles] {
+ case current[utils.TpActionProfiles]:
+ if m.sameStorDB {
+ break
+ }
+ if err := m.migrateCurrentTPActionProfiles(); err != nil {
+ return err
+ }
+ }
+ return m.ensureIndexesStorDB(utils.TBLTPActionProfiles)
+}
diff --git a/migrator/tp_action_profile_it_test.go b/migrator/tp_action_profile_it_test.go
new file mode 100644
index 000000000..e511bf515
--- /dev/null
+++ b/migrator/tp_action_profile_it_test.go
@@ -0,0 +1,164 @@
+/*
+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"
+ "path"
+ "reflect"
+ "testing"
+
+ "github.com/cgrates/cgrates/engine"
+
+ "github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/utils"
+)
+
+var (
+ tpActPrfPathIn string
+ tpActPrfPathOut string
+ tpActPrfCfgIn *config.CGRConfig
+ tpActPrfCfgOut *config.CGRConfig
+ tpActPrfMigrator *Migrator
+ newDataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
+ actPrf []*utils.TPActionProfile
+)
+
+var sTestTpActPrfIT = []func(t *testing.T){
+ testTpActPrfConnect,
+ testTpActPrfFlush,
+ testTpACtPrfPopulate,
+ testTpACtPrfMove,
+ testTpACtPrfCheckData,
+}
+
+func TestTpActPrfMove(t *testing.T) {
+ for _, tests := range sTestTpActPrfIT {
+ t.Run("TestTpActPrfMove", tests)
+ }
+ tpActPrfMigrator.Close()
+}
+
+func testTpActPrfConnect(t *testing.T) {
+ var err error
+ tpActPrfPathIn = path.Join(*newDataDir, "conf", "samples", "tutmongo")
+ tpActPrfCfgIn, err = config.NewCGRConfigFromPath(tpActPrfPathIn)
+ if err != nil {
+ t.Fatal(err)
+ }
+ tpActPrfPathOut = path.Join(*newDataDir, "conf", "samples", "tutmysql")
+ tpActPrfCfgOut, err = config.NewCGRConfigFromPath(tpActPrfPathOut)
+ if err != nil {
+ t.Fatal(err)
+ }
+ storDBIn, err := NewMigratorStorDB(tpActPrfCfgIn.StorDbCfg().Type,
+ tpActPrfCfgIn.StorDbCfg().Host, tpActPrfCfgIn.StorDbCfg().Port,
+ tpActPrfCfgIn.StorDbCfg().Name, tpActPrfCfgIn.StorDbCfg().User,
+ tpActPrfCfgIn.StorDbCfg().Password, tpActPrfCfgIn.GeneralCfg().DBDataEncoding,
+ tpActPrfCfgIn.StorDbCfg().StringIndexedFields, tpActPrfCfgIn.StorDbCfg().PrefixIndexedFields,
+ tpActPrfCfgIn.StorDbCfg().Opts)
+ if err != nil {
+ t.Error(err)
+ }
+ storDBOut, err := NewMigratorStorDB(tpActPrfCfgOut.StorDbCfg().Type,
+ tpActPrfCfgOut.StorDbCfg().Host, tpActPrfCfgOut.StorDbCfg().Port,
+ tpActPrfCfgOut.StorDbCfg().Name, tpActPrfCfgOut.StorDbCfg().User,
+ tpActPrfCfgOut.StorDbCfg().Password, tpActPrfCfgOut.GeneralCfg().DBDataEncoding,
+ tpActPrfCfgOut.StorDbCfg().StringIndexedFields, tpActPrfCfgOut.StorDbCfg().PrefixIndexedFields,
+ tpActPrfCfgOut.StorDbCfg().Opts)
+ if err != nil {
+ t.Error(err)
+ }
+
+ tpActPrfMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut,
+ false, false, false, false)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testTpActPrfFlush(t *testing.T) {
+ if err := tpActPrfMigrator.storDBIn.StorDB().Flush(
+ path.Join(tpActPrfCfgIn.DataFolderPath, "storage", tpActPrfCfgIn.StorDbCfg().Type)); err != nil {
+ t.Error(err)
+ }
+ if err := tpActPrfMigrator.storDBOut.StorDB().Flush(
+ path.Join(tpActPrfCfgOut.DataFolderPath, "storage", tpActPrfCfgOut.StorDbCfg().Type)); err != nil {
+ t.Error(err)
+ }
+}
+
+func testTpACtPrfPopulate(t *testing.T) {
+ actPrf = []*utils.TPActionProfile{
+ {
+ Tenant: "cgrates.org",
+ TPid: "TEST_ID1",
+ ID: "sub_id1",
+ FilterIDs: []string{"*string:~*req.Account:1001"},
+ Weight: 20,
+ Schedule: utils.ASAP,
+ Actions: []*utils.TPAPAction{
+ {
+ ID: "TOPUP",
+ FilterIDs: []string{},
+ Type: "*topup",
+ Path: "~*balance.TestBalance.Value",
+ },
+ },
+ },
+ }
+ //empty in database
+ if _, err := tpActPrfMigrator.storDBIn.StorDB().GetTPActionProfiles(actPrf[0].TPid,
+ utils.EmptyString, actPrf[0].ID); err != utils.ErrNotFound {
+ t.Error(err)
+ }
+
+ //set an TPActionProfile in database
+ if err := tpActPrfMigrator.storDBIn.StorDB().SetTPActionProfiles(actPrf); err != nil {
+ t.Error(err)
+ }
+ currVersion := engine.CurrentStorDBVersions()
+ err := tpActPrfMigrator.storDBIn.StorDB().SetVersions(currVersion, false)
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func testTpACtPrfMove(t *testing.T) {
+ err, _ := tpActPrfMigrator.Migrate([]string{utils.MetaTpActionProfiles})
+ if err != nil {
+ t.Error("Error when migrating TpActionProfile ", err.Error())
+ }
+}
+
+func testTpACtPrfCheckData(t *testing.T) {
+ rcv, err := tpActPrfMigrator.storDBOut.StorDB().GetTPActionProfiles(actPrf[0].TPid,
+ utils.EmptyString, actPrf[0].ID)
+ if err != nil {
+ t.Error("Error when getting TPActionProfile from database", err)
+ }
+ if !reflect.DeepEqual(rcv[0], actPrf[0]) {
+ t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(actPrf[0]), utils.ToJSON(rcv[0]))
+ }
+
+ _, err = tpActPrfMigrator.storDBIn.StorDB().GetTPActionProfiles(actPrf[0].TPid,
+ utils.EmptyString, actPrf[0].ID)
+ if err != utils.ErrNotFound {
+ t.Error(err)
+ }
+}
diff --git a/utils/consts.go b/utils/consts.go
index 4dd2d9f54..df6b1114c 100755
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -1059,6 +1059,7 @@ const (
MetaTpStats = "*tp_stats"
MetaTpSharedGroups = "*tp_shared_groups"
MetaTpRatingProfiles = "*tp_rating_profiles"
+ MetaTpActionProfiles = "*tp_action_profiles"
MetaTpResources = "*tp_resources"
MetaTpRates = "*tp_rates"
MetaTpTimings = "*tp_timings"
diff --git a/utils/set_test.go b/utils/set_test.go
index 172fe603a..03a8bd565 100644
--- a/utils/set_test.go
+++ b/utils/set_test.go
@@ -222,7 +222,6 @@ func TestSetCloneEmpty(t *testing.T) {
func TestGetOne(t *testing.T) {
set := StringSet{
"test1": struct{}{},
- "test2": struct{}{},
}
value := set.GetOne()
expected := "test1"