diff --git a/apier/v1/attributes.go b/apier/v1/attributes.go index 2984564ce..4d1d18b8d 100644 --- a/apier/v1/attributes.go +++ b/apier/v1/attributes.go @@ -19,8 +19,6 @@ along with this program. If not, see package v1 import ( - "strings" - "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -41,18 +39,16 @@ func (apierV1 *ApierV1) GetAttributeProfile(arg utils.TenantID, reply *engine.At return nil } -// GetAttributeProfileIDs returns list of threshold IDs registered for a tenant +// GetAttributeProfileIDs returns list of attributeProfile IDs registered for a tenant func (apierV1 *ApierV1) GetAttributeProfileIDs(tenant string, attrPrfIDs *[]string) error { - prfx := utils.AttributeProfilePrefix + prfx := utils.AttributeProfilePrefix + tenant + ":" keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) if err != nil { return err } - retIDs := make([]string, 0) - for _, key := range keys { - if strings.Contains(key, tenant) { - retIDs = append(retIDs, key[len(prfx):]) - } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] } *attrPrfIDs = retIDs return nil diff --git a/apier/v1/chargers.go b/apier/v1/chargers.go index b39c52f45..002663cc1 100644 --- a/apier/v1/chargers.go +++ b/apier/v1/chargers.go @@ -39,6 +39,21 @@ func (apierV1 *ApierV1) GetChargerProfile(arg utils.TenantID, reply *engine.Char return nil } +// GetChargerProfileIDs returns list of chargerProfile IDs registered for a tenant +func (apierV1 *ApierV1) GetChargerProfileIDs(tenant string, chPrfIDs *[]string) error { + prfx := utils.ChargerProfilePrefix + tenant + ":" + keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) + if err != nil { + return err + } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] + } + *chPrfIDs = retIDs + return nil +} + //SetChargerProfile add/update a new Charger Profile func (apierV1 *ApierV1) SetChargerProfile(cpp *engine.ChargerProfile, reply *string) error { if missing := utils.MissingStructFields(cpp, []string{"Tenant", "ID"}); len(missing) != 0 { diff --git a/apier/v1/chargers_it_test.go b/apier/v1/chargers_it_test.go index 32a8288c9..bacb26e4b 100755 --- a/apier/v1/chargers_it_test.go +++ b/apier/v1/chargers_it_test.go @@ -70,6 +70,7 @@ var sTestsCharger = []func(t *testing.T){ testChargerSGetChargersForEvent, testChargerSProcessEvent, testChargerSSetChargerProfile, + testChargerSGetChargerProfileIDs, testChargerSUpdateChargerProfile, testChargerSRemChargerProfile, testChargerSPing, @@ -229,6 +230,16 @@ func testChargerSSetChargerProfile(t *testing.T) { } } +func testChargerSGetChargerProfileIDs(t *testing.T) { + expected := []string{"Charger1", "ApierTest"} + var result []string + if err := chargerRPC.Call("ApierV1.GetChargerProfileIDs", "cgrates.org", &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + func testChargerSUpdateChargerProfile(t *testing.T) { chargerProfile.RunID = "*rated" var result string diff --git a/apier/v1/filters.go b/apier/v1/filters.go index 680a31204..7a6d688c4 100644 --- a/apier/v1/filters.go +++ b/apier/v1/filters.go @@ -51,6 +51,21 @@ func (self *ApierV1) GetFilter(arg utils.TenantID, reply *engine.Filter) error { return nil } +// GetFilterIDs returns list of Filter IDs registered for a tenant +func (apierV1 *ApierV1) GetFilterIDs(tenant string, fltrIDs *[]string) error { + prfx := utils.FilterPrefix + tenant + ":" + keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) + if err != nil { + return err + } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] + } + *fltrIDs = retIDs + return nil +} + //RemoveFilter remove a specific filter func (self *ApierV1) RemoveFilter(arg utils.TenantID, reply *string) error { if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing diff --git a/apier/v1/filters_it_test.go b/apier/v1/filters_it_test.go index 5392d1380..6260967bd 100644 --- a/apier/v1/filters_it_test.go +++ b/apier/v1/filters_it_test.go @@ -50,6 +50,7 @@ var sTestsFilter = []func(t *testing.T){ testFilterGetFilterBeforeSet, testFilterSetFilter, testFilterGetFilterAfterSet, + testFilterGetFilterIDs, testFilterUpdateFilter, testFilterGetFilterAfterUpdate, testFilterRemoveFilter, @@ -151,6 +152,16 @@ func testFilterSetFilter(t *testing.T) { } } +func testFilterGetFilterIDs(t *testing.T) { + expected := []string{"Filter1"} + var result []string + if err := filterRPC.Call("ApierV1.GetFilterIDs", "cgrates.org", &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + func testFilterGetFilterAfterSet(t *testing.T) { var reply *engine.Filter if err := filterRPC.Call("ApierV1.GetFilter", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err != nil { diff --git a/apier/v1/resourcesv1.go b/apier/v1/resourcesv1.go index 59aeb2b31..40eba55de 100644 --- a/apier/v1/resourcesv1.go +++ b/apier/v1/resourcesv1.go @@ -73,6 +73,21 @@ func (apierV1 *ApierV1) GetResourceProfile(arg utils.TenantID, reply *engine.Res return nil } +// GetResourceProfileIDs returns list of resourceProfile IDs registered for a tenant +func (apierV1 *ApierV1) GetResourceProfileIDs(tenant string, rsPrfIDs *[]string) error { + prfx := utils.ResourceProfilesPrefix + tenant + ":" + keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) + if err != nil { + return err + } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] + } + *rsPrfIDs = retIDs + return nil +} + //SetResourceProfile add a new resource configuration func (apierV1 *ApierV1) SetResourceProfile(res *engine.ResourceProfile, reply *string) error { if missing := utils.MissingStructFields(res, []string{"Tenant", "ID"}); len(missing) != 0 { diff --git a/apier/v1/resourcesv1_it_test.go b/apier/v1/resourcesv1_it_test.go index 8eecdbdbb..14fde5bf7 100644 --- a/apier/v1/resourcesv1_it_test.go +++ b/apier/v1/resourcesv1_it_test.go @@ -56,6 +56,7 @@ var sTestsRLSV1 = []func(t *testing.T){ testV1RsDBStore, testV1RsGetResourceProfileBeforeSet, testV1RsSetResourceProfile, + testV1RsGetResourceProfileIDs, testV1RsGetResourceProfileAfterSet, testV1RsUpdateResourceProfile, testV1RsGetResourceProfileAfterUpdate, @@ -605,6 +606,16 @@ func testV1RsSetResourceProfile(t *testing.T) { } } +func testV1RsGetResourceProfileIDs(t *testing.T) { + expected := []string{"ResGroup2", "ResGroup1", "ResGroup3", "RES_GR_TEST"} + var result []string + if err := rlsV1Rpc.Call("ApierV1.GetResourceProfileIDs", "cgrates.org", &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + func testV1RsGetResourceProfileAfterSet(t *testing.T) { var reply *engine.ResourceProfile if err := rlsV1Rpc.Call("ApierV1.GetResourceProfile", diff --git a/apier/v1/stats.go b/apier/v1/stats.go index ef4c8012a..9112c5fa0 100644 --- a/apier/v1/stats.go +++ b/apier/v1/stats.go @@ -37,6 +37,21 @@ func (apierV1 *ApierV1) GetStatQueueProfile(arg *utils.TenantID, reply *engine.S return } +// GetStatQueueProfileIDs returns list of statQueueProfile IDs registered for a tenant +func (apierV1 *ApierV1) GetStatQueueProfileIDs(tenant string, stsPrfIDs *[]string) error { + prfx := utils.StatQueueProfilePrefix + tenant + ":" + keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) + if err != nil { + return err + } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] + } + *stsPrfIDs = retIDs + return nil +} + // SetStatQueueProfile alters/creates a StatQueueProfile func (apierV1 *ApierV1) SetStatQueueProfile(sqp *engine.StatQueueProfile, reply *string) error { if missing := utils.MissingStructFields(sqp, []string{"Tenant", "ID"}); len(missing) != 0 { diff --git a/apier/v1/stats_it_test.go b/apier/v1/stats_it_test.go index 0496ecba0..3056bc5f4 100644 --- a/apier/v1/stats_it_test.go +++ b/apier/v1/stats_it_test.go @@ -81,6 +81,7 @@ var sTestsStatSV1 = []func(t *testing.T){ testV1STSProcessEvent, testV1STSGetStatsAfterRestart, testV1STSSetStatQueueProfile, + testV1STSGetStatQueueProfileIDs, testV1STSUpdateStatQueueProfile, testV1STSRemoveStatQueueProfile, testV1STSStatsPing, @@ -358,6 +359,16 @@ func testV1STSSetStatQueueProfile(t *testing.T) { } } +func testV1STSGetStatQueueProfileIDs(t *testing.T) { + expected := []string{"Stats1", "TEST_PROFILE1"} + var result []string + if err := stsV1Rpc.Call("ApierV1.GetStatQueueProfileIDs", "cgrates.org", &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + func testV1STSUpdateStatQueueProfile(t *testing.T) { var result string filter = &engine.Filter{ diff --git a/apier/v1/thresholds.go b/apier/v1/thresholds.go index 1e5321f0c..5c51e907b 100644 --- a/apier/v1/thresholds.go +++ b/apier/v1/thresholds.go @@ -71,6 +71,21 @@ func (apierV1 *ApierV1) GetThresholdProfile(arg *utils.TenantID, reply *engine.T return } +// GetThresholdProfileIDs returns list of thresholdProfile IDs registered for a tenant +func (apierV1 *ApierV1) GetThresholdProfileIDs(tenant string, thPrfIDs *[]string) error { + prfx := utils.ThresholdProfilePrefix + tenant + ":" + keys, err := apierV1.DataManager.DataDB().GetKeysForPrefix(prfx) + if err != nil { + return err + } + retIDs := make([]string, len(keys)) + for i, key := range keys { + retIDs[i] = key[len(prfx):] + } + *thPrfIDs = retIDs + return nil +} + // SetThresholdProfile alters/creates a ThresholdProfile func (apierV1 *ApierV1) SetThresholdProfile(thp *engine.ThresholdProfile, reply *string) error { if missing := utils.MissingStructFields(thp, []string{"Tenant", "ID"}); len(missing) != 0 { diff --git a/apier/v1/thresholds_it_test.go b/apier/v1/thresholds_it_test.go index 60e9b5755..f89dd18cb 100644 --- a/apier/v1/thresholds_it_test.go +++ b/apier/v1/thresholds_it_test.go @@ -160,6 +160,7 @@ var sTestsThresholdSV1 = []func(t *testing.T){ testV1TSProcessEvent, testV1TSGetThresholdsAfterProcess, testV1TSGetThresholdsAfterRestart, + testv1TSGetThresholdProfileIDs, testV1TSSetThresholdProfile, testV1TSUpdateThresholdProfile, testV1TSRemoveThresholdProfile, @@ -344,6 +345,16 @@ func testV1TSGetThresholdsAfterRestart(t *testing.T) { } } +func testv1TSGetThresholdProfileIDs(t *testing.T) { + expected := []string{"THD_STATS_1", "THD_STATS_2", "THD_STATS_3", "THD_RES_1", "THD_CDRS_1", "THD_ACNT_BALANCE_1", "THD_ACNT_EXPIRED"} + var result []string + if err := tSv1Rpc.Call("ApierV1.GetThresholdProfileIDs", "cgrates.org", &result); err != nil { + t.Error(err) + } else if len(expected) != len(result) { + t.Errorf("Expecting : %+v, received: %+v", expected, result) + } +} + func testV1TSSetThresholdProfile(t *testing.T) { var reply *engine.ThresholdProfile var result string diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 1de46383a..728619fb0 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -602,12 +602,26 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result = append(result, utils.REVERSE_ALIASES_PREFIX+keyResult.Key) } case utils.ResourceProfilesPrefix: - iter := db.C(colRsP).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colRsP).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.ResourceProfilesPrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.ResourcesPrefix: - iter := db.C(colRes).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colRes).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.ResourcesPrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } @@ -624,7 +638,14 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result = append(result, utils.StatQueuePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.StatQueueProfilePrefix: - iter := db.C(colSqp).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colSqp).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.StatQueueProfilePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } @@ -639,7 +660,14 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result = append(result, utils.TimingsPrefix+idResult.Id) } case utils.FilterPrefix: - iter := db.C(colFlt).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colFlt).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.FilterPrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } @@ -656,22 +684,50 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result = append(result, utils.ThresholdPrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.ThresholdProfilePrefix: - iter := db.C(colTps).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colTps).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.ThresholdProfilePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.SupplierProfilePrefix: - iter := db.C(colSpp).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colSpp).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.SupplierProfilePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.AttributeProfilePrefix: - iter := db.C(colAttr).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colAttr).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.AttributeProfilePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) } case utils.ChargerProfilePrefix: - iter := db.C(colCpp).Find(bson.M{"id": bson.M{"$regex": bson.RegEx{Pattern: subject}}}).Select(bson.M{"tenant": 1, "id": 1}).Iter() + qry := bson.M{} + if tntID.Tenant != "" { + qry["tenant"] = tntID.Tenant + } + if tntID.ID != "" { + qry["id"] = bson.M{"$regex": bson.RegEx{Pattern: subject}} + } + iter := db.C(colCpp).Find(qry).Select(bson.M{"tenant": 1, "id": 1}).Iter() for iter.Next(&idResult) { result = append(result, utils.ChargerProfilePrefix+utils.ConcatenatedKey(idResult.Tenant, idResult.Id)) }