mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-16 13:49:53 +05:00
Fix SessionDisconnect call on FreeSWITCH and Kamailio agents, adding CGRReply structure
This commit is contained in:
@@ -333,7 +333,7 @@ func (sm *FSsessions) Shutdown() (err error) {
|
||||
|
||||
// rpcclient.RpcClientConnection interface
|
||||
func (sm *FSsessions) Call(serviceMethod string, args interface{}, reply interface{}) error {
|
||||
return utils.APIerRPCCall(sm, serviceMethod, args, reply)
|
||||
return utils.RPCCall(sm, serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
// Internal method to disconnect session in asterisk
|
||||
|
||||
@@ -78,7 +78,7 @@ func (self *KamailioAgent) Shutdown() error {
|
||||
|
||||
// rpcclient.RpcClientConnection interface
|
||||
func (ka *KamailioAgent) Call(serviceMethod string, args interface{}, reply interface{}) error {
|
||||
return utils.APIerRPCCall(ka, serviceMethod, args, reply)
|
||||
return utils.RPCCall(ka, serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
// onCgrAuth is called when new event of type CGR_AUTH_REQUEST is coming
|
||||
|
||||
79
utils/cgrreply.go
Normal file
79
utils/cgrreply.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOev. 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/>
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CGRReplier is the interface supported by replies convertible to CGRReply
|
||||
type CGRReplier interface {
|
||||
AsCGRReply() (CGRReply, error)
|
||||
}
|
||||
|
||||
func NewCGRReply(rply CGRReplier, errRply error) (cgrReply CGRReply, err error) {
|
||||
if errRply != nil {
|
||||
return CGRReply{Error: errRply.Error()}, nil
|
||||
}
|
||||
if cgrReply, err = rply.AsCGRReply(); err != nil {
|
||||
return
|
||||
}
|
||||
cgrReply[Error] = "" // enforce empty error
|
||||
return
|
||||
}
|
||||
|
||||
// CGRReply represents the CGRateS answer which can be used in templates
|
||||
// it can be layered, case when interface{} will be castable into map[string]interface{}
|
||||
type CGRReply map[string]interface{}
|
||||
|
||||
// GetFieldAsString returns the field value as string for the path specified
|
||||
func (cgrReply CGRReply) GetFieldAsString(fldPath string, sep string) (fldVal string, err error) {
|
||||
path := strings.Split(fldPath, sep)
|
||||
lenPath := len(path)
|
||||
if lenPath == 0 {
|
||||
return "", errors.New("empty field path")
|
||||
}
|
||||
if path[0] == MetaCGRReply {
|
||||
path = path[1:]
|
||||
lenPath -= 1
|
||||
}
|
||||
lastMp := cgrReply // last map when layered
|
||||
var canCast bool
|
||||
for i, spath := range path {
|
||||
if i == lenPath-1 { // lastElement
|
||||
fldValIf, has := lastMp[spath]
|
||||
if !has {
|
||||
return "", fmt.Errorf("no field with path: <%s>", fldPath)
|
||||
}
|
||||
|
||||
if fldVal, canCast = CastFieldIfToString(fldValIf); !canCast {
|
||||
return "", fmt.Errorf("cannot cast field: %s to string", ToJSON(fldValIf))
|
||||
}
|
||||
return
|
||||
} else {
|
||||
lastMp, canCast = lastMp[spath].(map[string]interface{})
|
||||
if !canCast {
|
||||
return "", fmt.Errorf("cannot cast field: %s to map[string]interface{}", ToJSON(lastMp[spath]))
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", errors.New("end of function")
|
||||
}
|
||||
86
utils/cgrreply_test.go
Normal file
86
utils/cgrreply_test.go
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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/>
|
||||
*/
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type myEv map[string]interface{}
|
||||
|
||||
func (ev myEv) AsCGRReply() (CGRReply, error) {
|
||||
return CGRReply(ev), nil
|
||||
}
|
||||
|
||||
func TestCGRReplyNew(t *testing.T) {
|
||||
eCgrRply := CGRReply(map[string]interface{}{
|
||||
Error: "some",
|
||||
})
|
||||
if rpl, err := NewCGRReply(nil, errors.New("some")); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCgrRply, rpl) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", ToJSON(eCgrRply), ToJSON(rpl))
|
||||
}
|
||||
ev := myEv{
|
||||
"FirstLevel": map[string]interface{}{
|
||||
"SecondLevel": map[string]interface{}{
|
||||
"Fld1": "Val1",
|
||||
},
|
||||
},
|
||||
}
|
||||
eCgrRply = CGRReply(ev)
|
||||
eCgrRply[Error] = ""
|
||||
if rpl, err := NewCGRReply(CGRReplier(ev), nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCgrRply, rpl) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eCgrRply, rpl)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCGRReplyGetFieldAsString(t *testing.T) {
|
||||
ev := myEv{
|
||||
"FirstLevel": map[string]interface{}{
|
||||
"SecondLevel": map[string]interface{}{
|
||||
"ThirdLevel": map[string]interface{}{
|
||||
"Fld1": "Val1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"AnotherFirstLevel": "ValAnotherFirstLevel",
|
||||
}
|
||||
cgrRply, _ := NewCGRReply(CGRReplier(ev), nil)
|
||||
if strVal, err := cgrRply.GetFieldAsString("*cgrReply>Error", ">"); err != nil {
|
||||
t.Error(err)
|
||||
} else if strVal != "" {
|
||||
t.Error("received: <%s>", strVal)
|
||||
}
|
||||
eVal := "Val1"
|
||||
if strVal, err := cgrRply.GetFieldAsString("*cgrReply>FirstLevel>SecondLevel>ThirdLevel>Fld1", ">"); err != nil {
|
||||
t.Error(err)
|
||||
} else if strVal != eVal {
|
||||
t.Error("expecting: <%s> received: <%s>", eVal, strVal)
|
||||
}
|
||||
eVal = "ValAnotherFirstLevel"
|
||||
if strVal, err := cgrRply.GetFieldAsString("*cgrReply>AnotherFirstLevel", ">"); err != nil {
|
||||
t.Error(err)
|
||||
} else if strVal != eVal {
|
||||
t.Error("expecting: <%s> received: <%s>", eVal, strVal)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user