Changed DispatcherS CSV loader

This commit is contained in:
Trial97
2019-02-07 14:28:25 +02:00
committed by Dan Christian Bogos
parent f74dd8ae73
commit 7a82689226
14 changed files with 245 additions and 172 deletions

View File

@@ -18,11 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package v1
/*
import (
"github.com/cgrates/cgrates/dispatchers"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/sessions"
"github.com/cgrates/cgrates/utils"
)
@@ -85,6 +82,8 @@ func (apierV1 *ApierV1) RemoveDispatcherProfile(arg *utils.TenantID, reply *stri
return nil
}
/*
func NewDispatcherThresholdSv1(dps *dispatchers.DispatcherService) *DispatcherThresholdSv1 {
return &DispatcherThresholdSv1{dS: dps}
}

View File

@@ -163,6 +163,10 @@ func testPrecacheGetCacheStatsBeforeLoad(t *testing.T) {
Items: 0,
Groups: 0,
},
"dispatcher_routes": {
Items: 0,
Groups: 0,
},
"derived_chargers": {
Items: 0,
Groups: 0,
@@ -331,6 +335,10 @@ func testPrecacheGetCacheStatsAfterRestart(t *testing.T) {
Items: 0,
Groups: 0,
},
"dispatcher_routes": {
Items: 0,
Groups: 0,
},
"derived_chargers": {
Items: 1, // expected to have 1 item
Groups: 0,

View File

@@ -196,7 +196,7 @@ func testDspAttrTestMissingApiKey(t *testing.T) {
}
var attrReply *engine.AttributeProfile
if err := dspAttrRPC.Call(utils.AttributeSv1GetAttributeForEvent,
args, &attrReply); err.Error() != utils.NewErrMandatoryIeMissing(utils.APIKey).Error() {
args, &attrReply); err == nil || err.Error() != utils.NewErrMandatoryIeMissing(utils.APIKey).Error() {
t.Error(err)
}
}
@@ -215,7 +215,7 @@ func testDspAttrTestUnknownApiKey(t *testing.T) {
}
var attrReply *engine.AttributeProfile
if err := dspAttrRPC.Call(utils.AttributeSv1GetAttributeForEvent,
args, &attrReply); err.Error() != utils.ErrUnknownApiKey.Error() {
args, &attrReply); err == nil || err.Error() != utils.ErrUnknownApiKey.Error() {
t.Error(err)
}
}
@@ -234,7 +234,7 @@ func testDspAttrTestAuthKey(t *testing.T) {
}
var attrReply *engine.AttributeProfile
if err := dspAttrRPC.Call(utils.AttributeSv1GetAttributeForEvent,
args, &attrReply); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &attrReply); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -192,7 +192,7 @@ func testDspCppTestAuthKey(t *testing.T) {
}
var reply *engine.ChargerProfiles
if err := dspCppRPC.Call(utils.ChargerSv1GetChargersForEvent,
args, &reply); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &reply); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -71,7 +71,8 @@ func (dS *DispatcherService) Shutdown() error {
func (dS *DispatcherService) dispatcherForEvent(ev *utils.CGREvent,
subsys string) (d Dispatcher, err error) {
// find out the matching profiles
idxKeyPrfx := utils.ConcatenatedKey(ev.Tenant, utils.META_ANY)
anyIdxPrfx := utils.ConcatenatedKey(ev.Tenant, utils.META_ANY)
idxKeyPrfx := anyIdxPrfx
if subsys != "" {
idxKeyPrfx = utils.ConcatenatedKey(ev.Tenant, subsys)
}
@@ -90,7 +91,6 @@ func (dS *DispatcherService) dispatcherForEvent(ev *utils.CGREvent,
if err != utils.ErrNotFound {
return nil, err
}
anyIdxPrfx := utils.ConcatenatedKey(ev.Tenant, utils.META_ANY)
if idxKeyPrfx == anyIdxPrfx {
continue // already checked *any
}

View File

@@ -197,7 +197,7 @@ func testDspResTestAuthKey(t *testing.T) {
}
if err := dspResRPC.Call(utils.ResourceSv1GetResourcesForEvent,
args, &rs); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &rs); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -214,7 +214,7 @@ func testDspSessionTestAuthKey(t *testing.T) {
}
var rply sessions.V1AuthorizeReplyWithDigest
if err := dspSessionRPC.Call(utils.SessionSv1AuthorizeEventWithDigest,
args, &rply); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &rply); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -196,7 +196,7 @@ func testDspStsTestAuthKey(t *testing.T) {
utils.PDD: time.Duration(12 * time.Second)}},
}}
if err := dspStsRPC.Call(utils.StatSv1ProcessEvent,
args, &reply); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &reply); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
@@ -210,7 +210,7 @@ func testDspStsTestAuthKey(t *testing.T) {
var metrics map[string]string
if err := dspStsRPC.Call(utils.StatSv1GetQueueStringMetrics,
args2, &metrics); err.Error() != utils.ErrUnauthorizedApi.Error() {
args2, &metrics); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -200,7 +200,7 @@ func testDspSupTestAuthKey(t *testing.T) {
},
}
if err := dspSupRPC.Call(utils.SupplierSv1GetSuppliers,
args, &rpl); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &rpl); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
}

View File

@@ -196,7 +196,7 @@ func testDspThTestAuthKey(t *testing.T) {
}
if err := dspThRPC.Call(utils.ThresholdSv1ProcessEvent,
args, &ids); err.Error() != utils.ErrUnauthorizedApi.Error() {
args, &ids); err == nil || err.Error() != utils.ErrUnauthorizedApi.Error() {
t.Error(err)
}
var th *engine.Thresholds

View File

@@ -297,7 +297,8 @@ cgrates.org,Charger1,*string:Account:1001,2014-07-29T15:00:00Z,*rated,ATTR_1001_
`
dispatcherProfiles = `
#Tenant,ID,FilterIDs,ActivationInterval,Strategy,Hosts,Weight
cgrates.org,D1,*string:Account:1001,2014-07-29T15:00:00Z,*first,192.168.56.203;192.168.56.204,20
cgrates.org,D1,*any,*string:Account:1001,2014-07-29T15:00:00Z,*first,,C1,*gt:Usage:10,10,false,192.168.56.203,20
cgrates.org,D1,,,,*first,,C2,*lt:Usage:10,10,false,192.168.56.204,
`
)
@@ -1723,38 +1724,68 @@ func TestLoadChargerProfiles(t *testing.T) {
}
func TestLoadDispatcherProfiles(t *testing.T) {
eDispatcherProfiles := map[utils.TenantID]*utils.TPDispatcherProfile{
utils.TenantID{Tenant: "cgrates.org", ID: "D1"}: &utils.TPDispatcherProfile{
TPid: testTPID,
Tenant: "cgrates.org",
ID: "D1",
FilterIDs: []string{"*string:Account:1001"},
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-29T15:00:00Z",
},
Strategy: "*first",
Hosts: []string{"192.168.56.203", "192.168.56.204"},
Weight: 20,
},
}
revHosts := &utils.TPDispatcherProfile{
TPid: testTPID,
Tenant: "cgrates.org",
ID: "D1",
FilterIDs: []string{"*string:Account:1001"},
eDispatcherProfiles := &utils.TPDispatcherProfile{
TPid: testTPID,
Tenant: "cgrates.org",
ID: "D1",
Subsystems: []string{"*any"},
FilterIDs: []string{"*string:Account:1001"},
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-29T15:00:00Z",
},
Strategy: "*first",
Hosts: []string{"192.168.56.204", "192.168.56.203"},
Weight: 20,
Conns: []*utils.TPDispatcherConns{
&utils.TPDispatcherConns{
ID: "C1",
FilterIDs: []string{"*gt:Usage:10"},
Weight: 10,
Params: []interface{}{"192.168.56.203"},
Blocker: false,
},
&utils.TPDispatcherConns{
ID: "C2",
FilterIDs: []string{"*lt:Usage:10"},
Weight: 10,
Params: []interface{}{"192.168.56.204"},
Blocker: false,
},
},
}
revHosts := &utils.TPDispatcherProfile{
TPid: testTPID,
Tenant: "cgrates.org",
ID: "D1",
Subsystems: []string{"*any"},
FilterIDs: []string{"*string:Account:1001"},
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-29T15:00:00Z",
},
Strategy: "*first",
Weight: 20,
Conns: []*utils.TPDispatcherConns{
&utils.TPDispatcherConns{
ID: "C2",
FilterIDs: []string{"*lt:Usage:10"},
Weight: 10,
Params: []interface{}{"192.168.56.204"},
Blocker: false,
},
&utils.TPDispatcherConns{
ID: "C1",
FilterIDs: []string{"*gt:Usage:10"},
Weight: 10,
Params: []interface{}{"192.168.56.203"},
Blocker: false,
},
},
}
dppKey := utils.TenantID{Tenant: "cgrates.org", ID: "D1"}
if len(csvr.dispatcherProfiles) != len(eDispatcherProfiles) {
if len(csvr.dispatcherProfiles) != 1 {
t.Errorf("Failed to load chargerProfiles: %s", utils.ToIJSON(csvr.chargerProfiles))
} else if !reflect.DeepEqual(eDispatcherProfiles[dppKey], csvr.dispatcherProfiles[dppKey]) &&
} else if !reflect.DeepEqual(eDispatcherProfiles, csvr.dispatcherProfiles[dppKey]) &&
!reflect.DeepEqual(revHosts, csvr.dispatcherProfiles[dppKey]) {
t.Errorf("Expecting: %+v, received: %+v", eDispatcherProfiles[dppKey], csvr.dispatcherProfiles[dppKey])
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eDispatcherProfiles), utils.ToJSON(csvr.dispatcherProfiles[dppKey]))
}
}

View File

@@ -2719,92 +2719,98 @@ func (tps TPDispatchers) AsTPDispatchers() (result []*utils.TPDispatcherProfile)
for filter := range connsFilterMap[tntID][conID] {
conn.FilterIDs = append(conn.FilterIDs, filter)
}
result[i].Conns = append(result[i].Conns, &conn)
result[i].Conns = append(result[i].Conns, &utils.TPDispatcherConns{
ID: conn.ID,
FilterIDs: conn.FilterIDs,
Weight: conn.Weight,
Params: conn.Params,
Blocker: conn.Blocker,
})
}
i++
}
return
}
func APItoModelTPDispatcher(tpDPP *utils.TPDispatcherProfile) (mdls TPDispatchers) {
// if tpDPP != nil {
// min := len(tpDPP.FilterIDs)
// isFilter := true
// if min > len(tpDPP.Hosts) {
// min = len(tpDPP.Hosts)
// isFilter = false
// }
// if min == 0 {
// mdl := &TPDispatcher{
// Tenant: tpDPP.Tenant,
// Tpid: tpDPP.TPid,
// ID: tpDPP.ID,
// Weight: tpDPP.Weight,
// Strategy: tpDPP.Strategy,
// }
// if tpDPP.ActivationInterval != nil {
// if tpDPP.ActivationInterval.ActivationTime != "" {
// mdl.ActivationInterval = tpDPP.ActivationInterval.ActivationTime
// }
// if tpDPP.ActivationInterval.ExpiryTime != "" {
// mdl.ActivationInterval += utils.INFIELD_SEP + tpDPP.ActivationInterval.ExpiryTime
// }
// }
// if isFilter && len(tpDPP.Hosts) > 0 {
// mdl.Hosts = tpDPP.Hosts[0]
// } else if len(tpDPP.FilterIDs) > 0 {
// mdl.FilterIDs = tpDPP.FilterIDs[0]
// }
// min = 1
// mdls = append(mdls, mdl)
// } else {
// for i := 0; i < min; i++ {
// mdl := &TPDispatcher{
// Tenant: tpDPP.Tenant,
// Tpid: tpDPP.TPid,
// ID: tpDPP.ID,
// }
// if i == 0 {
// mdl.Weight = tpDPP.Weight
// mdl.Strategy = tpDPP.Strategy
// if tpDPP.ActivationInterval != nil {
// if tpDPP.ActivationInterval.ActivationTime != "" {
// mdl.ActivationInterval = tpDPP.ActivationInterval.ActivationTime
// }
// if tpDPP.ActivationInterval.ExpiryTime != "" {
// mdl.ActivationInterval += utils.INFIELD_SEP + tpDPP.ActivationInterval.ExpiryTime
// }
// }
// }
// mdl.Hosts = tpDPP.Hosts[i]
// mdl.FilterIDs = tpDPP.FilterIDs[i]
// mdls = append(mdls, mdl)
// }
// }
// if len(tpDPP.FilterIDs)-min > 0 {
// for i := min; i < len(tpDPP.FilterIDs); i++ {
// mdl := &TPDispatcher{
// Tenant: tpDPP.Tenant,
// Tpid: tpDPP.TPid,
// ID: tpDPP.ID,
// }
// mdl.FilterIDs = tpDPP.FilterIDs[i]
// mdls = append(mdls, mdl)
// }
// }
// if len(tpDPP.Hosts)-min > 0 {
// for i := min; i < len(tpDPP.Hosts); i++ {
// mdl := &TPDispatcher{
// Tenant: tpDPP.Tenant,
// Tpid: tpDPP.TPid,
// ID: tpDPP.ID,
// }
// mdl.Hosts = tpDPP.Hosts[i]
// mdls = append(mdls, mdl)
// }
// }
func paramsToString(sp []interface{}) (strategy string) {
if len(sp) != 0 {
strategy = sp[0].(string)
for i := 1; i < len(sp); i++ {
strategy += utils.INFIELD_SEP + sp[i].(string)
}
}
return
}
// }
func APItoModelTPDispatcher(tpDPP *utils.TPDispatcherProfile) (mdls TPDispatchers) {
if tpDPP == nil {
return
}
filters := strings.Join(tpDPP.FilterIDs, utils.INFIELD_SEP)
context := strings.Join(tpDPP.Subsystems, utils.INFIELD_SEP)
interval := ""
if tpDPP.ActivationInterval != nil {
if tpDPP.ActivationInterval.ActivationTime != "" {
interval = tpDPP.ActivationInterval.ActivationTime
}
if tpDPP.ActivationInterval.ExpiryTime != "" {
interval += utils.INFIELD_SEP + tpDPP.ActivationInterval.ExpiryTime
}
}
strategy := paramsToString(tpDPP.StrategyParams)
if len(tpDPP.Conns) == 0 {
return append(mdls, &TPDispatcher{
Tpid: tpDPP.TPid,
Tenant: tpDPP.Tenant,
ID: tpDPP.ID,
Contexts: context,
FilterIDs: filters,
ActivationInterval: interval,
Strategy: tpDPP.Strategy,
StrategyParameters: strategy,
Weight: tpDPP.Weight,
})
}
confilter := strings.Join(tpDPP.Conns[0].FilterIDs, utils.INFIELD_SEP)
conparam := paramsToString(tpDPP.Conns[0].Params)
mdls = append(mdls, &TPDispatcher{
Tpid: tpDPP.TPid,
Tenant: tpDPP.Tenant,
ID: tpDPP.ID,
Contexts: context,
FilterIDs: filters,
ActivationInterval: interval,
Strategy: tpDPP.Strategy,
StrategyParameters: strategy,
Weight: tpDPP.Weight,
ConnID: tpDPP.Conns[0].ID,
ConnFilterIDs: confilter,
ConnWeight: tpDPP.Conns[0].Weight,
ConnBlocker: tpDPP.Conns[0].Blocker,
ConnParameters: conparam,
})
for i := 1; i < len(tpDPP.Conns); i++ {
confilter = strings.Join(tpDPP.Conns[i].FilterIDs, utils.INFIELD_SEP)
conparam = paramsToString(tpDPP.Conns[i].Params)
mdls = append(mdls, &TPDispatcher{
Tpid: tpDPP.TPid,
Tenant: tpDPP.Tenant,
ID: tpDPP.ID,
ConnID: tpDPP.Conns[i].ID,
ConnFilterIDs: confilter,
ConnWeight: tpDPP.Conns[i].Weight,
ConnBlocker: tpDPP.Conns[i].Blocker,
ConnParameters: conparam,
})
}
return
}

View File

@@ -1770,29 +1770,49 @@ func TestModelAsTPChargers(t *testing.T) {
func TestAPItoDispatcherProfile(t *testing.T) {
tpDPP := &utils.TPDispatcherProfile{
TPid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
TPid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
Hosts: []string{"localhost", "192.168.56.203"},
Weight: 20,
StrategyParams: []interface{}{},
Weight: 20,
Conns: []*utils.TPDispatcherConns{
&utils.TPDispatcherConns{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: []interface{}{"192.168.54.203"},
Blocker: false,
},
},
}
expected := &DispatcherProfile{
Tenant: "cgrates.org",
ID: "Dsp",
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
// Hosts: []string{"localhost", "192.168.56.203"},
Weight: 20,
StrategyParams: map[string]interface{}{},
Weight: 20,
Conns: DispatcherConns{
&DispatcherConn{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: map[string]interface{}{"\u0000": "192.168.54.203"},
Blocker: false,
},
},
}
if rcv, err := APItoDispatcherProfile(tpDPP, "UTC"); err != nil {
t.Error(err)
@@ -1803,36 +1823,58 @@ func TestAPItoDispatcherProfile(t *testing.T) {
func TestAPItoModelTPDispatcher(t *testing.T) {
tpDPP := &utils.TPDispatcherProfile{
TPid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
TPid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
Hosts: []string{"localhost", "192.168.56.203"},
Weight: 20,
StrategyParams: []interface{}{},
Weight: 20,
Conns: []*utils.TPDispatcherConns{
&utils.TPDispatcherConns{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: []interface{}{"192.168.54.203"},
Blocker: false,
},
&utils.TPDispatcherConns{
ID: "C2",
FilterIDs: []string{},
Weight: 10,
Params: []interface{}{"192.168.54.204"},
Blocker: false,
},
},
}
expected := TPDispatchers{
&TPDispatcher{
Tpid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
FilterIDs: "FLTR_ACNT_dan",
Contexts: "*any",
FilterIDs: "FLTR_ACNT_dan;FLTR_DST_DE",
Strategy: utils.MetaFirst,
Hosts: "localhost",
ActivationInterval: "2014-07-14T14:35:00Z",
Weight: 20,
ConnID: "C1",
ConnWeight: 10,
ConnBlocker: false,
ConnParameters: "192.168.54.203",
},
&TPDispatcher{
Tpid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
FilterIDs: "FLTR_DST_DE",
Hosts: "192.168.56.203",
ActivationInterval: "",
Tpid: "TP1",
Tenant: "cgrates.org",
ID: "Dsp",
ConnID: "C2",
ConnWeight: 10,
ConnBlocker: false,
ConnParameters: "192.168.54.204",
},
}
rcv := APItoModelTPDispatcher(tpDPP)

View File

@@ -504,34 +504,21 @@ type TPCharger struct {
CreatedAt time.Time
}
// type TPDispatcher struct {
// PK uint `gorm:"primary_key"`
// Tpid string
// Tenant string `index:"0" re:""`
// ID string `index:"1" re:""`
// FilterIDs string `index:"2" re:""`
// ActivationInterval string `index:"3" re:""`
// Strategy string `index:"4" re:""`
// Hosts string `index:"5" re:""`
// Weight float64 `index:"6" re:"\d+\.?\d*"`
// CreatedAt time.Time
// }
type TPDispatcher struct {
PK uint `gorm:"primary_key"`
Tpid string //
Tenant string `index:"0" re:""` //
ID string `index:"1" re:""` //
Contexts string `index:"2" re:""` //
FilterIDs string `index:"3" re:""` //
ActivationInterval string `index:"4" re:""` //
Strategy string `index:"5" re:""` //
StrategyParameters string `index:"6" re:""` //
ConnID string `index:"7" re:""` //
ConnFilterIDs string `index:"8" re:""` //
ConnWeight float64 `index:"9" re:"\d+\.?\d*"` //
ConnBlocker bool `index:"10" re:""` //
ConnParameters string `index:"11" re:""` //
Weight float64 `index:"12" re:"\d+\.?\d*"` //
Tenant string `index:"0" re:""`
ID string `index:"1" re:""`
Contexts string `index:"2" re:""`
FilterIDs string `index:"3" re:""`
ActivationInterval string `index:"4" re:""`
Strategy string `index:"5" re:""`
StrategyParameters string `index:"6" re:""`
ConnID string `index:"7" re:""`
ConnFilterIDs string `index:"8" re:""`
ConnWeight float64 `index:"9" re:"\d+\.?\d*"`
ConnBlocker bool `index:"10" re:""`
ConnParameters string `index:"11" re:""`
Weight float64 `index:"12" re:"\d+\.?\d*"`
CreatedAt time.Time
}