mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 14:19:54 +05:00
Merge fixes
This commit is contained in:
@@ -28,7 +28,7 @@ func (self *ApierV1) SetFilter(attrs *engine.Filter, reply *string) error {
|
||||
if missing := utils.MissingStructFields(attrs, []string{"Tenant", "ID"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if err := self.DataManager.DataDB().SetFilter(attrs); err != nil {
|
||||
if err := self.DataManager.SetFilter(attrs); err != nil {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
*reply = utils.OK
|
||||
@@ -40,7 +40,7 @@ func (self *ApierV1) GetFilter(arg utils.TenantID, reply *engine.Filter) error {
|
||||
if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if fltr, err := self.DataManager.DataDB().GetFilter(arg.Tenant, arg.ID, true, utils.NonTransactional); err != nil {
|
||||
if fltr, err := self.DataManager.GetFilter(arg.Tenant, arg.ID, true, utils.NonTransactional); err != nil {
|
||||
if err.Error() != utils.ErrNotFound.Error() {
|
||||
err = utils.NewErrServerError(err)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (self *ApierV1) RemFilter(arg utils.TenantID, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if err := self.DataManager.DataDB().RemoveFilter(arg.Tenant, arg.ID, utils.NonTransactional); err != nil {
|
||||
if err := self.DataManager.RemoveFilter(arg.Tenant, arg.ID, utils.NonTransactional); err != nil {
|
||||
if err.Error() != utils.ErrNotFound.Error() {
|
||||
err = utils.NewErrServerError(err)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package v1
|
||||
|
||||
/*
|
||||
import (
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
@@ -30,172 +29,185 @@ import (
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
filterProfileCfgPath string
|
||||
filterProfileCfg *config.CGRConfig
|
||||
filterProfileRPC *rpc.Client
|
||||
filterProfileDataDir = "/usr/share/cgrates"
|
||||
filterProfile *engine.FilterProfile
|
||||
filterProfileDelay int
|
||||
filterProfileConfigDIR string //run tests for specific configuration
|
||||
filterCfgPath string
|
||||
filterCfg *config.CGRConfig
|
||||
filterRPC *rpc.Client
|
||||
filterDataDir = "/usr/share/cgrates"
|
||||
filter *engine.Filter
|
||||
filterDelay int
|
||||
filterConfigDIR string //run tests for specific configuration
|
||||
)
|
||||
|
||||
var sTestsFilterProfile = []func(t *testing.T){
|
||||
testFilterProfileInitCfg,
|
||||
testFilterProfileResetDataDB,
|
||||
testFilterProfileStartEngine,
|
||||
testFilterProfileRpcConn,
|
||||
testFilterProfileGetFilterProfileBeforeSet,
|
||||
testFilterProfileSetFilterProfile,
|
||||
testFilterProfileGetFilterProfileAfterSet,
|
||||
testFilterProfileUpdateFilterProfile,
|
||||
testFilterProfileGetFilterProfileAfterUpdate,
|
||||
testFilterProfileRemFilterProfile,
|
||||
testFilterProfileGetFilterProfileAfterRemove,
|
||||
testFilterProfileKillEngine,
|
||||
var sTestsFilter = []func(t *testing.T){
|
||||
testFilterInitCfg,
|
||||
testFilterResetDataDB,
|
||||
testFilterStartEngine,
|
||||
testFilterRpcConn,
|
||||
testFilterGetFilterBeforeSet,
|
||||
testFilterSetFilter,
|
||||
testFilterGetFilterAfterSet,
|
||||
testFilterUpdateFilter,
|
||||
testFilterGetFilterAfterUpdate,
|
||||
testFilterRemFilter,
|
||||
testFilterGetFilterAfterRemove,
|
||||
testFilterKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestFilterProfileITMySql(t *testing.T) {
|
||||
filterProfileConfigDIR = "tutmysql"
|
||||
for _, stest := range sTestsFilterProfile {
|
||||
t.Run(filterProfileConfigDIR, stest)
|
||||
func TestFilterITMySql(t *testing.T) {
|
||||
filterConfigDIR = "tutmysql"
|
||||
for _, stest := range sTestsFilter {
|
||||
t.Run(filterConfigDIR, stest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterProfileITMongo(t *testing.T) {
|
||||
filterProfileConfigDIR = "tutmongo"
|
||||
for _, stest := range sTestsFilterProfile {
|
||||
t.Run(filterProfileConfigDIR, stest)
|
||||
func TestFilterITMongo(t *testing.T) {
|
||||
filterConfigDIR = "tutmongo"
|
||||
for _, stest := range sTestsFilter {
|
||||
t.Run(filterConfigDIR, stest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterProfileITPG(t *testing.T) {
|
||||
filterProfileConfigDIR = "tutpostgres"
|
||||
for _, stest := range sTestsFilterProfile {
|
||||
t.Run(filterProfileConfigDIR, stest)
|
||||
func TestFilterITPG(t *testing.T) {
|
||||
filterConfigDIR = "tutpostgres"
|
||||
for _, stest := range sTestsFilter {
|
||||
t.Run(filterConfigDIR, stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileInitCfg(t *testing.T) {
|
||||
func testFilterInitCfg(t *testing.T) {
|
||||
var err error
|
||||
filterProfileCfgPath = path.Join(filterProfileDataDir, "conf", "samples", filterProfileConfigDIR)
|
||||
filterProfileCfg, err = config.NewCGRConfigFromFolder(filterProfileCfgPath)
|
||||
filterCfgPath = path.Join(filterDataDir, "conf", "samples", filterConfigDIR)
|
||||
filterCfg, err = config.NewCGRConfigFromFolder(filterCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
filterProfileCfg.DataFolderPath = filterProfileDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(filterProfileCfg)
|
||||
switch filterProfileConfigDIR {
|
||||
filterCfg.DataFolderPath = filterDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(filterCfg)
|
||||
switch filterConfigDIR {
|
||||
case "tutmongo": // Mongo needs more time to reset db, need to investigate
|
||||
filterProfileDelay = 2000
|
||||
filterDelay = 2000
|
||||
default:
|
||||
filterProfileDelay = 1000
|
||||
filterDelay = 1000
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testFilterProfileResetDataDB(t *testing.T) {
|
||||
if err := engine.InitDataDb(filterProfileCfg); err != nil {
|
||||
func testFilterResetDataDB(t *testing.T) {
|
||||
if err := engine.InitDataDb(filterCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testFilterProfileStartEngine(t *testing.T) {
|
||||
if _, err := engine.StopStartEngine(filterProfileCfgPath, filterProfileDelay); err != nil {
|
||||
func testFilterStartEngine(t *testing.T) {
|
||||
if _, err := engine.StopStartEngine(filterCfgPath, filterDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testFilterProfileRpcConn(t *testing.T) {
|
||||
func testFilterRpcConn(t *testing.T) {
|
||||
var err error
|
||||
filterProfileRPC, err = jsonrpc.Dial("tcp", filterProfileCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
filterRPC, err = jsonrpc.Dial("tcp", filterCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileGetFilterProfileBeforeSet(t *testing.T) {
|
||||
var reply *engine.FilterProfile
|
||||
if err := filterProfileRPC.Call("ApierV1.GetFilterProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
func testFilterGetFilterBeforeSet(t *testing.T) {
|
||||
var reply *engine.Filter
|
||||
if err := filterRPC.Call("ApierV1.GetFilter", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileSetFilterProfile(t *testing.T) {
|
||||
filterProfile = &engine.FilterProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter1",
|
||||
FilterType: "*string_prefix",
|
||||
FilterFieldName: "Account",
|
||||
FilterFieldValues: []string{"10", "20"},
|
||||
func testFilterSetFilter(t *testing.T) {
|
||||
filter = &engine.Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter1",
|
||||
RequestFilters: []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
FieldName: "*string",
|
||||
Type: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC).Local(),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC).Local(),
|
||||
},
|
||||
}
|
||||
|
||||
var result string
|
||||
if err := filterProfileRPC.Call("ApierV1.SetFilterProfile", filterProfile, &result); err != nil {
|
||||
if err := filterRPC.Call("ApierV1.SetFilter", filter, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileGetFilterProfileAfterSet(t *testing.T) {
|
||||
var reply *engine.FilterProfile
|
||||
if err := filterProfileRPC.Call("ApierV1.GetFilterProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err != nil {
|
||||
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 {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(filterProfile, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", filterProfile, reply)
|
||||
} else if !reflect.DeepEqual(filter, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", filter, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileUpdateFilterProfile(t *testing.T) {
|
||||
filterProfile = &engine.FilterProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter1",
|
||||
FilterType: "*string_prefix",
|
||||
FilterFieldName: "Destination",
|
||||
FilterFieldValues: []string{"1001", "1002"},
|
||||
func testFilterUpdateFilter(t *testing.T) {
|
||||
filter.RequestFilters = []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
FieldName: "*string",
|
||||
Type: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&engine.RequestFilter{
|
||||
FieldName: "*string_prefix",
|
||||
Type: "Destination",
|
||||
Values: []string{"10", "20"},
|
||||
},
|
||||
}
|
||||
var result string
|
||||
if err := filterProfileRPC.Call("ApierV1.SetFilterProfile", filterProfile, &result); err != nil {
|
||||
if err := filterRPC.Call("ApierV1.SetFilter", filter, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileGetFilterProfileAfterUpdate(t *testing.T) {
|
||||
var reply *engine.FilterProfile
|
||||
if err := filterProfileRPC.Call("ApierV1.GetFilterProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err != nil {
|
||||
func testFilterGetFilterAfterUpdate(t *testing.T) {
|
||||
var reply *engine.Filter
|
||||
if err := filterRPC.Call("ApierV1.GetFilter", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(filterProfile, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", filterProfile, reply)
|
||||
} else if !reflect.DeepEqual(filter, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", filter, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileRemFilterProfile(t *testing.T) {
|
||||
func testFilterRemFilter(t *testing.T) {
|
||||
var resp string
|
||||
if err := filterProfileRPC.Call("ApierV1.RemFilterProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &resp); err != nil {
|
||||
if err := filterRPC.Call("ApierV1.RemFilter", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &resp); err != nil {
|
||||
t.Error(err)
|
||||
} else if resp != utils.OK {
|
||||
t.Error("Unexpected reply returned", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileGetFilterProfileAfterRemove(t *testing.T) {
|
||||
var reply *engine.FilterProfile
|
||||
if err := filterProfileRPC.Call("ApierV1.GetFilterProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
func testFilterGetFilterAfterRemove(t *testing.T) {
|
||||
var reply *engine.Filter
|
||||
if err := filterRPC.Call("ApierV1.GetFilter", &utils.TenantID{Tenant: "cgrates.org", ID: "Filter1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testFilterProfileKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(filterProfileDelay); err != nil {
|
||||
func testFilterKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(filterDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -507,8 +507,8 @@ func testV1RsSetResourceProfile(t *testing.T) {
|
||||
rlsConfig = &engine.ResourceProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "RCFG1",
|
||||
Filters: []*engine.Filter{
|
||||
&engine.Filter{
|
||||
Filters: []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
Type: "type",
|
||||
FieldName: "Name",
|
||||
Values: []string{"FilterValue1", "FilterValue2"},
|
||||
@@ -546,13 +546,13 @@ func testV1RsGetResourceProfileAfterSet(t *testing.T) {
|
||||
|
||||
func testV1RsUpdateResourceProfile(t *testing.T) {
|
||||
var result string
|
||||
rlsConfig.Filters = []*engine.Filter{
|
||||
&engine.Filter{
|
||||
rlsConfig.Filters = []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
Type: "type",
|
||||
FieldName: "Name",
|
||||
Values: []string{"FilterValue1", "FilterValue2"},
|
||||
},
|
||||
&engine.Filter{
|
||||
&engine.RequestFilter{
|
||||
Type: "*string",
|
||||
FieldName: "Accout",
|
||||
Values: []string{"1001", "1002"},
|
||||
|
||||
@@ -277,8 +277,8 @@ func testV1STSSetStatQueueProfile(t *testing.T) {
|
||||
statConfig = &engine.StatQueueProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "TEST_PROFILE1",
|
||||
Filters: []*engine.Filter{
|
||||
&engine.Filter{
|
||||
Filters: []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
Type: "type",
|
||||
FieldName: "Name",
|
||||
Values: []string{"FilterValue1", "FilterValue2"},
|
||||
@@ -313,18 +313,18 @@ func testV1STSSetStatQueueProfile(t *testing.T) {
|
||||
|
||||
func testV1STSUpdateStatQueueProfile(t *testing.T) {
|
||||
var result string
|
||||
statConfig.Filters = []*engine.Filter{
|
||||
&engine.Filter{
|
||||
statConfig.Filters = []*engine.RequestFilter{
|
||||
&engine.RequestFilter{
|
||||
Type: "type",
|
||||
FieldName: "Name",
|
||||
Values: []string{"FilterValue1", "FilterValue2"},
|
||||
},
|
||||
&engine.Filter{
|
||||
&engine.RequestFilter{
|
||||
Type: "*string",
|
||||
FieldName: "Accout",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&engine.Filter{
|
||||
&engine.RequestFilter{
|
||||
Type: "*string_prefix",
|
||||
FieldName: "Destination",
|
||||
Values: []string{"10", "20"},
|
||||
|
||||
@@ -128,12 +128,20 @@ func ttestTPFilterGetTPFilterBeforeSet(t *testing.T) {
|
||||
|
||||
func testTPFilterSetTPFilter(t *testing.T) {
|
||||
tpFilter = &utils.TPFilter{
|
||||
TPid: "TP1",
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter",
|
||||
FilterType: "*string",
|
||||
FilterFieldName: "Account",
|
||||
FilterFielValues: []string{"1001", "1002"},
|
||||
TPid: "TP1",
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
Type: "*string",
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.TPActivationInterval{
|
||||
ActivationTime: "2014-07-29T15:00:00Z",
|
||||
ExpiryTime: "",
|
||||
},
|
||||
}
|
||||
|
||||
var result string
|
||||
@@ -166,15 +174,18 @@ func testTPFilterGetFilterIds(t *testing.T) {
|
||||
}
|
||||
|
||||
func testTPFilterUpdateTPFilter(t *testing.T) {
|
||||
tpFilter = &utils.TPFilter{
|
||||
TPid: "TP1",
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter",
|
||||
FilterType: "*string_prefix",
|
||||
FilterFieldName: "Account",
|
||||
FilterFielValues: []string{"10", "20"},
|
||||
tpFilter.Filters = []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
Type: "*string",
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&utils.TPRequestFilter{
|
||||
Type: "*string_prefix",
|
||||
FieldName: "Destination",
|
||||
Values: []string{"10", "20"},
|
||||
},
|
||||
}
|
||||
|
||||
var result string
|
||||
if err := tpFilterRPC.Call("ApierV1.SetTPFilter", tpFilter, &result); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -147,6 +147,7 @@ func testTPThreholdSetTPThrehold(t *testing.T) {
|
||||
Blocker: true,
|
||||
Weight: 10,
|
||||
ActionIDs: []string{"Thresh1", "Thresh2"},
|
||||
Async: true,
|
||||
}
|
||||
var result string
|
||||
if err := tpThresholdRPC.Call("ApierV1.SetTPThreshold", tpThreshold, &result); err != nil {
|
||||
|
||||
@@ -465,6 +465,7 @@ CREATE TABLE tp_thresholds (
|
||||
`blocker` BOOLEAN NOT NULL,
|
||||
`weight` decimal(8,2) NOT NULL,
|
||||
`action_ids` varchar(64) NOT NULL,
|
||||
`async` BOOLEAN NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `tpid` (`tpid`),
|
||||
@@ -484,6 +485,7 @@ CREATE TABLE tp_filters (
|
||||
`filter_type` varchar(16) NOT NULL,
|
||||
`filter_field_name` varchar(64) NOT NULL,
|
||||
`filter_field_values` varchar(256) NOT NULL,
|
||||
`activation_interval` varchar(64) NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `tpid` (`tpid`),
|
||||
|
||||
@@ -460,6 +460,7 @@ CREATE TABLE tp_thresholds (
|
||||
"blocker" BOOLEAN NOT NULL,
|
||||
"weight" decimal(8,2) NOT NULL,
|
||||
"action_ids" varchar(64) NOT NULL,
|
||||
"async" BOOLEAN NOT NULL,
|
||||
"created_at" TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
CREATE INDEX tp_thresholds_idx ON tp_thresholds (tpid);
|
||||
@@ -478,6 +479,7 @@ CREATE TABLE tp_filters (
|
||||
"filter_type" varchar(16) NOT NULL,
|
||||
"filter_field_name" varchar(64) NOT NULL,
|
||||
"filter_field_values" varchar(256) NOT NULL,
|
||||
"activation_interval" varchar(64) NOT NULL,
|
||||
"created_at" TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
CREATE INDEX tp_filters_idx ON tp_filters (tpid);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4]
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002)
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5]
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002),
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL,2014-07-29T15:00:00Z
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#Tenant[0],Id[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5],Recurrent[6],MinSleep[7],Blocker[8],Weight[9],ActionIDs[10]
|
||||
cgrates.org,Threshold1,*string,Account,1001;1002,2014-07-29T15:00:00Z,true,1s,true,10,THRESH1;THRESH2
|
||||
#Tenant[0],Id[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5],Recurrent[6],MinSleep[7],Blocker[8],Weight[9],ActionIDs[10],Async[11]
|
||||
cgrates.org,Threshold1,*string,Account,1001;1002,2014-07-29T15:00:00Z,true,1s,true,10,THRESH1;THRESH2,true
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5]
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002)
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002),
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL,2014-07-29T15:00:00Z
|
||||
|
||||
|
@@ -78,3 +78,37 @@ func (dm *DataManager) RemStatQueue(tenant, id string, transactionID string) (er
|
||||
cache.RemKey(utils.StatQueuePrefix+utils.ConcatenatedKey(tenant, id), cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
func (dm *DataManager) GetFilter(tenant, id string, skipCache bool, transactionID string) (fltr *Filter, err error) {
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
if !skipCache {
|
||||
if x, ok := cache.Get(key); ok {
|
||||
if x == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return x.(*Filter), nil
|
||||
}
|
||||
}
|
||||
fltr, err = dm.dataDB.GetFilterDrv(tenant, id)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
cache.Set(key, nil, cacheCommit(transactionID), transactionID)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
cache.Set(key, fltr, cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
func (dm *DataManager) SetFilter(fltr *Filter) (err error) {
|
||||
return dm.DataDB().SetFilterDrv(fltr)
|
||||
}
|
||||
|
||||
func (dm *DataManager) RemoveFilter(tenant, id, transactionID string) (err error) {
|
||||
if err = dm.DataDB().RemoveFilterDrv(tenant, id); err != nil {
|
||||
return
|
||||
}
|
||||
cache.RemKey(utils.FilterPrefix+utils.ConcatenatedKey(tenant, id),
|
||||
cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/*
|
||||
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/>
|
||||
*/
|
||||
@@ -29,13 +26,13 @@ func TestReqFilterPassString(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Subject: "dan", Destination: "+4986517174963",
|
||||
TimeStart: time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC), TimeEnd: time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC),
|
||||
DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}}
|
||||
rf := &Filter{Type: MetaString, FieldName: "Category", Values: []string{"call"}}
|
||||
rf := &RequestFilter{Type: MetaString, FieldName: "Category", Values: []string{"call"}}
|
||||
if passes, err := rf.passString(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !passes {
|
||||
t.Error("Not passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaString, FieldName: "Category", Values: []string{"cal"}}
|
||||
rf = &RequestFilter{Type: MetaString, FieldName: "Category", Values: []string{"cal"}}
|
||||
if passes, err := rf.passString(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if passes {
|
||||
@@ -47,37 +44,37 @@ func TestReqFilterPassStringPrefix(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Subject: "dan", Destination: "+4986517174963",
|
||||
TimeStart: time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC), TimeEnd: time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC),
|
||||
DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}}
|
||||
rf := &Filter{Type: MetaStringPrefix, FieldName: "Category", Values: []string{"call"}}
|
||||
rf := &RequestFilter{Type: MetaStringPrefix, FieldName: "Category", Values: []string{"call"}}
|
||||
if passes, err := rf.passStringPrefix(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !passes {
|
||||
t.Error("Not passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaStringPrefix, FieldName: "Category", Values: []string{"premium"}}
|
||||
rf = &RequestFilter{Type: MetaStringPrefix, FieldName: "Category", Values: []string{"premium"}}
|
||||
if passes, err := rf.passStringPrefix(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if passes {
|
||||
t.Error("Passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"+49"}}
|
||||
rf = &RequestFilter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"+49"}}
|
||||
if passes, err := rf.passStringPrefix(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !passes {
|
||||
t.Error("Not passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"+499"}}
|
||||
rf = &RequestFilter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"+499"}}
|
||||
if passes, err := rf.passStringPrefix(cd, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if passes {
|
||||
t.Error("Passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaStringPrefix, FieldName: "navigation", Values: []string{"off"}}
|
||||
rf = &RequestFilter{Type: MetaStringPrefix, FieldName: "navigation", Values: []string{"off"}}
|
||||
if passes, err := rf.passStringPrefix(cd, "ExtraFields"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !passes {
|
||||
t.Error("Not passes filter")
|
||||
}
|
||||
rf = &Filter{Type: MetaStringPrefix, FieldName: "nonexisting", Values: []string{"off"}}
|
||||
rf = &RequestFilter{Type: MetaStringPrefix, FieldName: "nonexisting", Values: []string{"off"}}
|
||||
if passing, err := rf.passStringPrefix(cd, "ExtraFields"); err != nil {
|
||||
t.Error(err)
|
||||
} else if passing {
|
||||
@@ -89,7 +86,7 @@ func TestReqFilterPassRSRFields(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Subject: "dan", Destination: "+4986517174963",
|
||||
TimeStart: time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC), TimeEnd: time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC),
|
||||
DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}}
|
||||
rf, err := NewFilter(MetaRSRFields, "", []string{"Tenant(~^cgr.*\\.org$)"})
|
||||
rf, err := NewRequestFilter(MetaRSRFields, "", []string{"Tenant(~^cgr.*\\.org$)"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -98,7 +95,7 @@ func TestReqFilterPassRSRFields(t *testing.T) {
|
||||
} else if !passes {
|
||||
t.Error("Not passing")
|
||||
}
|
||||
rf, err = NewFilter(MetaRSRFields, "", []string{"navigation(on)"})
|
||||
rf, err = NewRequestFilter(MetaRSRFields, "", []string{"navigation(on)"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -107,7 +104,7 @@ func TestReqFilterPassRSRFields(t *testing.T) {
|
||||
} else if passes {
|
||||
t.Error("Passing")
|
||||
}
|
||||
rf, err = NewFilter(MetaRSRFields, "", []string{"navigation(off)"})
|
||||
rf, err = NewRequestFilter(MetaRSRFields, "", []string{"navigation(off)"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -123,7 +120,7 @@ func TestReqFilterPassDestinations(t *testing.T) {
|
||||
cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Subject: "dan", Destination: "+4986517174963",
|
||||
TimeStart: time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC), TimeEnd: time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC),
|
||||
DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}}
|
||||
rf, err := NewFilter(MetaDestinations, "Destination", []string{"DE"})
|
||||
rf, err := NewRequestFilter(MetaDestinations, "Destination", []string{"DE"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -132,7 +129,7 @@ func TestReqFilterPassDestinations(t *testing.T) {
|
||||
} else if !passes {
|
||||
t.Error("Not passing")
|
||||
}
|
||||
rf, err = NewFilter(MetaDestinations, "Destination", []string{"RO"})
|
||||
rf, err = NewRequestFilter(MetaDestinations, "Destination", []string{"RO"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func (rfi *ReqFilterIndexer) ChangedKeys() utils.StringMap {
|
||||
}
|
||||
|
||||
// IndexFilters parses reqFltrs, adding itemID in the indexes and marks the changed keys in chngdIndxKeys
|
||||
func (rfi *ReqFilterIndexer) IndexFilters(itemID string, reqFltrs []*Filter) {
|
||||
func (rfi *ReqFilterIndexer) IndexFilters(itemID string, reqFltrs []*RequestFilter) {
|
||||
var hasMetaString bool
|
||||
for _, fltr := range reqFltrs {
|
||||
if fltr.Type != MetaString {
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/*
|
||||
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/>
|
||||
*/
|
||||
@@ -40,7 +37,7 @@ const (
|
||||
MetaMaxCapPrefix = "*max_"
|
||||
)
|
||||
|
||||
func NewFilter(rfType, fieldName string, vals []string) (*Filter, error) {
|
||||
func NewRequestFilter(rfType, fieldName string, vals []string) (*RequestFilter, error) {
|
||||
if !utils.IsSliceMember([]string{MetaStringPrefix, MetaTimings, MetaRSRFields, MetaStatS, MetaDestinations}, rfType) {
|
||||
return nil, fmt.Errorf("Unsupported filter Type: %s", rfType)
|
||||
}
|
||||
@@ -50,7 +47,7 @@ func NewFilter(rfType, fieldName string, vals []string) (*Filter, error) {
|
||||
if len(vals) == 0 && utils.IsSliceMember([]string{MetaStringPrefix, MetaTimings, MetaRSRFields, MetaDestinations, MetaDestinations}, rfType) {
|
||||
return nil, fmt.Errorf("Values is mandatory for Type: %s", rfType)
|
||||
}
|
||||
rf := &Filter{Type: rfType, FieldName: fieldName, Values: vals}
|
||||
rf := &RequestFilter{Type: rfType, FieldName: fieldName, Values: vals}
|
||||
if err := rf.CompileValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,16 +60,22 @@ type RFStatSThreshold struct {
|
||||
ThresholdValue float64
|
||||
}
|
||||
|
||||
// Filter filters requests coming into various places
|
||||
// RequestFilter filters requests coming into various places
|
||||
// Pass rule: default negative, one mathing rule should pass the filter
|
||||
type RequestFilter struct {
|
||||
Type string // Filter type (*string, *timing, *rsr_filters, *cdr_stats)
|
||||
FieldName string // Name of the field providing us the Values to check (used in case of some )
|
||||
Values []string // Filter definition
|
||||
ActivationInterval *utils.ActivationInterval
|
||||
rsrFields utils.RSRFields // Cache here the RSRFilter Values
|
||||
statSThresholds []*RFStatSThreshold // Cached compiled RFStatsThreshold out of Values
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Tenant string
|
||||
ID string
|
||||
Type string // Filter type (*string, *timing, *rsr_filters, *cdr_stats)
|
||||
FieldName string // Name of the field providing us the Values to check (used in case of some )
|
||||
Values []string // Filter definition
|
||||
rsrFields utils.RSRFields // Cache here the RSRFilter Values
|
||||
statSThresholds []*RFStatSThreshold // Cached compiled RFStatsThreshold out of Values
|
||||
Tenant string
|
||||
ID string
|
||||
RequestFilters []*RequestFilter
|
||||
ActivationInterval *utils.ActivationInterval
|
||||
}
|
||||
|
||||
func (flt *Filter) TenantID() string {
|
||||
@@ -80,7 +83,7 @@ func (flt *Filter) TenantID() string {
|
||||
}
|
||||
|
||||
// Separate method to compile RSR fields
|
||||
func (rf *Filter) CompileValues() (err error) {
|
||||
func (rf *RequestFilter) CompileValues() (err error) {
|
||||
if rf.Type == MetaRSRFields {
|
||||
if rf.rsrFields, err = utils.ParseRSRFieldsFromSlice(rf.Values); err != nil {
|
||||
return
|
||||
@@ -110,7 +113,7 @@ func (rf *Filter) CompileValues() (err error) {
|
||||
}
|
||||
|
||||
// Pass is the method which should be used from outside.
|
||||
func (fltr *Filter) Pass(req interface{}, extraFieldsLabel string, rpcClnt rpcclient.RpcClientConnection) (bool, error) {
|
||||
func (fltr *RequestFilter) Pass(req interface{}, extraFieldsLabel string, rpcClnt rpcclient.RpcClientConnection) (bool, error) {
|
||||
switch fltr.Type {
|
||||
case MetaString:
|
||||
return fltr.passString(req, extraFieldsLabel)
|
||||
@@ -129,7 +132,7 @@ func (fltr *Filter) Pass(req interface{}, extraFieldsLabel string, rpcClnt rpccl
|
||||
}
|
||||
}
|
||||
|
||||
func (fltr *Filter) passString(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
func (fltr *RequestFilter) passString(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
strVal, err := utils.ReflectFieldAsString(req, fltr.FieldName, extraFieldsLabel)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -145,7 +148,7 @@ func (fltr *Filter) passString(req interface{}, extraFieldsLabel string) (bool,
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *Filter) passStringPrefix(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
func (fltr *RequestFilter) passStringPrefix(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
strVal, err := utils.ReflectFieldAsString(req, fltr.FieldName, extraFieldsLabel)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -162,11 +165,11 @@ func (fltr *Filter) passStringPrefix(req interface{}, extraFieldsLabel string) (
|
||||
}
|
||||
|
||||
// ToDo when Timings will be available in DataDb
|
||||
func (fltr *Filter) passTimings(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
func (fltr *RequestFilter) passTimings(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
return false, utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (fltr *Filter) passDestinations(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
func (fltr *RequestFilter) passDestinations(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
dst, err := utils.ReflectFieldAsString(req, fltr.FieldName, extraFieldsLabel)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -188,7 +191,7 @@ func (fltr *Filter) passDestinations(req interface{}, extraFieldsLabel string) (
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *Filter) passRSRFields(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
func (fltr *RequestFilter) passRSRFields(req interface{}, extraFieldsLabel string) (bool, error) {
|
||||
for _, rsrFld := range fltr.rsrFields {
|
||||
if strVal, err := utils.ReflectFieldAsString(req, rsrFld.Id, extraFieldsLabel); err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -202,7 +205,7 @@ func (fltr *Filter) passRSRFields(req interface{}, extraFieldsLabel string) (boo
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *Filter) passStatS(req interface{}, extraFieldsLabel string, stats rpcclient.RpcClientConnection) (bool, error) {
|
||||
func (fltr *RequestFilter) passStatS(req interface{}, extraFieldsLabel string, stats rpcclient.RpcClientConnection) (bool, error) {
|
||||
if stats == nil || reflect.ValueOf(stats).IsNil() {
|
||||
return false, errors.New("Missing StatS information")
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
type StatQueueProfile struct {
|
||||
Tenant string
|
||||
ID string // QueueID
|
||||
Filters []*Filter
|
||||
Filters []*RequestFilter
|
||||
ActivationInterval *utils.ActivationInterval // Activation interval
|
||||
QueueLength int
|
||||
TTL time.Duration
|
||||
|
||||
@@ -18,13 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/cache"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"log"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/cache"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -278,17 +277,17 @@ cgrates.org,Stats1,*string,Account,1001;1002,2014-07-29T15:00:00Z,100,1s,*asr;*a
|
||||
`
|
||||
|
||||
thresholds = `
|
||||
#Tenant[0],Id[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5],Recurrent[6],MinSleep[7],Blocker[8],Weight[9],ActionIDs[10]
|
||||
cgrates.org,Threshold1,*string,Account,1001;1002,2014-07-29T15:00:00Z,true,1s,true,10,THRESH1;THRESH2
|
||||
#Tenant[0],Id[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5],Recurrent[6],MinSleep[7],Blocker[8],Weight[9],ActionIDs[10],Async[11]
|
||||
cgrates.org,Threshold1,*string,Account,1001;1002,2014-07-29T15:00:00Z,true,1s,true,10,THRESH1;THRESH2,true
|
||||
`
|
||||
filters = `
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4]
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002)
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL
|
||||
#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5]
|
||||
cgrates.org,FLTR_1,*string,Account,1001;1002,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*string_prefix,Destination,10;20,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_1,*rsr_fields,,Subject(~^1.*1$);Destination(1002),
|
||||
cgrates.org,FLTR_ACNT_dan,*string,Account,dan,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_DE,*destinations,Destination,DST_DE,2014-07-29T15:00:00Z
|
||||
cgrates.org,FLTR_DST_NL,*destinations,Destination,DST_NL,2014-07-29T15:00:00Z
|
||||
`
|
||||
)
|
||||
|
||||
@@ -356,6 +355,9 @@ func init() {
|
||||
if err := csvr.LoadThresholds(); err != nil {
|
||||
log.Print("error in LoadThresholds:", err)
|
||||
}
|
||||
if err := csvr.LoadFilter(); err != nil {
|
||||
log.Print("error in LoadFilter:", err)
|
||||
}
|
||||
csvr.WriteToDatabase(false, false, false)
|
||||
cache.Flush()
|
||||
dm.DataDB().LoadDataDBCache(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
@@ -1441,12 +1443,11 @@ func TestLoadResourceProfiles(t *testing.T) {
|
||||
t.Errorf("Failed to load resourceProfiles: %s", utils.ToIJSON(csvr.resProfiles))
|
||||
} else if !reflect.DeepEqual(eResProfiles["cgrates.org"]["ResGroup22"], csvr.resProfiles["cgrates.org"]["ResGroup22"]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eResProfiles["cgrates.org"]["ResGroup22"], csvr.resProfiles["cgrates.org"]["ResGroup22"])
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestLoadStats(t *testing.T) {
|
||||
func TestLoadStatProfiles(t *testing.T) {
|
||||
eStats := map[string]map[string]*utils.TPStats{
|
||||
"cgrates.org": map[string]*utils.TPStats{
|
||||
"Stats1": &utils.TPStats{
|
||||
@@ -1479,7 +1480,7 @@ func TestLoadStats(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadThresholds(t *testing.T) {
|
||||
func TestLoadThresholdProfiles(t *testing.T) {
|
||||
eThresholds := map[string]map[string]*utils.TPThreshold{
|
||||
"cgrates.org": map[string]*utils.TPThreshold{
|
||||
"Threshold1": &utils.TPThreshold{
|
||||
@@ -1497,6 +1498,7 @@ func TestLoadThresholds(t *testing.T) {
|
||||
Blocker: true,
|
||||
Weight: 10,
|
||||
ActionIDs: []string{"THRESH1", "THRESH2"},
|
||||
Async: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1506,3 +1508,156 @@ func TestLoadThresholds(t *testing.T) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eThresholds["cgrates.org"]["Threshold1"], csvr.thProfiles["cgrates.org"]["Threshold1"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadFilterProfiles(t *testing.T) {
|
||||
eFilters := map[string]map[string]*utils.TPFilter{
|
||||
"cgrates.org": map[string]*utils.TPFilter{
|
||||
"FLTR_1": &utils.TPFilter{
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_1",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Account",
|
||||
Type: "*string",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Destination",
|
||||
Type: "*string_prefix",
|
||||
Values: []string{"10", "20"},
|
||||
},
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "",
|
||||
Type: "*rsr_fields",
|
||||
Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.TPActivationInterval{
|
||||
ActivationTime: "2014-07-29T15:00:00Z",
|
||||
},
|
||||
},
|
||||
"FLTR_ACNT_dan": &utils.TPFilter{
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_ACNT_dan",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Account",
|
||||
Type: "*string",
|
||||
Values: []string{"dan"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.TPActivationInterval{
|
||||
ActivationTime: "2014-07-29T15:00:00Z",
|
||||
},
|
||||
},
|
||||
"FLTR_DST_DE": &utils.TPFilter{
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_DST_DE",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Destination",
|
||||
Type: "*destinations",
|
||||
Values: []string{"DST_DE"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.TPActivationInterval{
|
||||
ActivationTime: "2014-07-29T15:00:00Z",
|
||||
},
|
||||
},
|
||||
"FLTR_DST_NL": &utils.TPFilter{
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_DST_NL",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Destination",
|
||||
Type: "*destinations",
|
||||
Values: []string{"DST_NL"},
|
||||
},
|
||||
},
|
||||
ActivationInterval: &utils.TPActivationInterval{
|
||||
ActivationTime: "2014-07-29T15:00:00Z",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if len(csvr.flProfiles["cgrates.org"]) != len(eFilters["cgrates.org"]) {
|
||||
t.Errorf("Failed to load FilterProfiles: %s", utils.ToIJSON(csvr.flProfiles))
|
||||
} else if !reflect.DeepEqual(eFilters["cgrates.org"]["FLTR_1"], csvr.flProfiles["cgrates.org"]["FLTR_1"]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eFilters["cgrates.org"]["FLTR_1"], csvr.flProfiles["cgrates.org"]["FLTR_1"])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestLoadResource(t *testing.T) {
|
||||
eResources := []*utils.TenantID{
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ResGroup21",
|
||||
},
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ResGroup22",
|
||||
},
|
||||
}
|
||||
if len(csvr.resources) != len(eResources) {
|
||||
t.Errorf("Failed to load resources: %s", utils.ToIJSON(csvr.resources))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadstatQueues(t *testing.T) {
|
||||
eStatQueues := []*utils.TenantID{
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Stats1",
|
||||
},
|
||||
}
|
||||
|
||||
if len(csvr.statQueues) != len(eStatQueues) {
|
||||
t.Errorf("Failed to load statQueues: %s", utils.ToIJSON(csvr.statQueues))
|
||||
} else if !reflect.DeepEqual(eStatQueues, csvr.statQueues) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eStatQueues, csvr.statQueues)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadThresholds(t *testing.T) {
|
||||
eThresholds := []*utils.TenantID{
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Threshold1",
|
||||
},
|
||||
}
|
||||
|
||||
if len(csvr.thresholds) != len(eThresholds) {
|
||||
t.Errorf("Failed to load thresholds: %s", utils.ToIJSON(csvr.thresholds))
|
||||
} else if !reflect.DeepEqual(eThresholds, csvr.thresholds) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eThresholds, csvr.thresholds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadFilters(t *testing.T) {
|
||||
eFilters := []*utils.TenantID{
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_1",
|
||||
},
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_ACNT_dan",
|
||||
},
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_DST_DE",
|
||||
},
|
||||
&utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "FLTR_DST_NL",
|
||||
},
|
||||
}
|
||||
if len(csvr.filters) != len(eFilters) {
|
||||
t.Errorf("Failed to load filters: %s", utils.ToIJSON(csvr.filters))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1934,7 +1934,7 @@ func APItoResource(tpRL *utils.TPResource, timezone string) (rp *ResourceProfile
|
||||
Weight: tpRL.Weight,
|
||||
Blocker: tpRL.Blocker,
|
||||
Stored: tpRL.Stored,
|
||||
Filters: make([]*Filter, len(tpRL.Filters)),
|
||||
Filters: make([]*RequestFilter, len(tpRL.Filters)),
|
||||
}
|
||||
if tpRL.UsageTTL != "" {
|
||||
if rp.UsageTTL, err = utils.ParseDurationWithSecs(tpRL.UsageTTL); err != nil {
|
||||
@@ -1942,7 +1942,7 @@ func APItoResource(tpRL *utils.TPResource, timezone string) (rp *ResourceProfile
|
||||
}
|
||||
}
|
||||
for i, f := range tpRL.Filters {
|
||||
rf := &Filter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
rf := &RequestFilter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
if err := rf.CompileValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2095,7 +2095,7 @@ func APItoStats(tpST *utils.TPStats, timezone string) (st *StatQueueProfile, err
|
||||
Blocker: tpST.Blocker,
|
||||
Stored: tpST.Stored,
|
||||
MinItems: tpST.MinItems,
|
||||
Filters: make([]*Filter, len(tpST.Filters)),
|
||||
Filters: make([]*RequestFilter, len(tpST.Filters)),
|
||||
}
|
||||
if tpST.TTL != "" {
|
||||
if st.TTL, err = utils.ParseDurationWithSecs(tpST.TTL); err != nil {
|
||||
@@ -2110,7 +2110,7 @@ func APItoStats(tpST *utils.TPStats, timezone string) (st *StatQueueProfile, err
|
||||
|
||||
}
|
||||
for i, f := range tpST.Filters {
|
||||
rf := &Filter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
rf := &RequestFilter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
if err := rf.CompileValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2138,6 +2138,7 @@ func (tps TpThresholdS) AsTPThreshold() (result []*utils.TPThreshold) {
|
||||
Blocker: tp.Blocker,
|
||||
Recurrent: tp.Recurrent,
|
||||
MinSleep: tp.MinSleep,
|
||||
Async: tp.Async,
|
||||
}
|
||||
}
|
||||
if tp.ActionIDs != "" {
|
||||
@@ -2188,6 +2189,7 @@ func APItoModelTPThreshold(th *utils.TPThreshold) (mdls TpThresholdS) {
|
||||
mdl.Weight = th.Weight
|
||||
mdl.Recurrent = th.Recurrent
|
||||
mdl.MinSleep = th.MinSleep
|
||||
mdl.Async = th.Async
|
||||
if th.ActivationInterval != nil {
|
||||
if th.ActivationInterval.ActivationTime != "" {
|
||||
mdl.ActivationInterval = th.ActivationInterval.ActivationTime
|
||||
@@ -2209,10 +2211,9 @@ func APItoModelTPThreshold(th *utils.TPThreshold) (mdls TpThresholdS) {
|
||||
mdl.FilterFieldName = fltr.FieldName
|
||||
for i, val := range fltr.Values {
|
||||
if i != 0 {
|
||||
mdl.FilterFieldValues = mdl.FilterFieldValues + utils.INFIELD_SEP + val
|
||||
} else {
|
||||
mdl.FilterFieldValues = val
|
||||
mdl.FilterFieldValues += utils.INFIELD_SEP
|
||||
}
|
||||
mdl.FilterFieldValues += val
|
||||
}
|
||||
mdls = append(mdls, mdl)
|
||||
}
|
||||
@@ -2226,7 +2227,8 @@ func APItoThresholdProfile(tpTH *utils.TPThreshold, timezone string) (th *Thresh
|
||||
Recurrent: tpTH.Recurrent,
|
||||
Weight: tpTH.Weight,
|
||||
Blocker: tpTH.Blocker,
|
||||
Filters: make([]*Filter, len(tpTH.Filters)),
|
||||
Async: tpTH.Async,
|
||||
Filters: make([]*RequestFilter, len(tpTH.Filters)),
|
||||
}
|
||||
if tpTH.MinSleep != "" {
|
||||
if th.MinSleep, err = utils.ParseDurationWithSecs(tpTH.MinSleep); err != nil {
|
||||
@@ -2238,7 +2240,7 @@ func APItoThresholdProfile(tpTH *utils.TPThreshold, timezone string) (th *Thresh
|
||||
|
||||
}
|
||||
for i, f := range tpTH.Filters {
|
||||
rf := &Filter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
rf := &RequestFilter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
if err := rf.CompileValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2260,15 +2262,26 @@ func (tps TpFilterS) AsTPFilter() (result []*utils.TPFilter) {
|
||||
th, found := mst[tp.ID]
|
||||
if !found {
|
||||
th = &utils.TPFilter{
|
||||
TPid: tp.Tpid,
|
||||
Tenant: tp.Tenant,
|
||||
ID: tp.ID,
|
||||
FilterType: tp.Type,
|
||||
FilterFieldName: tp.Name,
|
||||
TPid: tp.Tpid,
|
||||
Tenant: tp.Tenant,
|
||||
ID: tp.ID,
|
||||
}
|
||||
}
|
||||
if tp.Values != "" {
|
||||
th.FilterFielValues = append(th.FilterFielValues, strings.Split(tp.Values, utils.INFIELD_SEP)...)
|
||||
if len(tp.ActivationInterval) != 0 {
|
||||
th.ActivationInterval = new(utils.TPActivationInterval)
|
||||
aiSplt := strings.Split(tp.ActivationInterval, utils.INFIELD_SEP)
|
||||
if len(aiSplt) == 2 {
|
||||
th.ActivationInterval.ActivationTime = aiSplt[0]
|
||||
th.ActivationInterval.ExpiryTime = aiSplt[1]
|
||||
} else if len(aiSplt) == 1 {
|
||||
th.ActivationInterval.ActivationTime = aiSplt[0]
|
||||
}
|
||||
}
|
||||
if tp.FilterType != "" {
|
||||
th.Filters = append(th.Filters, &utils.TPRequestFilter{
|
||||
Type: tp.FilterType,
|
||||
FieldName: tp.FilterFieldName,
|
||||
Values: strings.Split(tp.FilterFieldValues, utils.INFIELD_SEP)})
|
||||
}
|
||||
mst[tp.ID] = th
|
||||
}
|
||||
@@ -2282,32 +2295,54 @@ func (tps TpFilterS) AsTPFilter() (result []*utils.TPFilter) {
|
||||
}
|
||||
|
||||
func APItoModelTPFilter(th *utils.TPFilter) (mdls TpFilterS) {
|
||||
mdl := &TpFilter{
|
||||
Tpid: th.TPid,
|
||||
Tenant: th.Tenant,
|
||||
ID: th.ID,
|
||||
Name: th.FilterFieldName,
|
||||
Type: th.FilterType,
|
||||
if len(th.Filters) == 0 {
|
||||
return
|
||||
}
|
||||
for i, val := range th.FilterFielValues {
|
||||
if i != 0 {
|
||||
mdl.Values += utils.INFIELD_SEP
|
||||
for _, fltr := range th.Filters {
|
||||
mdl := &TpFilter{
|
||||
Tpid: th.TPid,
|
||||
Tenant: th.Tenant,
|
||||
ID: th.ID,
|
||||
}
|
||||
mdl.Values += val
|
||||
mdl.FilterType = fltr.Type
|
||||
mdl.FilterFieldName = fltr.FieldName
|
||||
if th.ActivationInterval != nil {
|
||||
if th.ActivationInterval.ActivationTime != "" {
|
||||
mdl.ActivationInterval = th.ActivationInterval.ActivationTime
|
||||
}
|
||||
if th.ActivationInterval.ExpiryTime != "" {
|
||||
mdl.ActivationInterval += utils.INFIELD_SEP + th.ActivationInterval.ExpiryTime
|
||||
}
|
||||
}
|
||||
for i, val := range fltr.Values {
|
||||
if i != 0 {
|
||||
mdl.FilterFieldValues += utils.INFIELD_SEP
|
||||
}
|
||||
mdl.FilterFieldValues += val
|
||||
}
|
||||
mdls = append(mdls, mdl)
|
||||
}
|
||||
mdls = append(mdls, mdl)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func APItoFilter(tpTH *utils.TPFilter) (th *Filter, err error) {
|
||||
func APItoFilter(tpTH *utils.TPFilter, timezone string) (th *Filter, err error) {
|
||||
th = &Filter{
|
||||
Tenant: tpTH.Tenant,
|
||||
ID: tpTH.ID,
|
||||
FieldName: tpTH.FilterFieldName,
|
||||
Type: tpTH.FilterType,
|
||||
Tenant: tpTH.Tenant,
|
||||
ID: tpTH.ID,
|
||||
RequestFilters: make([]*RequestFilter, len(tpTH.Filters)),
|
||||
}
|
||||
for _, ati := range tpTH.FilterFielValues {
|
||||
th.Values = append(th.Values, ati)
|
||||
for i, f := range tpTH.Filters {
|
||||
rf := &RequestFilter{Type: f.Type, FieldName: f.FieldName, Values: f.Values}
|
||||
if err := rf.CompileValues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
th.RequestFilters[i] = rf
|
||||
}
|
||||
if tpTH.ActivationInterval != nil {
|
||||
if th.ActivationInterval, err = tpTH.ActivationInterval.AsActivationInterval(timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return th, nil
|
||||
}
|
||||
|
||||
@@ -818,18 +818,18 @@ func TestAPItoResource(t *testing.T) {
|
||||
Stored: tpRL.Stored,
|
||||
Blocker: tpRL.Blocker,
|
||||
Weight: tpRL.Weight,
|
||||
Filters: make([]*Filter, len(tpRL.Filters))}
|
||||
eRL.Filters[0] = &Filter{Type: MetaString,
|
||||
Filters: make([]*RequestFilter, len(tpRL.Filters))}
|
||||
eRL.Filters[0] = &RequestFilter{Type: MetaString,
|
||||
FieldName: "Account", Values: []string{"1001", "1002"}}
|
||||
eRL.Filters[1] = &Filter{Type: MetaStringPrefix,
|
||||
eRL.Filters[1] = &RequestFilter{Type: MetaStringPrefix,
|
||||
FieldName: "Destination", Values: []string{"10", "20"}}
|
||||
eRL.Filters[2] = &Filter{Type: MetaStatS,
|
||||
eRL.Filters[2] = &RequestFilter{Type: MetaStatS,
|
||||
Values: []string{"CDRST1:*min_asr:34", "CDRST_1001:*min_asr:20"},
|
||||
statSThresholds: []*RFStatSThreshold{
|
||||
&RFStatSThreshold{QueueID: "CDRST1", ThresholdType: "*min_asr", ThresholdValue: 34},
|
||||
&RFStatSThreshold{QueueID: "CDRST_1001", ThresholdType: "*min_asr", ThresholdValue: 20},
|
||||
}}
|
||||
eRL.Filters[3] = &Filter{Type: MetaRSRFields, Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
eRL.Filters[3] = &RequestFilter{Type: MetaRSRFields, Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
rsrFields: utils.ParseRSRFieldsMustCompile("Subject(~^1.*1$);Destination(1002)", utils.INFIELD_SEP),
|
||||
}
|
||||
at, _ := utils.ParseTimeDetectLayout("2014-07-29T15:00:00Z", "UTC")
|
||||
@@ -913,7 +913,7 @@ func TestAPItoTPStats(t *testing.T) {
|
||||
QueueLength: tps.QueueLength,
|
||||
Metrics: []string{"*asr", "*acd", "*acc"},
|
||||
Thresholds: []string{"THRESH1", "THRESH2"},
|
||||
Filters: make([]*Filter, len(tps.Filters)),
|
||||
Filters: make([]*RequestFilter, len(tps.Filters)),
|
||||
Stored: tps.Stored,
|
||||
Blocker: tps.Blocker,
|
||||
Weight: 20.0,
|
||||
@@ -923,7 +923,7 @@ func TestAPItoTPStats(t *testing.T) {
|
||||
t.Errorf("Got error: %+v", err)
|
||||
}
|
||||
|
||||
eTPs.Filters[0] = &Filter{Type: MetaString,
|
||||
eTPs.Filters[0] = &RequestFilter{Type: MetaString,
|
||||
FieldName: "Account", Values: []string{"1001", "1002"}}
|
||||
at, _ := utils.ParseTimeDetectLayout("2014-07-29T15:00:00Z", "UTC")
|
||||
eTPs.ActivationInterval = &utils.ActivationInterval{ActivationTime: at}
|
||||
@@ -995,7 +995,7 @@ func TestAPItoTPThreshold(t *testing.T) {
|
||||
|
||||
eTPs := &ThresholdProfile{
|
||||
ID: tps.ID,
|
||||
Filters: make([]*Filter, len(tps.Filters)),
|
||||
Filters: make([]*RequestFilter, len(tps.Filters)),
|
||||
Recurrent: tps.Recurrent,
|
||||
Blocker: tps.Blocker,
|
||||
Weight: tps.Weight,
|
||||
@@ -1004,7 +1004,7 @@ func TestAPItoTPThreshold(t *testing.T) {
|
||||
if eTPs.MinSleep, err = utils.ParseDurationWithSecs(tps.MinSleep); err != nil {
|
||||
t.Errorf("Got error: %+v", err)
|
||||
}
|
||||
eTPs.Filters[0] = &Filter{Type: MetaString,
|
||||
eTPs.Filters[0] = &RequestFilter{Type: MetaString,
|
||||
FieldName: "Account", Values: []string{"1001", "1002"}}
|
||||
at, _ := utils.ParseTimeDetectLayout("2014-07-29T15:00:00Z", "UTC")
|
||||
eTPs.ActivationInterval = &utils.ActivationInterval{ActivationTime: at}
|
||||
@@ -1018,20 +1018,24 @@ func TestAPItoTPThreshold(t *testing.T) {
|
||||
func TestTPFilterAsTPFilter(t *testing.T) {
|
||||
tps := []*TpFilter{
|
||||
&TpFilter{
|
||||
Tpid: "TEST_TPID",
|
||||
ID: "Filter1",
|
||||
Type: MetaStringPrefix,
|
||||
Name: "Account",
|
||||
Values: "1001;1002",
|
||||
Tpid: "TEST_TPID",
|
||||
ID: "Filter1",
|
||||
FilterType: MetaStringPrefix,
|
||||
FilterFieldName: "Account",
|
||||
FilterFieldValues: "1001;1002",
|
||||
},
|
||||
}
|
||||
eTPs := []*utils.TPFilter{
|
||||
&utils.TPFilter{
|
||||
TPid: tps[0].Tpid,
|
||||
ID: tps[0].ID,
|
||||
FilterType: tps[0].Type,
|
||||
FilterFieldName: tps[0].Name,
|
||||
FilterFielValues: []string{"1001", "1002"},
|
||||
TPid: tps[0].Tpid,
|
||||
ID: tps[0].ID,
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
Type: MetaStringPrefix,
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1043,22 +1047,30 @@ func TestTPFilterAsTPFilter(t *testing.T) {
|
||||
|
||||
func TestAPItoTPFilter(t *testing.T) {
|
||||
tps := &utils.TPFilter{
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter1",
|
||||
FilterType: "*string",
|
||||
FilterFieldName: "Acount",
|
||||
FilterFielValues: []string{"1001", "1002"},
|
||||
TPid: testTPID,
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Filter1",
|
||||
Filters: []*utils.TPRequestFilter{
|
||||
&utils.TPRequestFilter{
|
||||
FieldName: "Account",
|
||||
Type: "*string",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
eTPs := &Filter{
|
||||
Tenant: "cgrates.org",
|
||||
ID: tps.ID,
|
||||
FieldName: tps.FilterFieldName,
|
||||
Type: tps.FilterType,
|
||||
Values: tps.FilterFielValues,
|
||||
Tenant: "cgrates.org",
|
||||
ID: tps.ID,
|
||||
RequestFilters: []*RequestFilter{
|
||||
&RequestFilter{
|
||||
FieldName: "Account",
|
||||
Type: "*string",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
},
|
||||
}
|
||||
if st, err := APItoFilter(tps); err != nil {
|
||||
if st, err := APItoFilter(tps, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eTPs, st) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eTPs, st)
|
||||
|
||||
@@ -514,16 +514,18 @@ type TpThreshold struct {
|
||||
Blocker bool `index:"8" re:""`
|
||||
Weight float64 `index:"9" re:"\d+\.?\d*"`
|
||||
ActionIDs string `index:"10" re:""`
|
||||
Async bool `index:"8" re:""`
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type TpFilter struct {
|
||||
PK uint `gorm:"primary_key"`
|
||||
Tpid string
|
||||
Tenant string `index:"0" re:""`
|
||||
ID string `index:"1" re:""`
|
||||
Type string `index:"2" re:"^\*[A-Za-z].*"`
|
||||
Name string `index:"3" re:""`
|
||||
Values string `index:"4" re:""`
|
||||
CreatedAt time.Time
|
||||
PK uint `gorm:"primary_key"`
|
||||
Tpid string
|
||||
Tenant string `index:"0" re:""`
|
||||
ID string `index:"1" re:""`
|
||||
FilterType string `index:"2" re:"^\*[A-Za-z].*"`
|
||||
FilterFieldName string `index:"3" re:""`
|
||||
FilterFieldValues string `index:"4" re:""`
|
||||
ActivationInterval string `index:"5" re:""`
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ func init() {
|
||||
type ResourceProfile struct {
|
||||
Tenant string
|
||||
ID string // identifier of this resource
|
||||
Filters []*Filter // filters for the request
|
||||
Filters []*RequestFilter // filters for the request
|
||||
ActivationInterval *utils.ActivationInterval // time when this resource becomes active and expires
|
||||
UsageTTL time.Duration // auto-expire the usage after this duration
|
||||
Limit float64 // limit value
|
||||
|
||||
@@ -53,13 +53,13 @@ func TestRSRecordUsage1(t *testing.T) {
|
||||
rPrf: &ResourceProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "RL1",
|
||||
Filters: []*Filter{
|
||||
&Filter{
|
||||
Filters: []*RequestFilter{
|
||||
&RequestFilter{
|
||||
Type: MetaString,
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&Filter{
|
||||
&RequestFilter{
|
||||
Type: MetaRSRFields,
|
||||
Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
rsrFields: utils.ParseRSRFieldsMustCompile("Subject(~^1.*1$);Destination(1002)", utils.INFIELD_SEP),
|
||||
@@ -134,13 +134,13 @@ func TestRSRsort(t *testing.T) {
|
||||
ID: "RL2",
|
||||
rPrf: &ResourceProfile{
|
||||
ID: "RL2",
|
||||
Filters: []*Filter{
|
||||
&Filter{
|
||||
Filters: []*RequestFilter{
|
||||
&RequestFilter{
|
||||
Type: MetaString,
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&Filter{
|
||||
&RequestFilter{
|
||||
Type: MetaRSRFields,
|
||||
Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
rsrFields: utils.ParseRSRFieldsMustCompile("Subject(~^1.*1$);Destination(1002)", utils.INFIELD_SEP),
|
||||
@@ -249,13 +249,13 @@ func TestRSCacheSetGet(t *testing.T) {
|
||||
rPrf: &ResourceProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "RL",
|
||||
Filters: []*Filter{
|
||||
&Filter{
|
||||
Filters: []*RequestFilter{
|
||||
&RequestFilter{
|
||||
Type: MetaString,
|
||||
FieldName: "Account",
|
||||
Values: []string{"1001", "1002"},
|
||||
},
|
||||
&Filter{
|
||||
&RequestFilter{
|
||||
Type: MetaRSRFields,
|
||||
Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
|
||||
rsrFields: utils.ParseRSRFieldsMustCompile("Subject(~^1.*1$);Destination(1002)", utils.INFIELD_SEP),
|
||||
|
||||
@@ -126,9 +126,9 @@ type DataDB interface {
|
||||
GetThreshold(string, string, bool, string) (*Threshold, error)
|
||||
SetThreshold(*Threshold) error
|
||||
RemoveThreshold(string, string, string) error
|
||||
GetFilter(string, string, bool, string) (*Filter, error)
|
||||
SetFilter(*Filter) error
|
||||
RemoveFilter(string, string, string) error
|
||||
GetFilterDrv(string, string) (*Filter, error)
|
||||
SetFilterDrv(*Filter) error
|
||||
RemoveFilterDrv(string, string) error
|
||||
// CacheDataFromDB loads data to cache, prefix represents the cache prefix, IDs should be nil if all available data should be loaded
|
||||
CacheDataFromDB(prefix string, IDs []string, mustBeCached bool) error // ToDo: Move this to dataManager
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ func (ms *MapStorage) HasData(categ, subject string) (bool, error) {
|
||||
switch categ {
|
||||
case utils.DESTINATION_PREFIX, utils.RATING_PLAN_PREFIX, utils.RATING_PROFILE_PREFIX,
|
||||
utils.ACTION_PREFIX, utils.ACTION_PLAN_PREFIX, utils.ACCOUNT_PREFIX, utils.DERIVEDCHARGERS_PREFIX,
|
||||
utils.ResourcesPrefix, utils.StatQueuePrefix, utils.ThresholdPrefix:
|
||||
utils.ResourcesPrefix, utils.StatQueuePrefix, utils.ThresholdPrefix, utils.FilterPrefix:
|
||||
_, exists := ms.dict[categ+subject]
|
||||
return exists, nil
|
||||
}
|
||||
@@ -1669,32 +1669,18 @@ func (ms *MapStorage) RemoveThreshold(tenant, id string, transactionID string) (
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetFilter(tenant, id string, skipCache bool, transactionID string) (r *Filter, err error) {
|
||||
func (ms *MapStorage) GetFilterDrv(tenant, id string) (r *Filter, err error) {
|
||||
ms.mu.RLock()
|
||||
defer ms.mu.RUnlock()
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
if !skipCache {
|
||||
if x, ok := cache.Get(key); ok {
|
||||
if x != nil {
|
||||
return x.(*Filter), nil
|
||||
}
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
}
|
||||
values, ok := ms.dict[key]
|
||||
values, ok := ms.dict[utils.FilterPrefix+utils.ConcatenatedKey(tenant, id)]
|
||||
if !ok {
|
||||
cache.Set(key, nil, cacheCommit(transactionID), transactionID)
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
err = ms.ms.Unmarshal(values, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cache.Set(key, r, cacheCommit(transactionID), transactionID)
|
||||
err = ms.ms.Unmarshal(values, &r)
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) SetFilter(r *Filter) (err error) {
|
||||
func (ms *MapStorage) SetFilterDrv(r *Filter) (err error) {
|
||||
ms.mu.Lock()
|
||||
defer ms.mu.Unlock()
|
||||
result, err := ms.ms.Marshal(r)
|
||||
@@ -1705,12 +1691,12 @@ func (ms *MapStorage) SetFilter(r *Filter) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) RemoveFilter(tenant, id string, transactionID string) (err error) {
|
||||
func (ms *MapStorage) RemoveFilterDrv(tenant, id string) (err error) {
|
||||
ms.mu.Lock()
|
||||
defer ms.mu.Unlock()
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
delete(ms.dict, key)
|
||||
cache.RemKey(key, cacheCommit(transactionID), transactionID)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ func (ms *MongoStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached
|
||||
_, err = ms.GetThreshold(tntID.Tenant, tntID.ID, true, utils.NonTransactional)
|
||||
case utils.FilterPrefix:
|
||||
tntID := utils.NewTenantID(dataID)
|
||||
_, err = ms.GetFilter(tntID.Tenant, tntID.ID, true, utils.NonTransactional)
|
||||
_, err = ms.GetFilterDrv(tntID.Tenant, tntID.ID)
|
||||
}
|
||||
if err != nil {
|
||||
return utils.NewCGRError(utils.MONGO,
|
||||
@@ -2253,44 +2253,30 @@ func (ms *MongoStorage) RemoveThreshold(tenant, id string, transactionID string)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetFilter(tenant, id string, skipCache bool, transactionID string) (r *Filter, err error) {
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
if !skipCache {
|
||||
if x, ok := cache.Get(key); ok {
|
||||
if x == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return x.(*Filter), nil
|
||||
}
|
||||
}
|
||||
func (ms *MongoStorage) GetFilterDrv(tenant, id string) (r *Filter, err error) {
|
||||
session, col := ms.conn(colFlt)
|
||||
defer session.Close()
|
||||
r = new(Filter)
|
||||
if err = col.Find(bson.M{"tenant": tenant, "id": id}).One(r); err != nil {
|
||||
if err = col.Find(bson.M{"tenant": tenant, "id": id}).One(&r); err != nil {
|
||||
if err == mgo.ErrNotFound {
|
||||
err = utils.ErrNotFound
|
||||
cache.Set(key, nil, cacheCommit(transactionID), transactionID)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
cache.Set(key, r, cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetFilter(r *Filter) (err error) {
|
||||
func (ms *MongoStorage) SetFilterDrv(r *Filter) (err error) {
|
||||
session, col := ms.conn(colFlt)
|
||||
defer session.Close()
|
||||
_, err = col.Upsert(bson.M{"tenant": r.Tenant, "id": r.ID}, r)
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) RemoveFilter(tenant, id string, transactionID string) (err error) {
|
||||
func (ms *MongoStorage) RemoveFilterDrv(tenant, id string) (err error) {
|
||||
session, col := ms.conn(colFlt)
|
||||
defer session.Close()
|
||||
if err = col.Remove(bson.M{"tenant": tenant, "id": id}); err != nil {
|
||||
return
|
||||
}
|
||||
cache.RemKey(utils.FilterPrefix+utils.ConcatenatedKey(tenant, id),
|
||||
cacheCommit(transactionID), transactionID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1776,20 +1776,11 @@ func (rs *RedisStorage) RemoveThreshold(tenant, id string, transactionID string)
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetFilter(tenant, id string, skipCache bool, transactionID string) (r *Filter, err error) {
|
||||
func (rs *RedisStorage) GetFilterDrv(tenant, id string) (r *Filter, err error) {
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
if !skipCache {
|
||||
if x, ok := cache.Get(key); ok {
|
||||
if x == nil {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return x.(*Filter), nil
|
||||
}
|
||||
}
|
||||
var values []byte
|
||||
if values, err = rs.Cmd("GET", key).Bytes(); err != nil {
|
||||
if err == redis.ErrRespNil { // did not find the destination
|
||||
cache.Set(key, nil, cacheCommit(transactionID), transactionID)
|
||||
err = utils.ErrNotFound
|
||||
}
|
||||
return
|
||||
@@ -1797,11 +1788,10 @@ func (rs *RedisStorage) GetFilter(tenant, id string, skipCache bool, transaction
|
||||
if err = rs.ms.Unmarshal(values, &r); err != nil {
|
||||
return
|
||||
}
|
||||
cache.Set(key, r, cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetFilter(r *Filter) (err error) {
|
||||
func (rs *RedisStorage) SetFilterDrv(r *Filter) (err error) {
|
||||
result, err := rs.ms.Marshal(r)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1809,12 +1799,11 @@ func (rs *RedisStorage) SetFilter(r *Filter) (err error) {
|
||||
return rs.Cmd("SET", utils.FilterPrefix+utils.ConcatenatedKey(r.Tenant, r.ID), result).Err
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) RemoveFilter(tenant, id string, transactionID string) (err error) {
|
||||
func (rs *RedisStorage) RemoveFilterDrv(tenant, id string) (err error) {
|
||||
key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id)
|
||||
if err = rs.Cmd("DEL", key).Err; err != nil {
|
||||
return
|
||||
}
|
||||
cache.RemKey(key, cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,14 @@ import (
|
||||
type ThresholdProfile struct {
|
||||
Tenant string
|
||||
ID string
|
||||
Filters []*Filter // Filters for the request
|
||||
Filters []*RequestFilter // Filters for the request
|
||||
ActivationInterval *utils.ActivationInterval // Time when this limit becomes active and expires
|
||||
Recurrent bool
|
||||
MinSleep time.Duration
|
||||
Blocker bool // blocker flag to stop processing on filters matched
|
||||
Weight float64 // Weight to sort the thresholds
|
||||
ActionIDs []string
|
||||
Async bool
|
||||
}
|
||||
|
||||
func (tp *ThresholdProfile) TenantID() string {
|
||||
|
||||
@@ -153,10 +153,10 @@ func (tpr *TpReader) LoadDestinationsFiltered(tag string) (bool, error) {
|
||||
for _, tpDst := range tpDests {
|
||||
dst := NewDestinationFromTPDestination(tpDst)
|
||||
// ToDo: Fix transactions at onlineDB level
|
||||
if err = tpr.dataStorage.SetDestination(dst, transID); err != nil {
|
||||
if err = tpr.dm.DataDB().SetDestination(dst, transID); err != nil {
|
||||
cache.RollbackTransaction(transID)
|
||||
}
|
||||
if err = tpr.dataStorage.SetReverseDestination(dst, transID); err != nil {
|
||||
if err = tpr.dm.DataDB().SetReverseDestination(dst, transID); err != nil {
|
||||
cache.RollbackTransaction(transID)
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ func (tpr *TpReader) LoadDestinationRates() (err error) {
|
||||
_, destinationExists = tpr.destinations[dr.DestinationId]
|
||||
}
|
||||
if !destinationExists && tpr.dataStorage != nil {
|
||||
if destinationExists, err = tpr.dataStorage.HasData(utils.DESTINATION_PREFIX, dr.DestinationId); err != nil {
|
||||
if destinationExists, err = tpr.dm.DataDB().HasData(utils.DESTINATION_PREFIX, dr.DestinationId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@ func (tpr *TpReader) LoadRatingPlansFiltered(tag string) (bool, error) {
|
||||
}
|
||||
destsExist := len(dms) != 0
|
||||
if !destsExist && tpr.dataStorage != nil {
|
||||
if dbExists, err := tpr.dataStorage.HasData(utils.DESTINATION_PREFIX, drate.DestinationId); err != nil {
|
||||
if dbExists, err := tpr.dm.DataDB().HasData(utils.DESTINATION_PREFIX, drate.DestinationId); err != nil {
|
||||
return false, err
|
||||
} else if dbExists {
|
||||
destsExist = true
|
||||
@@ -319,12 +319,12 @@ func (tpr *TpReader) LoadRatingPlansFiltered(tag string) (bool, error) {
|
||||
return false, fmt.Errorf("could not get destination for tag %v", drate.DestinationId)
|
||||
}
|
||||
for _, destination := range dms {
|
||||
tpr.dataStorage.SetDestination(destination, utils.NonTransactional)
|
||||
tpr.dataStorage.SetReverseDestination(destination, utils.NonTransactional)
|
||||
tpr.dm.DataDB().SetDestination(destination, utils.NonTransactional)
|
||||
tpr.dm.DataDB().SetReverseDestination(destination, utils.NonTransactional)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := tpr.dataStorage.SetRatingPlan(ratingPlan, utils.NonTransactional); err != nil {
|
||||
if err := tpr.dm.DataDB().SetRatingPlan(ratingPlan, utils.NonTransactional); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@@ -381,7 +381,7 @@ func (tpr *TpReader) LoadRatingProfilesFiltered(qriedRpf *utils.TPRatingProfile)
|
||||
}
|
||||
_, exists := tpr.ratingPlans[tpRa.RatingPlanId]
|
||||
if !exists && tpr.dataStorage != nil {
|
||||
if exists, err = tpr.dataStorage.HasData(utils.RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
if exists, err = tpr.dm.DataDB().HasData(utils.RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -396,7 +396,7 @@ func (tpr *TpReader) LoadRatingProfilesFiltered(qriedRpf *utils.TPRatingProfile)
|
||||
CdrStatQueueIds: strings.Split(tpRa.CdrStatQueueIds, utils.INFIELD_SEP),
|
||||
})
|
||||
}
|
||||
if err := tpr.dataStorage.SetRatingProfile(resultRatingProfile, utils.NonTransactional); err != nil {
|
||||
if err := tpr.dm.DataDB().SetRatingProfile(resultRatingProfile, utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -421,7 +421,7 @@ func (tpr *TpReader) LoadRatingProfiles() (err error) {
|
||||
}
|
||||
_, exists := tpr.ratingPlans[tpRa.RatingPlanId]
|
||||
if !exists && tpr.dataStorage != nil { // Only query if there is a connection, eg on dry run there is none
|
||||
if exists, err = tpr.dataStorage.HasData(utils.RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
if exists, err = tpr.dm.DataDB().HasData(utils.RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -465,7 +465,7 @@ func (tpr *TpReader) LoadSharedGroupsFiltered(tag string, save bool) (err error)
|
||||
}
|
||||
if save {
|
||||
for _, sg := range tpr.sharedGroups {
|
||||
if err := tpr.dataStorage.SetSharedGroup(sg, utils.NonTransactional); err != nil {
|
||||
if err := tpr.dm.DataDB().SetSharedGroup(sg, utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -495,7 +495,7 @@ func (tpr *TpReader) LoadLCRs() (err error) {
|
||||
}
|
||||
}
|
||||
if !found && tpr.dataStorage != nil {
|
||||
if keys, err := tpr.dataStorage.GetKeysForPrefix(utils.RATING_PROFILE_PREFIX + ratingProfileSearchKey); err != nil {
|
||||
if keys, err := tpr.dm.DataDB().GetKeysForPrefix(utils.RATING_PROFILE_PREFIX + ratingProfileSearchKey); err != nil {
|
||||
return fmt.Errorf("[LCR] error querying dataDb %s", err.Error())
|
||||
} else if len(keys) != 0 {
|
||||
found = true
|
||||
@@ -509,7 +509,7 @@ func (tpr *TpReader) LoadLCRs() (err error) {
|
||||
if rule.DestinationId != "" && rule.DestinationId != utils.ANY {
|
||||
_, found := tpr.destinations[rule.DestinationId]
|
||||
if !found && tpr.dataStorage != nil {
|
||||
if found, err = tpr.dataStorage.HasData(utils.DESTINATION_PREFIX, rule.DestinationId); err != nil {
|
||||
if found, err = tpr.dm.DataDB().HasData(utils.DESTINATION_PREFIX, rule.DestinationId); err != nil {
|
||||
return fmt.Errorf("[LCR] error querying dataDb %s", err.Error())
|
||||
}
|
||||
}
|
||||
@@ -675,7 +675,7 @@ func (tpr *TpReader) LoadActionPlans() (err error) {
|
||||
|
||||
_, exists := tpr.actions[at.ActionsId]
|
||||
if !exists && tpr.dataStorage != nil {
|
||||
if exists, err = tpr.dataStorage.HasData(utils.ACTION_PREFIX, at.ActionsId); err != nil {
|
||||
if exists, err = tpr.dm.DataDB().HasData(utils.ACTION_PREFIX, at.ActionsId); err != nil {
|
||||
return fmt.Errorf("[ActionPlans] Error querying actions: %v - %s", at.ActionsId, err.Error())
|
||||
}
|
||||
}
|
||||
@@ -829,7 +829,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
if accountAction.ActionPlanId != "" {
|
||||
// get old userBalanceIds
|
||||
exitingAccountIds := make(utils.StringMap)
|
||||
existingActionPlan, err := tpr.dataStorage.GetActionPlan(accountAction.ActionPlanId, true, utils.NonTransactional)
|
||||
existingActionPlan, err := tpr.dm.DataDB().GetActionPlan(accountAction.ActionPlanId, true, utils.NonTransactional)
|
||||
if err == nil && existingActionPlan != nil {
|
||||
exitingAccountIds = existingActionPlan.AccountIDs
|
||||
}
|
||||
@@ -899,20 +899,20 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
AccountID: accID,
|
||||
ActionsID: at.ActionsID,
|
||||
}
|
||||
if err = tpr.dataStorage.PushTask(t); err != nil {
|
||||
if err = tpr.dm.DataDB().PushTask(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// write action plan
|
||||
if err = tpr.dataStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false, utils.NonTransactional); err != nil {
|
||||
if err = tpr.dm.DataDB().SetActionPlan(accountAction.ActionPlanId, actionPlan, false, utils.NonTransactional); err != nil {
|
||||
return errors.New(err.Error() + " (SetActionPlan): " + accountAction.ActionPlanId)
|
||||
}
|
||||
if err = tpr.dataStorage.SetAccountActionPlans(id, []string{accountAction.ActionPlanId}, false); err != nil {
|
||||
if err = tpr.dm.DataDB().SetAccountActionPlans(id, []string{accountAction.ActionPlanId}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tpr.dataStorage.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{id}, true); err != nil {
|
||||
if err = tpr.dm.DataDB().CacheDataFromDB(utils.AccountActionPlansPrefix, []string{id}, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1012,7 +1012,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
actionIDs = append(actionIDs, atr.ActionsID)
|
||||
}
|
||||
// write action triggers
|
||||
err = tpr.dataStorage.SetActionTriggers(accountAction.ActionTriggersId, actionTriggers, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActionTriggers(accountAction.ActionTriggersId, actionTriggers, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return errors.New(err.Error() + " (SetActionTriggers): " + accountAction.ActionTriggersId)
|
||||
}
|
||||
@@ -1124,12 +1124,12 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
}
|
||||
// write actions
|
||||
for k, as := range facts {
|
||||
err = tpr.dataStorage.SetActions(k, as, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActions(k, as, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ub, err := tpr.dataStorage.GetAccount(id)
|
||||
ub, err := tpr.dm.DataDB().GetAccount(id)
|
||||
if err != nil {
|
||||
ub = &Account{
|
||||
ID: id,
|
||||
@@ -1138,7 +1138,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
ub.ActionTriggers = actionTriggers
|
||||
// init counters
|
||||
ub.InitCounters()
|
||||
if err := tpr.dataStorage.SetAccount(ub); err != nil {
|
||||
if err := tpr.dm.DataDB().SetAccount(ub); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1224,7 +1224,7 @@ func (tpr *TpReader) LoadDerivedChargersFiltered(filter *utils.TPDerivedChargers
|
||||
}
|
||||
if save {
|
||||
for dcsKey, dcs := range tpr.derivedChargers {
|
||||
if err := tpr.dataStorage.SetDerivedChargers(dcsKey, dcs, utils.NonTransactional); err != nil {
|
||||
if err := tpr.dm.DataDB().SetDerivedChargers(dcsKey, dcs, utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
|
||||
return fmt.Errorf("could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag)
|
||||
}
|
||||
// write action triggers
|
||||
err = tpr.dataStorage.SetActionTriggers(triggerTag, triggers, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActionTriggers(triggerTag, triggers, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return errors.New(err.Error() + " (SetActionTriggers): " + triggerTag)
|
||||
}
|
||||
@@ -1453,13 +1453,13 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
|
||||
if save {
|
||||
// write actions
|
||||
for k, as := range tpr.actions {
|
||||
err = tpr.dataStorage.SetActions(k, as, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActions(k, as, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, stat := range tpr.cdrStats {
|
||||
if err := tpr.dataStorage.SetCdrStats(stat); err != nil {
|
||||
if err := tpr.dm.DataDB().SetCdrStats(stat); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1485,7 +1485,7 @@ func (tpr *TpReader) LoadUsersFiltered(filter *utils.TPUsers) (bool, error) {
|
||||
for _, up := range tpUser.Profile {
|
||||
user.Profile[up.AttrName] = up.AttrValue
|
||||
}
|
||||
tpr.dataStorage.SetUser(user)
|
||||
tpr.dm.DataDB().SetUser(user)
|
||||
}
|
||||
return len(tpUsers) > 0, err
|
||||
}
|
||||
@@ -1546,8 +1546,8 @@ func (tpr *TpReader) LoadAliasesFiltered(filter *utils.TPAliases) (bool, error)
|
||||
|
||||
}
|
||||
}
|
||||
tpr.dataStorage.SetAlias(alias, utils.NonTransactional)
|
||||
tpr.dataStorage.SetReverseAlias(alias, utils.NonTransactional)
|
||||
tpr.dm.DataDB().SetAlias(alias, utils.NonTransactional)
|
||||
tpr.dm.DataDB().SetReverseAlias(alias, utils.NonTransactional)
|
||||
return len(tpAliases) > 0, err
|
||||
}
|
||||
|
||||
@@ -1615,7 +1615,7 @@ func (tpr *TpReader) LoadResourceProfilesFiltered(tag string) error {
|
||||
for tenant, mpID := range mapRsPfls {
|
||||
for id := range mpID {
|
||||
rTid := &utils.TenantID{tenant, id}
|
||||
if has, err := tpr.dataStorage.HasData(utils.ResourcesPrefix, rTid.TenantID()); err != nil {
|
||||
if has, err := tpr.dm.DataDB().HasData(utils.ResourcesPrefix, rTid.TenantID()); err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
tpr.resources = append(tpr.resources, rTid)
|
||||
@@ -1645,7 +1645,7 @@ func (tpr *TpReader) LoadStatsFiltered(tag string) error {
|
||||
for tenant, mpID := range mapSTs {
|
||||
for sqID := range mpID {
|
||||
sqTntID := &utils.TenantID{tenant, sqID}
|
||||
if has, err := tpr.dataStorage.HasData(utils.StatQueuePrefix, sqTntID.TenantID()); err != nil {
|
||||
if has, err := tpr.dm.DataDB().HasData(utils.StatQueuePrefix, sqTntID.TenantID()); err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
tpr.statQueues = append(tpr.statQueues, sqTntID)
|
||||
@@ -1675,7 +1675,7 @@ func (tpr *TpReader) LoadThresholdsFiltered(tag string) error {
|
||||
for tenant, mpID := range mapTHs {
|
||||
for thID := range mpID {
|
||||
thTntID := &utils.TenantID{Tenant: tenant, ID: thID}
|
||||
if has, err := tpr.dataStorage.HasData(utils.ThresholdPrefix, thTntID.TenantID()); err != nil {
|
||||
if has, err := tpr.dm.DataDB().HasData(utils.ThresholdPrefix, thTntID.TenantID()); err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
tpr.thresholds = append(tpr.thresholds, thTntID)
|
||||
@@ -1705,7 +1705,7 @@ func (tpr *TpReader) LoadFilterFiltered(tag string) error {
|
||||
for tenant, mpID := range mapTHs {
|
||||
for thID := range mpID {
|
||||
thTntID := &utils.TenantID{Tenant: tenant, ID: thID}
|
||||
if has, err := tpr.dataStorage.HasData(utils.FilterPrefix, thTntID.TenantID()); err != nil {
|
||||
if has, err := tpr.dm.DataDB().HasData(utils.FilterPrefix, thTntID.TenantID()); err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
tpr.filters = append(tpr.filters, thTntID)
|
||||
@@ -1807,13 +1807,13 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
return errors.New("no database connection")
|
||||
}
|
||||
if flush { // ToDo
|
||||
//tpr.dataStorage.Flush("")
|
||||
//tpr.dm.DataDB().Flush("")
|
||||
}
|
||||
if verbose {
|
||||
log.Print("Destinations:")
|
||||
}
|
||||
for _, d := range tpr.destinations {
|
||||
err = tpr.dataStorage.SetDestination(d, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetDestination(d, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1831,7 +1831,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Rating Plans:")
|
||||
}
|
||||
for _, rp := range tpr.ratingPlans {
|
||||
err = tpr.dataStorage.SetRatingPlan(rp, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetRatingPlan(rp, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1843,7 +1843,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Rating Profiles:")
|
||||
}
|
||||
for _, rp := range tpr.ratingProfiles {
|
||||
err = tpr.dataStorage.SetRatingProfile(rp, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetRatingProfile(rp, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1866,7 +1866,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if verbose {
|
||||
log.Println("\tTask: ", t)
|
||||
}
|
||||
if err = tpr.dataStorage.PushTask(t); err != nil {
|
||||
if err = tpr.dm.DataDB().PushTask(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1878,13 +1878,13 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if verbose {
|
||||
log.Println("\tTask: ", t)
|
||||
}
|
||||
if err = tpr.dataStorage.PushTask(t); err != nil {
|
||||
if err = tpr.dm.DataDB().PushTask(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = tpr.dataStorage.SetActionPlan(k, ap, false, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActionPlan(k, ap, false, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1902,7 +1902,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Action Triggers:")
|
||||
}
|
||||
for k, atrs := range tpr.actionsTriggers {
|
||||
err = tpr.dataStorage.SetActionTriggers(k, atrs, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActionTriggers(k, atrs, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1914,7 +1914,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Shared Groups:")
|
||||
}
|
||||
for k, sg := range tpr.sharedGroups {
|
||||
err = tpr.dataStorage.SetSharedGroup(sg, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetSharedGroup(sg, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1926,7 +1926,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("LCR Rules:")
|
||||
}
|
||||
for k, lcr := range tpr.lcrs {
|
||||
err = tpr.dataStorage.SetLCR(lcr, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetLCR(lcr, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1938,7 +1938,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Actions:")
|
||||
}
|
||||
for k, as := range tpr.actions {
|
||||
err = tpr.dataStorage.SetActions(k, as, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetActions(k, as, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1950,7 +1950,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Account Actions:")
|
||||
}
|
||||
for _, ub := range tpr.accountActions {
|
||||
err = tpr.dataStorage.SetAccount(ub)
|
||||
err = tpr.dm.DataDB().SetAccount(ub)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1962,7 +1962,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Derived Chargers:")
|
||||
}
|
||||
for key, dcs := range tpr.derivedChargers {
|
||||
err = tpr.dataStorage.SetDerivedChargers(key, dcs, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetDerivedChargers(key, dcs, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1974,7 +1974,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("CDR Stats Queues:")
|
||||
}
|
||||
for _, sq := range tpr.cdrStats {
|
||||
err = tpr.dataStorage.SetCdrStats(sq)
|
||||
err = tpr.dm.DataDB().SetCdrStats(sq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1986,7 +1986,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Users:")
|
||||
}
|
||||
for _, u := range tpr.users {
|
||||
err = tpr.dataStorage.SetUser(u)
|
||||
err = tpr.dm.DataDB().SetUser(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1998,7 +1998,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Aliases:")
|
||||
}
|
||||
for _, al := range tpr.aliases {
|
||||
err = tpr.dataStorage.SetAlias(al, utils.NonTransactional)
|
||||
err = tpr.dm.DataDB().SetAlias(al, utils.NonTransactional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2021,7 +2021,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tpr.dataStorage.SetResourceProfile(rsp); err != nil {
|
||||
if err = tpr.dm.DataDB().SetResourceProfile(rsp); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2033,7 +2033,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Resources:")
|
||||
}
|
||||
for _, rTid := range tpr.resources {
|
||||
if err = tpr.dataStorage.SetResource(&Resource{Tenant: rTid.Tenant, ID: rTid.ID, Usages: make(map[string]*ResourceUsage)}); err != nil {
|
||||
if err = tpr.dm.DataDB().SetResource(&Resource{Tenant: rTid.Tenant, ID: rTid.ID, Usages: make(map[string]*ResourceUsage)}); err != nil {
|
||||
return
|
||||
}
|
||||
if verbose {
|
||||
@@ -2049,7 +2049,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tpr.dataStorage.SetStatQueueProfile(st); err != nil {
|
||||
if err = tpr.dm.DataDB().SetStatQueueProfile(st); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2086,7 +2086,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tpr.dataStorage.SetThresholdProfile(th); err != nil {
|
||||
if err = tpr.dm.DataDB().SetThresholdProfile(th); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2098,7 +2098,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
log.Print("Thresholds:")
|
||||
}
|
||||
for _, thd := range tpr.thresholds {
|
||||
if err = tpr.dataStorage.SetThreshold(&Threshold{Tenant: thd.Tenant, ID: thd.ID}); err != nil {
|
||||
if err = tpr.dm.DataDB().SetThreshold(&Threshold{Tenant: thd.Tenant, ID: thd.ID}); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2106,15 +2106,15 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
log.Print("Filters:")
|
||||
log.Print("FilterProfile:")
|
||||
}
|
||||
for _, mpID := range tpr.flProfiles {
|
||||
for _, tpTH := range mpID {
|
||||
th, err := APItoFilter(tpTH)
|
||||
th, err := APItoFilter(tpTH, tpr.timezone)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tpr.dataStorage.SetFilter(th); err != nil {
|
||||
if err = tpr.dm.SetFilter(th); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2122,11 +2122,22 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
}
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
log.Print("Filters:")
|
||||
}
|
||||
for _, thd := range tpr.filters {
|
||||
if err = tpr.dm.SetFilter(&Filter{Tenant: thd.Tenant, ID: thd.ID}); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
log.Print("\t", thd.TenantID())
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
log.Print("Timings:")
|
||||
}
|
||||
for _, t := range tpr.timings {
|
||||
if err = tpr.dataStorage.SetTiming(t, utils.NonTransactional); err != nil {
|
||||
if err = tpr.dm.DataDB().SetTiming(t, utils.NonTransactional); err != nil {
|
||||
return err
|
||||
}
|
||||
if verbose {
|
||||
@@ -2138,7 +2149,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if verbose {
|
||||
log.Print("Rebuilding reverse destinations")
|
||||
}
|
||||
if err = tpr.dataStorage.RebuildReverseForPrefix(utils.REVERSE_DESTINATION_PREFIX); err != nil {
|
||||
if err = tpr.dm.DataDB().RebuildReverseForPrefix(utils.REVERSE_DESTINATION_PREFIX); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -2146,7 +2157,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if verbose {
|
||||
log.Print("Rebuilding account action plans")
|
||||
}
|
||||
if err = tpr.dataStorage.RebuildReverseForPrefix(utils.AccountActionPlansPrefix); err != nil {
|
||||
if err = tpr.dm.DataDB().RebuildReverseForPrefix(utils.AccountActionPlansPrefix); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -2154,7 +2165,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
if verbose {
|
||||
log.Print("Rebuilding reverse aliases")
|
||||
}
|
||||
if err = tpr.dataStorage.RebuildReverseForPrefix(utils.REVERSE_ALIASES_PREFIX); err != nil {
|
||||
if err = tpr.dm.DataDB().RebuildReverseForPrefix(utils.REVERSE_ALIASES_PREFIX); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -2230,6 +2241,31 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(tpr.flProfiles) > 0 {
|
||||
if verbose {
|
||||
log.Print("Indexing Filters")
|
||||
}
|
||||
for tenant, mpID := range tpr.flProfiles {
|
||||
stIdxr, err := NewReqFilterIndexer(tpr.dm, utils.FilterIndex+tenant)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tpTH := range mpID {
|
||||
if th, err := APItoFilter(tpTH, tpr.timezone); err != nil {
|
||||
return err
|
||||
} else {
|
||||
stIdxr.IndexFilters(th.ID, th.RequestFilters)
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
log.Printf("Indexed filters tenant: %s, keys %+v", tenant, stIdxr.ChangedKeys().Slice())
|
||||
}
|
||||
if err := stIdxr.StoreIndexes(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -2297,6 +2333,8 @@ func (tpr *TpReader) ShowStatistics() {
|
||||
log.Print("Stats: ", len(tpr.sqProfiles))
|
||||
// thresholds
|
||||
log.Print("Thresholds: ", len(tpr.thProfiles))
|
||||
// filters
|
||||
log.Print("Filters: ", len(tpr.flProfiles))
|
||||
}
|
||||
|
||||
// Returns the identities loaded for a specific category, useful for cache reloads
|
||||
|
||||
@@ -1366,14 +1366,13 @@ type TPThreshold struct {
|
||||
Blocker bool // blocker flag to stop processing on filters matched
|
||||
Weight float64 // Weight to sort the thresholds
|
||||
ActionIDs []string
|
||||
Async bool
|
||||
}
|
||||
|
||||
type TPFilter struct {
|
||||
TPid string
|
||||
Tenant string
|
||||
ID string
|
||||
FilterType string // Filter type (*string, *timing, *rsr_filters, *cdr_stats)
|
||||
FilterFieldName string // Name of the field providing us the Values to check (used in case of some )
|
||||
FilterFielValues []string // Filter definition
|
||||
|
||||
TPid string
|
||||
Tenant string
|
||||
ID string
|
||||
Filters []*TPRequestFilter
|
||||
ActivationInterval *TPActivationInterval // Time when this limit becomes active and expires
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user