mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-24 00:28:44 +05:00
AttributeS with Compile method and attributesIdx, Substitute as utils.RSRParsers
This commit is contained in:
@@ -168,15 +168,18 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) (
|
||||
rply = &AttrSProcessEventReply{
|
||||
MatchedProfiles: []string{attrPrf.ID},
|
||||
CGREvent: args.Clone()}
|
||||
for fldName, initialMp := range attrPrf.attributes {
|
||||
for fldName, initialMp := range attrPrf.attributesIdx {
|
||||
initEvValIf, has := args.Event[fldName]
|
||||
if !has {
|
||||
anyInitial, hasAny := initialMp[utils.ANY]
|
||||
if hasAny && anyInitial.Append &&
|
||||
initialMp[utils.ANY].Substitute.Id() != utils.META_NONE {
|
||||
rply.CGREvent.Event[fldName] = anyInitial.Substitute.Id()
|
||||
if hasAny && anyInitial.Append { // add field name
|
||||
substitute, err := anyInitial.Substitute.ParseEvent(args.Event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rply.CGREvent.Event[fldName] = substitute
|
||||
rply.AlteredFields = append(rply.AlteredFields, fldName)
|
||||
}
|
||||
rply.AlteredFields = append(rply.AlteredFields, fldName)
|
||||
continue
|
||||
}
|
||||
attrVal, has := initialMp[initEvValIf]
|
||||
@@ -184,10 +187,14 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) (
|
||||
attrVal, has = initialMp[utils.ANY]
|
||||
}
|
||||
if has {
|
||||
if attrVal.Substitute.Id() == utils.META_NONE {
|
||||
substitute, err := attrVal.Substitute.ParseEvent(args.Event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if substitute == utils.META_NONE {
|
||||
delete(rply.CGREvent.Event, fldName)
|
||||
} else {
|
||||
rply.CGREvent.Event[fldName] = attrVal.Substitute.Id()
|
||||
rply.CGREvent.Event[fldName] = substitute
|
||||
}
|
||||
rply.AlteredFields = append(rply.AlteredFields, fldName)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ var (
|
||||
utils.META_ANY: &Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "1010", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
@@ -101,12 +101,12 @@ var (
|
||||
&Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "1010", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
attributes: mapSubstitutes,
|
||||
Weight: 20,
|
||||
attributesIdx: mapSubstitutes,
|
||||
},
|
||||
&AttributeProfile{
|
||||
Tenant: config.CgrConfig().DefaultTenant,
|
||||
@@ -121,12 +121,12 @@ var (
|
||||
&Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "1010", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
attributes: mapSubstitutes,
|
||||
Weight: 20,
|
||||
attributesIdx: mapSubstitutes,
|
||||
},
|
||||
&AttributeProfile{
|
||||
Tenant: config.CgrConfig().DefaultTenant,
|
||||
@@ -141,12 +141,12 @@ var (
|
||||
&Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "1010", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
attributes: mapSubstitutes,
|
||||
Weight: 20,
|
||||
attributesIdx: mapSubstitutes,
|
||||
Weight: 20,
|
||||
},
|
||||
&AttributeProfile{
|
||||
Tenant: config.CgrConfig().DefaultTenant,
|
||||
@@ -161,12 +161,12 @@ var (
|
||||
&Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "1010", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
attributes: mapSubstitutes,
|
||||
Weight: 20,
|
||||
attributesIdx: mapSubstitutes,
|
||||
Weight: 20,
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -463,20 +463,14 @@ func TestAttributeIndexer(t *testing.T) {
|
||||
},
|
||||
Attributes: []*Attribute{
|
||||
&Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Append: true,
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: utils.NewRSRParsersMustCompile("1010", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
//populate Substitute from attributes
|
||||
rsrFields, err := utils.ParseRSRFields("^1010", utils.INFIELD_SEP)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
attrPrf.Attributes[0].Substitute = rsrFields
|
||||
|
||||
if err := dmAtr.SetAttributeProfile(attrPrf, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -1068,7 +1068,7 @@ func (dm *DataManager) RemoveSupplierProfile(tenant, id, transactionID string, w
|
||||
}
|
||||
|
||||
func (dm *DataManager) GetAttributeProfile(tenant, id string, skipCache bool,
|
||||
transactionID string) (alsPrf *AttributeProfile, err error) {
|
||||
transactionID string) (attrPrfl *AttributeProfile, err error) {
|
||||
tntID := utils.ConcatenatedKey(tenant, id)
|
||||
if !skipCache {
|
||||
if x, ok := Cache.Get(utils.CacheAttributeProfiles, tntID); ok {
|
||||
@@ -1078,7 +1078,7 @@ func (dm *DataManager) GetAttributeProfile(tenant, id string, skipCache bool,
|
||||
return x.(*AttributeProfile), nil
|
||||
}
|
||||
}
|
||||
alsPrf, err = dm.dataDB.GetAttributeProfileDrv(tenant, id)
|
||||
attrPrfl, err = dm.dataDB.GetAttributeProfileDrv(tenant, id)
|
||||
if err != nil {
|
||||
if err == utils.ErrNotFound {
|
||||
Cache.Set(utils.CacheAttributeProfiles, tntID, nil, nil,
|
||||
@@ -1086,17 +1086,10 @@ func (dm *DataManager) GetAttributeProfile(tenant, id string, skipCache bool,
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
alsPrf.attributes = make(map[string]map[interface{}]*Attribute)
|
||||
for _, attr := range alsPrf.Attributes {
|
||||
alsPrf.attributes[attr.FieldName] = make(map[interface{}]*Attribute)
|
||||
alsPrf.attributes[attr.FieldName][attr.Initial] = &Attribute{
|
||||
FieldName: attr.FieldName,
|
||||
Initial: attr.Initial,
|
||||
Substitute: attr.Substitute,
|
||||
Append: attr.Append,
|
||||
}
|
||||
if err = attrPrfl.Compile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Cache.Set(utils.CacheAttributeProfiles, tntID, alsPrf, nil,
|
||||
Cache.Set(utils.CacheAttributeProfiles, tntID, attrPrfl, nil,
|
||||
cacheCommit(transactionID), transactionID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
type Attribute struct {
|
||||
FieldName string
|
||||
Initial interface{}
|
||||
Substitute utils.RSRFields
|
||||
Substitute utils.RSRParsers
|
||||
Append bool
|
||||
}
|
||||
|
||||
@@ -36,10 +36,37 @@ type AttributeProfile struct {
|
||||
ID string
|
||||
Contexts []string // bind this AttributeProfile to multiple contexts
|
||||
FilterIDs []string
|
||||
ActivationInterval *utils.ActivationInterval // Activation interval
|
||||
attributes map[string]map[interface{}]*Attribute // map[FieldName][InitialValue]*Attribute
|
||||
ActivationInterval *utils.ActivationInterval // Activation interval
|
||||
Attributes []*Attribute
|
||||
Weight float64
|
||||
|
||||
attributesIdx map[string]map[interface{}]*Attribute // map[FieldName][InitialValue]*Attribute, used as event match index
|
||||
}
|
||||
|
||||
// computeAttributesIndex populates .attributes
|
||||
func (ap *AttributeProfile) computeAttributesIndex() {
|
||||
ap.attributesIdx = make(map[string]map[interface{}]*Attribute)
|
||||
for _, attr := range ap.Attributes {
|
||||
if _, has := ap.attributesIdx[attr.FieldName]; !has {
|
||||
ap.attributesIdx[attr.FieldName] = make(map[interface{}]*Attribute)
|
||||
}
|
||||
ap.attributesIdx[attr.FieldName][attr.Initial] = attr
|
||||
}
|
||||
}
|
||||
|
||||
func (ap *AttributeProfile) compileSubstitutes() (err error) {
|
||||
for _, attr := range ap.Attributes {
|
||||
if err = attr.Substitute.Compile(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Compile is a wrapper for convenience setting up the AttributeProfile
|
||||
func (ap *AttributeProfile) Compile() error {
|
||||
ap.computeAttributesIndex()
|
||||
return ap.compileSubstitutes()
|
||||
}
|
||||
|
||||
func (als *AttributeProfile) TenantID() string {
|
||||
|
||||
@@ -2803,31 +2803,17 @@ func APItoAttributeProfile(tpTH *utils.TPAttributeProfile, timezone string) (th
|
||||
for _, context := range tpTH.Contexts {
|
||||
th.Contexts = append(th.Contexts, context)
|
||||
}
|
||||
th.attributes = make(map[string]map[interface{}]*Attribute)
|
||||
for _, reqAttr := range tpTH.Attributes {
|
||||
th.Attributes = append(th.Attributes, &Attribute{
|
||||
Append: reqAttr.Append,
|
||||
FieldName: reqAttr.FieldName,
|
||||
Initial: reqAttr.Initial,
|
||||
Substitute: utils.RSRFields{
|
||||
&utils.RSRField{
|
||||
Id: reqAttr.Substitute,
|
||||
RSRules: []*utils.ReSearchReplace{}, //from mongo we get empty slice and from redis nil
|
||||
},
|
||||
},
|
||||
})
|
||||
th.attributes[reqAttr.FieldName] = make(map[interface{}]*Attribute)
|
||||
th.attributes[reqAttr.FieldName][reqAttr.Initial] = &Attribute{
|
||||
FieldName: reqAttr.FieldName,
|
||||
Initial: reqAttr.Initial,
|
||||
Substitute: utils.RSRFields{
|
||||
&utils.RSRField{
|
||||
Id: reqAttr.Substitute,
|
||||
RSRules: []*utils.ReSearchReplace{}, //from mongo we get empty slice and from redis nil
|
||||
},
|
||||
},
|
||||
Append: reqAttr.Append,
|
||||
sbstPrsr, err := utils.NewRSRParsers(reqAttr.Substitute, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
th.Attributes = append(th.Attributes, &Attribute{
|
||||
Append: reqAttr.Append,
|
||||
FieldName: reqAttr.FieldName,
|
||||
Initial: reqAttr.Initial,
|
||||
Substitute: sbstPrsr,
|
||||
})
|
||||
}
|
||||
if tpTH.ActivationInterval != nil {
|
||||
if th.ActivationInterval, err = tpTH.ActivationInterval.AsActivationInterval(timezone); err != nil {
|
||||
|
||||
@@ -1475,7 +1475,7 @@ func TestAPItoAttributeProfile(t *testing.T) {
|
||||
mapSubstitutes["FL1"]["In1"] = &Attribute{
|
||||
FieldName: "FL1",
|
||||
Initial: "In1",
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "Al1", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("Al1", true),
|
||||
Append: true,
|
||||
}
|
||||
expected := &AttributeProfile{
|
||||
@@ -1490,12 +1490,11 @@ func TestAPItoAttributeProfile(t *testing.T) {
|
||||
&Attribute{
|
||||
FieldName: "FL1",
|
||||
Initial: "In1",
|
||||
Substitute: utils.RSRFields{&utils.RSRField{Id: "Al1", RSRules: []*utils.ReSearchReplace{}}},
|
||||
Substitute: utils.NewRSRParsersMustCompile("Al1", true),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
attributes: mapSubstitutes,
|
||||
Weight: 20,
|
||||
}
|
||||
if rcv, err := APItoAttributeProfile(tpAlsPrf, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
Reference in New Issue
Block a user