Disable by default storing of session costs, enable session caching, session usage reflected by API call

This commit is contained in:
DanB
2019-03-22 13:01:31 +01:00
parent 94db8add70
commit ce752d4f27
5 changed files with 13 additions and 155 deletions

View File

@@ -60,7 +60,6 @@ var sTestsDiam = []func(t *testing.T){
testDiamItCCRUpdate,
testDiamItCCRTerminate,
testDiamItCCRSMS,
// testDiamTerminateWithoutAnswerTime,
testDiamItKillEngine,
}
@@ -819,151 +818,6 @@ func testDiamInitWithSessionDisconnect(t *testing.T) {
}
}
/*
func testDiamTerminateWithoutAnswerTime(t *testing.T) {
// Init Session
m := diam.NewRequest(diam.CreditControl, 4, nil)
m.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("bb97be2b9f37c2be9614fff71c8b1d08b1acbff8"))
m.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("192.168.1.1"))
m.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
m.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4))
m.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(1))
m.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(1))
m.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA"))
m.NewAVP(avp.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
m.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("voice@DiamItCCRInit"))
m.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2018, 10, 4, 14, 42, 20, 0, time.UTC)))
m.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("1006")), // Subscription-Id-Data
}})
m.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0))
m.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(300))}})
m.NewAVP(avp.UsedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(0))}})
m.NewAVP(873, avp.Mbit, 10415, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(20300, avp.Mbit, 2011, &diam.GroupedAVP{ // IN-Information
AVP: []*diam.AVP{
diam.NewAVP(831, avp.Mbit, 10415, datatype.UTF8String("1006")), // Calling-Party-Address
diam.NewAVP(832, avp.Mbit, 10415, datatype.UTF8String("1002")), // Called-Party-Address
diam.NewAVP(20327, avp.Mbit, 2011, datatype.UTF8String("1002")), // Real-Called-Number
diam.NewAVP(20339, avp.Mbit, 2011, datatype.Unsigned32(0)), // Charge-Flow-Type
diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-Vlr-Number
diam.NewAVP(20303, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-CellID-Or-SAI
diam.NewAVP(20313, avp.Mbit, 2011, datatype.UTF8String("")), // Bearer-Capability
diam.NewAVP(20321, avp.Mbit, 2011, datatype.UTF8String("bb97be2b9f37c2be9614fff71c8b1d08b1acbff8")), // Call-Reference-Number
diam.NewAVP(20322, avp.Mbit, 2011, datatype.UTF8String("")), // MSC-Address
diam.NewAVP(20324, avp.Mbit, 2011, datatype.Unsigned32(0)), // Time-Zone
diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String("")), // Called-Party-NP
diam.NewAVP(20386, avp.Mbit, 2011, datatype.UTF8String("")), // SSP-Time
},
}),
}})
if err := diamClnt.SendMessage(m); err != nil {
t.Error(err)
}
msg := diamClnt.ReceivedMessage(rplyTimeout)
if msg == nil {
t.Fatal("No message returned")
}
// Result-Code
eVal := "2001"
if avps, err := msg.FindAVPsWithPath([]interface{}{"Result-Code"}, dict.UndefinedVendorID); err != nil {
t.Error(err)
} else if len(avps) == 0 {
t.Error("Missing AVP")
} else if val, err := diamAVPAsString(avps[0]); err != nil {
t.Error(err)
} else if val != eVal {
t.Errorf("expecting: %s, received: <%s>", eVal, val)
}
// Result-Code
eVal = "300" // 5 mins of session
if avps, err := msg.FindAVPsWithPath([]interface{}{"Granted-Service-Unit", "CC-Time"},
dict.UndefinedVendorID); err != nil {
t.Error(err)
} else if len(avps) == 0 {
t.Error("Missing AVP")
} else if val, err := diamAVPAsString(avps[0]); err != nil {
t.Error(err)
} else if val != eVal {
t.Errorf("expecting: %s, received: <%s>", eVal, val)
}
//Terminate session without answer time in template
//It should take the answer time from init but in DB store 0
m2 := diam.NewRequest(diam.CreditControl, 4, nil)
m2.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("bb97be2b9f37c2be9614fff71c8b1d08b1acbff8"))
m2.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("192.168.1.1"))
m2.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
m2.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4))
m2.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(3))
m2.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(3))
m2.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA"))
m2.NewAVP(avp.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
m2.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("voice@DiamItCCRInit"))
m2.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2018, 10, 4, 15, 12, 20, 0, time.UTC)))
m2.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("1006")), // Subscription-Id-Data
}})
m2.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0))
m2.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(0))}})
m2.NewAVP(avp.UsedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(250))}})
m2.NewAVP(873, avp.Mbit, 10415, &diam.GroupedAVP{
AVP: []*diam.AVP{
diam.NewAVP(20300, avp.Mbit, 2011, &diam.GroupedAVP{ // IN-Information
AVP: []*diam.AVP{
diam.NewAVP(831, avp.Mbit, 10415, datatype.UTF8String("1006")), // Calling-Party-Address
diam.NewAVP(832, avp.Mbit, 10415, datatype.UTF8String("1002")), // Called-Party-Address
diam.NewAVP(20327, avp.Mbit, 2011, datatype.UTF8String("1002")), // Real-Called-Number
diam.NewAVP(20339, avp.Mbit, 2011, datatype.Unsigned32(0)), // Charge-Flow-Type
diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-Vlr-Number
diam.NewAVP(20303, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-CellID-Or-SAI
diam.NewAVP(20313, avp.Mbit, 2011, datatype.UTF8String("")), // Bearer-Capability
diam.NewAVP(20321, avp.Mbit, 2011, datatype.UTF8String("bb97be2b9f37c2be9614fff71c8b1d08b1acbff8")), // Call-Reference-Number
diam.NewAVP(20322, avp.Mbit, 2011, datatype.UTF8String("")), // MSC-Address
diam.NewAVP(20324, avp.Mbit, 2011, datatype.Unsigned32(0)), // Time-Zone
diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String("")), // Called-Party-NP
diam.NewAVP(20386, avp.Mbit, 2011, datatype.UTF8String("")), // SSP-Time
},
}),
}})
if err := diamClnt.SendMessage(m2); err != nil {
t.Error(err)
}
time.Sleep(time.Duration(*waitRater) * time.Millisecond)
var cdrs []*engine.CDR
args := utils.RPCCDRsFilter{RunIDs: []string{utils.MetaRaw}}
if err := apierRpc.Call(utils.CDRsV1GetCDRs, args, &cdrs); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if len(cdrs) != 1 {
t.Error("Unexpected number of CDRs returned: ", len(cdrs))
} else {
if cdrs[0].Usage != 550*time.Second {
t.Errorf("Unexpected Usage CDR: %+v", cdrs[0])
}
// in case of sctp we get OriginHost ip1/ip2/ip3/...
if !strings.Contains(cdrs[0].OriginHost, "127.0.0.1") {
t.Errorf("Unexpected OriginHost CDR: %+v", cdrs[0])
}
if cdrs[0].AnswerTime.IsZero() {
t.Errorf("Unexpected AnswerTime: %+v", cdrs[0].AnswerTime)
}
}
}
*/
func testDiamItKillEngine(t *testing.T) {
if err := engine.KillEngine(1000); err != nil {
t.Error(err)

View File

@@ -150,7 +150,7 @@ const CGRATES_CFG_JSON = `
"dispatcher_routes": {"limit": -1, "ttl": "", "static_ttl": false}, // control dispatcher routes caching
"diameter_messages": {"limit": -1, "ttl": "3h", "static_ttl": false}, // diameter messages caching
"rpc_responses": {"limit": 0, "ttl": "2s", "static_ttl": false}, // RPC responses caching
"closed_sessions": {"limit": 0, "ttl": "10s", "static_ttl": false}, // closed sessions cached for CDRs
"closed_sessions": {"limit": -1, "ttl": "10s", "static_ttl": false}, // closed sessions cached for CDRs
},
@@ -306,7 +306,7 @@ const CGRATES_CFG_JSON = `
"attributes_conns": [], // connections to AttributeS for altering event fields <""|*internal|127.0.0.1:2013>
"session_replication_conns": [], // replicate sessions towards these session services
"debit_interval": "0s", // interval to perform debits on.
"store_session_costs": true, // enable storing of the session costs within CDRs
"store_session_costs": false, // enable storing of the session costs within CDRs
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
"max_call_duration": "3h", // maximum call duration a prepaid call can last
"session_ttl": "0s", // time after a session with no updates is terminated, not defined by default

View File

@@ -155,7 +155,7 @@ func TestCacheJsonCfg(t *testing.T) {
Ttl: utils.StringPointer("3h"), Static_ttl: utils.BoolPointer(false)},
utils.CacheRPCResponses: &CacheParamJsonCfg{Limit: utils.IntPointer(0),
Ttl: utils.StringPointer("2s"), Static_ttl: utils.BoolPointer(false)},
utils.CacheClosedSessions: &CacheParamJsonCfg{Limit: utils.IntPointer(0),
utils.CacheClosedSessions: &CacheParamJsonCfg{Limit: utils.IntPointer(-1),
Ttl: utils.StringPointer("10s"), Static_ttl: utils.BoolPointer(false)},
}
@@ -482,7 +482,7 @@ func TestSmgJsonCfg(t *testing.T) {
Attributes_conns: &[]*HaPoolJsonCfg{},
Session_replication_conns: &[]*HaPoolJsonCfg{},
Debit_interval: utils.StringPointer("0s"),
Store_session_costs: utils.BoolPointer(true),
Store_session_costs: utils.BoolPointer(false),
Min_call_duration: utils.StringPointer("0s"),
Max_call_duration: utils.StringPointer("3h"),
Session_ttl: utils.StringPointer("0s"),

View File

@@ -624,7 +624,7 @@ func TestCgrCfgJSONDefaultsSMGenericCfg(t *testing.T) {
AttrSConns: []*HaPoolConfig{},
SessionReplicationConns: []*HaPoolConfig{},
DebitInterval: 0 * time.Second,
StoreSCosts: true,
StoreSCosts: false,
MinCallDuration: 0 * time.Second,
MaxCallDuration: 3 * time.Hour,
SessionTTL: 0 * time.Second,
@@ -704,7 +704,7 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) {
TTL: time.Duration(3 * time.Hour), StaticTTL: false},
utils.CacheRPCResponses: &CacheParamCfg{Limit: 0,
TTL: time.Duration(2 * time.Second), StaticTTL: false},
utils.CacheClosedSessions: &CacheParamCfg{Limit: 0,
utils.CacheClosedSessions: &CacheParamCfg{Limit: -1,
TTL: time.Duration(10 * time.Second), StaticTTL: false},
}

View File

@@ -1290,7 +1290,10 @@ func (sS *SessionS) endSession(s *Session, tUsage, lastUsage *time.Duration) (er
// FixMe: make sure refund is reflected inside EventCost
}
sr.Event[utils.Cost] = sr.EventCost.GetCost()
sr.Event[utils.Usage] = sr.EventCost.GetUsage()
sr.Event[utils.Usage] = sr.TotalUsage
}
if sRunIdx == 0 {
s.EventStart.Set(utils.Usage, sr.TotalUsage)
}
if sS.cgrCfg.SessionSCfg().StoreSCosts {
if err := sS.storeSCost(s, sRunIdx); err != nil {
@@ -1299,9 +1302,10 @@ func (sS *SessionS) endSession(s *Session, tUsage, lastUsage *time.Duration) (er
utils.SessionS, s.CGRID, sRunIdx, err.Error()))
}
}
engine.Cache.Set(utils.CacheClosedSessions, s.CGRID, s,
nil, true, utils.NonTransactional)
}
engine.Cache.Set(utils.CacheClosedSessions, s.CGRID, s,
nil, true, utils.NonTransactional)
s.Unlock()
return
}