mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
DiameterAgent - support for sharing group variables via request processors, fixes #1302
This commit is contained in:
@@ -50,15 +50,15 @@ var sTestsDiam = []func(t *testing.T){
|
||||
testDiamItInitCfg,
|
||||
testDiamItResetDataDb,
|
||||
testDiamItResetStorDb,
|
||||
//testDiamItStartEngine,
|
||||
testDiamItStartEngine,
|
||||
testDiamItConnectDiameterClient,
|
||||
testDiamItApierRpcConn,
|
||||
testDiamItTPFromFolder,
|
||||
testDiamItDryRun,
|
||||
//testDiamItCCRInit,
|
||||
//testDiamItCCRUpdate,
|
||||
//testDiamItCCRTerminate,
|
||||
//testDiamItCCRSMS,
|
||||
testDiamItCCRInit,
|
||||
testDiamItCCRUpdate,
|
||||
testDiamItCCRTerminate,
|
||||
testDiamItCCRSMS,
|
||||
testDiamItKillEngine,
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,6 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.DARequestProcessor,
|
||||
reqProcessor.Filters, agReq); err != nil || !pass {
|
||||
return pass, err
|
||||
}
|
||||
fmt.Printf("processRequest, processor: %s, agreq: %s\n", utils.ToJSON(reqProcessor), utils.ToJSON(agReq))
|
||||
if agReq.CGRRequest, err = agReq.AsNavigableMap(reqProcessor.RequestFields); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -318,8 +317,8 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.DARequestProcessor,
|
||||
}
|
||||
if nM, err := agReq.AsNavigableMap(reqProcessor.ReplyFields); err != nil {
|
||||
return false, err
|
||||
} else if err := agReq.Reply.Merge(nM); err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
agReq.Reply.Merge(nM)
|
||||
}
|
||||
if reqType == utils.MetaDryRun {
|
||||
utils.Logger.Info(
|
||||
|
||||
@@ -92,6 +92,7 @@ func (nM *NavigableMap) Set(path []string, data interface{}, apnd, ordered bool)
|
||||
|
||||
// FieldAsInterface returns the field value as interface{} for the path specified
|
||||
// implements DataProvider
|
||||
// supports spath with selective elements in case of []*NMItem
|
||||
func (nM *NavigableMap) FieldAsInterface(fldPath []string) (fldVal interface{}, err error) {
|
||||
lenPath := len(fldPath)
|
||||
if lenPath == 0 {
|
||||
@@ -101,6 +102,10 @@ func (nM *NavigableMap) FieldAsInterface(fldPath []string) (fldVal interface{},
|
||||
var canCast bool
|
||||
for i, spath := range fldPath {
|
||||
if i == lenPath-1 { // lastElement
|
||||
if idxStart := strings.Index(spath, utils.IdxStart); idxStart != -1 &&
|
||||
strings.HasSuffix(spath, utils.IdxEnd) {
|
||||
spath = spath[:idxStart] // ignore the selector for now since it is processed in other places
|
||||
}
|
||||
var has bool
|
||||
fldVal, has = lastMp[spath]
|
||||
if !has {
|
||||
@@ -182,28 +187,27 @@ func (nM *NavigableMap) AsNavigableMap(
|
||||
}
|
||||
|
||||
// Merge will update nM with values from a second one
|
||||
func (nM *NavigableMap) Merge(nM2 *NavigableMap) (err error) {
|
||||
func (nM *NavigableMap) Merge(nM2 *NavigableMap) {
|
||||
if nM2 == nil {
|
||||
return
|
||||
}
|
||||
for k, v := range nM2.data {
|
||||
oV, has := nM.data[k]
|
||||
if !has {
|
||||
nM.data[k] = v
|
||||
continue
|
||||
}
|
||||
if oItms, isNMItems := oV.([]*NMItem); isNMItems {
|
||||
vItms, isItms := v.([]*NMItem)
|
||||
if !isItms {
|
||||
return utils.ErrIncompatible
|
||||
}
|
||||
oItms = append(oItms, vItms...)
|
||||
continue
|
||||
}
|
||||
nM.data[k] = v
|
||||
if len(nM2.order) == 0 {
|
||||
indexMapPaths(nM2.data, nil, &nM.order)
|
||||
}
|
||||
if len(nM2.order) != 0 {
|
||||
nM.order = append(nM.order, nM2.order...)
|
||||
pathIdx := make(map[string]int) // will hold references for last index exported in case of []*NMItem
|
||||
for _, path := range nM2.order {
|
||||
val, _ := nM2.FieldAsInterface(path)
|
||||
if valItms, isItms := val.([]*NMItem); isItms {
|
||||
pathStr := strings.Join(path, utils.NestingSep)
|
||||
pathIdx[pathStr] += 1
|
||||
if pathIdx[pathStr] > len(valItms) {
|
||||
val = valItms[len(valItms)-1:] // slice with only last element in, so we can set it unlimited
|
||||
} else {
|
||||
val = []*NMItem{valItms[pathIdx[pathStr]-1]} // set only one item per path
|
||||
}
|
||||
}
|
||||
nM.Set(path, val, true,
|
||||
(len(nM.order) != 0 || len(nM.data) == 0))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -841,3 +841,35 @@ func TestNavMapAsCGREvent(t *testing.T) {
|
||||
t.Errorf("expecting: %+v, \nreceived: %+v", utils.ToJSON(eEv), utils.ToJSON(cgrEv.Event))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNavMapMerge(t *testing.T) {
|
||||
nM2 := &NavigableMap{
|
||||
data: map[string]interface{}{
|
||||
"FirstLevel": map[string]interface{}{
|
||||
"SecondLevel": map[string]interface{}{
|
||||
"ThirdLevel": map[string]interface{}{
|
||||
"Fld1": []*NMItem{
|
||||
{
|
||||
Path: []string{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
|
||||
Data: "Val1",
|
||||
},
|
||||
{
|
||||
Path: []string{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
|
||||
Data: "Val2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
order: [][]string{
|
||||
{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
|
||||
{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
|
||||
},
|
||||
}
|
||||
nM := NewNavigableMap(nil)
|
||||
nM.Merge(nM2)
|
||||
if !reflect.DeepEqual(nM2, nM) {
|
||||
t.Errorf("expecting: %+v, received: %+v", nM2, nM)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"id": "dryrun1",
|
||||
"filters": ["*string:*vars.*cmd:CCR", "*string:*req.Service-Context-Id:TestDiamItDryRun"],
|
||||
"flags": ["*dryrun"],
|
||||
"continue_on_success": true,
|
||||
"request_fields":[
|
||||
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"},
|
||||
{"tag": "Val1", "field_id": "Val1", "type": "*constant", "value": "1"},
|
||||
@@ -38,7 +39,7 @@
|
||||
},
|
||||
{
|
||||
"id": "dryrun2",
|
||||
"filters": ["*rsr::~*rep.Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets[~Rating-Group(1)](!^$)"], // make sure the CC-Total-Octets was populated in the previous processor
|
||||
"filters": ["*rsr::~*rep.Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets[0](!^$)"], // make sure the CC-Total-Octets was populated in the previous processor
|
||||
"flags": ["*dryrun"],
|
||||
"request_fields":[
|
||||
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"},
|
||||
|
||||
@@ -535,6 +535,8 @@ const (
|
||||
OriginRealm = "OriginRealm"
|
||||
ProductName = "ProductName"
|
||||
CGRSubsystems = "cgr_subsystems"
|
||||
IdxStart = "["
|
||||
IdxEnd = "]"
|
||||
)
|
||||
|
||||
// Migrator Action
|
||||
|
||||
Reference in New Issue
Block a user