diff --git a/agents/diam_it_test.go b/agents/diam_it_test.go index 78fd5212e..dd847d657 100644 --- a/agents/diam_it_test.go +++ b/agents/diam_it_test.go @@ -67,10 +67,13 @@ var ( testDiamItCCRSMS, testDiamItCCRMMS, + testDiamItEmulateTerminate, + testDiamItTemplateErr, testDiamItCCRInitWithForceDuration, testDiamItDRR, + testDiamItKillEngine, } ) @@ -1423,3 +1426,154 @@ func testDiamItTemplateErr(t *testing.T) { t.Errorf("expecting: %s, received: <%s>", eVal, val) } } + +func testDiamItEmulateTerminate(t *testing.T) { + if diamConfigDIR == "dispatchers/diamagent" { + t.SkipNow() + } + var result string + //add the second charger + chargerProfile := &engine.ChargerProfile{ + Tenant: "cgrates.com", + ID: "CustomCharger", + RunID: "CustomCharger", + AttributeIDs: []string{"*constant:*req.Category:custom_charger"}, + Weight: 20, + } + + if err := apierRpc.Call(utils.APIerSv1SetChargerProfile, chargerProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + //add the second charger + chargerProfile2 := &engine.ChargerProfile{ + Tenant: "cgrates.com", + ID: "Default", + RunID: "*default", + AttributeIDs: []string{"*none"}, + Weight: 20, + } + + if err := apierRpc.Call(utils.APIerSv1SetChargerProfile, chargerProfile2, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + //set the account + attrSetBalance := utils.AttrSetBalance{ + Tenant: "cgrates.com", + Account: "testDiamItEmulateTerminate", + Value: float64(1) * float64(time.Hour), + BalanceType: utils.VOICE, + Balance: map[string]interface{}{ + utils.ID: "testDiamItEmulateTerminate", + utils.Categories: "custom_charger", + }, + } + var reply string + if err := apierRpc.Call(utils.APIerSv2SetBalance, attrSetBalance, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Received: %s", reply) + } + var acnt *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.com", Account: "testDiamItEmulateTerminate"} + if err := apierRpc.Call(utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != float64(time.Hour) { + t.Errorf("Expected: %f, received: %f", float64(time.Hour), acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } + + 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(0)) + m.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA")) + m.NewAVP(avp.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.com")) + 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("testDiamItEmulateTerminate")), // 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.OctetString("")), // 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 + }, + }), + }}) + // ============================================ + // prevent nil pointer dereference + // ============================================ + if diamClnt == nil { + t.Fatal("Diameter client should not be nil") + } + if diamClnt.conn == nil { + t.Fatal("Diameter connection should not be nil") + } + if m == nil { + t.Fatal("The mesage to diameter should not be nil") + } + // ============================================ + 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 = "0" // 0 from sessions + 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) + } + + if err := apierRpc.Call(utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.VOICE].GetTotalValue() != float64(time.Hour) { + t.Errorf("Expected: %f, received: %f", float64(time.Hour), acnt.BalanceMap[utils.VOICE].GetTotalValue()) + } +} diff --git a/data/conf/samples/diamagent_internal/voice.json b/data/conf/samples/diamagent_internal/voice.json index 91de9c026..1c7201894 100644 --- a/data/conf/samples/diamagent_internal/voice.json +++ b/data/conf/samples/diamagent_internal/voice.json @@ -109,7 +109,7 @@ "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice" ], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes", "*continue"], "request_fields":[ { "tag": "ToR", @@ -201,6 +201,35 @@ }, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": [ diff --git a/data/conf/samples/diamagent_mongo/voice.json b/data/conf/samples/diamagent_mongo/voice.json index 91de9c026..1110de3cf 100644 --- a/data/conf/samples/diamagent_mongo/voice.json +++ b/data/conf/samples/diamagent_mongo/voice.json @@ -109,7 +109,7 @@ "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice" ], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes","*continue"], "request_fields":[ { "tag": "ToR", @@ -201,6 +201,35 @@ }, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": [ diff --git a/data/conf/samples/diamagent_mysql/voice.json b/data/conf/samples/diamagent_mysql/voice.json index 91de9c026..1c7201894 100644 --- a/data/conf/samples/diamagent_mysql/voice.json +++ b/data/conf/samples/diamagent_mysql/voice.json @@ -109,7 +109,7 @@ "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice" ], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes", "*continue"], "request_fields":[ { "tag": "ToR", @@ -201,6 +201,35 @@ }, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": [ diff --git a/data/conf/samples/diamsctpagent_internal/voice.json b/data/conf/samples/diamsctpagent_internal/voice.json index bef1e37bc..4c707886d 100755 --- a/data/conf/samples/diamsctpagent_internal/voice.json +++ b/data/conf/samples/diamsctpagent_internal/voice.json @@ -106,7 +106,7 @@ "id": "VoiceInit", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice"], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes","*continue"], "request_fields":[ {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", @@ -133,6 +133,35 @@ "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:2", diff --git a/data/conf/samples/diamsctpagent_mongo/voice.json b/data/conf/samples/diamsctpagent_mongo/voice.json index bef1e37bc..468ec852d 100755 --- a/data/conf/samples/diamsctpagent_mongo/voice.json +++ b/data/conf/samples/diamsctpagent_mongo/voice.json @@ -106,7 +106,7 @@ "id": "VoiceInit", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice"], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes", "*continue"], "request_fields":[ {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", @@ -133,6 +133,35 @@ "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:2", diff --git a/data/conf/samples/diamsctpagent_mysql/voice.json b/data/conf/samples/diamsctpagent_mysql/voice.json index bef1e37bc..4c707886d 100755 --- a/data/conf/samples/diamsctpagent_mysql/voice.json +++ b/data/conf/samples/diamsctpagent_mysql/voice.json @@ -106,7 +106,7 @@ "id": "VoiceInit", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice"], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes","*continue"], "request_fields":[ {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", @@ -133,6 +133,35 @@ "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:2", diff --git a/data/conf/samples/dispatchers/diamagent/voice.json b/data/conf/samples/dispatchers/diamagent/voice.json index 8666d2b3d..762842679 100644 --- a/data/conf/samples/dispatchers/diamagent/voice.json +++ b/data/conf/samples/dispatchers/diamagent/voice.json @@ -106,7 +106,7 @@ "id": "VoiceInit", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", "*prefix:~*req.Service-Context-Id:voice"], - "flags": ["*initiate", "*accounts", "*attributes"], + "flags": ["*initiate", "*accounts", "*attributes","*continue"], "request_fields":[ {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, {"tag": "APIKey", "path": "*opts.*apiKey", "type": "*constant", "value": "ses12345"}, @@ -134,6 +134,36 @@ "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, ], }, + { + "id": "VoiceTerminateEmulate", + "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:1", + "*prefix:~*req.Service-Context-Id:voice","*eq:~*cgrep.MaxUsage:0"], + "flags": ["*terminate", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*voice"}, + {"tag": "APIKey", "path": "*opts.*apiKey", "type": "*constant", "value": "ses12345"}, + {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "path": "*cgreq.OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*attributes"}, + {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, + {"tag": "Account", "path": "*cgreq.Account", "type": "*constant", "value": "*attributes"}, + {"tag": "Destination", "path": "*cgreq.Destination", "type": "*variable", + "value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true}, + {"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true}, + {"tag": "Usage", "path": "*cgreq.Usage", "type": "*variable", + "value": "0s", "mandatory": true}, + {"tag": "SubscriberID", "path": "*cgreq.SubscriberId", "type": "*variable", + "value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true} + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*notempty:~*cgrep.Error:"], + "path": "*rep.Result-Code", "type": "*constant", "value": "5030", "blocker": true}, + {"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant", "value": "2001"}, + ], + }, { "id": "VoiceUpdate", "filters": ["*string:~*vars.*cmd:CCR", "*string:~*req.CC-Request-Type:2", diff --git a/data/conf/samples/sessions_mysql/cgrates.json b/data/conf/samples/sessions_mysql/cgrates.json index 95864e4b5..e52ad4246 100644 --- a/data/conf/samples/sessions_mysql/cgrates.json +++ b/data/conf/samples/sessions_mysql/cgrates.json @@ -82,8 +82,8 @@ "sessions": { "enabled": true, "session_ttl": "50ms", - "chargers_conns": ["*internal"], - "rals_conns": ["*internal"], + "chargers_conns": ["*localhost"], + "rals_conns": ["*localhost"], "cdrs_conns": ["*internal"], "resources_conns": ["*internal"], "thresholds_conns": ["*internal"], diff --git a/data/tariffplans/tutorial/Attributes.csv b/data/tariffplans/tutorial/Attributes.csv index 2a7a41590..d764c908d 100644 --- a/data/tariffplans/tutorial/Attributes.csv +++ b/data/tariffplans/tutorial/Attributes.csv @@ -22,3 +22,5 @@ cgrates.com,ATTR_TNT_ALIAS,*any,,,,*req.RequestType,*constant,*prepaid,, cgrates.com,ATTR_TNT_ALIAS,*any,,,,*tenant,*constant,cgrates.org,, cgrates.com,ATTR_TNT_1001,*any,*string:~*req.Account:1001,,,*tenant,*constant,cgrates.org,, cgrates.com,ATTR_TNT_DISC,*any,*string:~*req.Account:testDiamInitWithSessionDisconnect,,,*tenant,*constant,cgrates.org,, +cgrates.com,ATTR_ACC_EMULATE_TERMINATE,*any,*string:~*req.SubscriberId:testDiamItEmulateTerminate,,,*req.Account,*constant,testDiamItEmulateTerminate,false,10 +cgrates.com,ATTR_ACC_EMULATE_TERMINATE,*any,,,,*req.RequestType,*constant,*prepaid,, diff --git a/data/tariffplans/tutorial/RatingProfiles.csv b/data/tariffplans/tutorial/RatingProfiles.csv index 5ac2010fa..33e7f7cbf 100644 --- a/data/tariffplans/tutorial/RatingProfiles.csv +++ b/data/tariffplans/tutorial/RatingProfiles.csv @@ -4,4 +4,6 @@ cgrates.org,call,1002,2014-01-14T00:00:00Z,RP_1002, cgrates.org,call,1003,2014-01-14T00:00:00Z,RP_1003, cgrates.org,sms,*any,2014-01-14T00:00:00Z,RP_SMS, cgrates.org,mms,*any,2014-01-14T00:00:00Z,RP_MMS, +cgrates.com,custom_charger,*any,2014-01-14T00:00:00Z,RP_1001, +cgrates.com,call,*any,2014-01-14T00:00:00Z,RP_1001,