mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
New AttributeProfile structure ( version3)
This commit is contained in:
committed by
Dan Christian Bogos
parent
cc818b0199
commit
a5ee8e8398
@@ -102,11 +102,14 @@ func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.Attri
|
||||
}
|
||||
for fieldname, vals := range av.Pairs {
|
||||
for initial, substitute := range vals {
|
||||
filterIDs := make([]string, 0)
|
||||
if initial != utils.META_ANY {
|
||||
filterIDs = append(filterIDs, utils.MetaString+":"+fieldname+":"+initial)
|
||||
}
|
||||
out.Attributes = append(out.Attributes, &engine.Attribute{
|
||||
FilterIDs: filterIDs,
|
||||
FieldName: fieldname,
|
||||
Initial: initial,
|
||||
Substitute: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,16 +163,14 @@ func testAlsITMigrateAndMove(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FilterIDs: []string{"*string:Category:call_1001"},
|
||||
FieldName: "Category",
|
||||
Initial: "call_1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -215,7 +213,7 @@ func testAlsITMigrateAndMove(t *testing.T) {
|
||||
result.Compile()
|
||||
sort.Slice(result.Attributes, func(i, j int) bool {
|
||||
if result.Attributes[i].FieldName == result.Attributes[j].FieldName {
|
||||
return result.Attributes[i].Initial.(string) < result.Attributes[j].Initial.(string)
|
||||
return result.Attributes[i].FilterIDs[0] < result.Attributes[j].FilterIDs[0]
|
||||
}
|
||||
return result.Attributes[i].FieldName < result.Attributes[j].FieldName
|
||||
}) // only for test; map returns random keys
|
||||
@@ -235,7 +233,8 @@ func testAlsITMigrateAndMove(t *testing.T) {
|
||||
"*out:*any:*any:1001:call_1001:*rated": true,
|
||||
},
|
||||
}
|
||||
if alsidx, err := alsMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix], utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
if alsidx, err := alsMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix],
|
||||
utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expAlsIdx, alsidx) {
|
||||
t.Errorf("Expected %v, recived: %v", utils.ToJSON(expAlsIdx), utils.ToJSON(alsidx))
|
||||
|
||||
@@ -164,10 +164,9 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -181,16 +180,14 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1003"},
|
||||
FieldName: "Account",
|
||||
Initial: "1003",
|
||||
Substitute: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -204,16 +201,14 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1003"},
|
||||
FieldName: "Account",
|
||||
Initial: "1003",
|
||||
Substitute: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -231,16 +226,14 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FilterIDs: []string{"*string:Subject:1001"},
|
||||
FieldName: "Subject",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -258,16 +251,14 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
ActivationInterval: nil,
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
FieldName: "Account",
|
||||
Initial: "1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FilterIDs: []string{"*string:Category:call_1001"},
|
||||
FieldName: "Category",
|
||||
Initial: "call_1001",
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -278,7 +269,7 @@ func TestAlias2AtttributeProfile(t *testing.T) {
|
||||
rply := alias2AtttributeProfile(aliases[i], defaultTenant)
|
||||
sort.Slice(rply.Attributes, func(i, j int) bool {
|
||||
if rply.Attributes[i].FieldName == rply.Attributes[j].FieldName {
|
||||
return rply.Attributes[i].Initial.(string) < rply.Attributes[j].Initial.(string)
|
||||
return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0]
|
||||
}
|
||||
return rply.Attributes[i].FieldName < rply.Attributes[j].FieldName
|
||||
}) // only for test; map returns random keys
|
||||
|
||||
@@ -112,6 +112,45 @@ func (m *Migrator) migrateV1Attributes() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Migrator) migrateV2Attributes() (err error) {
|
||||
var v2Attr *v2AttributeProfile
|
||||
for {
|
||||
v2Attr, err = m.dmIN.getV2AttributeProfile()
|
||||
if err != nil && err != utils.ErrNoMoreData {
|
||||
return err
|
||||
}
|
||||
if err == utils.ErrNoMoreData {
|
||||
break
|
||||
}
|
||||
if v2Attr != nil {
|
||||
attrPrf, err := v2Attr.AsAttributeProfile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.dryRun != true {
|
||||
if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.dmIN.remV2AttributeProfile(v2Attr.Tenant, v2Attr.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
m.stats[utils.Attributes] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if m.dryRun != true {
|
||||
// All done, update version wtih current one
|
||||
vrs := engine.Versions{utils.Attributes: engine.CurrentDataDBVersions()[utils.Attributes]}
|
||||
if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil {
|
||||
return utils.NewCGRError(utils.Migrator,
|
||||
utils.ServerErrorCaps,
|
||||
err.Error(),
|
||||
fmt.Sprintf("error: <%s> when updating Thresholds version into dataDB", err.Error()))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Migrator) migrateAttributeProfile() (err error) {
|
||||
var vrs engine.Versions
|
||||
current := engine.CurrentDataDBVersions()
|
||||
@@ -140,6 +179,10 @@ func (m *Migrator) migrateAttributeProfile() (err error) {
|
||||
if err := m.migrateV1Attributes(); err != nil {
|
||||
return err
|
||||
}
|
||||
case 2:
|
||||
if err := m.migrateV2Attributes(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -155,18 +198,70 @@ func (v1AttrPrf v1AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib
|
||||
}
|
||||
for _, mp := range v1AttrPrf.Attributes {
|
||||
for _, attr := range mp {
|
||||
initIface := utils.StringToInterface(attr.Initial)
|
||||
filterIDs := make([]string, 0)
|
||||
//append false translate to if FieldName exist do stuff
|
||||
if attr.Append == false {
|
||||
filterIDs = append(filterIDs, utils.MetaExists+":"+attr.FieldName+":")
|
||||
}
|
||||
//Initial not *any translate to if value of fieldName = initial do stuff
|
||||
if attr.Initial != utils.META_ANY {
|
||||
filterIDs = append(filterIDs, utils.MetaString+":"+attr.FieldName+":"+attr.Initial)
|
||||
}
|
||||
sbstPrsr, err := config.NewRSRParsers(attr.Substitute, true, config.CgrConfig().GeneralCfg().RsrSepatarot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{
|
||||
FilterIDs: filterIDs,
|
||||
FieldName: attr.FieldName,
|
||||
Initial: initIface,
|
||||
Substitute: sbstPrsr,
|
||||
Append: attr.Append,
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type v2Attribute struct {
|
||||
FieldName string
|
||||
Initial interface{}
|
||||
Substitute config.RSRParsers
|
||||
Append bool
|
||||
}
|
||||
|
||||
type v2AttributeProfile struct {
|
||||
Tenant string
|
||||
ID string
|
||||
Contexts []string // bind this AttributeProfile to multiple contexts
|
||||
FilterIDs []string
|
||||
ActivationInterval *utils.ActivationInterval // Activation interval
|
||||
Attributes []*v2Attribute
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func (v2AttrPrf v2AttributeProfile) AsAttributeProfile() (attrPrf *engine.AttributeProfile, err error) {
|
||||
attrPrf = &engine.AttributeProfile{
|
||||
Tenant: v2AttrPrf.Tenant,
|
||||
ID: v2AttrPrf.ID,
|
||||
Contexts: v2AttrPrf.Contexts,
|
||||
FilterIDs: v2AttrPrf.FilterIDs,
|
||||
Weight: v2AttrPrf.Weight,
|
||||
ActivationInterval: v2AttrPrf.ActivationInterval,
|
||||
}
|
||||
for _, attr := range v2AttrPrf.Attributes {
|
||||
filterIDs := make([]string, 0)
|
||||
//append false translate to if FieldName exist do stuff
|
||||
if attr.Append == false {
|
||||
filterIDs = append(filterIDs, utils.MetaExists+":"+attr.FieldName+":")
|
||||
}
|
||||
//Initial not *any translate to if value of fieldName = initial do stuff
|
||||
if attr.Initial.(string) != utils.META_ANY {
|
||||
filterIDs = append(filterIDs, utils.MetaString+":"+attr.FieldName+":"+attr.Initial.(string))
|
||||
}
|
||||
attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{
|
||||
FilterIDs: filterIDs,
|
||||
FieldName: attr.FieldName,
|
||||
Substitute: attr.Substitute,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -253,10 +253,9 @@ func testAttrITMigrateAndMove(t *testing.T) {
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FilterIDs: []string{"*string:FL1:In1"},
|
||||
FieldName: "FL1",
|
||||
Initial: "In1",
|
||||
Substitute: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
@@ -286,7 +285,7 @@ func testAttrITMigrateAndMove(t *testing.T) {
|
||||
|
||||
if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if vrs[utils.Attributes] != 2 {
|
||||
} else if vrs[utils.Attributes] != 3 {
|
||||
t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes])
|
||||
}
|
||||
result, err := attrMigrator.dmOut.DataManager().GetAttributeProfile("cgrates.org",
|
||||
|
||||
@@ -64,10 +64,9 @@ func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FilterIDs: []string{"*string:FL1:In1"},
|
||||
FieldName: "FL1",
|
||||
Initial: "In1",
|
||||
Substitute: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
|
||||
@@ -84,11 +84,10 @@ func fieldinfo2Attribute(attr []*engine.Attribute, fieldName, fieldInfo string)
|
||||
}
|
||||
return append(attr, &engine.Attribute{
|
||||
FieldName: fieldName,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: rp,
|
||||
Append: true,
|
||||
})
|
||||
}
|
||||
|
||||
func derivedChargers2AttributeProfile(dc *v1DerivedCharger, tenant, key string, filters []string) (attr *engine.AttributeProfile) {
|
||||
attr = &engine.AttributeProfile{
|
||||
Tenant: tenant,
|
||||
|
||||
@@ -169,15 +169,11 @@ func testDCITMigrateAndMove(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: utils.Subject,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -232,9 +228,6 @@ func testDCITMigrateAndMove(t *testing.T) {
|
||||
}
|
||||
result.Compile()
|
||||
sort.Slice(result.Attributes, func(i, j int) bool {
|
||||
if result.Attributes[i].FieldName == result.Attributes[j].FieldName {
|
||||
return result.Attributes[i].Initial.(string) < result.Attributes[j].Initial.(string)
|
||||
}
|
||||
return result.Attributes[i].FieldName < result.Attributes[j].FieldName
|
||||
}) // only for test; map returns random keys
|
||||
if !reflect.DeepEqual(*attrProf, *result) {
|
||||
@@ -257,7 +250,8 @@ func testDCITMigrateAndMove(t *testing.T) {
|
||||
"*out:cgrates.org:*any:1003:*any_0": true,
|
||||
},
|
||||
}
|
||||
if dcidx, err := dcMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix], utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
if dcidx, err := dcMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix],
|
||||
utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expDcIdx, dcidx) {
|
||||
t.Errorf("Expected %v, recived: %v", utils.ToJSON(expDcIdx), utils.ToJSON(dcidx))
|
||||
@@ -267,7 +261,8 @@ func testDCITMigrateAndMove(t *testing.T) {
|
||||
"*out:cgrates.org:*any:1003:*any_0": true,
|
||||
},
|
||||
}
|
||||
if dcidx, err := dcMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.ChargerProfilePrefix], utils.ConcatenatedKey("cgrates.org", utils.META_ANY),
|
||||
if dcidx, err := dcMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.ChargerProfilePrefix],
|
||||
utils.ConcatenatedKey("cgrates.org", utils.META_ANY),
|
||||
utils.MetaString, nil); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
t.Errorf("Expected error %v, recived: %v with reply: %v", utils.ErrNotFound, err, utils.ToJSON(dcidx))
|
||||
}
|
||||
|
||||
@@ -54,9 +54,7 @@ func TestFieldinfo2Attribute(t *testing.T) {
|
||||
Expected: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -67,9 +65,7 @@ func TestFieldinfo2Attribute(t *testing.T) {
|
||||
Expected: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Subject,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile(`~effective_caller_id_number:s/(\d+)/+$1/`, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -79,23 +75,17 @@ func TestFieldinfo2Attribute(t *testing.T) {
|
||||
Initial: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Expected: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Subject,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -134,15 +124,11 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Category,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -169,27 +155,19 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Category,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Account,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Subject,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1003_to_1004", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
&engine.Attribute{
|
||||
FieldName: utils.Destination,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
|
||||
@@ -55,6 +55,9 @@ type MigratorDataDB interface {
|
||||
getV1DerivedChargers() (v1d *v1DerivedChargersWithKey, err error)
|
||||
setV1DerivedChargers(dc *v1DerivedChargersWithKey) (err error)
|
||||
remV1DerivedChargers(key string) (err error)
|
||||
getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error)
|
||||
setV2AttributeProfile(x *v2AttributeProfile) (err error)
|
||||
remV2AttributeProfile(tenant, id string) (err error)
|
||||
|
||||
DataManager() *engine.DataManager
|
||||
}
|
||||
|
||||
@@ -214,3 +214,19 @@ func (v1ms *mapMigrator) setV1DerivedChargers(dc *v1DerivedChargersWithKey) (err
|
||||
func (v1ms *mapMigrator) remV1DerivedChargers(key string) (err error) {
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
//AttributeProfile methods
|
||||
//get
|
||||
func (v1ms *mapMigrator) getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error) {
|
||||
return nil, utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
//set
|
||||
func (v1ms *mapMigrator) setV2AttributeProfile(x *v2AttributeProfile) (err error) {
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
//rem
|
||||
func (v1ms *mapMigrator) remV2AttributeProfile(tenant, id string) (err error) {
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
@@ -522,3 +522,38 @@ func (v1ms *mongoMigrator) remV1DerivedChargers(key string) (err error) {
|
||||
_, err = v1ms.mgoDB.DB().Collection(v1DerivedChargersCol).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"key": key})
|
||||
return
|
||||
}
|
||||
|
||||
//AttributeProfile methods
|
||||
//get
|
||||
func (v1ms *mongoMigrator) getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error) {
|
||||
if v1ms.cursor == nil {
|
||||
var cursor mongo.Cursor
|
||||
cursor, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).Find(v1ms.mgoDB.GetContext(), bson.D{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v1ms.cursor = &cursor
|
||||
}
|
||||
if !(*v1ms.cursor).Next(v1ms.mgoDB.GetContext()) {
|
||||
(*v1ms.cursor).Close(v1ms.mgoDB.GetContext())
|
||||
v1ms.cursor = nil
|
||||
return nil, utils.ErrNoMoreData
|
||||
}
|
||||
v2attrPrf = new(v2AttributeProfile)
|
||||
if err := (*v1ms.cursor).Decode(v2attrPrf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v2attrPrf, nil
|
||||
}
|
||||
|
||||
//set
|
||||
func (v1ms *mongoMigrator) setV2AttributeProfile(x *v2AttributeProfile) (err error) {
|
||||
_, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).InsertOne(v1ms.mgoDB.GetContext(), x)
|
||||
return
|
||||
}
|
||||
|
||||
//rem
|
||||
func (v1ms *mongoMigrator) remV2AttributeProfile(tenant, id string) (err error) {
|
||||
_, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"tenant": tenant, "id": id})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -654,3 +654,51 @@ func (v1rs *redisMigrator) setV1DerivedChargers(dc *v1DerivedChargersWithKey) (e
|
||||
func (v1rs *redisMigrator) remV1DerivedChargers(key string) (err error) {
|
||||
return v1rs.rds.Cmd("DEL", utils.DERIVEDCHARGERS_PREFIX+key).Err
|
||||
}
|
||||
|
||||
//AttributeProfile methods
|
||||
//get
|
||||
func (v1rs *redisMigrator) getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error) {
|
||||
var v2attr *v2AttributeProfile
|
||||
if v1rs.qryIdx == nil {
|
||||
v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.AttributeProfilePrefix)
|
||||
if err != nil {
|
||||
return
|
||||
} else if len(v1rs.dataKeys) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
v1rs.qryIdx = utils.IntPointer(0)
|
||||
}
|
||||
if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
|
||||
strVal, err := v1rs.rds.Cmd("GET", v1rs.dataKeys[*v1rs.qryIdx]).Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v2attr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*v1rs.qryIdx = *v1rs.qryIdx + 1
|
||||
} else {
|
||||
v1rs.qryIdx = nil
|
||||
return nil, utils.ErrNoMoreData
|
||||
}
|
||||
return v2attr, nil
|
||||
}
|
||||
|
||||
//set
|
||||
func (v1rs *redisMigrator) setV2AttributeProfile(x *v2AttributeProfile) (err error) {
|
||||
key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(x.Tenant, x.ID)
|
||||
bit, err := v1rs.rds.Marshaler().Marshal(x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = v1rs.rds.Cmd("SET", key, bit).Err; err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//rem
|
||||
func (v1rs *redisMigrator) remV2AttributeProfile(tenant, id string) (err error) {
|
||||
key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(tenant, id)
|
||||
return v1rs.rds.Cmd("DEL", key).Err
|
||||
}
|
||||
|
||||
@@ -64,9 +64,7 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr
|
||||
if user.Tenant != attr.Tenant {
|
||||
attr.Attributes = append(attr.Attributes, &engine.Attribute{
|
||||
FieldName: utils.MetaTenant,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile(user.Tenant, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
})
|
||||
}
|
||||
for fieldName, substitute := range user.Profile {
|
||||
@@ -79,9 +77,7 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr
|
||||
}
|
||||
attr.Attributes = append(attr.Attributes, &engine.Attribute{
|
||||
FieldName: fieldName,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
})
|
||||
}
|
||||
return
|
||||
|
||||
@@ -150,21 +150,15 @@ func testUsrITMigrateAndMove(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FieldName: utils.MetaTenant,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("cgrates.com", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: utils.RequestType,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: "msisdn",
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -206,9 +200,6 @@ func testUsrITMigrateAndMove(t *testing.T) {
|
||||
}
|
||||
result.Compile()
|
||||
sort.Slice(result.Attributes, func(i, j int) bool {
|
||||
if result.Attributes[i].FieldName == result.Attributes[j].FieldName {
|
||||
return result.Attributes[i].Initial.(string) < result.Attributes[j].Initial.(string)
|
||||
}
|
||||
return result.Attributes[i].FieldName < result.Attributes[j].FieldName
|
||||
}) // only for test; map returns random keys
|
||||
if !reflect.DeepEqual(*attrProf, *result) {
|
||||
@@ -224,7 +215,8 @@ func testUsrITMigrateAndMove(t *testing.T) {
|
||||
"1001": true,
|
||||
},
|
||||
}
|
||||
if usridx, err := usrMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix], utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
if usridx, err := usrMigrator.dmOut.DataManager().GetFilterIndexes(utils.PrefixToIndexCache[utils.AttributeProfilePrefix],
|
||||
utils.ConcatenatedKey("cgrates.org", utils.META_ANY), utils.MetaString, nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expUsrIdx, usridx) {
|
||||
t.Errorf("Expected %v, recived: %v", utils.ToJSON(expUsrIdx), utils.ToJSON(usridx))
|
||||
|
||||
@@ -93,15 +93,11 @@ func TestUserProfile2attributeProfile(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FieldName: utils.MetaTenant,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: "Subject",
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -116,15 +112,11 @@ func TestUserProfile2attributeProfile(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FieldName: utils.RequestType,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: "msisdn",
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -139,15 +131,11 @@ func TestUserProfile2attributeProfile(t *testing.T) {
|
||||
Attributes: []*engine.Attribute{
|
||||
{
|
||||
FieldName: utils.MetaTenant,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
{
|
||||
FieldName: utils.RequestType,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP),
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Blocker: false,
|
||||
@@ -158,7 +146,7 @@ func TestUserProfile2attributeProfile(t *testing.T) {
|
||||
rply := userProfile2attributeProfile(users[i])
|
||||
sort.Slice(rply.Attributes, func(i, j int) bool {
|
||||
if rply.Attributes[i].FieldName == rply.Attributes[j].FieldName {
|
||||
return rply.Attributes[i].Initial.(string) < rply.Attributes[j].Initial.(string)
|
||||
return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0]
|
||||
}
|
||||
return rply.Attributes[i].FieldName < rply.Attributes[j].FieldName
|
||||
}) // only for test; map returns random keys
|
||||
|
||||
Reference in New Issue
Block a user