Added requestprocessor diff functions

This commit is contained in:
Trial97
2021-04-22 19:09:09 +03:00
committed by Dan Christian Bogos
parent b63649eef4
commit 338273899f
10 changed files with 617 additions and 535 deletions

View File

@@ -46,55 +46,22 @@ func (acS *AccountSCfg) loadFromJSONCfg(jsnCfg *AccountSJsonCfg) (err error) {
acS.IndexedSelects = *jsnCfg.Indexed_selects
}
if jsnCfg.Attributes_conns != nil {
acS.AttributeSConns = make([]string, len(*jsnCfg.Attributes_conns))
for idx, conn := range *jsnCfg.Attributes_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.AttributeSConns[idx] = conn
if conn == utils.MetaInternal {
acS.AttributeSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)
}
}
acS.AttributeSConns = updateInternalConns(*jsnCfg.Attributes_conns, utils.MetaAttributes)
}
if jsnCfg.Rates_conns != nil {
acS.RateSConns = make([]string, len(*jsnCfg.Rates_conns))
for idx, conn := range *jsnCfg.Rates_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.RateSConns[idx] = conn
if conn == utils.MetaInternal {
acS.RateSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRateS)
}
}
acS.RateSConns = updateInternalConns(*jsnCfg.Rates_conns, utils.MetaRateS)
}
if jsnCfg.Thresholds_conns != nil {
acS.ThresholdSConns = make([]string, len(*jsnCfg.Thresholds_conns))
for idx, conn := range *jsnCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.ThresholdSConns[idx] = conn
if conn == utils.MetaInternal {
acS.ThresholdSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
}
}
acS.ThresholdSConns = updateInternalConns(*jsnCfg.Thresholds_conns, utils.MetaThresholds)
}
if jsnCfg.String_indexed_fields != nil {
sif := make([]string, len(*jsnCfg.String_indexed_fields))
for i, fID := range *jsnCfg.String_indexed_fields {
sif[i] = fID
}
acS.StringIndexedFields = &sif
acS.StringIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.String_indexed_fields))
}
if jsnCfg.Prefix_indexed_fields != nil {
pif := make([]string, len(*jsnCfg.Prefix_indexed_fields))
for i, fID := range *jsnCfg.Prefix_indexed_fields {
pif[i] = fID
}
acS.PrefixIndexedFields = &pif
acS.PrefixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Prefix_indexed_fields))
}
if jsnCfg.Suffix_indexed_fields != nil {
sif := make([]string, len(*jsnCfg.Suffix_indexed_fields))
for i, fID := range *jsnCfg.Suffix_indexed_fields {
sif[i] = fID
}
acS.SuffixIndexedFields = &sif
acS.SuffixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Suffix_indexed_fields))
}
if jsnCfg.Nested_fields != nil {
acS.NestedFields = *jsnCfg.Nested_fields
@@ -119,55 +86,22 @@ func (acS *AccountSCfg) AsMapInterface() (initialMP map[string]interface{}) {
utils.MaxIterations: acS.MaxIterations,
}
if acS.AttributeSConns != nil {
attributeSConns := make([]string, len(acS.AttributeSConns))
for i, item := range acS.AttributeSConns {
attributeSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) {
attributeSConns[i] = utils.MetaInternal
}
}
initialMP[utils.AttributeSConnsCfg] = attributeSConns
initialMP[utils.AttributeSConnsCfg] = getInternalJSONConns(acS.AttributeSConns)
}
if acS.RateSConns != nil {
rateSConns := make([]string, len(acS.RateSConns))
for i, item := range acS.RateSConns {
rateSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRateS) {
rateSConns[i] = utils.MetaInternal
}
}
initialMP[utils.RateSConnsCfg] = rateSConns
initialMP[utils.RateSConnsCfg] = getInternalJSONConns(acS.RateSConns)
}
if acS.ThresholdSConns != nil {
thresholdSConns := make([]string, len(acS.ThresholdSConns))
for i, item := range acS.ThresholdSConns {
thresholdSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
thresholdSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ThresholdSConnsCfg] = thresholdSConns
initialMP[utils.ThresholdSConnsCfg] = getInternalJSONConns(acS.ThresholdSConns)
}
if acS.StringIndexedFields != nil {
stringIndexedFields := make([]string, len(*acS.StringIndexedFields))
for i, item := range *acS.StringIndexedFields {
stringIndexedFields[i] = item
}
initialMP[utils.StringIndexedFieldsCfg] = stringIndexedFields
initialMP[utils.StringIndexedFieldsCfg] = utils.CloneStringSlice(*acS.StringIndexedFields)
}
if acS.PrefixIndexedFields != nil {
prefixIndexedFields := make([]string, len(*acS.PrefixIndexedFields))
for i, item := range *acS.PrefixIndexedFields {
prefixIndexedFields[i] = item
}
initialMP[utils.PrefixIndexedFieldsCfg] = prefixIndexedFields
initialMP[utils.PrefixIndexedFieldsCfg] = utils.CloneStringSlice(*acS.PrefixIndexedFields)
}
if acS.SuffixIndexedFields != nil {
suffixIndexedFields := make([]string, len(*acS.SuffixIndexedFields))
for i, item := range *acS.SuffixIndexedFields {
suffixIndexedFields[i] = item
}
initialMP[utils.SuffixIndexedFieldsCfg] = suffixIndexedFields
initialMP[utils.SuffixIndexedFieldsCfg] = utils.CloneStringSlice(*acS.SuffixIndexedFields)
}
if acS.MaxUsage != nil {
initialMP[utils.MaxUsage] = acS.MaxUsage.String()
@@ -185,43 +119,76 @@ func (acS AccountSCfg) Clone() (cln *AccountSCfg) {
MaxUsage: acS.MaxUsage,
}
if acS.AttributeSConns != nil {
cln.AttributeSConns = make([]string, len(acS.AttributeSConns))
for i, con := range acS.AttributeSConns {
cln.AttributeSConns[i] = con
}
cln.AttributeSConns = utils.CloneStringSlice(acS.AttributeSConns)
}
if acS.RateSConns != nil {
cln.RateSConns = make([]string, len(acS.RateSConns))
for i, con := range acS.RateSConns {
cln.RateSConns[i] = con
}
cln.RateSConns = utils.CloneStringSlice(acS.RateSConns)
}
if acS.ThresholdSConns != nil {
cln.ThresholdSConns = make([]string, len(acS.ThresholdSConns))
for i, con := range acS.ThresholdSConns {
cln.ThresholdSConns[i] = con
}
cln.ThresholdSConns = utils.CloneStringSlice(acS.ThresholdSConns)
}
if acS.StringIndexedFields != nil {
idx := make([]string, len(*acS.StringIndexedFields))
for i, dx := range *acS.StringIndexedFields {
idx[i] = dx
}
cln.StringIndexedFields = &idx
cln.StringIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.StringIndexedFields))
}
if acS.PrefixIndexedFields != nil {
idx := make([]string, len(*acS.PrefixIndexedFields))
for i, dx := range *acS.PrefixIndexedFields {
idx[i] = dx
}
cln.PrefixIndexedFields = &idx
cln.PrefixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.PrefixIndexedFields))
}
if acS.SuffixIndexedFields != nil {
idx := make([]string, len(*acS.SuffixIndexedFields))
for i, dx := range *acS.SuffixIndexedFields {
idx[i] = dx
}
cln.SuffixIndexedFields = &idx
cln.SuffixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.SuffixIndexedFields))
}
return
}
// Account service config section
type AccountSJsonCfg struct {
Enabled *bool
Indexed_selects *bool
Attributes_conns *[]string
Rates_conns *[]string
Thresholds_conns *[]string
String_indexed_fields *[]string
Prefix_indexed_fields *[]string
Suffix_indexed_fields *[]string
Nested_fields *bool // applies when indexed fields is not defined
Max_iterations *int
Max_usage *string
}
func diffAccountSJsonCfg(d *AccountSJsonCfg, v1, v2 *AccountSCfg) *AccountSJsonCfg {
if d == nil {
d = new(AccountSJsonCfg)
}
if v1.Enabled != v2.Enabled {
d.Enabled = utils.BoolPointer(v2.Enabled)
}
if !utils.SliceStringEqual(v1.AttributeSConns, v2.AttributeSConns) {
d.Attributes_conns = utils.SliceStringPointer(getInternalJSONConns(v2.AttributeSConns))
}
if !utils.SliceStringEqual(v1.RateSConns, v2.RateSConns) {
d.Rates_conns = utils.SliceStringPointer(getInternalJSONConns(v2.RateSConns))
}
if !utils.SliceStringEqual(v1.ThresholdSConns, v2.ThresholdSConns) {
d.Thresholds_conns = utils.SliceStringPointer(getInternalJSONConns(v2.ThresholdSConns))
}
if v1.IndexedSelects != v2.IndexedSelects {
d.Indexed_selects = utils.BoolPointer(v2.IndexedSelects)
}
d.String_indexed_fields = diffIndexSlice(d.String_indexed_fields, v1.StringIndexedFields, v2.StringIndexedFields)
d.Prefix_indexed_fields = diffIndexSlice(d.Prefix_indexed_fields, v1.PrefixIndexedFields, v2.PrefixIndexedFields)
d.Suffix_indexed_fields = diffIndexSlice(d.Suffix_indexed_fields, v1.SuffixIndexedFields, v2.SuffixIndexedFields)
if v1.NestedFields != v2.NestedFields {
d.Nested_fields = utils.BoolPointer(v2.NestedFields)
}
if v1.MaxIterations != v2.MaxIterations {
d.Max_iterations = utils.IntPointer(v2.MaxIterations)
}
if v2.MaxUsage != nil {
if v1.MaxUsage == nil ||
v1.MaxUsage.Cmp(v2.MaxUsage.Big) != 0 {
d.Max_usage = utils.StringPointer(v2.MaxUsage.String())
}
} else {
d.Max_usage = nil
}
return d
}

View File

@@ -40,89 +40,38 @@ func (acS *ActionSCfg) loadFromJSONCfg(jsnCfg *ActionSJsonCfg) (err error) {
if jsnCfg == nil {
return
}
if jsnCfg.Cdrs_conns != nil {
acS.CDRsConns = make([]string, len(*jsnCfg.Cdrs_conns))
for idx, connID := range *jsnCfg.Cdrs_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.CDRsConns[idx] = connID
if connID == utils.MetaInternal {
acS.CDRsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)
}
}
}
if jsnCfg.Ees_conns != nil {
acS.EEsConns = make([]string, len(*jsnCfg.Ees_conns))
for idx, connID := range *jsnCfg.Ees_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.EEsConns[idx] = connID
if connID == utils.MetaInternal {
acS.EEsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs)
}
}
}
if jsnCfg.Thresholds_conns != nil {
acS.ThresholdSConns = make([]string, len(*jsnCfg.Thresholds_conns))
for idx, connID := range *jsnCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.ThresholdSConns[idx] = connID
if connID == utils.MetaInternal {
acS.ThresholdSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
}
}
}
if jsnCfg.Stats_conns != nil {
acS.StatSConns = make([]string, len(*jsnCfg.Stats_conns))
for idx, connID := range *jsnCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.StatSConns[idx] = connID
if connID == utils.MetaInternal {
acS.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)
}
}
}
if jsnCfg.Accounts_conns != nil {
acS.AccountSConns = make([]string, len(*jsnCfg.Accounts_conns))
for idx, connID := range *jsnCfg.Accounts_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
acS.AccountSConns[idx] = connID
if connID == utils.MetaInternal {
acS.AccountSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts)
}
}
}
if jsnCfg.Enabled != nil {
acS.Enabled = *jsnCfg.Enabled
}
if jsnCfg.Cdrs_conns != nil {
acS.CDRsConns = updateInternalConns(*jsnCfg.Cdrs_conns, utils.MetaCDRs)
}
if jsnCfg.Ees_conns != nil {
acS.EEsConns = updateInternalConns(*jsnCfg.Ees_conns, utils.MetaEEs)
}
if jsnCfg.Thresholds_conns != nil {
acS.ThresholdSConns = updateInternalConns(*jsnCfg.Thresholds_conns, utils.MetaThresholds)
}
if jsnCfg.Stats_conns != nil {
acS.StatSConns = updateInternalConns(*jsnCfg.Stats_conns, utils.MetaStats)
}
if jsnCfg.Accounts_conns != nil {
acS.AccountSConns = updateInternalConns(*jsnCfg.Accounts_conns, utils.MetaAccounts)
}
if jsnCfg.Tenants != nil {
tnt := make([]string, len(*jsnCfg.Tenants))
for i, fID := range *jsnCfg.Tenants {
tnt[i] = fID
}
acS.Tenants = &tnt
acS.Tenants = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Tenants))
}
if jsnCfg.Indexed_selects != nil {
acS.IndexedSelects = *jsnCfg.Indexed_selects
}
if jsnCfg.String_indexed_fields != nil {
sif := make([]string, len(*jsnCfg.String_indexed_fields))
for i, fID := range *jsnCfg.String_indexed_fields {
sif[i] = fID
}
acS.StringIndexedFields = &sif
acS.StringIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.String_indexed_fields))
}
if jsnCfg.Prefix_indexed_fields != nil {
pif := make([]string, len(*jsnCfg.Prefix_indexed_fields))
for i, fID := range *jsnCfg.Prefix_indexed_fields {
pif[i] = fID
}
acS.PrefixIndexedFields = &pif
acS.PrefixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Prefix_indexed_fields))
}
if jsnCfg.Suffix_indexed_fields != nil {
sif := make([]string, len(*jsnCfg.Suffix_indexed_fields))
for i, fID := range *jsnCfg.Suffix_indexed_fields {
sif[i] = fID
}
acS.SuffixIndexedFields = &sif
acS.SuffixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Suffix_indexed_fields))
}
if jsnCfg.Nested_fields != nil {
acS.NestedFields = *jsnCfg.Nested_fields
@@ -138,82 +87,31 @@ func (acS *ActionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
utils.NestedFieldsCfg: acS.NestedFields,
}
if acS.CDRsConns != nil {
CDRsConns := make([]string, len(acS.CDRsConns))
for i, item := range acS.CDRsConns {
CDRsConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs) {
CDRsConns[i] = utils.MetaInternal
}
}
initialMP[utils.CDRsConnsCfg] = CDRsConns
initialMP[utils.CDRsConnsCfg] = getInternalJSONConns(acS.CDRsConns)
}
if acS.ThresholdSConns != nil {
threshSConns := make([]string, len(acS.ThresholdSConns))
for i, item := range acS.ThresholdSConns {
threshSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
threshSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ThresholdSConnsCfg] = threshSConns
initialMP[utils.ThresholdSConnsCfg] = getInternalJSONConns(acS.ThresholdSConns)
}
if acS.StatSConns != nil {
statSConns := make([]string, len(acS.StatSConns))
for i, item := range acS.StatSConns {
statSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) {
statSConns[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = statSConns
initialMP[utils.StatSConnsCfg] = getInternalJSONConns(acS.StatSConns)
}
if acS.AccountSConns != nil {
accountSConns := make([]string, len(acS.AccountSConns))
for i, item := range acS.AccountSConns {
accountSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts) {
accountSConns[i] = utils.MetaInternal
}
}
initialMP[utils.AccountSConnsCfg] = accountSConns
initialMP[utils.AccountSConnsCfg] = getInternalJSONConns(acS.AccountSConns)
}
if acS.EEsConns != nil {
eesConns := make([]string, len(acS.EEsConns))
for i, item := range acS.EEsConns {
eesConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs) {
eesConns[i] = utils.MetaInternal
}
}
initialMP[utils.EEsConnsCfg] = eesConns
initialMP[utils.EEsConnsCfg] = getInternalJSONConns(acS.EEsConns)
}
if acS.Tenants != nil {
Tenants := make([]string, len(*acS.Tenants))
for i, item := range *acS.Tenants {
Tenants[i] = item
}
initialMP[utils.Tenants] = Tenants
initialMP[utils.Tenants] = utils.CloneStringSlice(*acS.Tenants)
}
if acS.StringIndexedFields != nil {
stringIndexedFields := make([]string, len(*acS.StringIndexedFields))
for i, item := range *acS.StringIndexedFields {
stringIndexedFields[i] = item
}
initialMP[utils.StringIndexedFieldsCfg] = stringIndexedFields
initialMP[utils.StringIndexedFieldsCfg] = utils.CloneStringSlice(*acS.StringIndexedFields)
}
if acS.PrefixIndexedFields != nil {
prefixIndexedFields := make([]string, len(*acS.PrefixIndexedFields))
for i, item := range *acS.PrefixIndexedFields {
prefixIndexedFields[i] = item
}
initialMP[utils.PrefixIndexedFieldsCfg] = prefixIndexedFields
initialMP[utils.PrefixIndexedFieldsCfg] = utils.CloneStringSlice(*acS.PrefixIndexedFields)
}
if acS.SuffixIndexedFields != nil {
suffixIndexedFields := make([]string, len(*acS.SuffixIndexedFields))
for i, item := range *acS.SuffixIndexedFields {
suffixIndexedFields[i] = item
}
initialMP[utils.SuffixIndexedFieldsCfg] = suffixIndexedFields
initialMP[utils.SuffixIndexedFieldsCfg] = utils.CloneStringSlice(*acS.SuffixIndexedFields)
}
return
}
@@ -226,62 +124,91 @@ func (acS ActionSCfg) Clone() (cln *ActionSCfg) {
NestedFields: acS.NestedFields,
}
if acS.CDRsConns != nil {
cln.CDRsConns = make([]string, len(acS.CDRsConns))
for i, con := range acS.CDRsConns {
cln.CDRsConns[i] = con
}
cln.CDRsConns = utils.CloneStringSlice(acS.CDRsConns)
}
if acS.ThresholdSConns != nil {
cln.ThresholdSConns = make([]string, len(acS.ThresholdSConns))
for i, con := range acS.ThresholdSConns {
cln.ThresholdSConns[i] = con
}
cln.ThresholdSConns = utils.CloneStringSlice(acS.ThresholdSConns)
}
if acS.StatSConns != nil {
cln.StatSConns = make([]string, len(acS.StatSConns))
for i, con := range acS.StatSConns {
cln.StatSConns[i] = con
}
cln.StatSConns = utils.CloneStringSlice(acS.StatSConns)
}
if acS.AccountSConns != nil {
cln.AccountSConns = make([]string, len(acS.AccountSConns))
for i, con := range acS.AccountSConns {
cln.AccountSConns[i] = con
}
cln.AccountSConns = utils.CloneStringSlice(acS.AccountSConns)
}
if acS.EEsConns != nil {
cln.EEsConns = make([]string, len(acS.EEsConns))
for i, k := range acS.EEsConns {
cln.EEsConns[i] = k
}
cln.EEsConns = utils.CloneStringSlice(acS.EEsConns)
}
if acS.Tenants != nil {
tnt := make([]string, len(*acS.Tenants))
for i, dx := range *acS.Tenants {
tnt[i] = dx
}
cln.Tenants = &tnt
cln.Tenants = utils.SliceStringPointer(utils.CloneStringSlice(*acS.Tenants))
}
if acS.StringIndexedFields != nil {
idx := make([]string, len(*acS.StringIndexedFields))
for i, dx := range *acS.StringIndexedFields {
idx[i] = dx
}
cln.StringIndexedFields = &idx
cln.StringIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.StringIndexedFields))
}
if acS.PrefixIndexedFields != nil {
idx := make([]string, len(*acS.PrefixIndexedFields))
for i, dx := range *acS.PrefixIndexedFields {
idx[i] = dx
}
cln.PrefixIndexedFields = &idx
cln.PrefixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.PrefixIndexedFields))
}
if acS.SuffixIndexedFields != nil {
idx := make([]string, len(*acS.SuffixIndexedFields))
for i, dx := range *acS.SuffixIndexedFields {
idx[i] = dx
}
cln.SuffixIndexedFields = &idx
cln.SuffixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*acS.SuffixIndexedFields))
}
return
}
// Action service config section
type ActionSJsonCfg struct {
Enabled *bool
Cdrs_conns *[]string
Ees_conns *[]string
Thresholds_conns *[]string
Stats_conns *[]string
Accounts_conns *[]string
Tenants *[]string
Indexed_selects *bool
String_indexed_fields *[]string
Prefix_indexed_fields *[]string
Suffix_indexed_fields *[]string
Nested_fields *bool // applies when indexed fields is not defined
}
func diffActionSJsonCfg(d *ActionSJsonCfg, v1, v2 *ActionSCfg) *ActionSJsonCfg {
if d == nil {
d = new(ActionSJsonCfg)
}
if v1.Enabled != v2.Enabled {
d.Enabled = utils.BoolPointer(v2.Enabled)
}
if !utils.SliceStringEqual(v1.CDRsConns, v2.CDRsConns) {
d.Cdrs_conns = utils.SliceStringPointer(getInternalJSONConns(v2.CDRsConns))
}
if !utils.SliceStringEqual(v1.EEsConns, v2.EEsConns) {
d.Ees_conns = utils.SliceStringPointer(getInternalJSONConns(v2.EEsConns))
}
if !utils.SliceStringEqual(v1.ThresholdSConns, v2.ThresholdSConns) {
d.Thresholds_conns = utils.SliceStringPointer(getInternalJSONConns(v2.ThresholdSConns))
}
if !utils.SliceStringEqual(v1.StatSConns, v2.StatSConns) {
d.Stats_conns = utils.SliceStringPointer(getInternalJSONConns(v2.StatSConns))
}
if !utils.SliceStringEqual(v1.AccountSConns, v2.AccountSConns) {
d.Accounts_conns = utils.SliceStringPointer(getInternalJSONConns(v2.AccountSConns))
}
if v1.Tenants != v2.Tenants {
d.Tenants = utils.SliceStringPointer(utils.CloneStringSlice(*v2.Tenants))
}
if v1.IndexedSelects != v2.IndexedSelects {
d.Indexed_selects = utils.BoolPointer(v2.IndexedSelects)
}
if v1.StringIndexedFields != v2.StringIndexedFields {
d.String_indexed_fields = diffIndexSlice(d.String_indexed_fields, v1.StringIndexedFields, v2.StringIndexedFields)
}
if v1.PrefixIndexedFields != v2.PrefixIndexedFields {
d.Prefix_indexed_fields = diffIndexSlice(d.Prefix_indexed_fields, v1.PrefixIndexedFields, v2.PrefixIndexedFields)
}
if v1.SuffixIndexedFields != v2.SuffixIndexedFields {
d.Suffix_indexed_fields = diffIndexSlice(d.Suffix_indexed_fields, v1.SuffixIndexedFields, v2.SuffixIndexedFields)
}
if v1.NestedFields != v2.NestedFields {
d.Nested_fields = utils.BoolPointer(v2.NestedFields)
}
return d
}

View File

@@ -229,8 +229,7 @@ func newCGRConfig(config []byte) (cfg *CGRConfig, err error) {
dfltKamConnConfig = cfg.kamAgentCfg.EvapiConns[0]
dfltAstConnCfg = cfg.asteriskAgentCfg.AsteriskConns[0]
dfltLoaderConfig = cfg.loaderCfg[0].Clone()
dfltRemoteHost = new(RemoteHost)
*dfltRemoteHost = *cfg.rpcConns[utils.MetaLocalHost].Conns[0]
dfltRemoteHost = cfg.rpcConns[utils.MetaLocalHost].Conns[0].Clone()
err = cfg.checkConfigSanity()
return
}

View File

@@ -20,7 +20,6 @@ package config
import (
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/rpcclient"
)
// DiameterAgentCfg the config section that describes the Diameter Agent
@@ -59,15 +58,7 @@ func (da *DiameterAgentCfg) loadFromJSONCfg(jsnCfg *DiameterAgentJsonCfg, separa
da.DictionariesPath = *jsnCfg.Dictionaries_path
}
if jsnCfg.Sessions_conns != nil {
da.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
da.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal ||
attrConn == rpcclient.BiRPCInternal {
da.SessionSConns[idx] = utils.ConcatenatedKey(attrConn, utils.MetaSessionS)
}
}
da.SessionSConns = updateBiRPCInternalConns(*jsnCfg.Sessions_conns, utils.MetaSessionS)
}
if jsnCfg.Origin_host != nil {
da.OriginHost = *jsnCfg.Origin_host
@@ -143,16 +134,7 @@ func (da *DiameterAgentCfg) AsMapInterface(separator string) (initialMP map[stri
initialMP[utils.RequestProcessorsCfg] = requestProcessors
if da.SessionSConns != nil {
sessionSConns := make([]string, len(da.SessionSConns))
for i, item := range da.SessionSConns {
sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
sessionSConns[i] = utils.MetaInternal
} else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) {
sessionSConns[i] = rpcclient.BiRPCInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
initialMP[utils.SessionSConnsCfg] = getBiRPCInternalJSONConns(da.SessionSConns)
}
return
}
@@ -175,10 +157,7 @@ func (da DiameterAgentCfg) Clone() (cln *DiameterAgentCfg) {
ForcedDisconnect: da.ForcedDisconnect,
}
if da.SessionSConns != nil {
cln.SessionSConns = make([]string, len(da.SessionSConns))
for i, con := range da.SessionSConns {
cln.SessionSConns[i] = con
}
cln.SessionSConns = utils.CloneStringSlice(da.SessionSConns)
}
if da.RequestProcessors != nil {
cln.RequestProcessors = make([]*RequestProcessor, len(da.RequestProcessors))
@@ -188,3 +167,72 @@ func (da DiameterAgentCfg) Clone() (cln *DiameterAgentCfg) {
}
return
}
// DiameterAgent configuration
type DiameterAgentJsonCfg struct {
Enabled *bool
Listen *string
Listen_net *string
Dictionaries_path *string
Sessions_conns *[]string
Origin_host *string
Origin_realm *string
Vendor_id *int
Product_name *string
Concurrent_requests *int
Synced_conn_requests *bool
Asr_template *string
Rar_template *string
Forced_disconnect *string
Request_processors *[]*ReqProcessorJsnCfg
}
func diffDiameterAgentJsonCfg(d *DiameterAgentJsonCfg, v1, v2 *DiameterAgentCfg, separator string) *DiameterAgentJsonCfg {
if d == nil {
d = new(DiameterAgentJsonCfg)
}
if v1.Enabled != v2.Enabled {
d.Enabled = utils.BoolPointer(v2.Enabled)
}
if v1.ListenNet != v2.ListenNet {
d.Listen_net = utils.StringPointer(v2.ListenNet)
}
if v1.Listen != v2.Listen {
d.Listen = utils.StringPointer(v2.Listen)
}
if v1.DictionariesPath != v2.DictionariesPath {
d.Dictionaries_path = utils.StringPointer(v2.DictionariesPath)
}
if !utils.SliceStringEqual(v1.SessionSConns, v2.SessionSConns) {
d.Sessions_conns = utils.SliceStringPointer(getBiRPCInternalJSONConns(v2.SessionSConns))
}
if v1.OriginHost != v2.OriginHost {
d.Origin_host = utils.StringPointer(v2.OriginHost)
}
if v1.OriginRealm != v2.OriginRealm {
d.Origin_realm = utils.StringPointer(v2.OriginRealm)
}
if v1.VendorID != v2.VendorID {
d.Vendor_id = utils.IntPointer(v2.VendorID)
}
if v1.ProductName != v2.ProductName {
d.Product_name = utils.StringPointer(v2.ProductName)
}
if v1.ConcurrentReqs != v2.ConcurrentReqs {
d.Concurrent_requests = utils.IntPointer(v2.ConcurrentReqs)
}
if v1.SyncedConnReqs != v2.SyncedConnReqs {
d.Synced_conn_requests = utils.BoolPointer(v2.SyncedConnReqs)
}
if v1.ASRTemplate != v2.ASRTemplate {
d.Asr_template = utils.StringPointer(v2.ASRTemplate)
}
if v1.RARTemplate != v2.RARTemplate {
d.Rar_template = utils.StringPointer(v2.RARTemplate)
}
if v1.ForcedDisconnect != v2.ForcedDisconnect {
d.Forced_disconnect = utils.StringPointer(v2.ForcedDisconnect)
}
d.Request_processors = diffReqProcessorsJsnCfg(d.Request_processors, v1.RequestProcessors, v2.RequestProcessors, separator)
return d
}

View File

@@ -130,108 +130,3 @@ func (da DNSAgentCfg) Clone() (cln *DNSAgentCfg) {
}
return
}
// RequestProcessor is the request processor configuration
type RequestProcessor struct {
ID string
Tenant RSRParsers
Filters []string
Flags utils.FlagsWithParams
Timezone string
RequestFields []*FCTemplate
ReplyFields []*FCTemplate
}
func (rp *RequestProcessor) loadFromJSONCfg(jsnCfg *ReqProcessorJsnCfg, sep string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.ID != nil {
rp.ID = *jsnCfg.ID
}
if jsnCfg.Filters != nil {
rp.Filters = make([]string, len(*jsnCfg.Filters))
for i, fltr := range *jsnCfg.Filters {
rp.Filters[i] = fltr
}
}
if jsnCfg.Flags != nil {
rp.Flags = utils.FlagsWithParamsFromSlice(*jsnCfg.Flags)
}
if jsnCfg.Timezone != nil {
rp.Timezone = *jsnCfg.Timezone
}
if jsnCfg.Tenant != nil {
if rp.Tenant, err = NewRSRParsers(*jsnCfg.Tenant, sep); err != nil {
return err
}
}
if jsnCfg.Request_fields != nil {
if rp.RequestFields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Request_fields, sep); err != nil {
return
}
}
if jsnCfg.Reply_fields != nil {
if rp.ReplyFields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Reply_fields, sep); err != nil {
return
}
}
return nil
}
// AsMapInterface returns the config as a map[string]interface{}
func (rp *RequestProcessor) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.IDCfg: rp.ID,
utils.FiltersCfg: rp.Filters,
utils.FlagsCfg: rp.Flags.SliceFlags(),
utils.TimezoneCfg: rp.Timezone,
}
if rp.Tenant != nil {
initialMP[utils.TenantCfg] = rp.Tenant.GetRule(separator)
}
if rp.RequestFields != nil {
requestFields := make([]map[string]interface{}, len(rp.RequestFields))
for i, item := range rp.RequestFields {
requestFields[i] = item.AsMapInterface(separator)
}
initialMP[utils.RequestFieldsCfg] = requestFields
}
if rp.ReplyFields != nil {
replyFields := make([]map[string]interface{}, len(rp.ReplyFields))
for i, item := range rp.ReplyFields {
replyFields[i] = item.AsMapInterface(separator)
}
initialMP[utils.ReplyFieldsCfg] = replyFields
}
return
}
// Clone returns a deep copy of APIBanCfg
func (rp RequestProcessor) Clone() (cln *RequestProcessor) {
cln = &RequestProcessor{
ID: rp.ID,
Tenant: rp.Tenant.Clone(),
Flags: rp.Flags.Clone(),
Timezone: rp.Timezone,
}
if rp.Filters != nil {
cln.Filters = make([]string, len(rp.Filters))
for i, fltr := range rp.Filters {
cln.Filters[i] = fltr
}
}
if rp.RequestFields != nil {
cln.RequestFields = make([]*FCTemplate, len(rp.RequestFields))
for i, rf := range rp.RequestFields {
cln.RequestFields[i] = rf.Clone()
}
}
if rp.ReplyFields != nil {
cln.ReplyFields = make([]*FCTemplate, len(rp.ReplyFields))
for i, rf := range rp.ReplyFields {
cln.ReplyFields[i] = rf.Clone()
}
}
return
}

View File

@@ -20,7 +20,6 @@ package config
import (
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/rpcclient"
)
// NewDfltKamConnConfig returns the first cached default value for a KamConnCfg connection
@@ -28,8 +27,7 @@ func NewDfltKamConnConfig() *KamConnCfg {
if dfltKamConnConfig == nil {
return new(KamConnCfg) // No defaults, most probably we are building the defaults now
}
dfltVal := *dfltKamConnConfig
return &dfltVal
return dfltKamConnConfig.Clone()
}
// KamConnCfg represents one connection instance towards Kamailio
@@ -90,15 +88,7 @@ func (ka *KamAgentCfg) loadFromJSONCfg(jsnCfg *KamAgentJsonCfg) error {
ka.Enabled = *jsnCfg.Enabled
}
if jsnCfg.Sessions_conns != nil {
ka.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
ka.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal ||
attrConn == rpcclient.BiRPCInternal {
ka.SessionSConns[idx] = utils.ConcatenatedKey(attrConn, utils.MetaSessionS)
}
}
ka.SessionSConns = updateBiRPCInternalConns(*jsnCfg.Sessions_conns, utils.MetaSessionS)
}
if jsnCfg.Create_cdr != nil {
ka.CreateCdr = *jsnCfg.Create_cdr
@@ -131,16 +121,7 @@ func (ka *KamAgentCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP[utils.EvapiConnsCfg] = evapiConns
}
if ka.SessionSConns != nil {
sessionSConns := make([]string, len(ka.SessionSConns))
for i, item := range ka.SessionSConns {
sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
sessionSConns[i] = utils.MetaInternal
} else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) {
sessionSConns[i] = rpcclient.BiRPCInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
initialMP[utils.SessionSConnsCfg] = getBiRPCInternalJSONConns(ka.SessionSConns)
}
return
}
@@ -153,10 +134,7 @@ func (ka KamAgentCfg) Clone() (cln *KamAgentCfg) {
Timezone: ka.Timezone,
}
if ka.SessionSConns != nil {
cln.SessionSConns = make([]string, len(ka.SessionSConns))
for i, con := range ka.SessionSConns {
cln.SessionSConns[i] = con
}
cln.SessionSConns = utils.CloneStringSlice(ka.SessionSConns)
}
if ka.EvapiConns != nil {
cln.EvapiConns = make([]*KamConnCfg, len(ka.EvapiConns))
@@ -166,3 +144,74 @@ func (ka KamAgentCfg) Clone() (cln *KamAgentCfg) {
}
return
}
// Represents one connection instance towards Kamailio
type KamConnJsonCfg struct {
Alias *string
Address *string
Reconnects *int
}
func diffKamConnJsonCfg(v1, v2 *KamConnCfg) (d *KamConnJsonCfg) {
d = new(KamConnJsonCfg)
if v1.Alias != v2.Alias {
d.Alias = utils.StringPointer(v2.Alias)
}
if v1.Address != v2.Address {
d.Address = utils.StringPointer(v2.Address)
}
if v1.Reconnects != v2.Reconnects {
d.Reconnects = utils.IntPointer(v2.Reconnects)
}
return
}
// KamAgentJsonCfg kamailio config section
type KamAgentJsonCfg struct {
Enabled *bool
Sessions_conns *[]string
Create_cdr *bool
Evapi_conns *[]*KamConnJsonCfg
Timezone *string
}
func equalsKamConnsCfg(v1, v2 []*KamConnCfg) bool {
if len(v1) != len(v2) {
return false
}
for i := range v2 {
if v1[i].Alias != v2[i].Alias ||
v1[i].Address != v2[i].Address ||
v1[i].Reconnects != v2[i].Reconnects {
return false
}
}
return true
}
func diffKamAgentJsonCfg(d *KamAgentJsonCfg, v1, v2 *KamAgentCfg) *KamAgentJsonCfg {
if d == nil {
d = new(KamAgentJsonCfg)
}
if v1.Enabled != v2.Enabled {
d.Enabled = utils.BoolPointer(v2.Enabled)
}
if !utils.SliceStringEqual(v1.SessionSConns, v2.SessionSConns) {
d.Sessions_conns = utils.SliceStringPointer(getBiRPCInternalJSONConns(v2.SessionSConns))
}
if v1.CreateCdr != v2.CreateCdr {
d.Create_cdr = utils.BoolPointer(v2.CreateCdr)
}
if !equalsKamConnsCfg(v1.EvapiConns, v2.EvapiConns) {
dft := NewDfltKamConnConfig()
conns := make([]*KamConnJsonCfg, len(v2.EvapiConns))
for i, conn := range v2.EvapiConns {
conns[i] = diffKamConnJsonCfg(dft, conn)
}
d.Evapi_conns = &conns
}
if v1.Timezone != v2.Timezone {
d.Timezone = utils.StringPointer(v2.Timezone)
}
return d
}

View File

@@ -26,63 +26,6 @@ import (
"github.com/cgrates/rpcclient"
)
type RPCConnsJson map[string]*RPCConnJson
type RPCConnJson struct {
Strategy *string
PoolSize *int
Conns *[]*RemoteHostJson
}
// Represents one connection instance towards a rater/cdrs server
type RemoteHostJson struct {
Id *string
Address *string
Transport *string
Synchronous *bool
Tls *bool
}
// SM-Kamailio config section
type KamAgentJsonCfg struct {
Enabled *bool
Sessions_conns *[]string
Create_cdr *bool
Evapi_conns *[]*KamConnJsonCfg
Timezone *string
}
// Represents one connection instance towards Kamailio
type KamConnJsonCfg struct {
Alias *string
Address *string
Reconnects *int
}
// Represents one connection instance towards OpenSIPS
type OsipsConnJsonCfg struct {
Mi_addr *string
Reconnects *int
}
// DiameterAgent configuration
type DiameterAgentJsonCfg struct {
Enabled *bool
Listen *string
Listen_net *string
Dictionaries_path *string
Sessions_conns *[]string
Origin_host *string
Origin_realm *string
Vendor_id *int
Product_name *string
Concurrent_requests *int
Synced_conn_requests *bool
Asr_template *string
Rar_template *string
Forced_disconnect *string
Request_processors *[]*ReqProcessorJsnCfg
}
// Radius Agent configuration section
type RadiusAgentJsonCfg struct {
Enabled *bool
@@ -116,16 +59,6 @@ type DNSAgentJsonCfg struct {
Request_processors *[]*ReqProcessorJsnCfg
}
type ReqProcessorJsnCfg struct {
ID *string
Filters *[]string
Tenant *string
Timezone *string
Flags *[]string
Request_fields *[]*FcTemplateJsonCfg
Reply_fields *[]*FcTemplateJsonCfg
}
// ChargerSJsonCfg service config section
type ChargerSJsonCfg struct {
Enabled *bool
@@ -339,37 +272,6 @@ type ConfigSCfgJson struct {
Root_dir *string
}
// Action service config section
type ActionSJsonCfg struct {
Enabled *bool
Cdrs_conns *[]string
Ees_conns *[]string
Thresholds_conns *[]string
Stats_conns *[]string
Accounts_conns *[]string
Tenants *[]string
Indexed_selects *bool
String_indexed_fields *[]string
Prefix_indexed_fields *[]string
Suffix_indexed_fields *[]string
Nested_fields *bool // applies when indexed fields is not defined
}
// Account service config section
type AccountSJsonCfg struct {
Enabled *bool
Indexed_selects *bool
Attributes_conns *[]string
Rates_conns *[]string
Thresholds_conns *[]string
String_indexed_fields *[]string
Prefix_indexed_fields *[]string
Suffix_indexed_fields *[]string
Nested_fields *bool // applies when indexed fields is not defined
Max_iterations *int
Max_usage *string
}
// updateInternalConns updates the connection list by specifying the subsystem for internal connections
func updateInternalConns(conns []string, subsystem string) (c []string) {
subsystem = utils.MetaInternal + utils.ConcatenatedKeySep + subsystem

View File

@@ -29,8 +29,7 @@ func NewDfltLoaderSCfg() *LoaderSCfg {
if dfltLoaderConfig == nil {
return new(LoaderSCfg)
}
dfltVal := *dfltLoaderConfig
return &dfltVal
return dfltLoaderConfig.Clone()
}
// LoaderSCfgs to export some methods for LoaderS profiles
@@ -196,7 +195,7 @@ func (l LoaderSCfg) Clone() (cln *LoaderSCfg) {
DryRun: l.DryRun,
RunDelay: l.RunDelay,
LockFileName: l.LockFileName,
CacheSConns: make([]string, len(l.CacheSConns)),
CacheSConns: utils.CloneStringSlice(l.CacheSConns),
FieldSeparator: l.FieldSeparator,
TpInDir: l.TpInDir,
TpOutDir: l.TpOutDir,

202
config/reqprocessorcfg.go Normal file
View File

@@ -0,0 +1,202 @@
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package config
import "github.com/cgrates/cgrates/utils"
// RequestProcessor is the request processor configuration
type RequestProcessor struct {
ID string
Tenant RSRParsers
Filters []string
Flags utils.FlagsWithParams
Timezone string
RequestFields []*FCTemplate
ReplyFields []*FCTemplate
}
func (rp *RequestProcessor) loadFromJSONCfg(jsnCfg *ReqProcessorJsnCfg, sep string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.ID != nil {
rp.ID = *jsnCfg.ID
}
if jsnCfg.Filters != nil {
rp.Filters = utils.CloneStringSlice(*jsnCfg.Filters)
}
if jsnCfg.Flags != nil {
rp.Flags = utils.FlagsWithParamsFromSlice(*jsnCfg.Flags)
}
if jsnCfg.Timezone != nil {
rp.Timezone = *jsnCfg.Timezone
}
if jsnCfg.Tenant != nil {
if rp.Tenant, err = NewRSRParsers(*jsnCfg.Tenant, sep); err != nil {
return
}
}
if jsnCfg.Request_fields != nil {
if rp.RequestFields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Request_fields, sep); err != nil {
return
}
}
if jsnCfg.Reply_fields != nil {
if rp.ReplyFields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Reply_fields, sep); err != nil {
return
}
}
return
}
// AsMapInterface returns the config as a map[string]interface{}
func (rp *RequestProcessor) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.IDCfg: rp.ID,
utils.FiltersCfg: utils.CloneStringSlice(rp.Filters),
utils.FlagsCfg: rp.Flags.SliceFlags(),
utils.TimezoneCfg: rp.Timezone,
}
if rp.Tenant != nil {
initialMP[utils.TenantCfg] = rp.Tenant.GetRule(separator)
}
if rp.RequestFields != nil {
requestFields := make([]map[string]interface{}, len(rp.RequestFields))
for i, item := range rp.RequestFields {
requestFields[i] = item.AsMapInterface(separator)
}
initialMP[utils.RequestFieldsCfg] = requestFields
}
if rp.ReplyFields != nil {
replyFields := make([]map[string]interface{}, len(rp.ReplyFields))
for i, item := range rp.ReplyFields {
replyFields[i] = item.AsMapInterface(separator)
}
initialMP[utils.ReplyFieldsCfg] = replyFields
}
return
}
// Clone returns a deep copy of APIBanCfg
func (rp RequestProcessor) Clone() (cln *RequestProcessor) {
cln = &RequestProcessor{
ID: rp.ID,
Tenant: rp.Tenant.Clone(),
Flags: rp.Flags.Clone(),
Timezone: rp.Timezone,
}
if rp.Filters != nil {
cln.Filters = utils.CloneStringSlice(rp.Filters)
}
if rp.RequestFields != nil {
cln.RequestFields = make([]*FCTemplate, len(rp.RequestFields))
for i, rf := range rp.RequestFields {
cln.RequestFields[i] = rf.Clone()
}
}
if rp.ReplyFields != nil {
cln.ReplyFields = make([]*FCTemplate, len(rp.ReplyFields))
for i, rf := range rp.ReplyFields {
cln.ReplyFields[i] = rf.Clone()
}
}
return
}
type ReqProcessorJsnCfg struct {
ID *string
Filters *[]string
Tenant *string
Timezone *string
Flags *[]string
Request_fields *[]*FcTemplateJsonCfg
Reply_fields *[]*FcTemplateJsonCfg
}
func diffReqProcessorJsnCfg(d *ReqProcessorJsnCfg, v1, v2 *RequestProcessor, separator string) *ReqProcessorJsnCfg {
if d == nil {
d = new(ReqProcessorJsnCfg)
}
if v1.ID != v2.ID {
d.ID = utils.StringPointer(v2.ID)
}
tnt1 := v1.Tenant.GetRule(separator)
tnt2 := v2.Tenant.GetRule(separator)
if tnt1 != tnt2 {
d.Tenant = utils.StringPointer(tnt2)
}
if !utils.SliceStringEqual(v1.Filters, v2.Filters) {
d.Filters = utils.SliceStringPointer(utils.CloneStringSlice(v2.Filters))
}
flag1 := v1.Flags.SliceFlags()
flag2 := v2.Flags.SliceFlags()
if !utils.SliceStringEqual(flag1, flag2) {
d.Flags = utils.SliceStringPointer(flag2)
}
if v1.Timezone != v2.Timezone {
d.Timezone = utils.StringPointer(v2.Timezone)
}
var req []*FcTemplateJsonCfg
if d.Request_fields != nil {
req = *d.Request_fields
}
req = diffFcTemplateJsonCfg(req, v1.RequestFields, v2.RequestFields, separator)
d.Request_fields = &req
var rply []*FcTemplateJsonCfg
if d.Reply_fields != nil {
rply = *d.Reply_fields
}
rply = diffFcTemplateJsonCfg(rply, v1.ReplyFields, v2.ReplyFields, separator)
d.Reply_fields = &rply
return d
}
func getReqProcessorJsnCfg(d []*ReqProcessorJsnCfg, id string) (*ReqProcessorJsnCfg, int) {
for i, v := range d {
if v.ID != nil && *v.ID == id {
return v, i
}
}
return nil, -1
}
func getRequestProcessor(d []*RequestProcessor, id string) *RequestProcessor {
for _, v := range d {
if v.ID == id {
return v
}
}
return new(RequestProcessor)
}
func diffReqProcessorsJsnCfg(d *[]*ReqProcessorJsnCfg, v1, v2 []*RequestProcessor, separator string) *[]*ReqProcessorJsnCfg {
if d == nil || *d == nil {
d = &[]*ReqProcessorJsnCfg{}
}
for _, val := range v2 {
dv, i := getReqProcessorJsnCfg(*d, val.ID)
dv = diffReqProcessorJsnCfg(dv, getRequestProcessor(v1, val.ID), val, separator)
if i == -1 {
*d = append(*d, dv)
} else {
(*d)[i] = dv
}
}
return d
}

View File

@@ -28,8 +28,7 @@ func NewDfltRemoteHost() *RemoteHost {
if dfltRemoteHost == nil {
return new(RemoteHost) // No defaults, most probably we are building the defaults now
}
dfltVal := *dfltRemoteHost // Copy the value instead of it's pointer
return &dfltVal
return dfltRemoteHost.Clone()
}
// NewDfltRPCConn returns the default value for a RPCConn
@@ -215,3 +214,98 @@ func RemoveRPCCons(rpcConns RPCConns, hosts utils.StringSet) (connIDs utils.Stri
}
return
}
// Represents one connection instance towards a rater/cdrs server
type RemoteHostJson struct {
Id *string
Address *string
Transport *string
Synchronous *bool
Tls *bool
}
func diffRemoteHostJson(v1, v2 *RemoteHost) (d *RemoteHostJson) {
d = new(RemoteHostJson)
if v1.ID != v2.ID {
d.Id = utils.StringPointer(v2.ID)
}
if v1.Address != v2.Address {
d.Address = utils.StringPointer(v2.Address)
}
if v1.Transport != v2.Transport {
d.Transport = utils.StringPointer(v2.Transport)
}
if v1.Synchronous != v2.Synchronous {
d.Synchronous = utils.BoolPointer(v2.Synchronous)
}
if v1.TLS != v2.TLS {
d.Tls = utils.BoolPointer(v2.TLS)
}
return
}
type RPCConnJson struct {
Strategy *string
PoolSize *int
Conns *[]*RemoteHostJson
}
func diffRPCConnJson(d *RPCConnJson, v1, v2 *RPCConn) *RPCConnJson {
if d == nil {
d = new(RPCConnJson)
}
if v1.Strategy != v2.Strategy {
d.Strategy = utils.StringPointer(v2.Strategy)
}
if v1.PoolSize != v2.PoolSize {
d.PoolSize = utils.IntPointer(v2.PoolSize)
}
if v2.Conns != nil {
conns := make([]*RemoteHostJson, len(v2.Conns))
dft := NewDfltRemoteHost()
for i, conn := range v2.Conns {
conns[i] = diffRemoteHostJson(dft, conn)
}
d.Conns = &conns
}
return d
}
func equalsRemoteHosts(v1, v2 []*RemoteHost) bool {
if len(v1) != len(v2) {
return false
}
for i := range v2 {
if v1[i].ID != v2[i].ID ||
v1[i].Address != v2[i].Address ||
v1[i].Transport != v2[i].Transport ||
v1[i].Synchronous != v2[i].Synchronous ||
v1[i].TLS != v2[i].TLS {
return false
}
}
return true
}
func equalsRPCConn(v1, v2 *RPCConn) bool {
return (v1 == nil && v2 == nil) ||
(v1 != nil && v2 != nil &&
v1.Strategy == v2.Strategy &&
v1.PoolSize == v2.PoolSize &&
equalsRemoteHosts(v1.Conns, v2.Conns))
}
type RPCConnsJson map[string]*RPCConnJson
func diffRPCConnsJson(d RPCConnsJson, v1, v2 RPCConns) RPCConnsJson {
if d == nil {
d = make(RPCConnsJson)
}
dft := NewDfltRPCConn()
for k, val := range v2 {
if !equalsRPCConn(v1[k], val) {
d[k] = diffRPCConnJson(d[k], dft, val)
}
}
return d
}