Add new options to trends configuration

- store_interval
 - ees_conns
 - ees_exporter_ids
This commit is contained in:
armirveliaj
2024-10-08 06:23:04 -04:00
committed by Dan Christian Bogos
parent d2d161fcce
commit 2a95c49d3b
4 changed files with 268 additions and 36 deletions

View File

@@ -1178,7 +1178,10 @@ const CGRATES_CFG_JSON = `
"enabled": false, // starts TrendS service: <true|false>.
"stats_conns": [], // connections to StatS ,empty to disable stats functionality: <""|*internal|$rpc_conns_id>
"thresholds_conns": [], // connections to ThresholdS ,empty to disable stats functionality: <""|*internal|$rpc_conns_id>
"scheduled_ids": {}
"scheduled_ids": {},
"store_interval": "",
"ees_conns": [],
"ees_exporter_ids": []
},
"rankings":{ // RankingS config

File diff suppressed because one or more lines are too long

View File

@@ -20,6 +20,7 @@ package config
import (
"slices"
"time"
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/utils"
@@ -30,6 +31,9 @@ type TrendSCfg struct {
StatSConns []string
ThresholdSConns []string
ScheduledIDs map[string][]string
StoreInterval time.Duration
EEsConns []string
EEsExporterIDs []string
}
func (t *TrendSCfg) Load(ctx *context.Context, jsnCfg ConfigDB, _ *CGRConfig) (err error) {
@@ -56,12 +60,25 @@ func (t *TrendSCfg) loadFromJSONCfg(jsnCfg *TrendSJsonCfg) (err error) {
if jsnCfg.Scheduled_ids != nil {
t.ScheduledIDs = jsnCfg.Scheduled_ids
}
if jsnCfg.Store_interval != nil {
if t.StoreInterval, err = utils.ParseDurationWithNanosecs(*jsnCfg.Store_interval); err != nil {
return
}
}
if jsnCfg.Ees_conns != nil {
t.EEsConns = updateInternalConns(*jsnCfg.Ees_conns, utils.MetaEEs)
}
if jsnCfg.Ees_exporter_ids != nil {
t.EEsExporterIDs = append(t.EEsExporterIDs, *jsnCfg.Ees_exporter_ids...)
}
return
}
func (t *TrendSCfg) AsMapInterface(string) any {
mp := map[string]any{
utils.EnabledCfg: t.Enabled,
utils.EnabledCfg: t.Enabled,
utils.StoreIntervalCfg: utils.EmptyString,
utils.EEsExporterIDsCfg: slices.Clone(t.EEsExporterIDs),
}
if t.StatSConns != nil {
mp[utils.StatSConnsCfg] = getInternalJSONConns(t.StatSConns)
@@ -73,6 +90,12 @@ func (t *TrendSCfg) AsMapInterface(string) any {
if t.ScheduledIDs != nil {
mp[utils.ScheduledIDsCfg] = t.ScheduledIDs
}
if t.StoreInterval != 0 {
mp[utils.StoreIntervalCfg] = t.StoreInterval.String()
}
if t.EEsConns != nil {
mp[utils.EEsConnsCfg] = getInternalJSONConns(t.EEsConns)
}
return mp
}
@@ -81,7 +104,8 @@ func (t TrendSCfg) CloneSection() Section { return t.Clone() }
func (t *TrendSCfg) Clone() (cln *TrendSCfg) {
cln = &TrendSCfg{
Enabled: t.Enabled,
Enabled: t.Enabled,
StoreInterval: t.StoreInterval,
}
if t.StatSConns != nil {
cln.StatSConns = slices.Clone(t.StatSConns)
@@ -95,6 +119,12 @@ func (t *TrendSCfg) Clone() (cln *TrendSCfg) {
cln.ScheduledIDs[key] = slices.Clone(value)
}
}
if t.EEsConns != nil {
cln.EEsConns = slices.Clone(t.EEsConns)
}
if t.EEsExporterIDs != nil {
cln.EEsExporterIDs = slices.Clone(t.EEsExporterIDs)
}
return
}
@@ -103,6 +133,9 @@ type TrendSJsonCfg struct {
Stats_conns *[]string
Thresholds_conns *[]string
Scheduled_ids map[string][]string
Store_interval *string
Ees_conns *[]string
Ees_exporter_ids *[]string
}
func diffTrendsJsonCfg(d *TrendSJsonCfg, v1, v2 *TrendSCfg) *TrendSJsonCfg {
@@ -118,6 +151,15 @@ func diffTrendsJsonCfg(d *TrendSJsonCfg, v1, v2 *TrendSCfg) *TrendSJsonCfg {
if !slices.Equal(v1.ThresholdSConns, v2.ThresholdSConns) {
d.Thresholds_conns = utils.SliceStringPointer(getInternalJSONConns(v2.ThresholdSConns))
}
if v1.StoreInterval != v2.StoreInterval {
d.Store_interval = utils.StringPointer(v2.StoreInterval.String())
}
if !slices.Equal(v1.EEsConns, v2.EEsConns) {
d.Ees_conns = utils.SliceStringPointer(getInternalJSONConns(v2.EEsConns))
}
if !slices.Equal(v1.EEsExporterIDs, v2.EEsExporterIDs) {
d.Ees_exporter_ids = &v2.EEsExporterIDs
}
d.Scheduled_ids = diffMapStringSlice(d.Scheduled_ids, v1.ScheduledIDs, v2.ScheduledIDs)
return d

View File

@@ -22,39 +22,12 @@ import (
"errors"
"reflect"
"testing"
"time"
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/utils"
)
func TestTrendSLoadFromJSONCfg(t *testing.T) {
trendCfg := &TrendSCfg{
Enabled: true,
StatSConns: []string{"connection1"},
ThresholdSConns: []string{"threshold1"},
ScheduledIDs: map[string][]string{"tenant1": {"id1"}},
}
err := trendCfg.loadFromJSONCfg(nil)
if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
if trendCfg.Enabled != true {
t.Errorf("Expected Enabled to be true, but got: %v", trendCfg.Enabled)
}
if len(trendCfg.StatSConns) != 1 || trendCfg.StatSConns[0] != "connection1" {
t.Errorf("Expected StatSConns to be unchanged, but got: %v", trendCfg.StatSConns)
}
if len(trendCfg.ThresholdSConns) != 1 || trendCfg.ThresholdSConns[0] != "threshold1" {
t.Errorf("Expected ThresholdSConns to be unchanged, but got: %v", trendCfg.ThresholdSConns)
}
if len(trendCfg.ScheduledIDs) != 1 || trendCfg.ScheduledIDs["tenant1"][0] != "id1" {
t.Errorf("Expected ScheduledIDs to be unchanged, but got: %v", trendCfg.ScheduledIDs)
}
}
func TestScheduledIDsDiffTrendSJsonCfg(t *testing.T) {
v1 := &TrendSCfg{
Enabled: true,
@@ -80,6 +53,134 @@ func TestScheduledIDsDiffTrendSJsonCfg(t *testing.T) {
}
}
func TestTrendSLoadFromJSONCfg_NilConfig(t *testing.T) {
trendCfg := &TrendSCfg{
Enabled: true,
StatSConns: []string{"connection1"},
ThresholdSConns: []string{"threshold1"},
ScheduledIDs: map[string][]string{"tenant1": {"id1"}},
StoreInterval: 10 * time.Second,
EEsConns: []string{"conn1"},
EEsExporterIDs: []string{"exporter1"},
}
err := trendCfg.loadFromJSONCfg(nil)
if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
}
func TestLoadFromJSONCfgStoreInterval(t *testing.T) {
validInterval := "30"
jsnCfgValid := &TrendSJsonCfg{
Store_interval: &validInterval,
}
trendCfg := &TrendSCfg{}
err := trendCfg.loadFromJSONCfg(jsnCfgValid)
if err != nil {
t.Errorf("Expected no error, got: %v", err)
}
if trendCfg.StoreInterval != 30*time.Nanosecond {
t.Errorf("Expected StoreInterval to be 30ns, but got: %v", trendCfg.StoreInterval)
}
invalidInterval := "invalid_duration"
jsnCfgInvalid := &TrendSJsonCfg{
Store_interval: &invalidInterval,
}
trendCfg = &TrendSCfg{}
err = trendCfg.loadFromJSONCfg(jsnCfgInvalid)
if err == nil {
t.Errorf("Expected an error, got none")
}
}
func TestTrendSLoadFromJSONCfgEesConns(t *testing.T) {
trendCfg := &TrendSCfg{
EEsConns: []string{"old_conn1", "old_conn2"},
}
jsnCfg := &TrendSJsonCfg{
Ees_conns: &[]string{"new_conn1", "new_conn2"},
}
err := trendCfg.loadFromJSONCfg(jsnCfg)
if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
expectedConns := []string{"new_conn1", "new_conn2"}
if len(trendCfg.EEsConns) != len(expectedConns) {
t.Errorf("Expected EEsConns length to be %d, but got: %d", len(expectedConns), len(trendCfg.EEsConns))
}
for i, conn := range expectedConns {
if trendCfg.EEsConns[i] != conn {
t.Errorf("Expected EEsConns[%d] to be %v, but got: %v", i, conn, trendCfg.EEsConns[i])
}
}
}
func TestTrendSLoadFromJSONCfgEesExporterIDs(t *testing.T) {
trendCfg := &TrendSCfg{
EEsExporterIDs: []string{"old_exporter1", "old_exporter2"},
}
jsnCfg := &TrendSJsonCfg{
Ees_exporter_ids: &[]string{"new_exporter1", "new_exporter2"},
}
err := trendCfg.loadFromJSONCfg(jsnCfg)
if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
expectedIDs := []string{"old_exporter1", "old_exporter2", "new_exporter1", "new_exporter2"}
if len(trendCfg.EEsExporterIDs) != len(expectedIDs) {
t.Errorf("Expected EEsExporterIDs length to be %d, but got: %d", len(expectedIDs), len(trendCfg.EEsExporterIDs))
}
for i, id := range expectedIDs {
if trendCfg.EEsExporterIDs[i] != id {
t.Errorf("Expected EEsExporterIDs[%d] to be %v, but got: %v", i, id, trendCfg.EEsExporterIDs[i])
}
}
}
func TestTrendSCfgAsMapInterface(t *testing.T) {
storeInterval := 10 * time.Second
eesExporterIDs := []string{"exporter1", "exporter2"}
statSConns := []string{"statConn1"}
thresholdSConns := []string{"thresholdConn1"}
scheduledIDs := map[string][]string{"tenant1": {"id1"}}
eesConns := []string{"eesConn1"}
trendCfg := TrendSCfg{
Enabled: true,
StatSConns: statSConns,
ThresholdSConns: thresholdSConns,
ScheduledIDs: scheduledIDs,
StoreInterval: storeInterval,
EEsConns: eesConns,
EEsExporterIDs: eesExporterIDs,
}
expectedMap := map[string]any{
utils.EnabledCfg: true,
utils.StoreIntervalCfg: storeInterval.String(),
utils.StatSConnsCfg: getInternalJSONConns(statSConns),
utils.ThresholdSConnsCfg: getInternalJSONConns(thresholdSConns),
utils.ScheduledIDsCfg: scheduledIDs,
utils.EEsConnsCfg: getInternalJSONConns(eesConns),
utils.EEsExporterIDsCfg: eesExporterIDs,
}
result := trendCfg.AsMapInterface("").(map[string]any)
if !reflect.DeepEqual(result, expectedMap) {
t.Errorf("Expected: %+v, got: %+v", expectedMap, result)
}
trendCfg.StoreInterval = 0
expectedMap[utils.StoreIntervalCfg] = utils.EmptyString
result = trendCfg.AsMapInterface("").(map[string]any)
if result[utils.StoreIntervalCfg] != utils.EmptyString {
t.Errorf("Expected StoreInterval to be '%s', but got: %v", utils.EmptyString, result[utils.StoreIntervalCfg])
}
}
func TestDiffTrendSJsonCfg(t *testing.T) {
v1 := &TrendSCfg{
Enabled: true,
@@ -167,14 +268,13 @@ func TestTrendSCfgClone(t *testing.T) {
StatSConns: []string{"conn1", "conn2"},
ThresholdSConns: []string{"thresh1", "thresh2"},
ScheduledIDs: map[string][]string{"tenant1": {"id1", "id2"}, "tenant2": {"id3"}},
StoreInterval: 30 * time.Second,
EEsConns: []string{"eeconn1", "eeconn2"},
EEsExporterIDs: []string{"exporter1", "exporter2"},
}
cloned := original.Clone()
if cloned == original {
t.Error("Clone should return a different instance, but got the same")
}
if cloned.Enabled != original.Enabled {
t.Errorf("Enabled field mismatch: expected %v, got %v", original.Enabled, cloned.Enabled)
}
@@ -189,11 +289,23 @@ func TestTrendSCfgClone(t *testing.T) {
if !reflect.DeepEqual(cloned.ScheduledIDs, original.ScheduledIDs) {
t.Errorf("ScheduledIDs mismatch: expected %v, got %v", original.ScheduledIDs, cloned.ScheduledIDs)
}
if cloned.StoreInterval != original.StoreInterval {
t.Errorf("StoreInterval mismatch: expected %v, got %v", original.StoreInterval, cloned.StoreInterval)
}
if !reflect.DeepEqual(cloned.EEsConns, original.EEsConns) {
t.Errorf("EEsConns mismatch: expected %v, got %v", original.EEsConns, cloned.EEsConns)
}
if !reflect.DeepEqual(cloned.EEsExporterIDs, original.EEsExporterIDs) {
t.Errorf("EEsExporterIDs mismatch: expected %v, got %v", original.EEsExporterIDs, cloned.EEsExporterIDs)
}
cloned.Enabled = false
cloned.StatSConns[0] = "modified_conn"
cloned.ThresholdSConns[0] = "modified_thresh"
cloned.ScheduledIDs["tenant1"][0] = "modified_id"
cloned.StoreInterval = 45 * time.Second
cloned.EEsConns[0] = "modified_eeconn"
cloned.EEsExporterIDs[0] = "modified_exporter"
if cloned.Enabled == original.Enabled {
t.Error("Modifying cloned.Enabled should not affect original.Enabled")
@@ -207,6 +319,15 @@ func TestTrendSCfgClone(t *testing.T) {
if reflect.DeepEqual(cloned.ScheduledIDs, original.ScheduledIDs) {
t.Error("Modifying cloned.ScheduledIDs should not affect original.ScheduledIDs")
}
if cloned.StoreInterval == original.StoreInterval {
t.Error("Modifying cloned.StoreInterval should not affect original.StoreInterval")
}
if reflect.DeepEqual(cloned.EEsConns, original.EEsConns) {
t.Error("Modifying cloned.EEsConns should not affect original.EEsConns")
}
if reflect.DeepEqual(cloned.EEsExporterIDs, original.EEsExporterIDs) {
t.Error("Modifying cloned.EEsExporterIDs should not affect original.EEsExporterIDs")
}
}
func TestTrendSCfgCloneSection(t *testing.T) {
@@ -284,3 +405,69 @@ func TestTrendSCfgLoadError(t *testing.T) {
t.Errorf("expected error %v, got %v", expectedErr, err)
}
}
func TestDiffTrendsJsonCfgStoreInterval(t *testing.T) {
v1 := &TrendSCfg{
StoreInterval: 0,
}
v2 := &TrendSCfg{
StoreInterval: 2 * time.Second,
}
expected := &TrendSJsonCfg{
Store_interval: utils.StringPointer("2s"),
}
d := diffTrendsJsonCfg(nil, v1, v2)
if !reflect.DeepEqual(d.Store_interval, expected.Store_interval) {
t.Errorf("Store_interval mismatch. Got: %v, expected: %v", d.Store_interval, expected.Store_interval)
}
v2.StoreInterval = 0
expected.Store_interval = nil
d = diffTrendsJsonCfg(nil, v1, v2)
if d.Store_interval != nil {
t.Errorf("Expected Store_interval to be nil, but got: %v", d.Store_interval)
}
}
func TestDiffTrendsJsonCfgEEsConns(t *testing.T) {
v1 := &TrendSCfg{
EEsConns: []string{"conn1", "conn2"},
}
v2 := &TrendSCfg{
EEsConns: []string{"conn3", "conn4"},
}
expected := &TrendSJsonCfg{
Ees_conns: utils.SliceStringPointer(([]string{"conn3", "conn4"})),
}
d := diffTrendsJsonCfg(nil, v1, v2)
if !reflect.DeepEqual(d.Ees_conns, expected.Ees_conns) {
t.Errorf("Ees_conns mismatch. Got: %v, expected: %v", d.Ees_conns, expected.Ees_conns)
}
v2.EEsConns = []string{"conn1", "conn2"}
expected.Ees_conns = nil
d = diffTrendsJsonCfg(nil, v1, v2)
if d.Ees_conns != nil {
t.Errorf("Expected Ees_conns to be nil, but got: %v", d.Ees_conns)
}
}
func TestDiffTrendsJsonCfgEEsExporterIDs(t *testing.T) {
v1 := &TrendSCfg{
EEsExporterIDs: []string{"exporter1", "exporter2"},
}
v2 := &TrendSCfg{
EEsExporterIDs: []string{"exporter3", "exporter4"},
}
expected := &TrendSJsonCfg{
Ees_exporter_ids: &[]string{"exporter3", "exporter4"},
}
d := diffTrendsJsonCfg(nil, v1, v2)
if !reflect.DeepEqual(d.Ees_exporter_ids, expected.Ees_exporter_ids) {
t.Errorf("Ees_exporter_ids mismatch. Got: %v, expected: %v", d.Ees_exporter_ids, expected.Ees_exporter_ids)
}
v2.EEsExporterIDs = []string{"exporter1", "exporter2"}
expected.Ees_exporter_ids = nil
d = diffTrendsJsonCfg(nil, v1, v2)
if d.Ees_exporter_ids != nil {
t.Errorf("Expected Ees_exporter_ids to be nil, but got: %v", d.Ees_exporter_ids)
}
}