mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
NavigableMap moved to engine, DataProvider interface with AsNavigableMap method
This commit is contained in:
@@ -159,14 +159,14 @@ func (da DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestProce
|
||||
var initReply sessions.V1InitSessionReply
|
||||
err = da.sessionS.Call(utils.SessionSv1InitiateSession,
|
||||
procVars.asV1InitSessionArgs(cgrEv), &initReply)
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&initReply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&initReply, err); err != nil {
|
||||
return
|
||||
}
|
||||
case 2:
|
||||
var updateReply sessions.V1UpdateSessionReply
|
||||
err = da.sessionS.Call(utils.SessionSv1UpdateSession,
|
||||
procVars.asV1UpdateSessionArgs(cgrEv), &updateReply)
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&updateReply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&updateReply, err); err != nil {
|
||||
return
|
||||
}
|
||||
case 3, 4: // Handle them together since we generate CDR for them
|
||||
@@ -185,7 +185,7 @@ func (da DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestProce
|
||||
} else if evntRply.MaxUsage != nil {
|
||||
cgrEv.Event[utils.Usage] = *evntRply.MaxUsage // make sure the CDR reflects the debit
|
||||
}
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&evntRply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&evntRply, err); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ func (ha *HTTPAgent) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// processRequest represents one processor processing the request
|
||||
func (ha *HTTPAgent) processRequest(reqProcessor *config.HttpAgntProcCfg,
|
||||
dP utils.DataProvider, procVars processorVars,
|
||||
dP engine.DataProvider, procVars processorVars,
|
||||
reply *httpReplyFields) (processed bool, err error) {
|
||||
|
||||
tnt, err := dP.FieldAsString([]string{utils.Tenant})
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/fiorix/go-diameter/diam"
|
||||
@@ -38,7 +39,8 @@ import (
|
||||
var err error
|
||||
|
||||
func TestDisectUsageForCCR(t *testing.T) {
|
||||
if reqType, reqNr, reqCCTime, usedCCTime := disectUsageForCCR(time.Duration(0)*time.Second, time.Duration(300)*time.Second, false); reqType != 1 || reqNr != 0 || reqCCTime != 300 || usedCCTime != 0 {
|
||||
if reqType, reqNr, reqCCTime, usedCCTime := disectUsageForCCR(time.Duration(0)*time.Second,
|
||||
time.Duration(300)*time.Second, false); reqType != 1 || reqNr != 0 || reqCCTime != 300 || usedCCTime != 0 {
|
||||
t.Error(reqType, reqNr, reqCCTime, usedCCTime)
|
||||
}
|
||||
if reqType, reqNr, reqCCTime, usedCCTime := disectUsageForCCR(time.Duration(35)*time.Second, time.Duration(300)*time.Second, false); reqType != 2 || reqNr != 0 || reqCCTime != 300 || usedCCTime != 35 {
|
||||
@@ -226,7 +228,7 @@ func TestFieldOutVal(t *testing.T) {
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("*cgrReply>Error(^$);*cgrReply>MaxUsage(!300);*cgrReply>MaxUsage(!0)", utils.INFIELD_SEP),
|
||||
Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true}
|
||||
procVars := processorVars{
|
||||
utils.MetaCGRReply: utils.NavigableMap{
|
||||
utils.MetaCGRReply: engine.NavigableMap{
|
||||
utils.Error: "RALS_ERROR:NOT_FOUND",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
)
|
||||
|
||||
// httpReplyField is one field written in HTTP reply
|
||||
@@ -45,7 +45,7 @@ type httpReplyFields struct {
|
||||
|
||||
// newHAReqDecoder produces decoders
|
||||
func newHADataProvider(dpType string,
|
||||
req *http.Request) (dP utils.DataProvider, err error) {
|
||||
req *http.Request) (dP engine.DataProvider, err error) {
|
||||
switch dpType {
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported decoder type <%s>", dpType)
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
@@ -61,7 +62,7 @@ func (pv processorVars) valAsInterface(fldPath string) (val interface{}, err err
|
||||
err = errors.New("not found")
|
||||
return
|
||||
}
|
||||
return utils.NavigableMap(pv).FieldAsInterface(strings.Split(fldPath, utils.HIERARCHY_SEP))
|
||||
return engine.NavigableMap(pv).FieldAsInterface(strings.Split(fldPath, utils.HIERARCHY_SEP))
|
||||
}
|
||||
|
||||
// valAsString returns the string value for fldName
|
||||
@@ -74,7 +75,7 @@ func (pv processorVars) valAsString(fldPath string) (val string, err error) {
|
||||
if !pv.hasVar(fldName) {
|
||||
return "", utils.ErrNotFoundNoCaps
|
||||
}
|
||||
return utils.NavigableMap(pv).FieldAsString(strings.Split(fldPath, utils.HIERARCHY_SEP))
|
||||
return engine.NavigableMap(pv).FieldAsString(strings.Split(fldPath, utils.HIERARCHY_SEP))
|
||||
}
|
||||
|
||||
// asV1AuthorizeArgs returns the arguments needed by SessionSv1.AuthorizeEvent
|
||||
@@ -398,3 +399,18 @@ func radReplyAppendAttributes(reply *radigo.Packet, procVars map[string]interfac
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewCGRReply is specific to replies coming from CGRateS
|
||||
func NewCGRReply(rply engine.NavigableMapper,
|
||||
errRply error) (mp map[string]interface{}, err error) {
|
||||
if errRply != nil {
|
||||
return map[string]interface{}{
|
||||
utils.Error: errRply.Error()}, nil
|
||||
}
|
||||
nM, err := rply.AsNavigableMap(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nM[utils.Error] = "" // enforce empty error
|
||||
return map[string]interface{}(nM), nil // convert from NM to map due to decapsulation later
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -26,6 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
@@ -423,3 +425,34 @@ func TestRadReplyAppendAttributes(t *testing.T) {
|
||||
t.Errorf("Expecting: 3600, received: %s", avps[0].GetStringValue())
|
||||
}
|
||||
}
|
||||
|
||||
type myEv map[string]interface{}
|
||||
|
||||
func (ev myEv) AsNavigableMap(tpl []*config.CfgCdrField) (engine.NavigableMap, error) {
|
||||
return engine.NavigableMap(ev), nil
|
||||
}
|
||||
|
||||
func TestNewCGRReply(t *testing.T) {
|
||||
eCgrRply := map[string]interface{}{
|
||||
utils.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", utils.ToJSON(eCgrRply), utils.ToJSON(rpl))
|
||||
}
|
||||
ev := myEv{
|
||||
"FirstLevel": map[string]interface{}{
|
||||
"SecondLevel": map[string]interface{}{
|
||||
"Fld1": "Val1",
|
||||
},
|
||||
},
|
||||
}
|
||||
eCgrRply = ev
|
||||
eCgrRply[utils.Error] = ""
|
||||
if rpl, err := NewCGRReply(engine.NavigableMapper(ev), nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCgrRply, rpl) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eCgrRply, rpl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,21 +174,21 @@ func (ra *RadiusAgent) processRequest(reqProcessor *config.RARequestProcessor,
|
||||
var authReply sessions.V1AuthorizeReply
|
||||
err = ra.sessionS.Call(utils.SessionSv1AuthorizeEvent,
|
||||
procVars.asV1AuthorizeArgs(cgrEv), &authReply)
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&authReply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&authReply, err); err != nil {
|
||||
return
|
||||
}
|
||||
case MetaRadAcctStart:
|
||||
var initReply sessions.V1InitSessionReply
|
||||
err = ra.sessionS.Call(utils.SessionSv1InitiateSession,
|
||||
procVars.asV1InitSessionArgs(cgrEv), &initReply)
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&initReply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&initReply, err); err != nil {
|
||||
return
|
||||
}
|
||||
case MetaRadAcctUpdate:
|
||||
var updateReply sessions.V1UpdateSessionReply
|
||||
err = ra.sessionS.Call(utils.SessionSv1UpdateSession,
|
||||
procVars.asV1UpdateSessionArgs(cgrEv), &updateReply)
|
||||
if procVars[utils.MetaCGRReply], err = utils.NewCGRReply(&updateReply, err); err != nil {
|
||||
if procVars[utils.MetaCGRReply], err = NewCGRReply(&updateReply, err); err != nil {
|
||||
return
|
||||
}
|
||||
case MetaRadAcctStop:
|
||||
|
||||
@@ -91,7 +91,7 @@ func (alS *AttributeService) matchingAttributeProfilesForEvent(ev *utils.CGREven
|
||||
continue
|
||||
}
|
||||
if pass, err := alS.filterS.Pass(ev.Tenant, aPrfl.FilterIDs,
|
||||
utils.NavigableMap(ev.Event)); err != nil {
|
||||
NavigableMap(ev.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
|
||||
@@ -1454,3 +1454,8 @@ func (cd *CallDescriptor) FieldAsString(fldPath []string) (fldVal string, err er
|
||||
func (cd *CallDescriptor) String() string {
|
||||
return utils.ToJSON(cd)
|
||||
}
|
||||
|
||||
// AsNavigableMap is part of utils.DataProvider
|
||||
func (cd *CallDescriptor) AsNavigableMap(tpl []*config.CfgCdrField) (nM NavigableMap, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,11 +16,16 @@ 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
|
||||
package engine
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/config"
|
||||
)
|
||||
|
||||
// DataProvider is a data source from multiple formats
|
||||
type DataProvider interface {
|
||||
FieldAsInterface(fldPath []string) (interface{}, error)
|
||||
FieldAsString(fldPath []string) (string, error)
|
||||
String() string // printable versin of data
|
||||
AsNavigableMap(cfgFlds []*config.CfgCdrField) (NavigableMap, error)
|
||||
}
|
||||
@@ -76,8 +76,8 @@ func (fS *FilterS) connStatS() (err error) {
|
||||
|
||||
// Pass will check all filters wihin filterIDs and require them passing for dataProvider
|
||||
// there should be at least one filter passing, ie: if filters are not active event will fail to pass
|
||||
// receives the event as utils.DataProvider so we can accept undecoded data (ie: HttpRequest)
|
||||
func (fS *FilterS) Pass(tenant string, filterIDs []string, ev utils.DataProvider) (pass bool, err error) {
|
||||
// receives the event as DataProvider so we can accept undecoded data (ie: HttpRequest)
|
||||
func (fS *FilterS) Pass(tenant string, filterIDs []string, ev DataProvider) (pass bool, err error) {
|
||||
if len(filterIDs) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func (rf *FilterRule) CompileValues() (err error) {
|
||||
}
|
||||
|
||||
// Pass is the method which should be used from outside.
|
||||
func (fltr *FilterRule) Pass(dP utils.DataProvider, rpcClnt rpcclient.RpcClientConnection) (bool, error) {
|
||||
func (fltr *FilterRule) Pass(dP DataProvider, rpcClnt rpcclient.RpcClientConnection) (bool, error) {
|
||||
switch fltr.Type {
|
||||
case MetaString:
|
||||
return fltr.passString(dP)
|
||||
@@ -230,7 +230,7 @@ func (fltr *FilterRule) Pass(dP utils.DataProvider, rpcClnt rpcclient.RpcClientC
|
||||
}
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passString(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passString(dP DataProvider) (bool, error) {
|
||||
strVal, err := dP.FieldAsString(strings.Split(fltr.FieldName, utils.HIERARCHY_SEP))
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -246,7 +246,7 @@ func (fltr *FilterRule) passString(dP utils.DataProvider) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passStringPrefix(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passStringPrefix(dP DataProvider) (bool, error) {
|
||||
strVal, err := dP.FieldAsString(strings.Split(fltr.FieldName, utils.HIERARCHY_SEP))
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -263,11 +263,11 @@ func (fltr *FilterRule) passStringPrefix(dP utils.DataProvider) (bool, error) {
|
||||
}
|
||||
|
||||
// ToDo when Timings will be available in DataDb
|
||||
func (fltr *FilterRule) passTimings(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passTimings(dP DataProvider) (bool, error) {
|
||||
return false, utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passDestinations(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passDestinations(dP DataProvider) (bool, error) {
|
||||
dst, err := dP.FieldAsString(strings.Split(fltr.FieldName, utils.HIERARCHY_SEP))
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
@@ -289,7 +289,7 @@ func (fltr *FilterRule) passDestinations(dP utils.DataProvider) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passRSR(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passRSR(dP DataProvider) (bool, error) {
|
||||
for _, rsrFld := range fltr.rsrFields {
|
||||
fldIface, err := dP.FieldAsInterface(strings.Split(rsrFld.Id, utils.HIERARCHY_SEP))
|
||||
if err != nil {
|
||||
@@ -305,7 +305,7 @@ func (fltr *FilterRule) passRSR(dP utils.DataProvider) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passStatS(dP utils.DataProvider,
|
||||
func (fltr *FilterRule) passStatS(dP DataProvider,
|
||||
stats rpcclient.RpcClientConnection) (bool, error) {
|
||||
if stats == nil || reflect.ValueOf(stats).IsNil() {
|
||||
return false, errors.New("Missing StatS information")
|
||||
@@ -330,7 +330,7 @@ func (fltr *FilterRule) passStatS(dP utils.DataProvider,
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (fltr *FilterRule) passGreaterThan(dP utils.DataProvider) (bool, error) {
|
||||
func (fltr *FilterRule) passGreaterThan(dP DataProvider) (bool, error) {
|
||||
fldIf, err := dP.FieldAsInterface(strings.Split(fltr.FieldName, utils.HIERARCHY_SEP))
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
|
||||
@@ -154,7 +154,7 @@ func TestFilterPassGreaterThan(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ev := utils.NavigableMap{
|
||||
ev := NavigableMap{
|
||||
"ASR": 20,
|
||||
}
|
||||
if passes, err := rf.passGreaterThan(ev); err != nil {
|
||||
@@ -296,13 +296,13 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*string:Account:1007"}, utils.NavigableMap(failEvent)); err != nil {
|
||||
[]string{"*string:Account:1007"}, NavigableMap(failEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*string:Account:1007"}, utils.NavigableMap(passEvent)); err != nil {
|
||||
[]string{"*string:Account:1007"}, NavigableMap(passEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
@@ -314,13 +314,13 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
"Account": "1007",
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*prefix:Account:10"}, utils.NavigableMap(failEvent)); err != nil {
|
||||
[]string{"*prefix:Account:10"}, NavigableMap(failEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*prefix:Account:10"}, utils.NavigableMap(passEvent)); err != nil {
|
||||
[]string{"*prefix:Account:10"}, NavigableMap(passEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
@@ -332,13 +332,13 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
"Tenant": "cgrates.org",
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*rsr::Tenant(~^cgr.*\\.org$)"}, utils.NavigableMap(failEvent)); err != nil {
|
||||
[]string{"*rsr::Tenant(~^cgr.*\\.org$)"}, NavigableMap(failEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*rsr::Tenant(~^cgr.*\\.org$)"}, utils.NavigableMap(passEvent)); err != nil {
|
||||
[]string{"*rsr::Tenant(~^cgr.*\\.org$)"}, NavigableMap(passEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
@@ -352,13 +352,13 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
utils.Destination: "+4986517174963",
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*destinations:Destination:EU"}, utils.NavigableMap(failEvent)); err != nil {
|
||||
[]string{"*destinations:Destination:EU"}, NavigableMap(failEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*destinations:Destination:EU_LANDLINE"}, utils.NavigableMap(passEvent)); err != nil {
|
||||
[]string{"*destinations:Destination:EU_LANDLINE"}, NavigableMap(passEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
@@ -370,13 +370,13 @@ func TestInlineFilterPassFiltersForEvent(t *testing.T) {
|
||||
utils.Weight: 20,
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*gte:Weight:20"}, utils.NavigableMap(failEvent)); err != nil {
|
||||
[]string{"*gte:Weight:20"}, NavigableMap(failEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{"*gte:Weight:10"}, utils.NavigableMap(passEvent)); err != nil {
|
||||
[]string{"*gte:Weight:10"}, NavigableMap(passEvent)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
@@ -404,13 +404,13 @@ func TestPassFiltersForEventWithEmptyFilter(t *testing.T) {
|
||||
utils.Weight: 20,
|
||||
}
|
||||
if pass, err := filterS.Pass("cgrates.org",
|
||||
[]string{}, utils.NavigableMap(passEvent1)); err != nil {
|
||||
[]string{}, NavigableMap(passEvent1)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", false, pass)
|
||||
}
|
||||
if pass, err := filterS.Pass("itsyscom.com",
|
||||
[]string{}, utils.NavigableMap(passEvent2)); err != nil {
|
||||
[]string{}, NavigableMap(passEvent2)); err != nil {
|
||||
t.Errorf(err.Error())
|
||||
} else if !pass {
|
||||
t.Errorf("Expecting: %+v, received: %+v", true, pass)
|
||||
|
||||
@@ -16,16 +16,19 @@ 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
|
||||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
// CGRReplier is the interface supported by replies convertible to CGRReply
|
||||
type NavigableMapper interface {
|
||||
AsNavigableMap() (map[string]interface{}, error)
|
||||
AsNavigableMap([]*config.CfgCdrField) (NavigableMap, error)
|
||||
}
|
||||
|
||||
// NavigableMap is a map who's values can be navigated via path
|
||||
@@ -45,7 +48,7 @@ func (nM NavigableMap) FieldAsInterface(fldPath []string) (fldVal interface{}, e
|
||||
var has bool
|
||||
fldVal, has = lastMp[spath]
|
||||
if !has {
|
||||
return nil, ErrNotFound
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return
|
||||
} else {
|
||||
@@ -57,7 +60,7 @@ func (nM NavigableMap) FieldAsInterface(fldPath []string) (fldVal interface{}, e
|
||||
lastMp, canCast = elmnt.(map[string]interface{})
|
||||
if !canCast {
|
||||
err = fmt.Errorf("cannot cast field: %s to map[string]interface{}",
|
||||
ToJSON(elmnt))
|
||||
utils.ToJSON(elmnt))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -75,24 +78,17 @@ func (nM NavigableMap) FieldAsString(fldPath []string) (fldVal string, err error
|
||||
return
|
||||
}
|
||||
var canCast bool
|
||||
if fldVal, canCast = CastFieldIfToString(valIface); !canCast {
|
||||
return "", fmt.Errorf("cannot cast field: %s to string", ToJSON(valIface))
|
||||
if fldVal, canCast = utils.CastFieldIfToString(valIface); !canCast {
|
||||
return "", fmt.Errorf("cannot cast field: %s to string", utils.ToJSON(valIface))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (nM NavigableMap) String() string {
|
||||
return ToJSON(nM)
|
||||
return utils.ToJSON(nM)
|
||||
}
|
||||
|
||||
// NewCGRReply is specific to replies coming from CGRateS
|
||||
func NewCGRReply(rply NavigableMapper, errRply error) (nM map[string]interface{}, err error) {
|
||||
if errRply != nil {
|
||||
return NavigableMap{Error: errRply.Error()}, nil
|
||||
}
|
||||
if nM, err = rply.AsNavigableMap(); err != nil {
|
||||
return
|
||||
}
|
||||
nM[Error] = "" // enforce empty error
|
||||
// AsNavigableMap implements both NavigableMapper as well as DataProvider interfaces
|
||||
func (nM NavigableMap) AsNavigableMap(tpl []*config.CfgCdrField) (oNM NavigableMap, err error) {
|
||||
return
|
||||
}
|
||||
@@ -15,11 +15,10 @@ 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
|
||||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -61,28 +60,3 @@ type myEv map[string]interface{}
|
||||
func (ev myEv) AsNavigableMap() (map[string]interface{}, error) {
|
||||
return NavigableMap(ev), nil
|
||||
}
|
||||
|
||||
func TestCGRReplyNew(t *testing.T) {
|
||||
eCgrRply := 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 = ev
|
||||
eCgrRply[Error] = ""
|
||||
if rpl, err := NewCGRReply(NavigableMapper(ev), nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCgrRply, rpl) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eCgrRply, rpl)
|
||||
}
|
||||
}
|
||||
@@ -464,7 +464,7 @@ func (rS *ResourceService) matchingResourcesForEvent(ev *utils.CGREvent, usageTT
|
||||
continue
|
||||
}
|
||||
if pass, err := rS.filterS.Pass(ev.Tenant, rPrf.FilterIDs,
|
||||
utils.NavigableMap(ev.Event)); err != nil {
|
||||
NavigableMap(ev.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
|
||||
@@ -169,7 +169,7 @@ func (sS *StatService) matchingStatQueuesForEvent(ev *utils.CGREvent) (sqs StatQ
|
||||
continue
|
||||
}
|
||||
if pass, err := sS.filterS.Pass(ev.Tenant, sqPrfl.FilterIDs,
|
||||
utils.NavigableMap(ev.Event)); err != nil {
|
||||
NavigableMap(ev.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
|
||||
@@ -137,7 +137,7 @@ func (spS *SupplierService) matchingSupplierProfilesForEvent(ev *utils.CGREvent)
|
||||
continue
|
||||
}
|
||||
if pass, err := spS.filterS.Pass(ev.Tenant, splPrfl.FilterIDs,
|
||||
utils.NavigableMap(ev.Event)); err != nil {
|
||||
NavigableMap(ev.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
@@ -277,7 +277,7 @@ func (spS *SupplierService) sortedSuppliersForEvent(args *ArgsGetSuppliers) (sor
|
||||
for _, s := range splPrfl.Suppliers {
|
||||
if len(s.FilterIDs) != 0 { // filters should be applied, check them here
|
||||
if pass, err := spS.filterS.Pass(args.Tenant, s.FilterIDs,
|
||||
utils.NavigableMap(args.Event)); err != nil {
|
||||
NavigableMap(args.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
|
||||
@@ -246,7 +246,7 @@ func (tS *ThresholdService) matchingThresholdsForEvent(args *ArgsProcessEvent) (
|
||||
continue
|
||||
}
|
||||
if pass, err := tS.filterS.Pass(args.Tenant, tPrfl.FilterIDs,
|
||||
utils.NavigableMap(args.Event)); err != nil {
|
||||
NavigableMap(args.Event)); err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
|
||||
@@ -1336,8 +1336,8 @@ type V1AuthorizeReply struct {
|
||||
StatQueueIDs *[]string
|
||||
}
|
||||
|
||||
// AsCGRReply is part of utils.CGRReplier interface
|
||||
func (v1AuthReply *V1AuthorizeReply) AsNavigableMap() (cgrReply map[string]interface{}, err error) {
|
||||
// AsNavigableMap is part of engine.NavigableMapper interface
|
||||
func (v1AuthReply *V1AuthorizeReply) AsNavigableMap(ignr []*config.CfgCdrField) (cgrReply engine.NavigableMap, err error) {
|
||||
cgrReply = make(map[string]interface{})
|
||||
if v1AuthReply.Attributes != nil {
|
||||
attrs := make(map[string]interface{})
|
||||
@@ -1551,8 +1551,8 @@ type V1InitSessionReply struct {
|
||||
StatQueueIDs *[]string
|
||||
}
|
||||
|
||||
// AsCGRReply is part of utils.CGRReplier interface
|
||||
func (v1Rply *V1InitSessionReply) AsNavigableMap() (cgrReply map[string]interface{}, err error) {
|
||||
// AsNavigableMap is part of engine.NavigableMapper interface
|
||||
func (v1Rply *V1InitSessionReply) AsNavigableMap(ignr []*config.CfgCdrField) (cgrReply engine.NavigableMap, err error) {
|
||||
cgrReply = make(map[string]interface{})
|
||||
if v1Rply.Attributes != nil {
|
||||
attrs := make(map[string]interface{})
|
||||
@@ -1731,8 +1731,8 @@ type V1UpdateSessionReply struct {
|
||||
MaxUsage *time.Duration
|
||||
}
|
||||
|
||||
// AsCGRReply is part of utils.CGRReplier interface
|
||||
func (v1Rply *V1UpdateSessionReply) AsNavigableMap() (cgrReply map[string]interface{}, err error) {
|
||||
// AsNavigableMap is part of engine.NavigableMapper interface
|
||||
func (v1Rply *V1UpdateSessionReply) AsNavigableMap(ignr []*config.CfgCdrField) (cgrReply engine.NavigableMap, err error) {
|
||||
cgrReply = make(map[string]interface{})
|
||||
if v1Rply.Attributes != nil {
|
||||
attrs := make(map[string]interface{})
|
||||
@@ -1898,8 +1898,8 @@ type V1ProcessEventReply struct {
|
||||
Attributes *engine.AttrSProcessEventReply
|
||||
}
|
||||
|
||||
// AsCGRReply is part of utils.CGRReplier interface
|
||||
func (v1Rply *V1ProcessEventReply) AsNavigableMap() (cgrReply map[string]interface{}, err error) {
|
||||
// AsNavigableMap is part of engine.NavigableMapper interface
|
||||
func (v1Rply *V1ProcessEventReply) AsNavigableMap(ignr []*config.CfgCdrField) (cgrReply engine.NavigableMap, err error) {
|
||||
cgrReply = make(map[string]interface{})
|
||||
if v1Rply.MaxUsage != nil {
|
||||
cgrReply[utils.CapMaxUsage] = *v1Rply.MaxUsage
|
||||
|
||||
Reference in New Issue
Block a user