diff --git a/agents/dmtagent.go b/agents/dmtagent.go index dec21d553..a3624a99a 100644 --- a/agents/dmtagent.go +++ b/agents/dmtagent.go @@ -21,6 +21,7 @@ package agents import ( "fmt" "strconv" + "strings" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" @@ -135,16 +136,27 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro } } } - if err != nil { - if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(DiameterRatingFailed), - false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { - utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) - return nil - } - utils.Logger.Err(fmt.Sprintf(" Processing message: %+v, API error: %s", ccr.diamMessage, err)) - return cca - } var unauthorizedResultCode bool + if err != nil { + utils.Logger.Debug(fmt.Sprintf("Received error from rater: %+v", err)) + if strings.HasSuffix(err.Error(), utils.ErrAccountNotFound.Error()) { // 5030 in case of AccountNotFound + if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, "5030", + false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { + utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) + return nil + } + unauthorizedResultCode = true + } else { + if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(DiameterRatingFailed), + false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { + utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) + return nil + } + utils.Logger.Err(fmt.Sprintf(" Processing message: %+v, API error: %s", ccr.diamMessage, err)) + return cca + } + + } if ccr.CCRequestType != 3 && ccr.CCRequestType != 4 && maxUsage == 0 { // Not enough balance, RFC demands 4012 if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, "4012", false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { @@ -152,10 +164,12 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro return nil } unauthorizedResultCode = true - } else if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(diam.Success), - false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { - utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) - return nil + } else if !unauthorizedResultCode { + if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(diam.Success), + false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil { + utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) + return nil + } } if ccr.CCRequestType != 3 && ccr.CCRequestType != 4 && !unauthorizedResultCode { // For terminate or previously marked unauthorized, we don't add granted-service-unit AVP if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Granted-Service-Unit", "CC-Time"}, strconv.FormatFloat(maxUsage, 'f', 0, 64), diff --git a/agents/dmtagent_it_test.go b/agents/dmtagent_it_test.go index 58279745b..6d1dc1fe0 100644 --- a/agents/dmtagent_it_test.go +++ b/agents/dmtagent_it_test.go @@ -179,8 +179,7 @@ func TestDmtAgentTPFromFolder(t *testing.T) { time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } -// cgr-console 'cost Category="call" Tenant="cgrates.org" Subject="1001" Destination="1004" TimeStart="2015-11-07T08:42:26Z" TimeEnd="2015-11-07T08:47:26Z"' -func TestDmtAgentSendCCRInit(t *testing.T) { +func TestConnectDiameterClient(t *testing.T) { if !*testIntegration { return } @@ -189,6 +188,13 @@ func TestDmtAgentSendCCRInit(t *testing.T) { if err != nil { t.Fatal(err) } +} + +// cgr-console 'cost Category="call" Tenant="cgrates.org" Subject="1001" Destination="1004" TimeStart="2015-11-07T08:42:26Z" TimeEnd="2015-11-07T08:47:26Z"' +func TestDmtAgentSendCCRInit(t *testing.T) { + if !*testIntegration { + return + } cdr := &engine.CDR{CGRID: utils.Sha1("dsafdsaf", time.Date(2015, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1004", Supplier: "SUPPL1", @@ -426,6 +432,74 @@ func TestDmtAgentSendCCRSMS(t *testing.T) { */ } +func TestDmtAgentSendCCRSMSWrongAccount(t *testing.T) { + if !*testIntegration { + return + } + ccr := diam.NewRequest(diam.CreditControl, 4, nil) + ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("cgrates;1451911932;00083")) + ccr.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA")) + ccr.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org")) + ccr.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)) + ccr.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("message@huawei.com")) + ccr.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(4)) + ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(0)) + ccr.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2016, 1, 5, 11, 30, 10, 0, time.UTC))) + ccr.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(0)), + diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("non_existent")), // Subscription-Id-Data + }}) + ccr.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(1)), + diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("104502200011")), // Subscription-Id-Data + }}) + ccr.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0)) + ccr.NewAVP(avp.RequestedAction, avp.Mbit, 0, datatype.Enumerated(0)) + ccr.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{ + AVP: []*diam.AVP{ + diam.NewAVP(avp.CCTime, avp.Mbit, 0, datatype.Unsigned32(1))}}) + ccr.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(20302, avp.Mbit, 2011, datatype.UTF8String("22509")), // Calling-Vlr-Number + diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String("4002")), // Called-Party-NP + }, + }), + diam.NewAVP(2000, avp.Mbit, 10415, &diam.GroupedAVP{ // SMS-Information + AVP: []*diam.AVP{ + diam.NewAVP(886, avp.Mbit, 10415, &diam.GroupedAVP{ // Originator-Address + AVP: []*diam.AVP{ + diam.NewAVP(899, avp.Mbit, 10415, datatype.Enumerated(1)), // Address-Type + diam.NewAVP(897, avp.Mbit, 10415, datatype.UTF8String("49602200011")), // Address-Data + }}), + diam.NewAVP(1201, avp.Mbit, 10415, &diam.GroupedAVP{ // Recipient-Address + AVP: []*diam.AVP{ + diam.NewAVP(899, avp.Mbit, 10415, datatype.Enumerated(1)), // Address-Type + diam.NewAVP(897, avp.Mbit, 10415, datatype.UTF8String("49780029555")), // Address-Data + }}), + }, + }), + }}) + if err := dmtClient.SendMessage(ccr); err != nil { + t.Error(err) + } + time.Sleep(time.Duration(100) * time.Millisecond) + msg := dmtClient.ReceivedMessage() // Discard the received message so we can test next one + if msg == nil { + t.Fatal("No message returned") + } + if avps, err := msg.FindAVPsWithPath([]interface{}{"Result-Code"}, dict.UndefinedVendorID); err != nil { + t.Error(err) + } else if len(avps) == 0 { + t.Error("Result-Code") + } else if strResult := avpValAsString(avps[0]); strResult != "5030" { // Result-Code set in the template + t.Errorf("Expecting 5030, received: %s", strResult) + } +} + func TestDmtAgentCdrs(t *testing.T) { if !*testIntegration { return @@ -475,7 +549,7 @@ func TestDmtAgentDryRun1(t *testing.T) { } else if len(avps) == 0 { t.Error("Result-Code") } else if strResult := avpValAsString(avps[0]); strResult != "300" { // Result-Code set in the template - t.Errorf("Expecting 200, received: %s", strResult) + t.Errorf("Expecting 300, received: %s", strResult) } }