mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 10:36:24 +05:00
Diameter - remove hardcoded logic inside replies, expose processorVars in templates
This commit is contained in:
@@ -107,6 +107,7 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro
|
||||
}
|
||||
}
|
||||
var maxUsage float64
|
||||
processorVars := make(map[string]string)
|
||||
if reqProcessor.DryRun { // DryRun does not send over network
|
||||
utils.Logger.Info(fmt.Sprintf("<DiameterAgent> SMGenericEvent: %+v", smgEv))
|
||||
if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(diam.LimitedSuccess),
|
||||
@@ -136,57 +137,28 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro
|
||||
}
|
||||
}
|
||||
}
|
||||
var populatedResultCode bool
|
||||
processorVars[CGRResultCode] = strconv.Itoa(diam.Success)
|
||||
if err != nil {
|
||||
utils.Logger.Debug(fmt.Sprintf("Received error from rater: %+v", err))
|
||||
if strings.HasSuffix(err.Error(), utils.ErrAccountNotFound.Error()) || strings.HasSuffix(err.Error(), utils.ErrUserNotFound.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("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
populatedResultCode = true
|
||||
} else if strings.HasSuffix(err.Error(), utils.ErrCreditInsufficient.Error()) {
|
||||
if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, "4012",
|
||||
false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
populatedResultCode = 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("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v, API error: %s", ccr.diamMessage, err))
|
||||
return cca
|
||||
}
|
||||
|
||||
}
|
||||
if ccr.CCRequestType != 3 && ccr.CCRequestType != 4 && maxUsage == 0 && !populatedResultCode { // 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("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
populatedResultCode = true
|
||||
} else if !populatedResultCode {
|
||||
if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, strconv.Itoa(diam.Success),
|
||||
false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v, API error: %s", ccr.diamMessage, err))
|
||||
switch { // Prettify some errors
|
||||
case strings.HasSuffix(err.Error(), utils.ErrAccountNotFound.Error()):
|
||||
processorVars[CGRError] = utils.ErrAccountNotFound.Error()
|
||||
case strings.HasSuffix(err.Error(), utils.ErrUserNotFound.Error()):
|
||||
processorVars[CGRError] = utils.ErrUserNotFound.Error()
|
||||
case strings.HasSuffix(err.Error(), utils.ErrCreditInsufficient.Error()):
|
||||
processorVars[CGRError] = utils.ErrCreditInsufficient.Error()
|
||||
default: // Unknown error
|
||||
processorVars[CGRError] = err.Error()
|
||||
processorVars[CGRResultCode] = strconv.Itoa(DiameterRatingFailed)
|
||||
}
|
||||
}
|
||||
if ccr.CCRequestType != 3 && ccr.CCRequestType != 4 && !populatedResultCode { // 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),
|
||||
false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v set CCA Granted-Service-Unit, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
if err := messageSetAVPsWithPath(cca.diamMessage, []interface{}{"Result-Code"}, processorVars[CGRResultCode],
|
||||
false, self.cgrCfg.DiameterAgentCfg().Timezone); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := cca.SetProcessorAVPs(reqProcessor, maxUsage); err != nil {
|
||||
if err := cca.SetProcessorAVPs(reqProcessor, processorVars); 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("<DiameterAgent> Processing message: %+v set CCA Reply-Code, error: %s", ccr.diamMessage, err))
|
||||
|
||||
@@ -54,6 +54,9 @@ const (
|
||||
META_VALUE_EXPONENT = "*value_exponent"
|
||||
DIAMETER_CCR = "DIAMETER_CCR"
|
||||
DiameterRatingFailed = 5031
|
||||
CGRError = "CGRError"
|
||||
CGRMaxUsage = "CGRMaxUsage"
|
||||
CGRResultCode = "CGRResultCode"
|
||||
)
|
||||
|
||||
func loadDictionaries(dictsDir, componentId string) error {
|
||||
@@ -644,11 +647,11 @@ func (self *CCA) AsDiameterMessage() *diam.Message {
|
||||
}
|
||||
|
||||
// SetProcessorAVPs will add AVPs to self.diameterMessage based on template defined in processor.CCAFields
|
||||
func (self *CCA) SetProcessorAVPs(reqProcessor *config.DARequestProcessor, maxUsage float64) error {
|
||||
func (self *CCA) SetProcessorAVPs(reqProcessor *config.DARequestProcessor, processorVars map[string]string) error {
|
||||
for _, cfgFld := range reqProcessor.CCAFields {
|
||||
fmtOut, err := fieldOutVal(self.ccrMessage, cfgFld, maxUsage)
|
||||
fmtOut, err := fieldOutVal(self.ccrMessage, cfgFld, processorVars)
|
||||
if err == ErrFilterNotPassing { // Field not in or filter not passing, try match in answer
|
||||
fmtOut, err = fieldOutVal(self.diamMessage, cfgFld, maxUsage)
|
||||
fmtOut, err = fieldOutVal(self.diamMessage, cfgFld, processorVars)
|
||||
}
|
||||
if err != nil {
|
||||
if err == ErrFilterNotPassing {
|
||||
|
||||
@@ -302,7 +302,7 @@ func TestCCASetProcessorAVPs(t *testing.T) {
|
||||
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type
|
||||
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data
|
||||
}})
|
||||
if err := cca.SetProcessorAVPs(reqProcessor, 0); err != nil {
|
||||
if err := cca.SetProcessorAVPs(reqProcessor, map[string]string{}); err != nil {
|
||||
t.Error(err)
|
||||
} else if ccaMsg := cca.AsDiameterMessage(); !reflect.DeepEqual(eMessage, ccaMsg) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, ccaMsg)
|
||||
|
||||
Reference in New Issue
Block a user