Diameter - remove hardcoded logic inside replies, expose processorVars in templates

This commit is contained in:
DanB
2016-02-23 18:02:52 +01:00
parent 2f079b70ad
commit 2dcffd4dfd
3 changed files with 25 additions and 50 deletions

View File

@@ -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))

View File

@@ -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 {

View File

@@ -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)