From 1dfbb86fb3e2520add7ec7cc4841d54fcad5b5b0 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 20 Jan 2016 13:49:53 +0100 Subject: [PATCH] ChargeEvent returning maxUsage --- agents/dmtagent.go | 4 ++-- apier/v1/smgenericbirpcv1.go | 7 ++++--- apier/v1/smgenericv1.go | 9 +++++---- sessionmanager/smgeneric.go | 21 +++++++++++---------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/agents/dmtagent.go b/agents/dmtagent.go index db26b69b7..e1c0b6c6d 100644 --- a/agents/dmtagent.go +++ b/agents/dmtagent.go @@ -110,7 +110,7 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro if ccr.CCRequestType == 3 { err = self.smg.Call("SMGenericV1.SessionEnd", smgEv, &rpl) } else if ccr.CCRequestType == 4 { - err = self.smg.Call("SMGenericV1.ChargeEvent", smgEv, &rpl) + err = self.smg.Call("SMGenericV1.ChargeEvent", smgEv, &maxUsage) } if self.cgrCfg.DiameterAgentCfg().CreateCDR { if errCdr := self.smg.Call("SMGenericV1.ProcessCdr", smgEv, &rpl); errCdr != nil { @@ -127,7 +127,7 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro utils.Logger.Err(fmt.Sprintf(" Processing message: %+v, API error: %s", ccr.diamMessage, err)) return cca } - if ccr.CCRequestType != 3 && maxUsage == 0 { // Not enough balance, RFC demands 4012 + 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 { utils.Logger.Err(fmt.Sprintf(" Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err)) diff --git a/apier/v1/smgenericbirpcv1.go b/apier/v1/smgenericbirpcv1.go index b80bcf960..035d55b86 100644 --- a/apier/v1/smgenericbirpcv1.go +++ b/apier/v1/smgenericbirpcv1.go @@ -100,11 +100,12 @@ func (self *SMGenericBiRpcV1) SessionEnd(clnt *rpc2.Client, ev sessionmanager.SM } // Called on individual Events (eg SMS) -func (self *SMGenericBiRpcV1) ChargeEvent(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, reply *string) error { - if err := self.sm.ChargeEvent(ev, clnt); err != nil { +func (self *SMGenericBiRpcV1) ChargeEvent(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, maxUsage *float64) error { + if minMaxUsage, err := self.sm.ChargeEvent(ev, clnt); err != nil { return utils.NewErrServerError(err) + } else { + *maxUsage = minMaxUsage.Seconds() } - *reply = utils.OK return nil } diff --git a/apier/v1/smgenericv1.go b/apier/v1/smgenericv1.go index 834ebbe9f..d56c1d431 100644 --- a/apier/v1/smgenericv1.go +++ b/apier/v1/smgenericv1.go @@ -71,11 +71,12 @@ func (self *SMGenericV1) SessionEnd(ev sessionmanager.SMGenericEvent, reply *str } // Called on individual Events (eg SMS) -func (self *SMGenericV1) ChargeEvent(ev sessionmanager.SMGenericEvent, reply *string) error { - if err := self.sm.ChargeEvent(ev, nil); err != nil { +func (self *SMGenericV1) ChargeEvent(ev sessionmanager.SMGenericEvent, maxUsage *float64) error { + if minMaxUsage, err := self.sm.ChargeEvent(ev, nil); err != nil { return utils.NewErrServerError(err) + } else { + *maxUsage = minMaxUsage.Seconds() } - *reply = utils.OK return nil } @@ -146,7 +147,7 @@ func (self *SMGenericV1) Call(serviceMethod string, args interface{}, reply inte if !canConvert { return rpcclient.ErrWrongArgsType } - replyConverted, canConvert := reply.(*string) + replyConverted, canConvert := reply.(*float64) if !canConvert { return rpcclient.ErrWrongReplyType } diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index 69ae61088..dd3cf163f 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -205,14 +205,13 @@ func (self *SMGeneric) SessionEnd(gev SMGenericEvent, clnt *rpc2.Client) error { } // Processes one time events (eg: SMS) -func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) error { +func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) (maxDur time.Duration, err error) { var sessionRuns []*engine.SessionRun if err := self.rater.GetSessionRuns(gev.AsStoredCdr(self.cgrCfg, self.timezone), &sessionRuns); err != nil { - return err + return nilDuration, err } else if len(sessionRuns) == 0 { - return nil + return nilDuration, nil } - var err error for _, sR := range sessionRuns { cc := new(engine.CallCost) if err = self.rater.MaxDebit(sR.CallDescriptor, cc); err != nil { @@ -220,19 +219,21 @@ func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) error break } sR.CallCosts = append(sR.CallCosts, cc) // Save it so we can revert on issues - if cc.GetDuration() == 0 { + if ccDur := cc.GetDuration(); ccDur == 0 { err = errors.New("INSUFFICIENT_FUNDS") break + } else if ccDur < maxDur { + maxDur = ccDur } } if err != nil { // Refund the ones already taken since we have error on one of the debits for _, sR := range sessionRuns { for _, cc := range sR.CallCosts { - utils.Logger.Debug(fmt.Sprintf("%+v", cc)) - continue // Refund here + utils.Logger.Debug(fmt.Sprintf("%+v", cc)) // Refund here + continue } } - return err + return nilDuration, err } var withErrors bool for _, sR := range sessionRuns { @@ -253,9 +254,9 @@ func (self *SMGeneric) ChargeEvent(gev SMGenericEvent, clnt *rpc2.Client) error } } if withErrors { - return ErrPartiallyExecuted + return nilDuration, ErrPartiallyExecuted } - return nil + return maxDur, nil } func (self *SMGeneric) ProcessCdr(gev SMGenericEvent) error {