From 5c4b6e5da1adbb42c36cae3202517e4e533902f4 Mon Sep 17 00:00:00 2001 From: DanB Date: Fri, 21 Sep 2018 13:38:19 +0200 Subject: [PATCH] DiameterDP FieldAsInterface implementation --- agents/libdmt.go | 19 ++++++++++++----- agents/libdmt_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++ utils/slice.go | 9 +++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/agents/libdmt.go b/agents/libdmt.go index 60a50786d..7e074f49f 100644 --- a/agents/libdmt.go +++ b/agents/libdmt.go @@ -109,9 +109,9 @@ func diamAVPAsIface(dAVP *diam.AVP) (val interface{}, err error) { } // newDADataProvider constructs a DataProvider for a diameter message -func newDADataProvider(m *diam.Message) (dP config.DataProvider, err error) { - dP = &diameterDP{m: m, cache: config.NewNavigableMap(nil)} - return +func newDADataProvider(m *diam.Message) config.DataProvider { + return &diameterDP{m: m, cache: config.NewNavigableMap(nil)} + } // diameterDP implements engine.DataProvider, serving as diam.Message data decoder @@ -148,10 +148,19 @@ func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) { func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err error) { if data, err = dP.cache.FieldAsInterface(fldPath); err == nil || err != utils.ErrNotFound { // item found in cache - return + return nil, err } err = nil // cancel previous err - + var avps []*diam.AVP + if avps, err = dP.m.FindAVPsWithPath( + utils.SliceStringToIface(fldPath), dict.UndefinedVendorID); err != nil { + return nil, err + } else if len(avps) == 0 { + return nil, utils.ErrNotFound + } + if data, err = diamAVPAsIface(avps[0]); err != nil { + return nil, err + } dP.cache.Set(fldPath, data, false) return } diff --git a/agents/libdmt_test.go b/agents/libdmt_test.go index 2f5d97c32..32cd025a9 100644 --- a/agents/libdmt_test.go +++ b/agents/libdmt_test.go @@ -17,3 +17,50 @@ along with this program. If not, see */ package agents + +import ( + "testing" + + "github.com/fiorix/go-diameter/diam" + "github.com/fiorix/go-diameter/diam/avp" + "github.com/fiorix/go-diameter/diam/datatype" +) + +func TestDPFieldAsInterface(t *testing.T) { + m := diam.NewRequest(diam.CreditControl, 4, nil) + m.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002")) + m.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.CCMoney, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.UnitValue, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(10000)), + diam.NewAVP(avp.Exponent, avp.Mbit, 0, datatype.Integer32(-5)), + }, + }), + diam.NewAVP(avp.CurrencyCode, avp.Mbit, 0, datatype.Unsigned32(33)), + }, + }), + }, + }) + dP := newDADataProvider(m) + eOut := interface{}("simuhuawei;1449573472;00002") + if out, err := dP.FieldAsInterface([]string{"Session-Id"}); err != nil { + t.Error(err) + } else if eOut != out { + t.Errorf("Expecting: %v, received: %v", eOut, out) + } + eOut = interface{}(int64(10000)) + if out, err := dP.FieldAsInterface([]string{"Requested-Service-Unit", "CC-Money", "Unit-Value", "Value-Digits"}); err != nil { + t.Error(err) + } else if eOut != out { + t.Errorf("Expecting: %v, received: %v", eOut, out) + } + eOut = interface{}(uint32(33)) + if out, err := dP.FieldAsInterface([]string{"Requested-Service-Unit", "CC-Money", "Currency-Code"}); err != nil { + t.Error(err) + } else if eOut != out { + t.Errorf("Expecting: %v, received: %v", eOut, out) + } +} diff --git a/utils/slice.go b/utils/slice.go index 6d8ebeae7..b7f77e1ba 100644 --- a/utils/slice.go +++ b/utils/slice.go @@ -83,3 +83,12 @@ func StripSlicePrefix(slc []string, nrItems int) []string { } return slc[nrItems:] } + +// SliceStringToIface converts slice of strings into a slice of interfaces +func SliceStringToIface(slc []string) (ifc []interface{}) { + ifc = make([]interface{}, len(slc)) + for i, itm := range slc { + ifc[i] = itm + } + return +}