From 62cdc5c4b94e48997bd0b476a76a3622acb3b76d Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 9 Jan 2018 18:20:33 +0100 Subject: [PATCH] SessionSv1.ProcessEvent with integration tests --- apier/v1/sessions.go | 6 +++ apier/v1/sessionsv1_it_test.go | 80 +++++++++++++++++++++++++---- sessionmanager/smgeneric.go | 92 +++++++++++++++++++++++++++------- utils/consts.go | 1 + utils/errors.go | 2 +- 5 files changed, 150 insertions(+), 31 deletions(-) diff --git a/apier/v1/sessions.go b/apier/v1/sessions.go index 242312c06..45028d13a 100644 --- a/apier/v1/sessions.go +++ b/apier/v1/sessions.go @@ -40,6 +40,7 @@ func (ssv1 *SessionSv1) Handlers() map[string]interface{} { utils.SessionSv1UpdateSession: ssv1.SMG.BiRPCv1UpdateSession, utils.SessionSv1TerminateSession: ssv1.SMG.BiRPCv1TerminateSession, utils.SessionSv1ProcessCDR: ssv1.SMG.BiRPCv1ProcessCDR, + utils.SessionSv1ProcessEvent: ssv1.SMG.BiRPCv1ProcessEvent, } } @@ -66,3 +67,8 @@ func (ssv1 *SessionSv1) TerminateSession(args *sessionmanager.V1TerminateSession func (ssv1 *SessionSv1) ProcessCDR(cgrEv utils.CGREvent, rply *string) error { return ssv1.SMG.BiRPCv1ProcessCDR(nil, cgrEv, rply) } + +func (ssv1 *SessionSv1) ProcessEvent(args *sessionmanager.V1ProcessEventArgs, + rply *sessionmanager.V1ProcessEventReply) error { + return ssv1.SMG.BiRPCv1ProcessEvent(nil, args, rply) +} diff --git a/apier/v1/sessionsv1_it_test.go b/apier/v1/sessionsv1_it_test.go index d46e8c6dd..56943f47a 100644 --- a/apier/v1/sessionsv1_it_test.go +++ b/apier/v1/sessionsv1_it_test.go @@ -122,7 +122,7 @@ func TestSSv1ItAuth(t *testing.T) { Tenant: "cgrates.org", ID: "TestSSv1ItAuth", Event: map[string]interface{}{ - utils.ACCID: "TestSSv1It", + utils.ACCID: "TestSSv1It1", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", utils.Destination: "1002", @@ -165,14 +165,15 @@ func TestSSv1ItAuth(t *testing.T) { eAttrs := &engine.AttrSProcessEventReply{ MatchedProfile: "ATTR_ACNT_1001", AlteredFields: []string{"OfficeGroup"}, - CGREvent: &utils.CGREvent{Tenant: "cgrates.org", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", ID: "TestSSv1ItAuth", Context: utils.StringPointer(utils.MetaSessionS), Event: map[string]interface{}{ "Account": "1001", "Destination": "1002", "EventName": "CgrAuthorization", "OfficeGroup": "Marketing", - "OriginID": "TestSSv1It", + "OriginID": "TestSSv1It1", "RequestType": "*prepaid", "SetupTime": "2018-01-07T17:00:00Z", "Usage": 300000000000.0, @@ -180,7 +181,8 @@ func TestSSv1ItAuth(t *testing.T) { }, } if !reflect.DeepEqual(eAttrs, rply.Attributes) { - t.Errorf("expecting: %+v, received: %+v", utils.ToJSON(eAttrs), utils.ToJSON(rply.Attributes)) + t.Errorf("expecting: %+v, received: %+v", + utils.ToJSON(eAttrs), utils.ToJSON(rply.Attributes)) } } @@ -194,7 +196,7 @@ func TestSSv1ItInitiateSession(t *testing.T) { Tenant: "cgrates.org", ID: "TestSSv1ItInitiateSession", Event: map[string]interface{}{ - utils.ACCID: "TestSSv1It", + utils.ACCID: "TestSSv1It1", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", utils.Destination: "1002", @@ -218,13 +220,14 @@ func TestSSv1ItInitiateSession(t *testing.T) { eAttrs := &engine.AttrSProcessEventReply{ MatchedProfile: "ATTR_ACNT_1001", AlteredFields: []string{"OfficeGroup"}, - CGREvent: &utils.CGREvent{Tenant: "cgrates.org", + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", ID: "TestSSv1ItInitiateSession", Context: utils.StringPointer(utils.MetaSessionS), Event: map[string]interface{}{ "Account": "1001", "Destination": "1002", "OfficeGroup": "Marketing", - "OriginID": "TestSSv1It", + "OriginID": "TestSSv1It1", "RequestType": "*prepaid", "SetupTime": "2018-01-07T17:00:00Z", "AnswerTime": "2018-01-07T17:00:10Z", @@ -246,7 +249,7 @@ func TestSSv1ItUpdateSession(t *testing.T) { Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", Event: map[string]interface{}{ - utils.ACCID: "TestSSv1It", + utils.ACCID: "TestSSv1It1", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", utils.Destination: "1002", @@ -269,12 +272,12 @@ func TestSSv1ItUpdateSession(t *testing.T) { func TestSSv1ItTerminateSession(t *testing.T) { args := &sessionmanager.V1TerminateSessionArgs{ TerminateSession: true, - ReleaseResources: false, + ReleaseResources: true, CGREvent: utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", Event: map[string]interface{}{ - utils.ACCID: "TestSSv1It", + utils.ACCID: "TestSSv1It1", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", utils.Destination: "1002", @@ -299,7 +302,7 @@ func TestSSv1ItProcessCDR(t *testing.T) { Tenant: "cgrates.org", ID: "TestSSv1ItProcessCDR", Event: map[string]interface{}{ - utils.ACCID: "TestSSv1It", + utils.ACCID: "TestSSv1It1", utils.RequestType: utils.META_PREPAID, utils.Account: "1001", utils.Destination: "1002", @@ -318,6 +321,61 @@ func TestSSv1ItProcessCDR(t *testing.T) { } } +func TestSSv1ItProcessEvent(t *testing.T) { + initUsage := 5 * time.Minute + args := &sessionmanager.V1ProcessEventArgs{ + AllocateResources: true, + Debit: true, + GetAttributes: true, + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItProcessEvent", + Event: map[string]interface{}{ + utils.ACCID: "TestSSv1It2", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Destination: "1002", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), + utils.Usage: initUsage, + }, + }, + } + var rply sessionmanager.V1ProcessEventReply + if err := sSv1BiRpc.Call(utils.SessionSv1ProcessEvent, + args, &rply); err != nil { + t.Error(err) + } + if *rply.MaxUsage != initUsage { + t.Errorf("Unexpected MaxUsage: %v", rply.MaxUsage) + } + if *rply.ResourceAllocation != "RES_ACNT_1001" { + t.Errorf("Unexpected ResourceAllocation: %s", *rply.ResourceAllocation) + } + eAttrs := &engine.AttrSProcessEventReply{ + MatchedProfile: "ATTR_ACNT_1001", + AlteredFields: []string{"OfficeGroup"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSSv1ItProcessEvent", + Context: utils.StringPointer(utils.MetaSessionS), + Event: map[string]interface{}{ + "Account": "1001", "Destination": "1002", + "OfficeGroup": "Marketing", + "OriginID": "TestSSv1It2", + "RequestType": "*prepaid", + "SetupTime": "2018-01-07T17:00:00Z", + "AnswerTime": "2018-01-07T17:00:10Z", + "Usage": 300000000000.0, + }, + }, + } + if !reflect.DeepEqual(eAttrs, rply.Attributes) { + t.Errorf("expecting: %+v, received: %+v", + utils.ToJSON(eAttrs), utils.ToJSON(rply.Attributes)) + } +} + func TestSSv1ItStopCgrEngine(t *testing.T) { if err := sSv1BiRpc.Close(); err != nil { // Close the connection so we don't get EOF warnings from client t.Error(err) diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index 6fd02f330..d82931981 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -1388,7 +1388,7 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client, var rplyEv engine.AttrSProcessEventReply if err = smg.attrS.Call(utils.AttributeSv1ProcessEvent, args.CGREvent, &rplyEv); err != nil { - return + return utils.NewErrAttributeS(err) } authReply.Attributes = &rplyEv } @@ -1396,8 +1396,8 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client, } type V1InitSessionArgs struct { - InitSession bool AllocateResources bool + InitSession bool GetAttributes bool utils.CGREvent } @@ -1417,7 +1417,7 @@ func (smg *SMGeneric) BiRPCv1InitiateSession(clnt *rpc2.Client, } originID, err := args.CGREvent.FieldAsString(utils.ACCID) if err != nil { - return utils.NewErrServerError(err) + return utils.NewErrMandatoryIeMissing(utils.ACCID) } attrRU := utils.ArgRSv1ResourceUsage{ CGREvent: args.CGREvent, @@ -1427,7 +1427,7 @@ func (smg *SMGeneric) BiRPCv1InitiateSession(clnt *rpc2.Client, var allocMessage string if err = smg.resS.Call(utils.ResourceSv1AllocateResources, attrRU, &allocMessage); err != nil { - return err + return utils.NewErrResourceS(err) } rply.ResourceAllocation = &allocMessage } @@ -1436,10 +1436,7 @@ func (smg *SMGeneric) BiRPCv1InitiateSession(clnt *rpc2.Client, return utils.NewErrNotConnected(utils.RALService) } if maxUsage, err := smg.InitiateSession(args.CGREvent.Event, clnt); err != nil { - if err != rpcclient.ErrSessionNotFound { - err = utils.NewErrServerError(err) - } - return err + return utils.NewErrRALs(err) } else { rply.MaxUsage = &maxUsage } @@ -1454,7 +1451,7 @@ func (smg *SMGeneric) BiRPCv1InitiateSession(clnt *rpc2.Client, var rplyEv engine.AttrSProcessEventReply if err = smg.attrS.Call(utils.AttributeSv1ProcessEvent, args.CGREvent, &rplyEv); err != nil { - return + return utils.NewErrAttributeS(err) } rply.Attributes = &rplyEv } @@ -1478,10 +1475,7 @@ func (smg *SMGeneric) BiRPCv1UpdateSession(clnt *rpc2.Client, return utils.NewErrNotConnected(utils.RALService) } if maxUsage, err := smg.UpdateSession(args.CGREvent.Event, clnt); err != nil { - if err != rpcclient.ErrSessionNotFound { - err = utils.NewErrServerError(err) - } - return err + return utils.NewErrRALs(err) } else { rply.MaxUsage = &maxUsage } @@ -1525,10 +1519,7 @@ func (smg *SMGeneric) BiRPCv1TerminateSession(clnt *rpc2.Client, return utils.NewErrNotConnected(utils.RALService) } if err = smg.TerminateSession(args.CGREvent.Event, clnt); err != nil { - if err != rpcclient.ErrSessionNotFound { - err = utils.NewErrServerError(err) - } - return + return utils.NewErrRALs(err) } } if args.ReleaseResources { @@ -1537,7 +1528,7 @@ func (smg *SMGeneric) BiRPCv1TerminateSession(clnt *rpc2.Client, } originID, err := args.CGREvent.FieldAsString(utils.ACCID) if err != nil { - return utils.NewErrServerError(err) + return utils.NewErrMandatoryIeMissing(utils.ACCID) } var reply string argsRU := utils.ArgRSv1ResourceUsage{ @@ -1547,7 +1538,7 @@ func (smg *SMGeneric) BiRPCv1TerminateSession(clnt *rpc2.Client, } if err = smg.resS.Call(utils.ResourceSv1ReleaseResources, argsRU, &reply); err != nil { - return utils.NewErrServerError(err) + return utils.NewErrResourceS(err) } } *rply = utils.OK @@ -1563,3 +1554,66 @@ func (smg *SMGeneric) BiRPCv1ProcessCDR(clnt *rpc2.Client, *reply = utils.OK return nil } + +type V1ProcessEventArgs struct { + AllocateResources bool + Debit bool + GetAttributes bool + utils.CGREvent +} + +type V1ProcessEventReply struct { + MaxUsage *time.Duration + ResourceAllocation *string + Attributes *engine.AttrSProcessEventReply +} + +// Called on session end, should send the CDR to CDRS +func (smg *SMGeneric) BiRPCv1ProcessEvent(clnt *rpc2.Client, + args *V1ProcessEventArgs, rply *V1ProcessEventReply) (err error) { + if args.AllocateResources { + if smg.resS == nil { + return utils.NewErrNotConnected(utils.ResourceS) + } + originID, err := args.CGREvent.FieldAsString(utils.ACCID) + if err != nil { + return utils.NewErrMandatoryIeMissing(utils.ACCID) + } + attrRU := utils.ArgRSv1ResourceUsage{ + CGREvent: args.CGREvent, + UsageID: originID, + Units: 1, + } + var allocMessage string + if err = smg.resS.Call(utils.ResourceSv1AllocateResources, + attrRU, &allocMessage); err != nil { + return utils.NewErrResourceS(err) + } + rply.ResourceAllocation = &allocMessage + } + if args.Debit { + if smg.rals == nil { + return utils.NewErrNotConnected(utils.RALService) + } + if maxUsage, err := smg.ChargeEvent(args.CGREvent.Event); err != nil { + return utils.NewErrRALs(err) + } else { + rply.MaxUsage = &maxUsage + } + } + if args.GetAttributes { + if smg.attrS == nil { + return utils.NewErrNotConnected(utils.AttributeS) + } + if args.CGREvent.Context == nil { + args.CGREvent.Context = utils.StringPointer(utils.MetaSessionS) + } + var rplyEv engine.AttrSProcessEventReply + if err = smg.attrS.Call(utils.AttributeSv1ProcessEvent, + args.CGREvent, &rplyEv); err != nil { + return utils.NewErrAttributeS(err) + } + rply.Attributes = &rplyEv + } + return nil +} diff --git a/utils/consts.go b/utils/consts.go index ded1345d4..876f69306 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -599,6 +599,7 @@ const ( SessionSv1UpdateSession = "SessionSv1.UpdateSession" SessionSv1TerminateSession = "SessionSv1.TerminateSession" SessionSv1ProcessCDR = "SessionSv1.ProcessCDR" + SessionSv1ProcessEvent = "SessionSv1.ProcessEvent" SessionSv1DisconnectSession = "SessionSv1.DisconnectSession" SMGenericV1InitiateSession = "SMGenericV1.InitiateSession" SMGenericV2InitiateSession = "SMGenericV2.InitiateSession" diff --git a/utils/errors.go b/utils/errors.go index 32117829a..faf89c013 100644 --- a/utils/errors.go +++ b/utils/errors.go @@ -116,7 +116,7 @@ func NewErrSupplierS(err error) error { } func NewErrAttributeS(err error) error { - return fmt.Errorf("SUPPLIERS_ERROR: %s", err) + return fmt.Errorf("ATTRIBUTES_ERROR: %s", err) } // Centralized returns for APIs