diff --git a/config/configsanity_test.go b/config/configsanity_test.go index cb4e63546..56cb71ea9 100644 --- a/config/configsanity_test.go +++ b/config/configsanity_test.go @@ -1031,12 +1031,12 @@ func TestConfigSanityStatS(t *testing.T) { Enabled: true, ThresholdSConns: []string{utils.MetaInternal}, } - expected := " not enabled but requested by component" + expected := " not enabled but requested by component" if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected { t.Errorf("Expecting: %+q received: %+q", expected, err) } cfg.statsCfg.ThresholdSConns = []string{"test"} - expected = " connection with id: not defined" + expected = " connection with id: not defined" if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected { t.Errorf("Expecting: %+q received: %+q", expected, err) } @@ -1619,7 +1619,7 @@ func TestConfigSanityDataDB(t *testing.T) { cfg.resourceSCfg.Enabled = false cfg.statsCfg.Enabled = true - expected = " the StoreInterval field needs to be -1 when DataBD is *internal, received : 0" + expected = " the StoreInterval field needs to be -1 when DataBD is *internal, received : 0" if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected { t.Errorf("Expecting: %+q received: %+q", expected, err) } @@ -1749,7 +1749,7 @@ func TestConfigSanityFilterS(t *testing.T) { cfg = NewDefaultCGRConfig() cfg.filterSCfg.StatSConns = []string{utils.MetaInternal} - if err := cfg.checkConfigSanity(); err == nil || err.Error() != " not enabled but requested by component" { + if err := cfg.checkConfigSanity(); err == nil || err.Error() != " not enabled but requested by component" { t.Error(err) } cfg.filterSCfg.StatSConns = []string{"test"} diff --git a/engine/libengine.go b/engine/libengine.go index 8690ee0b4..a4dbaa87e 100644 --- a/engine/libengine.go +++ b/engine/libengine.go @@ -19,6 +19,7 @@ along with this program. If not, see package engine import ( + "errors" "fmt" "reflect" "strings" @@ -137,6 +138,7 @@ func NewServiceWithName(val interface{}, name string, useName bool) (_ IntServic if srv, err = birpc.NewService(val, name, useName); err != nil { return } + srv.Methods["Ping"] = pingM s := IntService{srv.Name: srv} for m, v := range srv.Methods { m = strings.TrimPrefix(m, "BiRPC") @@ -174,6 +176,7 @@ func NewDispatcherService(val interface{}) (_ IntService, err error) { if srv, err = birpc.NewService(val, utils.EmptyString, false); err != nil { return } + srv.Methods["Ping"] = pingM s := IntService{srv.Name: srv} for m, v := range srv.Methods { key := srv.Name @@ -226,11 +229,16 @@ func NewDispatcherService(val interface{}) (_ IntService, err error) { case strings.HasPrefix(m, utils.CDRs): m = strings.TrimPrefix(m, utils.CDRs) key = utils.CDRs - - case len(m) < 2 || m[0] != 'V': + } + if len(m) < 2 || unicode.ToLower(rune(m[0])) != 'v' { continue } - key += "v" + string(m[1]) + if unicode.IsLower(rune(key[len(key)-1])) { + key += "V" + } else { + key += "v" + } + key += string(m[1]) srv2, has := s[key] if !has { srv2 = new(birpc.Service) @@ -247,8 +255,12 @@ func NewDispatcherService(val interface{}) (_ IntService, err error) { type IntService map[string]*birpc.Service -func (s IntService) Call(ctx *context.Context, method string, args, reply interface{}) error { - return s[strings.Split(method, utils.NestingSep)[0]].Call(ctx, method, args, reply) +func (s IntService) Call(ctx *context.Context, serviceMethod string, args, reply interface{}) error { + service, has := s[strings.Split(serviceMethod, utils.NestingSep)[0]] + if !has { + return errors.New("rpc: can't find service " + serviceMethod) + } + return service.Call(ctx, serviceMethod, args, reply) } func ping(_ interface{}, _ *context.Context, _ *utils.CGREvent, reply *string) error { diff --git a/engine/libengine_test.go b/engine/libengine_test.go index 618a955df..017567197 100644 --- a/engine/libengine_test.go +++ b/engine/libengine_test.go @@ -20,6 +20,7 @@ package engine import ( "reflect" + "sort" "testing" "time" @@ -109,3 +110,133 @@ func TestLibengineNewRPCConnectionInternal(t *testing.T) { t.Error("Connections don't match") } } + +type TestRPCSrvMock struct{} // exported for service + +func (TestRPCSrvMock) Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCSrvMock) V1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCSrvMock) V2Do(*context.Context, interface{}, *string) error { return nil } + +type TestRPCSrvMockS struct{} // exported for service + +func (TestRPCSrvMockS) Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCSrvMockS) V1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCSrvMockS) V2Do(*context.Context, interface{}, *string) error { return nil } + +func getMethods(s IntService) (methods map[string][]string) { + methods = map[string][]string{} + for _, v := range s { + for m := range v.Methods { + methods[v.Name] = append(methods[v.Name], m) + } + } + for k := range methods { + sort.Strings(methods[k]) + } + return +} + +func TestIntServiceNewService(t *testing.T) { + expErrMsg := `rpc.Register: no service name for type struct {}` + if _, err := NewService(struct{}{}); err == nil || err.Error() != expErrMsg { + t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) + } + s, err := NewService(new(TestRPCSrvMock)) + if err != nil { + t.Fatal(err) + } + if len(s) != 3 { + t.Errorf("Not all rpc APIs were registerd") + } + methods := getMethods(s) + exp := map[string][]string{ + "TestRPCSrvMock": {"Do", "Ping", "V1Do", "V2Do"}, + "TestRPCSrvMockV1": {"Do", "Ping"}, + "TestRPCSrvMockV2": {"Do", "Ping"}, + } + if !reflect.DeepEqual(exp, methods) { + t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(methods)) + } + + s, err = NewService(new(TestRPCSrvMockS)) + if err != nil { + t.Fatal(err) + } + if len(s) != 3 { + t.Errorf("Not all rpc APIs were registerd") + } + methods = getMethods(s) + exp = map[string][]string{ + "TestRPCSrvMockS": {"Do", "Ping", "V1Do", "V2Do"}, + "TestRPCSrvMockSv1": {"Do", "Ping"}, + "TestRPCSrvMockSv2": {"Do", "Ping"}, + } + if !reflect.DeepEqual(exp, methods) { + t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(methods)) + } + + var rply string + if err := s.Call(context.Background(), "TestRPCSrvMockSv1.Ping", new(utils.CGREvent), &rply); err != nil { + t.Fatal(err) + } else if rply != utils.Pong { + t.Errorf("Expeceted: %q, received: %q", utils.Pong, rply) + } + + expErrMsg = `rpc: can't find service TestRPCSrvMockv1.Ping` + if err := s.Call(context.Background(), "TestRPCSrvMockv1.Ping", new(utils.CGREvent), &rply); err == nil || err.Error() != expErrMsg { + t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) + } + +} + +type TestRPCDspMock struct{} // exported for service + +func (TestRPCDspMock) AccountSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ActionSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) AttributeSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) CacheSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ChargerSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ConfigSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) DispatcherSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) GuardianSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) RateSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ReplicatorSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ResourceSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) RouteSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) SessionSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) StatSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) ThresholdSv1Do(*context.Context, interface{}, *string) error { return nil } +func (TestRPCDspMock) CDRsv1Do(*context.Context, interface{}, *string) error { return nil } +func TestIntServiceNewDispatcherService(t *testing.T) { + expErrMsg := `rpc.Register: no service name for type struct {}` + if _, err := NewDispatcherService(struct{}{}); err == nil || err.Error() != expErrMsg { + t.Errorf("Expeceted: %v, received: %v", expErrMsg, err) + } + + s, err := NewDispatcherService(new(TestRPCDspMock)) + if err != nil { + t.Fatal(err) + } + methods := getMethods(s) + exp := map[string][]string{ + "AccountSv1": {"Do", "Ping"}, + "ActionSv1": {"Do", "Ping"}, + "AttributeSv1": {"Do", "Ping"}, + "CDRsV1": {"Do", "Ping"}, + "CacheSv1": {"Do", "Ping"}, + "ChargerSv1": {"Do", "Ping"}, + "ConfigSv1": {"Do", "Ping"}, + "DispatcherSv1": {"Do", "Ping"}, + "GuardianSv1": {"Do", "Ping"}, + "RateSv1": {"Do", "Ping"}, + "ResourceSv1": {"Do", "Ping"}, + "RouteSv1": {"Do", "Ping"}, + "SessionSv1": {"Do", "Ping"}, + "StatSv1": {"Do", "Ping"}, + "TestRPCDspMock": {"AccountSv1Do", "ActionSv1Do", "AttributeSv1Do", "CDRsv1Do", "CacheSv1Do", "ChargerSv1Do", "ConfigSv1Do", "DispatcherSv1Do", "GuardianSv1Do", "Ping", "RateSv1Do", "ReplicatorSv1Do", "ResourceSv1Do", "RouteSv1Do", "SessionSv1Do", "StatSv1Do", "ThresholdSv1Do"}, + "ThresholdSv1": {"Do", "Ping"}, + } + if !reflect.DeepEqual(exp, methods) { + t.Errorf("Expeceted: %v, received: %v", utils.ToJSON(exp), utils.ToJSON(methods)) + } +} diff --git a/engine/version.go b/engine/version.go index a380ac3be..76339c0fc 100644 --- a/engine/version.go +++ b/engine/version.go @@ -137,7 +137,7 @@ func (vers Versions) Compare(curent Versions, storType string, isDataDB bool) st // CurrentDataDBVersions returns the needed DataDB versions func CurrentDataDBVersions() Versions { return Versions{ - utils.StatS: 4, + utils.Stats: 4, utils.Accounts: 3, utils.Actions: 2, utils.Thresholds: 4, diff --git a/engine/version_test.go b/engine/version_test.go index 7b5616230..2d2dc4a0d 100644 --- a/engine/version_test.go +++ b/engine/version_test.go @@ -72,7 +72,7 @@ func TestVersionCompare(t *testing.T) { func TestCurrentDBVersions(t *testing.T) { expVersDataDB := Versions{ - utils.StatS: 4, utils.Accounts: 3, utils.Actions: 2, + utils.Stats: 4, utils.Accounts: 3, utils.Actions: 2, utils.Thresholds: 4, utils.Routes: 2, utils.Attributes: 7, utils.RQF: 5, utils.Resource: 1, utils.Subscribers: 1, diff --git a/engine/z_versions_it_test.go b/engine/z_versions_it_test.go index 5435eb570..adf37c153 100644 --- a/engine/z_versions_it_test.go +++ b/engine/z_versions_it_test.go @@ -404,7 +404,7 @@ func testUpdateVersionsRoutes(t *testing.T) { func testUpdateVersionsStats(t *testing.T) { newVersions := CurrentDataDBVersions() - newVersions[utils.StatS] = 3 + newVersions[utils.Stats] = 3 if err := dm3.DataDB().SetVersions(newVersions, true); err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 574cfdbb0..5e68928b2 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/cenkalti/rpc2 v0.0.0-20210220005819-4a29bc83afe1 github.com/cgrates/aringo v0.0.0-20201113143849-3b299e4e636d github.com/cgrates/baningo v0.0.0-20210413080722-004ffd5e429f - github.com/cgrates/birpc v1.3.1-0.20210517105830-c9cc855bcec5 + github.com/cgrates/birpc v1.3.1-0.20211117095917-5b0ff29f3084 github.com/cgrates/cron v0.0.0-20201022095836-3522d5b72c70 github.com/cgrates/fsock v0.0.0-20191107070144-e7a331109df7 github.com/cgrates/kamevapi v0.0.0-20191001125829-7dbc3ad58817 diff --git a/go.sum b/go.sum index fa59f3201..6bc7f91c4 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/cgrates/aringo v0.0.0-20201113143849-3b299e4e636d/go.mod h1:mMAzSIjK1 github.com/cgrates/baningo v0.0.0-20210413080722-004ffd5e429f h1:dCp5BflGB8I8wlhWn4R5g0o4ok2pZRmcYHyzIks9Pbc= github.com/cgrates/baningo v0.0.0-20210413080722-004ffd5e429f/go.mod h1:3SwVROaS1Iml5lqEhj0gRhDRtmbBgypZpKcEkVTSleU= github.com/cgrates/birpc v1.3.1-0.20210413080448-f81834a37fd3/go.mod h1:z/PmNnDPqSQALedKJv5T8+eXIq6XHa9J0St1YsvAVns= -github.com/cgrates/birpc v1.3.1-0.20210517105830-c9cc855bcec5 h1:Pn9VGy13xCMm3zW5QaUCoIa3dsPbTIajgnCt4rcXJ2w= -github.com/cgrates/birpc v1.3.1-0.20210517105830-c9cc855bcec5/go.mod h1:z/PmNnDPqSQALedKJv5T8+eXIq6XHa9J0St1YsvAVns= +github.com/cgrates/birpc v1.3.1-0.20211117095917-5b0ff29f3084 h1:YIEepjEOjeHaFrewWaar/JkXYiDgO7gRw/R1zWITxEw= +github.com/cgrates/birpc v1.3.1-0.20211117095917-5b0ff29f3084/go.mod h1:z/PmNnDPqSQALedKJv5T8+eXIq6XHa9J0St1YsvAVns= github.com/cgrates/cron v0.0.0-20201022095836-3522d5b72c70 h1:/O+Dr12jcizDiCoIG2oK6wyE1pNRVQc62Wz+TfPWDhU= github.com/cgrates/cron v0.0.0-20201022095836-3522d5b72c70/go.mod h1:I9cUDn/uzkakr0hmYTjXkQqf6wagg44L2p01gSYRRz0= github.com/cgrates/fsock v0.0.0-20191107070144-e7a331109df7 h1:dxtBWRAr62vRRKkExmJZ0u1EbCw/y0vOkSfdFND5qXw= diff --git a/migrator/stats.go b/migrator/stats.go index 8422e1486..40e04bd03 100644 --- a/migrator/stats.go +++ b/migrator/stats.go @@ -92,7 +92,7 @@ func (m *Migrator) migrateCurrentStats() (err error) { if err := m.dmIN.DataManager().RemoveStatQueueProfile(context.TODO(), tntID[0], tntID[1], false); err != nil { return err } - m.stats[utils.StatS]++ + m.stats[utils.Stats]++ } return } @@ -141,7 +141,7 @@ func (m *Migrator) migrateV2Stats(v2Stats *engine.StatQueue) (v3Stats *engine.St func (m *Migrator) migrateStats() (err error) { var vrs engine.Versions current := engine.CurrentDataDBVersions() - if vrs, err = m.getVersions(utils.StatS); err != nil { + if vrs, err = m.getVersions(utils.Stats); err != nil { return } migrated := true @@ -151,12 +151,12 @@ func (m *Migrator) migrateStats() (err error) { var v2Stats *engine.StatQueue var v3Stats *engine.StatQueue for { - version := vrs[utils.StatS] + version := vrs[utils.Stats] for { switch version { default: return fmt.Errorf("Unsupported version %v", version) - case current[utils.StatS]: + case current[utils.Stats]: migrated = false if m.sameDataDB { break @@ -187,7 +187,7 @@ func (m *Migrator) migrateStats() (err error) { } version = 4 } - if version == current[utils.StatS] || err == utils.ErrNoMoreData { + if version == current[utils.Stats] || err == utils.ErrNoMoreData { break } } @@ -195,7 +195,7 @@ func (m *Migrator) migrateStats() (err error) { break } if !m.dryRun { - if vrs[utils.StatS] == 1 { + if vrs[utils.Stats] == 1 { if err = m.dmOut.DataManager().SetFilter(context.TODO(), filter, true); err != nil { return } @@ -210,7 +210,7 @@ func (m *Migrator) migrateStats() (err error) { } } } - m.stats[utils.StatS]++ + m.stats[utils.Stats]++ } if m.dryRun || !migrated { return nil @@ -218,7 +218,7 @@ func (m *Migrator) migrateStats() (err error) { // call the remove function here // All done, update version wtih current one - if err = m.setVersions(utils.StatS); err != nil { + if err = m.setVersions(utils.Stats); err != nil { return err } return m.ensureIndexesDataDB(engine.ColSqs) diff --git a/migrator/stats_it_test.go b/migrator/stats_it_test.go index e89e0bf9c..059ec39d3 100644 --- a/migrator/stats_it_test.go +++ b/migrator/stats_it_test.go @@ -376,7 +376,7 @@ func testStsITMigrateFromv1(t *testing.T) { t.Error("Error when setting v1Stat ", err.Error()) } - if err := stsMigrator.dmIN.DataManager().DataDB().SetVersions(engine.Versions{utils.StatS: 1}, true); err != nil { + if err := stsMigrator.dmIN.DataManager().DataDB().SetVersions(engine.Versions{utils.Stats: 1}, true); err != nil { t.Errorf("error: <%s> when updating Stats version into dataDB", err.Error()) } @@ -384,10 +384,10 @@ func testStsITMigrateFromv1(t *testing.T) { t.Error(err) } - if vrs, err := stsMigrator.dmOut.DataManager().DataDB().GetVersions(utils.StatS); err != nil { + if vrs, err := stsMigrator.dmOut.DataManager().DataDB().GetVersions(utils.Stats); err != nil { t.Errorf("error: <%s> when updating Stats version into dataDB", err.Error()) - } else if vrs[utils.StatS] != 4 { - t.Errorf("Expecting: 4, received: %+v", vrs[utils.StatS]) + } else if vrs[utils.Stats] != 4 { + t.Errorf("Expecting: 4, received: %+v", vrs[utils.Stats]) } //from V1 to V2 diff --git a/services/datadb_it_test.go b/services/datadb_it_test.go index 9495e2ae6..21de54063 100644 --- a/services/datadb_it_test.go +++ b/services/datadb_it_test.go @@ -163,7 +163,7 @@ func TestDataDBReloadBadType(t *testing.T) { }() err = dbConn.SetVersions(engine.Versions{ - utils.StatS: 4, + utils.Stats: 4, utils.Accounts: 3, utils.Actions: 2, utils.Thresholds: 4, @@ -309,7 +309,7 @@ func TestDataDBStartVersion(t *testing.T) { dbConn.Close() }() err = dbConn.SetVersions(engine.Versions{ - utils.StatS: 4, + utils.Stats: 4, utils.Accounts: 3, utils.Actions: 2, utils.Thresholds: 4, @@ -363,7 +363,7 @@ func TestDataDBReloadCastError(t *testing.T) { }() err = dbConn.SetVersions(engine.Versions{ - utils.StatS: 4, + utils.Stats: 4, utils.Accounts: 3, utils.Actions: 2, utils.Thresholds: 4, diff --git a/utils/consts.go b/utils/consts.go index 457c72881..f3adbed57 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -434,7 +434,7 @@ const ( Attributes = "Attributes" Chargers = "Chargers" Dispatchers = "Dispatchers" - StatS = "Stats" + StatS = "StatS" LoadIDsVrs = "LoadIDs" GlobalVarS = "GlobalVarS" CostSource = "CostSource"