SMG handling of subsessions, fix for usage, added *data balance to tutorial files

This commit is contained in:
DanB
2016-03-31 13:54:26 +02:00
parent 4e1b0ab7d1
commit c086b4e853
8 changed files with 46 additions and 45 deletions

View File

@@ -798,10 +798,10 @@ func TestDmtAgentSendDataGrpUpdate(t *testing.T) {
AVP: []*diam.AVP{
diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit
AVP: []*diam.AVP{
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(2)), // CC-Output-Octets
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1000)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(24)), // CC-Output-Octets
},
}),
diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(1)), // Data session for group 1
@@ -811,10 +811,10 @@ func TestDmtAgentSendDataGrpUpdate(t *testing.T) {
AVP: []*diam.AVP{
diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit
AVP: []*diam.AVP{
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(1)), // CC-Output-Octets
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1024)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(512)), // CC-Output-Octets
},
}),
diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(2)), // Data session for group 2
@@ -892,10 +892,10 @@ func TestDmtAgentSendDataGrpTerminate(t *testing.T) {
AVP: []*diam.AVP{
diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit
AVP: []*diam.AVP{
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(2)), // CC-Output-Octets
diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time
diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(512)), // CC-Input-Octets
diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(0)), // CC-Output-Octets
},
}),
},

View File

@@ -116,7 +116,7 @@ func TestSMGV1CacheStats(t *testing.T) {
}
var rcvStats *utils.CacheStats
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 7, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 8, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 3, LastLoadId: smgV1LoadInst.LoadId, LastLoadTime: smgV1LoadInst.LoadTime.Format(time.RFC3339)}
var args utils.AttrCacheStats
if err := smgV1Rpc.Call("ApierV2.GetCacheStats", args, &rcvStats); err != nil {

View File

@@ -19,7 +19,7 @@
{"tag": "Destination", "field_id": "Destination", "type": "*constant", "value": "data"},
{"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "3"},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "2048"},
],
"cca_fields": [
{"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "^2001"},
@@ -44,7 +44,7 @@
{"tag": "Destination", "field_id": "Destination", "type": "*constant", "value": "data"},
{"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "3"},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "2048"},
{"tag": "LastUsed", "field_id": "LastUsed", "field_filter":"Multiple-Services-Credit-Control>Rating-Group(1)", "type": "*handler", "handler_id": "*sum",
"value": "Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets;^|;Multiple-Services-Credit-Control>Used-Service-Unit>CC-Output-Octets"},
],
@@ -71,7 +71,7 @@
{"tag": "Destination", "field_id": "Destination", "type": "*constant", "value": "data"},
{"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", "value": "Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "3"},
{"tag": "Usage", "field_id": "Usage", "type": "*constant", "value": "2048"},
{"tag": "LastUsed", "field_id": "LastUsed", "field_filter":"Multiple-Services-Credit-Control>Rating-Group(2)", "type": "*handler", "handler_id": "*sum",
"value": "Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets;^|;Multiple-Services-Credit-Control>Used-Service-Unit>CC-Output-Octets"},
],

View File

@@ -6,3 +6,4 @@ USE_SHARED_A,SHARED_A_0,*asap,10
PACKAGE_1001,TOPUP_RST_5,*asap,10
PACKAGE_1001,TOPUP_RST_SHARED_5,*asap,10
PACKAGE_1001,TOPUP_120_DST1003,*asap,10
PACKAGE_1001,TOPUP_RST_DATA_100,*asap,10
1 #Id ActionsId TimingId Weight
6 PACKAGE_1001 TOPUP_RST_5 *asap 10
7 PACKAGE_1001 TOPUP_RST_SHARED_5 *asap 10
8 PACKAGE_1001 TOPUP_120_DST1003 *asap 10
9 PACKAGE_1001 TOPUP_RST_DATA_100 *asap 10

View File

@@ -5,6 +5,7 @@ TOPUP_RST_5,*topup_reset,,,,*voice,*out,,DST_1002,SPECIAL_1002,,*unlimited,,90,2
TOPUP_120_DST1003,*topup_reset,,,,*voice,*out,,DST_1003,,,*unlimited,,120,20,false,false,10
TOPUP_RST_SHARED_5,*topup,,,,*monetary,*out,,*any,,SHARED_A,*unlimited,,5,10,false,false,10
SHARED_A_0,*topup_reset,,,,*monetary,*out,,*any,,SHARED_A,*unlimited,,0,10,false,false,10
TOPUP_RST_DATA_100,*topup_reset,,,,*data,*out,,*any,,,*unlimited,,102400,10,false,false,10
LOG_WARNING,*log,,,,,,,,,,,,,,false,false,10
DISABLE_AND_LOG,*log,,,,,,,,,,,,,,false,false,10
DISABLE_AND_LOG,*disable_account,,,,,,,,,,,,,,false,false,10
1 #ActionsId[0] Action[1] ExtraParameters[2] Filter[3] BalanceId[4] BalanceType[5] Directions[6] Categories[7] DestinationIds[8] RatingSubject[9] SharedGroup[10] ExpiryTime[11] TimingIds[12] Units[13] BalanceWeight[14] BalanceBlocker[15] BalanceDisabled[16] Weight[17]
5 TOPUP_120_DST1003 *topup_reset *voice *out DST_1003 *unlimited 120 20 false false 10
6 TOPUP_RST_SHARED_5 *topup *monetary *out *any SHARED_A *unlimited 5 10 false false 10
7 SHARED_A_0 *topup_reset *monetary *out *any SHARED_A *unlimited 0 10 false false 10
8 TOPUP_RST_DATA_100 *topup_reset *data *out *any *unlimited 102400 10 false false 10
9 LOG_WARNING *log false false 10
10 DISABLE_AND_LOG *log false false 10
11 DISABLE_AND_LOG *disable_account false false 10

View File

@@ -114,7 +114,7 @@ func TestTutSMGCacheStats(t *testing.T) {
}
var rcvStats *utils.CacheStats
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 7, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 8, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 3, LastLoadId: smgLoadInst.LoadId, LastLoadTime: smgLoadInst.LoadTime.Format(time.RFC3339)}
var args utils.AttrCacheStats
if err := tutSMGRpc.Call("ApierV2.GetCacheStats", args, &rcvStats); err != nil {

View File

@@ -115,7 +115,7 @@ func TestTutLocalCacheStats(t *testing.T) {
}
var rcvStats *utils.CacheStats
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 7, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
expectedStats := &utils.CacheStats{Destinations: 4, RatingPlans: 4, RatingProfiles: 9, Actions: 8, ActionPlans: 4, SharedGroups: 1, Aliases: 1,
DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 3, LastLoadId: loadInst.LoadId, LastLoadTime: loadInst.LoadTime.Format(time.RFC3339)}
var args utils.AttrCacheStats
if err := tutLocalRpc.Call("ApierV2.GetCacheStats", args, &rcvStats); err != nil {

View File

@@ -115,7 +115,7 @@ func (self *SMGeneric) sessionStart(evStart SMGenericEvent, connId string) error
}
}
return nil, nil
}, time.Duration(3)*time.Second, sessionId)
}, time.Duration(2)*time.Second, sessionId)
return err
}
@@ -206,6 +206,14 @@ func (self *SMGeneric) GetLcrSuppliers(gev SMGenericEvent, clnt *rpc2.Client) ([
return lcr.SuppliersSlice()
}
// Called on session start
func (self *SMGeneric) SessionStart(gev SMGenericEvent, clnt *rpc2.Client) (time.Duration, error) {
if err := self.sessionStart(gev, getClientConnId(clnt)); err != nil {
return nilDuration, err
}
return self.SessionUpdate(gev, clnt)
}
// Execute debits for usage/maxUsage
func (self *SMGeneric) SessionUpdate(gev SMGenericEvent, clnt *rpc2.Client) (time.Duration, error) {
if initialID, err := gev.GetFieldAsString(utils.InitialOriginID); err == nil {
@@ -238,14 +246,6 @@ func (self *SMGeneric) SessionUpdate(gev SMGenericEvent, clnt *rpc2.Client) (tim
return evMaxUsage, nil
}
// Called on session start
func (self *SMGeneric) SessionStart(gev SMGenericEvent, clnt *rpc2.Client) (time.Duration, error) {
if err := self.sessionStart(gev, getClientConnId(clnt)); err != nil {
return nilDuration, err
}
return self.SessionUpdate(gev, clnt)
}
// Called on session end, should stop debit loop
func (self *SMGeneric) SessionEnd(gev SMGenericEvent, clnt *rpc2.Client) error {
if initialID, err := gev.GetFieldAsString(utils.InitialOriginID); err == nil {
@@ -261,34 +261,33 @@ func (self *SMGeneric) SessionEnd(gev SMGenericEvent, clnt *rpc2.Client) error {
if sessionIDPrefix, err := gev.GetFieldAsString(utils.OriginIDPrefix); err == nil { // OriginIDPrefix is present, OriginID will not be anymore considered
sessionIDs = self.getSessionIDsForPrefix(sessionIDPrefix)
}
usage, err := gev.GetUsage(utils.META_DEFAULT)
if err != nil {
if err != utils.ErrNotFound {
return err
usage, errUsage := gev.GetUsage(utils.META_DEFAULT)
var lastUsed time.Duration
if errUsage != nil {
if errUsage != utils.ErrNotFound {
return errUsage
}
lastUsed, err := gev.GetLastUsed(utils.META_DEFAULT)
var err error
lastUsed, err = gev.GetLastUsed(utils.META_DEFAULT)
if err != nil {
if err == utils.ErrNotFound {
err = utils.ErrMandatoryIeMissing
}
return err
}
var s *SMGSession
for _, sID := range sessionIDs {
for _, s = range self.getSession(sID) {
break
}
if s != nil {
break
}
}
if s == nil {
return nil
}
usage = s.TotalUsage() + lastUsed
}
var interimError error
for _, sessionID := range sessionIDs {
if errUsage != nil {
var s *SMGSession
for _, s = range self.getSession(sessionID) {
break
}
if s == nil {
continue // No session active, will not be able to close it anyway
}
usage = s.TotalUsage() + lastUsed
}
if err := self.sessionEnd(sessionID, usage); err != nil {
interimError = err // Last error will be the one returned as API result
}