diff --git a/actions/actions.go b/actions/actions.go deleted file mode 100644 index 2eb7e18fc..000000000 --- a/actions/actions.go +++ /dev/null @@ -1,305 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "context" - "fmt" - "sync" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/guardian" - "github.com/cgrates/cgrates/utils" - "github.com/cgrates/cron" -) - -// NewActionS instantiates the ActionS -func NewActionS(cfg *config.CGRConfig, fltrS *engine.FilterS, dm *engine.DataManager, connMgr *engine.ConnManager) (aS *ActionS) { - aS = &ActionS{ - cfg: cfg, - connMgr: connMgr, - fltrS: fltrS, - dm: dm, - crnLk: new(sync.RWMutex), - } - aS.schedInit() // initialize cron and schedule actions - return -} - -// ActionS manages exection of Actions -type ActionS struct { - cfg *config.CGRConfig - connMgr *engine.ConnManager - fltrS *engine.FilterS - dm *engine.DataManager - crn *cron.Cron - crnLk *sync.RWMutex -} - -// ListenAndServe keeps the service alive -func (aS *ActionS) ListenAndServe(stopChan, cfgRld chan struct{}) { - utils.Logger.Info(fmt.Sprintf("<%s> starting <%s>", - utils.CoreS, utils.ActionS)) - for { - select { - case <-stopChan: - return - case rld := <-cfgRld: // configuration was reloaded - cfgRld <- rld - } - } -} - -// Shutdown is called to shutdown the service -func (aS *ActionS) Shutdown() { - utils.Logger.Info(fmt.Sprintf("<%s> shutdown <%s>", utils.CoreS, utils.ActionS)) - aS.crnLk.RLock() - aS.crn.Stop() - aS.crnLk.RUnlock() -} - -// Call implements rpcclient.ClientConnector interface for internal RPC -func (aS *ActionS) Call(serviceMethod string, args interface{}, reply interface{}) error { - return utils.RPCCall(aS, serviceMethod, args, reply) -} - -// schedInit is called at service start -func (aS *ActionS) schedInit() { - utils.Logger.Info(fmt.Sprintf("<%s> initializing scheduler.", utils.ActionS)) - tnts := []string{aS.cfg.GeneralCfg().DefaultTenant} - if aS.cfg.ActionSCfg().Tenants != nil { - tnts = *aS.cfg.ActionSCfg().Tenants - } - cgrEvs := make([]*utils.CGREvent, len(tnts)) - for i, tnt := range tnts { - cgrEvs[i] = &utils.CGREvent{ - Tenant: tnt, - Time: utils.TimePointer(time.Now()), - APIOpts: map[string]interface{}{ - utils.EventType: utils.SchedulerInit, - utils.NodeID: aS.cfg.GeneralCfg().NodeID, - }, - } - } - aS.scheduleActions(cgrEvs, nil, true) -} - -// scheduleActions will set up cron and load the matching data -func (aS *ActionS) scheduleActions(cgrEvs []*utils.CGREvent, aPrflIDs []string, crnReset bool) (err error) { - aS.crnLk.Lock() // make sure we don't have parallel processes running setu - defer aS.crnLk.Unlock() - crn := aS.crn - if crnReset { - crn = cron.New() - } - var partExec bool - for _, cgrEv := range cgrEvs { - var schedActSet []*scheduledActs - if schedActSet, err = aS.scheduledActions(cgrEv.Tenant, cgrEv, aPrflIDs, false); err != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> scheduler init, ignoring tenant: <%s>, error: <%s>", - utils.ActionS, cgrEv.Tenant, err)) - partExec = true - continue - } - for _, sActs := range schedActSet { - if sActs.schedule == utils.MetaASAP { - go aS.asapExecuteActions(sActs) - continue - } - if _, err = crn.AddFunc(sActs.schedule, sActs.ScheduledExecute); err != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> scheduling ActionProfile with id: <%s:%s>, error: <%s>", - utils.ActionS, sActs.tenant, sActs.apID, err)) - partExec = true - continue - } - } - } - if partExec { - err = utils.ErrPartiallyExecuted - } - if crnReset { - if aS.crn != nil { - aS.crn.Stop() - } - aS.crn = crn - aS.crn.Start() - } - return -} - -// matchingActionProfilesForEvent returns the matched ActionProfiles for the given event -func (aS *ActionS) matchingActionProfilesForEvent(tnt string, - evNm utils.MapStorage, actTime *time.Time, aPrflIDs []string) (aPfs engine.ActionProfiles, err error) { - if len(aPrflIDs) == 0 { - var aPfIDMp utils.StringSet - if aPfIDMp, err = engine.MatchingItemIDsForEvent( - evNm, - aS.cfg.ActionSCfg().StringIndexedFields, - aS.cfg.ActionSCfg().PrefixIndexedFields, - aS.cfg.ActionSCfg().SuffixIndexedFields, - aS.dm, - utils.CacheActionProfilesFilterIndexes, - tnt, - aS.cfg.ActionSCfg().IndexedSelects, - aS.cfg.ActionSCfg().NestedFields, - ); err != nil { - return - } - aPrflIDs = aPfIDMp.AsSlice() - } - for _, aPfID := range aPrflIDs { - var aPf *engine.ActionProfile - if aPf, err = aS.dm.GetActionProfile(tnt, aPfID, - true, true, utils.NonTransactional); err != nil { - if err == utils.ErrNotFound { - err = nil - continue - } - return - } - if aPf.ActivationInterval != nil && actTime != nil && - !aPf.ActivationInterval.IsActiveAtTime(*actTime) { // not active - continue - } - var pass bool - if pass, err = aS.fltrS.Pass(tnt, aPf.FilterIDs, evNm); err != nil { - return - } else if !pass { - continue - } - aPfs = append(aPfs, aPf) - } - if len(aPfs) == 0 { - return nil, utils.ErrNotFound - } - aPfs.Sort() - return -} - -// scheduledActions is responsible for scheduling the action profiles matching cgrEv -func (aS *ActionS) scheduledActions(tnt string, cgrEv *utils.CGREvent, aPrflIDs []string, - forceASAP bool) (schedActs []*scheduledActs, err error) { - var aPfs engine.ActionProfiles - evNm := utils.MapStorage{ - utils.MetaReq: cgrEv.Event, - utils.MetaOpts: cgrEv.APIOpts, - } - if aPfs, err = aS.matchingActionProfilesForEvent(tnt, evNm, cgrEv.Time, aPrflIDs); err != nil { - return - } - - for _, aPf := range aPfs { - ctx := context.Background() - trgActs := map[string][]actioner{} // build here the list of actioners based on the trgKey - var partExec bool - for _, aCfg := range aPf.Actions { // create actioners and attach them to the right target - if act, errAct := newActioner(aS.cfg, aS.fltrS, aS.dm, aS.connMgr, aCfg, tnt); errAct != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> ignoring ActionProfile with id: <%s:%s> creating action: <%s>, error: <%s>", - utils.ActionS, aPf.Tenant, aPf.ID, aCfg.ID, errAct)) - partExec = true - break - } else { - trgTyp := actionTarget(aCfg.Type) - trgActs[trgTyp] = append(trgActs[trgTyp], act) - } - } - if partExec { - continue // skip this profile from processing further - } - for trg, acts := range trgActs { - if trg == utils.MetaNone { // only one scheduledActs set - schedActs = append(schedActs, newScheduledActs(ctx, aPf.Tenant, aPf.ID, trg, utils.EmptyString, aPf.Schedule, - evNm, acts)) - continue - } - for trgID := range aPf.Targets[trg] { - schedActs = append(schedActs, newScheduledActs(ctx, aPf.Tenant, aPf.ID, trg, trgID, aPf.Schedule, - evNm, acts)) - } - } - } - return -} - -// asapExecuteActions executes the scheduledActs and removes the executed from database -// uses locks to avoid concurrent access -func (aS *ActionS) asapExecuteActions(sActs *scheduledActs) (err error) { - _, err = guardian.Guardian.Guard(func() (gRes interface{}, gErr error) { - var ap *engine.ActionProfile - if ap, gErr = aS.dm.GetActionProfile(sActs.tenant, sActs.apID, true, true, utils.NonTransactional); gErr != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> querying ActionProfile with id: <%s:%s>, error: <%s>", - utils.ActionS, sActs.tenant, sActs.apID, err)) - return - } - if gErr = sActs.Execute(); gErr != nil { // cannot remove due to errors on execution - return - } - delete(ap.Targets[sActs.trgTyp], sActs.trgID) - if gErr = aS.dm.SetActionProfile(ap, true); gErr != nil { - utils.Logger.Warning( - fmt.Sprintf( - "<%s> saving ActionProfile with id: <%s:%s>, error: <%s>", - utils.ActionS, sActs.tenant, sActs.apID, err)) - } - return - }, aS.cfg.GeneralCfg().LockingTimeout, utils.ActionProfilePrefix+sActs.apID) - return -} - -// V1ScheduleActions will be called to schedule actions matching the arguments -func (aS *ActionS) V1ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { - if err = aS.scheduleActions([]*utils.CGREvent{args.CGREvent}, - args.ActionProfileIDs, false); err != nil { - return - } - *rpl = utils.OK - return -} - -// V1ExecuteActions will be called to execute ASAP action profiles, ignoring their Schedule field -func (aS *ActionS) V1ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { - var schedActSet []*scheduledActs - if schedActSet, err = aS.scheduledActions(args.CGREvent.Tenant, - args.CGREvent, args.ActionProfileIDs, true); err != nil { - return - } - var partExec bool - // execute the actions - for _, sActs := range schedActSet { - if err = aS.asapExecuteActions(sActs); err != nil { - partExec = true - } - } - if partExec { - err = utils.ErrPartiallyExecuted - return - } - *rpl = utils.OK - return -} diff --git a/actions/actions_test.go b/actions/actions_test.go deleted file mode 100644 index cbbddf7fa..000000000 --- a/actions/actions_test.go +++ /dev/null @@ -1,1052 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "bytes" - "context" - "fmt" - "log" - "os" - "reflect" - "strings" - "testing" - "time" - - "github.com/cgrates/cron" - - "github.com/cgrates/rpcclient" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -func TestMatchingActionProfilesForEvent(t *testing.T) { - defaultCfg := config.NewDefaultCGRConfig() - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - utils.MetaOpts: map[string]interface{}{}, - } - - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - - expActionPrf := engine.ActionProfiles{actPrf} - - if rcv, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Now()), []string{}); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, expActionPrf) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expActionPrf), utils.ToJSON(rcv)) - } - - evNM = utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - }, - utils.MetaOpts: map[string]interface{}{}, - } - //This Event is not matching with our filter - if _, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Now()), []string{}); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - evNM = utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "1001", - }, - utils.MetaOpts: map[string]interface{}{}, - } - actPrfIDs := []string{"inexisting_id"} - //Unable to get from database an ActionProfile if the ID won't match - if _, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Now()), actPrfIDs); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - actPrfIDs = []string{"test_id1"} - if _, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Now()), actPrfIDs); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - actPrf.ActivationInterval = &utils.ActivationInterval{ - ActivationTime: time.Date(2012, 7, 21, 0, 0, 0, 0, time.UTC), - ExpiryTime: time.Date(2012, 8, 21, 0, 0, 0, 0, time.UTC), - } - //this event is not active in this interval time - if _, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Date(2012, 6, 21, 0, 0, 0, 0, time.UTC)), actPrfIDs); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - actPrf.ActivationInterval = nil - - //when dataManager is nil, it won't be able to get ActionsProfile from database - acts.dm = nil - if _, err := acts.matchingActionProfilesForEvent("INVALID_TENANT", evNM, utils.TimePointer(time.Now()), actPrfIDs); err == nil || err != utils.ErrNoDatabaseConn { - t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err) - } - - acts.dm = engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - actPrf.FilterIDs = []string{"invalid_filters"} - //Set in database and invalid filter, so it won t pass - if err := acts.dm.SetActionProfile(actPrf, false); err != nil { - t.Error(err) - } - expected := "NOT_FOUND:invalid_filters" - if _, err := acts.matchingActionProfilesForEvent("cgrates.org", evNM, utils.TimePointer(time.Now()), actPrfIDs); err == nil || err.Error() != expected { - t.Errorf("Expected %+v, received %+v", expected, err) - } - - if err := acts.dm.RemoveActionProfile(actPrf.Tenant, actPrf.ID, utils.NonTransactional, false); err != nil { - t.Error(err) - } -} - -func TestScheduledActions(t *testing.T) { - defaultCfg := config.NewDefaultCGRConfig() - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - cgrEv := &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "TEST_ACTIONS1", - Event: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - } - evNM := utils.MapStorage{ - utils.MetaReq: cgrEv.Event, - utils.MetaOpts: map[string]interface{}{}, - } - - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - - if rcv, err := acts.scheduledActions(cgrEv.Tenant, cgrEv, []string{}, false); err != nil { - t.Error(err) - } else { - expSchedActs := newScheduledActs(context.Background(), cgrEv.Tenant, cgrEv.ID, utils.MetaNone, utils.EmptyString, - utils.EmptyString, evNM, rcv[0].acts) - if reflect.DeepEqual(expSchedActs, rcv) { - t.Errorf("Expected %+v, received %+v", expSchedActs, rcv) - } - } - - cgrEv = &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "TEST_ACTIONS1", - Event: map[string]interface{}{ - utils.Accounts: "10", - }, - } - if _, err := acts.scheduledActions(cgrEv.Tenant, cgrEv, []string{}, false); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } -} - -func TestScheduleAction(t *testing.T) { - defaultCfg := config.NewDefaultCGRConfig() - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - cgrEv := []*utils.CGREvent{ - { - Tenant: "cgrates.org", - ID: "TEST_ACTIONS1", - Event: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - }, - } - - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Schedule: "* * * * *", - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - - if err := acts.scheduleActions(cgrEv, []string{}, true); err != nil { - t.Error(err) - } - - //Cannot schedule an action if the ID is invalid - if err := acts.scheduleActions(cgrEv, []string{"INVALID_ID1"}, true); err == nil || err != utils.ErrPartiallyExecuted { - t.Errorf("Expected %+v, received %+v", utils.ErrPartiallyExecuted, err) - } - - //When schedule is "*asap", the action will execute immediately - actPrf.Schedule = utils.MetaASAP - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - if err := acts.scheduleActions(cgrEv, []string{}, true); err != nil { - t.Error(err) - } - - //Cannot execute the action if the cron is invalid - actPrf.Schedule = "* * * *" - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - if err := acts.scheduleActions(cgrEv, []string{}, true); err == nil || err != utils.ErrPartiallyExecuted { - t.Error(err) - } -} - -func TestAsapExecuteActions(t *testing.T) { - newData := &dataDBMockError{} - dm := engine.NewDataManager(newData, config.CgrConfig().CacheCfg(), nil) - defaultCfg := config.NewDefaultCGRConfig() - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - cgrEv := []*utils.CGREvent{ - { - Tenant: "cgrates.org", - ID: "CHANGED_ID", - Event: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - }, - } - - evNM := utils.MapStorage{ - utils.MetaReq: cgrEv[0].Event, - utils.MetaOpts: map[string]interface{}{}, - } - - expSchedActs := newScheduledActs(context.Background(), cgrEv[0].Tenant, cgrEv[0].ID, utils.MetaNone, utils.EmptyString, - utils.EmptyString, evNM, nil) - - if err := acts.asapExecuteActions(expSchedActs); err == nil || err != utils.ErrNoDatabaseConn { - t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err) - } - - data := engine.NewInternalDB(nil, nil, true) - acts.dm = engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - expSchedActs = newScheduledActs(context.Background(), cgrEv[0].Tenant, "another_id", utils.MetaNone, utils.EmptyString, - utils.EmptyString, evNM, nil) - if err := acts.asapExecuteActions(expSchedActs); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } -} - -func TestActionSListenAndServe(t *testing.T) { - newData := &dataDBMockError{} - dm := engine.NewDataManager(newData, config.CgrConfig().CacheCfg(), nil) - defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.ActionSCfg().Tenants = &[]string{"cgrates1.org", "cgrates.org2"} - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - stopChan := make(chan struct{}, 1) - cfgRld := make(chan struct{}, 1) - cfgRld <- struct{}{} - go func() { - time.Sleep(10) - stopChan <- struct{}{} - }() - var err error - utils.Logger, err = utils.Newlogger(utils.MetaStdLog, utils.EmptyString) - if err != nil { - t.Error(err) - } - utils.Logger.SetLogLevel(7) - buff := new(bytes.Buffer) - log.SetOutput(buff) - acts.ListenAndServe(stopChan, cfgRld) - expString := "CGRateS <> [INFO] starting " - if rcv := buff.String(); !strings.Contains(rcv, expString) { - t.Errorf("Expected %+v, received %+v", expString, rcv) - } - buff.Reset() -} - -func TestV1ScheduleActions(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - defaultCfg := config.NewDefaultCGRConfig() - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - var reply string - newArgs := &utils.ArgActionSv1ScheduleActions{ - ActionProfileIDs: []string{}, - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "test_id1", - Event: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - }, - } - - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Schedule: utils.MetaASAP, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - - if err := acts.V1ScheduleActions(newArgs, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Errorf("Unexpected reply %+v", reply) - } - - newArgs.ActionProfileIDs = []string{"invalid_id"} - if err := acts.V1ScheduleActions(newArgs, &reply); err == nil || err != utils.ErrPartiallyExecuted { - t.Errorf("Expected %+v, received %+v", utils.ErrPartiallyExecuted, err) - } - - if err := acts.dm.RemoveActionProfile(actPrf.Tenant, actPrf.ID, utils.NonTransactional, true); err != nil { - t.Error(err) - } -} - -func TestV1ExecuteActions(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - defaultCfg := config.NewDefaultCGRConfig() - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - - var reply string - newArgs := &utils.ArgActionSv1ScheduleActions{ - ActionProfileIDs: []string{}, - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "test_id1", - Event: map[string]interface{}{ - utils.AccountField: "1001", - utils.Destination: 1002, - }, - }, - } - - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Schedule: utils.MetaASAP, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - if err := acts.dm.SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - - if err := acts.V1ExecuteActions(newArgs, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Errorf("Unexpected reply %+v", reply) - } - - newArgs.ActionProfileIDs = []string{"invalid_id"} - if err := acts.V1ExecuteActions(newArgs, &reply); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - newData := &dataDBMockError{} - newDm := engine.NewDataManager(newData, config.CgrConfig().CacheCfg(), nil) - newActs := NewActionS(defaultCfg, filters, newDm, nil) - newArgs.ActionProfileIDs = []string{} - if err := newActs.V1ExecuteActions(newArgs, &reply); err == nil || err != utils.ErrPartiallyExecuted { - t.Errorf("Expected %+v, received %+v", utils.ErrPartiallyExecuted, err) - } - - if err := acts.dm.RemoveActionProfile(actPrf.Tenant, actPrf.ID, utils.NonTransactional, true); err != nil { - t.Error(err) - } -} - -func TestActionSCall(t *testing.T) { - acts := new(ActionS) - if err := acts.Call("UnsupportedServiceMethod", "args", "rply"); err == nil || err != rpcclient.ErrUnsupporteServiceMethod { - t.Errorf("Expected %+q, received %+q", rpcclient.ErrUnsupporteServiceMethod, err) - } -} - -func TestActionShutDown(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - defaultCfg := config.NewDefaultCGRConfig() - filters := engine.NewFilterS(defaultCfg, nil, dm) - acts := NewActionS(defaultCfg, filters, dm, nil) - acts.crn = &cron.Cron{} - - var err error - utils.Logger, err = utils.Newlogger(utils.MetaStdLog, utils.EmptyString) - if err != nil { - t.Error(err) - } - utils.Logger.SetLogLevel(7) - buff := new(bytes.Buffer) - log.SetOutput(buff) - - acts.Shutdown() - expBuff := "CGRateS <> [INFO] shutdown " - if rcv := buff.String(); !strings.Contains(rcv, expBuff) { - t.Errorf("Expected %+v, received %+v", expBuff, rcv) - } - - buff.Reset() -} - -type dataDBMockError struct { - *engine.DataDBMock -} - -func (dbM *dataDBMockError) GetActionProfileDrv(string, string) (*engine.ActionProfile, error) { - return &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "test_id1", - FilterIDs: []string{"*string:~*req.Account:1001|1002|1003", "*prefix:~*req.Destination:10"}, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - }, nil -} - -func (dbM *dataDBMockError) SetActionProfileDrv(*engine.ActionProfile) error { - return utils.ErrNoDatabaseConn -} - -func TestLogActionExecute(t *testing.T) { - output := new(bytes.Buffer) - log.SetOutput(output) - - loggertype := utils.MetaStdLog - id := "Engine1" - if newLogger, err := utils.Newlogger(loggertype, id); err != nil { - t.Error(err) - } else { - newLogger.SetLogLevel(7) - utils.Logger = newLogger - } - - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - }, - utils.MetaOpts: map[string]interface{}{}, - } - - logAction := actLog{} - if err := logAction.execute(nil, evNM, utils.MetaNone); err != nil { - t.Error(err) - } - - expected := "CGRateS [INFO] LOG Event: {\"*opts\":{},\"*req\":{\"Account\":\"10\"}}" - if rcv := output.String(); !strings.Contains(rcv, expected) { - t.Errorf("Expected %+v, received %+v", expected, rcv) - } - - log.SetOutput(os.Stderr) -} - -type testMockCDRsConn struct { - calls map[string]func(arg interface{}, rply interface{}) error -} - -func (s *testMockCDRsConn) Call(method string, arg interface{}, rply interface{}) error { - call, has := s.calls[method] - if !has { - return rpcclient.ErrUnsupporteServiceMethod - } - return call(arg, rply) -} - -func TestCDRLogActionExecute(t *testing.T) { - sMock := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.CDRsV1ProcessEvent: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*engine.ArgV1ProcessEvent) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if !reflect.DeepEqual(argConv.Flags, []string{utils.ConcatenatedKey(utils.MetaChargers, "false")}) { - return fmt.Errorf("Expected %+v, received %+v", []string{utils.ConcatenatedKey(utils.MetaChargers, "false")}, argConv.Flags) - } - if val, has := argConv.CGREvent.Event[utils.Subject]; !has { - return fmt.Errorf("missing Subject") - } else if strVal := utils.IfaceAsString(val); strVal != "10" { - return fmt.Errorf("Expected %+v, received %+v", "10", strVal) - } - if val, has := argConv.CGREvent.Event[utils.Cost]; !has { - return fmt.Errorf("missing Cost") - } else if strVal := utils.IfaceAsString(val); strVal != "0.15" { - return fmt.Errorf("Expected %+v, received %+v", "0.15", strVal) - } - if val, has := argConv.CGREvent.Event[utils.RequestType]; !has { - return fmt.Errorf("missing RequestType") - } else if strVal := utils.IfaceAsString(val); strVal != utils.MetaNone { - return fmt.Errorf("Expected %+v, received %+v", utils.MetaNone, strVal) - } - if val, has := argConv.CGREvent.Event[utils.RunID]; !has { - return fmt.Errorf("missing RunID") - } else if strVal := utils.IfaceAsString(val); strVal != utils.MetaTopUp { - return fmt.Errorf("Expected %+v, received %+v", utils.MetaNone, strVal) - } - return nil - }, - }, - } - internalCDRsChann := make(chan rpcclient.ClientConnector, 1) - internalCDRsChann <- sMock - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().CDRsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)} - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - filterS := engine.NewFilterS(cfg, nil, dm) - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs): internalCDRsChann, - }) - apA := &engine.APAction{ - ID: "ACT_CDRLOG", - Type: utils.MetaCdrLog, - } - cdrLogAction := &actCDRLog{ - config: cfg, - filterS: filterS, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - utils.Tenant: "cgrates.org", - utils.BalanceType: utils.MetaConcrete, - utils.Cost: 0.15, - utils.ActionType: utils.MetaTopUp, - }, - utils.MetaOpts: map[string]interface{}{}, - } - if err := cdrLogAction.execute(nil, evNM, utils.MetaNone); err != nil { - t.Error(err) - } -} - -func TestCDRLogActionWithOpts(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.CDRsV1ProcessEvent: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*engine.ArgV1ProcessEvent) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if !reflect.DeepEqual(argConv.Flags, []string{utils.ConcatenatedKey(utils.MetaChargers, "false")}) { - return fmt.Errorf("Expected %+v, received %+v", []string{utils.ConcatenatedKey(utils.MetaChargers, "false")}, argConv.Flags) - } - if val, has := argConv.CGREvent.Event[utils.Tenant]; !has { - return fmt.Errorf("missing Tenant") - } else if strVal := utils.IfaceAsString(val); strVal != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", strVal) - } - if val, has := argConv.CGREvent.APIOpts["EventFieldOpt"]; !has { - return fmt.Errorf("missing EventFieldOpt from Opts") - } else if strVal := utils.IfaceAsString(val); strVal != "eventValue" { - return fmt.Errorf("Expected %+v, received %+v", "eventValue", strVal) - } - if val, has := argConv.CGREvent.APIOpts["Option1"]; !has { - return fmt.Errorf("missing Option1 from Opts") - } else if strVal := utils.IfaceAsString(val); strVal != "Value1" { - return fmt.Errorf("Expected %+v, received %+v", "Value1", strVal) - } - if val, has := argConv.CGREvent.APIOpts["Option3"]; !has { - return fmt.Errorf("missing Option3 from Opts") - } else if strVal := utils.IfaceAsString(val); strVal != "eventValue" { - return fmt.Errorf("Expected %+v, received %+v", "eventValue", strVal) - } - return nil - }, - }, - } - internalCDRsChann := make(chan rpcclient.ClientConnector, 1) - internalCDRsChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().CDRsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)} - cfg.TemplatesCfg()["CustomTemplate"] = []*config.FCTemplate{ - { - Tag: "Tenant", - Type: "*constant", - Path: "*cdr.Tenant", - Value: config.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep), - Layout: time.RFC3339, - }, - { - Tag: "Opt1", - Type: "*constant", - Path: "*opts.Option1", - Value: config.NewRSRParsersMustCompile("Value1", utils.InfieldSep), - Layout: time.RFC3339, - }, - { - Tag: "Opt2", - Type: "*constant", - Path: "*opts.Option2", - Value: config.NewRSRParsersMustCompile("Value2", utils.InfieldSep), - Layout: time.RFC3339, - }, - { - Tag: "Opt3", - Type: "*variable", - Path: "*opts.Option3", - Value: config.NewRSRParsersMustCompile("~*opts.EventFieldOpt", utils.InfieldSep), - Layout: time.RFC3339, - }, - } - for _, tpl := range cfg.TemplatesCfg()["CustomTemplate"] { - tpl.ComputePath() - } - - data := engine.NewInternalDB(nil, nil, true) - dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - filterS := engine.NewFilterS(cfg, nil, dm) - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs): internalCDRsChann, - }) - apA := &engine.APAction{ - ID: "ACT_CDRLOG2", - Type: utils.MetaCdrLog, - Opts: map[string]interface{}{ - utils.MetaTemplateID: "CustomTemplate", - }, - } - cdrLogAction := &actCDRLog{ - config: cfg, - filterS: filterS, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - utils.Tenant: "cgrates.org", - utils.BalanceType: utils.MetaConcrete, - utils.Cost: 0.15, - utils.ActionType: utils.MetaTopUp, - }, - utils.MetaOpts: map[string]interface{}{ - "EventFieldOpt": "eventValue", - }, - } - if err := cdrLogAction.execute(nil, evNM, utils.MetaNone); err != nil { - t.Error(err) - } -} - -func TestExportAction(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.EeSv1ProcessEvent: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.CGREventWithEeIDs) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.CGREvent.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.CGREvent.Tenant) - } - return nil - }, - }, - } - internalCDRsChann := make(chan rpcclient.ClientConnector, 1) - internalCDRsChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().EEsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs): internalCDRsChann, - }) - apA := &engine.APAction{ - ID: "ACT_CDRLOG2", - Type: utils.MetaExport, - } - exportAction := &actExport{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - utils.Tenant: "cgrates.org", - utils.BalanceType: utils.MetaConcrete, - utils.Cost: 0.15, - utils.ActionType: utils.MetaTopUp, - }, - utils.MetaOpts: map[string]interface{}{ - "EventFieldOpt": "eventValue", - }, - } - if err := exportAction.execute(nil, evNM, utils.MetaNone); err != nil { - t.Error(err) - } -} - -func TestExportActionWithEeIDs(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.EeSv1ProcessEvent: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.CGREventWithEeIDs) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.CGREvent.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.CGREvent.Tenant) - } - if !reflect.DeepEqual(argConv.EeIDs, []string{"Exporter1", "Exporter2", "Exporter3"}) { - return fmt.Errorf("Expected %+v, received %+v", []string{"Exporter1", "Exporter2", "Exporter3"}, argConv.EeIDs) - } - return nil - }, - }, - } - internalCDRsChann := make(chan rpcclient.ClientConnector, 1) - internalCDRsChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().EEsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs): internalCDRsChann, - }) - apA := &engine.APAction{ - ID: "ACT_CDRLOG2", - Type: utils.MetaExport, - Opts: map[string]interface{}{ - utils.MetaExporterIDs: "Exporter1;Exporter2;Exporter3", - }, - } - exportAction := &actExport{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaReq: map[string]interface{}{ - utils.AccountField: "10", - utils.Tenant: "cgrates.org", - utils.BalanceType: utils.MetaConcrete, - utils.Cost: 0.15, - utils.ActionType: utils.MetaTopUp, - }, - utils.MetaOpts: map[string]interface{}{ - "EventFieldOpt": "eventValue", - }, - } - if err := exportAction.execute(nil, evNM, utils.MetaNone); err != nil { - t.Error(err) - } -} - -func TestExportActionResetThresholdStaticTenantID(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.ThresholdSv1ResetThreshold: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.TenantIDWithAPIOpts) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.Tenant) - } - if argConv.ID != "TH1" { - return fmt.Errorf("Expected %+v, received %+v", "TH1", argConv.ID) - } - return nil - }, - }, - } - internalChann := make(chan rpcclient.ClientConnector, 1) - internalChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalChann, - }) - apA := &engine.APAction{ - ID: "ACT_RESET_TH", - Type: utils.MetaResetThreshold, - Diktats: []*engine.APDiktat{{}}, - } - exportAction := &actResetThreshold{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaOpts: map[string]interface{}{}, - } - if err := exportAction.execute(nil, evNM, "cgrates.org:TH1"); err != nil { - t.Error(err) - } -} - -func TestExportActionResetThresholdStaticID(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.ThresholdSv1ResetThreshold: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.TenantIDWithAPIOpts) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.Tenant) - } - if argConv.ID != "TH1" { - return fmt.Errorf("Expected %+v, received %+v", "TH1", argConv.ID) - } - return nil - }, - }, - } - internalChann := make(chan rpcclient.ClientConnector, 1) - internalChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().ThresholdSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds): internalChann, - }) - apA := &engine.APAction{ - ID: "ACT_RESET_TH", - Type: utils.MetaResetThreshold, - Diktats: []*engine.APDiktat{{}}, - } - exportAction := &actResetThreshold{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaOpts: map[string]interface{}{}, - } - if err := exportAction.execute(nil, evNM, "TH1"); err != nil { - t.Error(err) - } -} - -func TestExportActionResetStatStaticTenantID(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.StatSv1ResetStatQueue: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.TenantIDWithAPIOpts) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.Tenant) - } - if argConv.ID != "ST1" { - return fmt.Errorf("Expected %+v, received %+v", "TH1", argConv.ID) - } - return nil - }, - }, - } - internalChann := make(chan rpcclient.ClientConnector, 1) - internalChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().StatSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalChann, - }) - apA := &engine.APAction{ - ID: "ACT_RESET_ST", - Type: utils.MetaResetStatQueue, - Diktats: []*engine.APDiktat{{}}, - } - exportAction := &actResetStat{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaOpts: map[string]interface{}{}, - } - if err := exportAction.execute(nil, evNM, "cgrates.org:ST1"); err != nil { - t.Error(err) - } -} - -func TestExportActionResetStatStaticID(t *testing.T) { - // Clear cache because connManager sets the internal connection in cache - engine.Cache.Clear([]string{utils.CacheRPCConnections}) - sMock2 := &testMockCDRsConn{ - calls: map[string]func(arg interface{}, rply interface{}) error{ - utils.StatSv1ResetStatQueue: func(arg interface{}, rply interface{}) error { - argConv, can := arg.(*utils.TenantIDWithAPIOpts) - if !can { - return fmt.Errorf("Wrong argument type: %T", arg) - } - if argConv.Tenant != "cgrates.org" { - return fmt.Errorf("Expected %+v, received %+v", "cgrates.org", argConv.Tenant) - } - if argConv.ID != "ST1" { - return fmt.Errorf("Expected %+v, received %+v", "TH1", argConv.ID) - } - return nil - }, - }, - } - internalChann := make(chan rpcclient.ClientConnector, 1) - internalChann <- sMock2 - cfg := config.NewDefaultCGRConfig() - cfg.ActionSCfg().StatSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)} - - connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalChann, - }) - apA := &engine.APAction{ - ID: "ACT_RESET_ST", - Type: utils.MetaResetStatQueue, - Diktats: []*engine.APDiktat{{ - Value: "ST1", - }}, - } - exportAction := &actResetStat{ - tnt: "cgrates.org", - config: cfg, - connMgr: connMgr, - aCfg: apA, - } - evNM := utils.MapStorage{ - utils.MetaOpts: map[string]interface{}{}, - } - if err := exportAction.execute(nil, evNM, "ST1"); err != nil { - t.Error(err) - } -} diff --git a/actions/export.go b/actions/export.go deleted file mode 100644 index c8c17b881..000000000 --- a/actions/export.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "strings" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -type actHTTPPost struct { - config *config.CGRConfig - aCfg *engine.APAction -} - -func (aL *actHTTPPost) id() string { - return aL.aCfg.ID -} - -func (aL *actHTTPPost) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actHTTPPost) execute(_ context.Context, data utils.MapStorage, _ string) (err error) { - var body []byte - if body, err = json.Marshal(data); err != nil { - return - } - var partExec bool - for _, actD := range aL.cfg().Diktats { - var pstr *engine.HTTPPoster - if pstr, err = engine.NewHTTPPoster(config.CgrConfig().GeneralCfg().ReplyTimeout, actD.Path, - utils.ContentJSON, aL.config.GeneralCfg().PosterAttempts); err != nil { - return - } - if async, has := aL.cfg().Opts[utils.MetaAsync]; has && utils.IfaceAsString(async) == utils.TrueStr { - go aL.post(pstr, body, actD.Path) - } else if err = aL.post(pstr, body, actD.Path); err != nil { - partExec = true - } - } - if partExec { - err = utils.ErrPartiallyExecuted - } - return -} - -func (aL *actHTTPPost) post(pstr *engine.HTTPPoster, body []byte, path string) (err error) { - if err = pstr.PostValues(body, make(http.Header)); err != nil { - utils.Logger.Warning(fmt.Sprintf("<%s> Failed posting event to: <%s> because: %s", utils.ActionS, path, err.Error())) - if aL.config.GeneralCfg().FailedPostsDir != utils.MetaNone { - engine.AddFailedPost(path, utils.MetaHTTPjson, utils.ActionsPoster+utils.HierarchySep+aL.cfg().Type, body, make(map[string]interface{})) - err = nil - } - } - return -} - -type actExport struct { - tnt string - config *config.CGRConfig - connMgr *engine.ConnManager - aCfg *engine.APAction -} - -func (aL *actExport) id() string { - return aL.aCfg.ID -} - -func (aL *actExport) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actExport) execute(_ context.Context, data utils.MapStorage, _ string) (err error) { - var exporterIDs []string - if expIDs, has := aL.cfg().Opts[utils.MetaExporterIDs]; has { - exporterIDs = strings.Split(utils.IfaceAsString(expIDs), utils.InfieldSep) - } - var rply map[string]map[string]interface{} - return aL.connMgr.Call(aL.config.ActionSCfg().EEsConns, nil, - utils.EeSv1ProcessEvent, &utils.CGREventWithEeIDs{ - EeIDs: exporterIDs, - CGREvent: &utils.CGREvent{ - Tenant: aL.tnt, - Time: utils.TimePointer(time.Now()), - ID: utils.GenUUID(), - Event: data[utils.MetaReq].(map[string]interface{}), - APIOpts: data[utils.MetaOpts].(map[string]interface{}), - }, - }, &rply) -} diff --git a/actions/libactions.go b/actions/libactions.go deleted file mode 100644 index 4b497cccb..000000000 --- a/actions/libactions.go +++ /dev/null @@ -1,146 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "context" - "fmt" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" - "github.com/cgrates/ltcache" -) - -// actionTarget returns the target attached to an action -func actionTarget(act string) string { - switch act { - case utils.MetaResetStatQueue: - return utils.MetaStats - case utils.MetaResetThreshold: - return utils.MetaThresholds - case utils.MetaAddBalance, utils.MetaSetBalance, utils.MetaRemBalance: - return utils.MetaAccounts - default: - return utils.MetaNone - } -} - -func newScheduledActs(ctx context.Context, tenant, apID, trgTyp, trgID, schedule string, - data utils.MapStorage, acts []actioner) (sActs *scheduledActs) { - return &scheduledActs{ - tenant: tenant, - apID: apID, - trgTyp: trgTyp, - trgID: trgID, - schedule: schedule, - ctx: ctx, - data: data, - acts: acts, - cch: ltcache.NewTransCache(map[string]*ltcache.CacheConfig{}), - } -} - -// scheduled is a set of actions which will be executed directly or by the cron.schedule -type scheduledActs struct { - tenant string - apID string - trgTyp string - trgID string - schedule string - ctx context.Context - data utils.MapStorage - acts []actioner - - cch *ltcache.TransCache // cache data between actions here -} - -// Execute is called when we want the ActionProfile to be executed -func (s *scheduledActs) ScheduledExecute() { - s.Execute() -} - -// Execute notifies possible errors on execution -func (s *scheduledActs) Execute() (err error) { - var partExec bool - for _, act := range s.acts { - //ctx, cancel := context.WithTimeout(s.ctx, act.cfg().TTL) - if err := act.execute(s.ctx, s.data, s.trgID); err != nil { - utils.Logger.Warning(fmt.Sprintf("executing action: <%s>, error: <%s>", act.id(), err)) - partExec = true - } - } - // postexec here - if partExec { - err = utils.ErrPartiallyExecuted - } - return -} - -// postExec will save data which was modified in actions and unlock guardian -func (s *scheduledActs) postExec() (err error) { - return -} - -// newActionersFromActions constructs multiple actioners out of APAction configurations -func newActionersFromActions(cfg *config.CGRConfig, fltrS *engine.FilterS, dm *engine.DataManager, - connMgr *engine.ConnManager, aCfgs []*engine.APAction, tnt string) (acts []actioner, err error) { - acts = make([]actioner, len(aCfgs)) - for i, aCfg := range aCfgs { - if acts[i], err = newActioner(cfg, fltrS, dm, connMgr, aCfg, tnt); err != nil { - return nil, err - } - } - return -} - -// newAction is the constructor to create actioner -func newActioner(cfg *config.CGRConfig, fltrS *engine.FilterS, dm *engine.DataManager, - connMgr *engine.ConnManager, aCfg *engine.APAction, tnt string) (act actioner, err error) { - switch aCfg.Type { - case utils.MetaLog: - return &actLog{aCfg}, nil - case utils.CDRLog: - return &actCDRLog{cfg, fltrS, connMgr, aCfg}, nil - case utils.MetaHTTPPost: - return &actHTTPPost{cfg, aCfg}, nil - case utils.MetaExport: - return &actExport{tnt, cfg, connMgr, aCfg}, nil - case utils.MetaResetStatQueue: - return &actResetStat{tnt, cfg, connMgr, aCfg}, nil - case utils.MetaResetThreshold: - return &actResetThreshold{tnt, cfg, connMgr, aCfg}, nil - case utils.MetaAddBalance: - return &actSetBalance{cfg, connMgr, aCfg, tnt, false}, nil - case utils.MetaSetBalance: - return &actSetBalance{cfg, connMgr, aCfg, tnt, true}, nil - case utils.MetaRemBalance: - return &actRemBalance{cfg, connMgr, aCfg, tnt}, nil - default: - return nil, fmt.Errorf("unsupported action type: <%s>", aCfg.Type) - - } -} - -// actioner is implemented by each action type -type actioner interface { - id() string - cfg() *engine.APAction - execute(ctx context.Context, data utils.MapStorage, trgID string) (err error) -} diff --git a/actions/log.go b/actions/log.go deleted file mode 100644 index 2a4dca0c1..000000000 --- a/actions/log.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "context" - "fmt" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -// actLogger will log data to CGRateS logger -type actLog struct { - aCfg *engine.APAction -} - -func (aL *actLog) id() string { - return aL.aCfg.ID -} - -func (aL *actLog) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (actLog) execute(_ context.Context, data utils.MapStorage, _ string) (err error) { - utils.Logger.Info(fmt.Sprintf("LOG Event: %s", data.String())) - return -} - -// actCDRLog will log data to CGRateS logger -type actCDRLog struct { - config *config.CGRConfig - filterS *engine.FilterS - connMgr *engine.ConnManager - aCfg *engine.APAction -} - -func (aL *actCDRLog) id() string { - return aL.aCfg.ID -} - -func (aL *actCDRLog) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actCDRLog) execute(_ context.Context, data utils.MapStorage, _ string) (err error) { - if len(aL.config.ActionSCfg().CDRsConns) == 0 { - return fmt.Errorf("no connection with CDR Server") - } - template := aL.config.TemplatesCfg()[utils.MetaCdrLog] - if id, has := aL.cfg().Opts[utils.MetaTemplateID]; has { // if templateID is not present we use default template - template = aL.config.TemplatesCfg()[utils.IfaceAsString(id)] - } - // split the data into Request and Opts to send as parameters to AgentRequest - reqNm := utils.MapStorage(data[utils.MetaReq].(map[string]interface{})).Clone() - optsMS := utils.MapStorage(data[utils.MetaOpts].(map[string]interface{})).Clone() - - oNm := map[string]*utils.OrderedNavigableMap{ - utils.MetaCDR: utils.NewOrderedNavigableMap(), - } - // construct an AgentRequest so we can build the reply and send it to CDRServer - cdrLogReq := engine.NewEventRequest(reqNm, nil, optsMS, nil, aL.config.GeneralCfg().DefaultTenant, - aL.config.GeneralCfg().DefaultTimezone, aL.filterS, oNm) - - if err = cdrLogReq.SetFields(template); err != nil { - return - } - var rply string - return aL.connMgr.Call(aL.config.ActionSCfg().CDRsConns, nil, - utils.CDRsV1ProcessEvent, - &engine.ArgV1ProcessEvent{ - Flags: []string{utils.ConcatenatedKey(utils.MetaChargers, utils.FalseStr)}, // do not try to get the chargers for cdrlog - CGREvent: *utils.NMAsCGREvent(cdrLogReq.OrdNavMP[utils.MetaCDR], cdrLogReq.Tenant, - utils.NestingSep, optsMS), - }, &rply) -} diff --git a/actions/reset.go b/actions/reset.go deleted file mode 100644 index e094ab365..000000000 --- a/actions/reset.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package actions - -import ( - "context" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -type actResetStat struct { - tnt string - config *config.CGRConfig - connMgr *engine.ConnManager - aCfg *engine.APAction -} - -func (aL *actResetStat) id() string { - return aL.aCfg.ID -} - -func (aL *actResetStat) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actResetStat) execute(_ context.Context, data utils.MapStorage, trgID string) (err error) { - args := &utils.TenantIDWithAPIOpts{ - TenantID: utils.NewTenantID(trgID), - APIOpts: data[utils.MetaOpts].(map[string]interface{}), - } - if args.Tenant == utils.EmptyString { // in case that user pass only ID we populate the tenant from the event - args.Tenant = aL.tnt - } - var rply string - return aL.connMgr.Call(aL.config.ActionSCfg().StatSConns, nil, - utils.StatSv1ResetStatQueue, args, &rply) -} - -type actResetThreshold struct { - tnt string - config *config.CGRConfig - connMgr *engine.ConnManager - aCfg *engine.APAction -} - -func (aL *actResetThreshold) id() string { - return aL.aCfg.ID -} - -func (aL *actResetThreshold) cfg() *engine.APAction { - return aL.aCfg -} - -// execute implements actioner interface -func (aL *actResetThreshold) execute(_ context.Context, data utils.MapStorage, trgID string) (err error) { - args := &utils.TenantIDWithAPIOpts{ - TenantID: utils.NewTenantID(trgID), - APIOpts: data[utils.MetaOpts].(map[string]interface{}), - } - if args.Tenant == utils.EmptyString { // in case that user pass only ID we populate the tenant from the event - args.Tenant = aL.tnt - } - var rply string - return aL.connMgr.Call(aL.config.ActionSCfg().ThresholdSConns, nil, - utils.ThresholdSv1ResetThreshold, args, &rply) -} diff --git a/apier/v1/actions.go b/apier/v1/actions.go deleted file mode 100644 index 0e9c5dc24..000000000 --- a/apier/v1/actions.go +++ /dev/null @@ -1,170 +0,0 @@ -/* -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 -*/ - -package v1 - -import ( - "time" - - "github.com/cgrates/cgrates/actions" - - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -// GetActionProfile returns an Action Profile -func (apierSv1 *APIerSv1) GetActionProfile(arg *utils.TenantIDWithAPIOpts, reply *engine.ActionProfile) error { - if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) - } - tnt := arg.Tenant - if tnt == utils.EmptyString { - tnt = apierSv1.Config.GeneralCfg().DefaultTenant - } - ap, err := apierSv1.DataManager.GetActionProfile(tnt, arg.ID, true, true, utils.NonTransactional) - if err != nil { - if err.Error() != utils.ErrNotFound.Error() { - err = utils.NewErrServerError(err) - } - return err - } - *reply = *ap - return nil -} - -// GetActionProfileIDs returns list of action profile IDs registered for a tenant -func (apierSv1 *APIerSv1) GetActionProfileIDs(args *utils.PaginatorWithTenant, actPrfIDs *[]string) error { - tnt := args.Tenant - if tnt == utils.EmptyString { - tnt = apierSv1.Config.GeneralCfg().DefaultTenant - } - prfx := utils.ActionProfilePrefix + tnt + utils.ConcatenatedKeySep - keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) - if err != nil { - return err - } - if len(keys) == 0 { - return utils.ErrNotFound - } - retIDs := make([]string, len(keys)) - for i, key := range keys { - retIDs[i] = key[len(prfx):] - } - *actPrfIDs = args.PaginateStringSlice(retIDs) - return nil -} - -// GetActionProfileIDsCount sets in reply var the total number of ActionProfileIDs registered for a tenant -// returns ErrNotFound in case of 0 ActionProfileIDs -func (apierSv1 *APIerSv1) GetActionProfileIDsCount(args *utils.TenantWithAPIOpts, reply *int) (err error) { - tnt := args.Tenant - if tnt == utils.EmptyString { - tnt = apierSv1.Config.GeneralCfg().DefaultTenant - } - var keys []string - prfx := utils.ActionProfilePrefix + tnt + utils.ConcatenatedKeySep - if keys, err = apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx); err != nil { - return err - } - if len(keys) == 0 { - return utils.ErrNotFound - } - *reply = len(keys) - return -} - -//SetActionProfile add/update a new Action Profile -func (apierSv1 *APIerSv1) SetActionProfile(ap *engine.ActionProfileWithAPIOpts, reply *string) error { - if missing := utils.MissingStructFields(ap.ActionProfile, []string{utils.ID, utils.Actions}); len(missing) != 0 { - return utils.NewErrMandatoryIeMissing(missing...) - } - if ap.Tenant == utils.EmptyString { - ap.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant - } - - if err := apierSv1.DataManager.SetActionProfile(ap.ActionProfile, true); err != nil { - return utils.APIErrorHandler(err) - } - //generate a loadID for CacheActionProfiles and store it in database - if err := apierSv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheActionProfiles: time.Now().UnixNano()}); err != nil { - return utils.APIErrorHandler(err) - } - if err := apierSv1.CallCache(utils.IfaceAsString(ap.APIOpts[utils.CacheOpt]), ap.Tenant, utils.CacheActionProfiles, - ap.TenantID(), &ap.FilterIDs, nil, ap.APIOpts); err != nil { - return utils.APIErrorHandler(err) - } - *reply = utils.OK - return nil -} - -// RemoveActionProfile remove a specific Action Profile -func (apierSv1 *APIerSv1) RemoveActionProfile(arg *utils.TenantIDWithAPIOpts, reply *string) error { - if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) - } - tnt := arg.Tenant - if tnt == utils.EmptyString { - tnt = apierSv1.Config.GeneralCfg().DefaultTenant - } - if err := apierSv1.DataManager.RemoveActionProfile(tnt, arg.ID, - utils.NonTransactional, true); err != nil { - return utils.APIErrorHandler(err) - } - //generate a loadID for CacheActionProfiles and store it in database - if err := apierSv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheActionProfiles: time.Now().UnixNano()}); err != nil { - return utils.APIErrorHandler(err) - } - if err := apierSv1.CallCache(utils.IfaceAsString(arg.APIOpts[utils.CacheOpt]), tnt, utils.CacheActionProfiles, - utils.ConcatenatedKey(tnt, arg.ID), nil, nil, arg.APIOpts); err != nil { - return utils.APIErrorHandler(err) - } - *reply = utils.OK - return nil -} - -// NewActionSv1 initializes ActionSv1 -func NewActionSv1(aS *actions.ActionS) *ActionSv1 { - return &ActionSv1{aS: aS} -} - -// ActionSv1 exports RPC from RLs -type ActionSv1 struct { - aS *actions.ActionS -} - -// Call implements rpcclient.ClientConnector interface for internal RPC -func (aSv1 *ActionSv1) Call(serviceMethod string, - args interface{}, reply interface{}) error { - return utils.APIerRPCCall(aSv1, serviceMethod, args, reply) -} - -// Ping return pong if the service is active -func (aSv1 *ActionSv1) Ping(ign *utils.CGREvent, reply *string) error { - *reply = utils.Pong - return nil -} - -// ScheduleActions will be called to schedule actions matching the arguments -func (aSv1 *ActionSv1) ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { - return aSv1.aS.V1ScheduleActions(args, rpl) -} - -// ExecuteActions will be called to execute ASAP action profiles, ignoring their Schedule field -func (aSv1 *ActionSv1) ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { - return aSv1.aS.V1ExecuteActions(args, rpl) -} diff --git a/apier/v1/actions_it_test.go b/apier/v1/actions_it_test.go deleted file mode 100644 index 00372d5d9..000000000 --- a/apier/v1/actions_it_test.go +++ /dev/null @@ -1,398 +0,0 @@ -// +build integration - -/* -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 -*/ - -package v1 - -import ( - "net/rpc" - "path" - "reflect" - "testing" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - actPrfCfgPath string - actPrfCfg *config.CGRConfig - actSRPC *rpc.Client - actPrf *engine.ActionProfileWithAPIOpts - actPrfConfigDIR string //run tests for specific configuration - - sTestsActPrf = []func(t *testing.T){ - testActionSInitCfg, - testActionSInitDataDb, - testActionSResetStorDb, - testActionSStartEngine, - testActionSRPCConn, - testActionSLoadFromFolder, - testActionSGetActionProfile, - testActionSPing, - testActionSSettActionProfile, - testActionSGetActionProfileIDs, - testActionSGetActionProfileIDsCount, - testActionSUpdateActionProfile, - testActionSRemoveActionProfile, - testActionSKillEngine, - //cache test - testActionSInitCfg, - testActionSInitDataDb, - testActionSResetStorDb, - testActionSStartEngine, - testActionSRPCConn, - testActionSCacheTestGetNotFound, - testActionSCacheTestSet, - testActionSCacheTestGetNotFound, - testActionSCacheReload, - testActionSCacheTestGetFound, - testActionSKillEngine, - } -) - -//Test start here -func TestActionSIT(t *testing.T) { - switch *dbType { - case utils.MetaInternal: - actPrfConfigDIR = "tutinternal" - case utils.MetaMySQL: - actPrfConfigDIR = "tutmysql" - case utils.MetaMongo: - actPrfConfigDIR = "tutmongo" - case utils.MetaPostgres: - t.SkipNow() - default: - t.Fatal("Unknown Database type") - } - for _, stest := range sTestsActPrf { - t.Run(actPrfConfigDIR, stest) - } -} - -func testActionSInitCfg(t *testing.T) { - var err error - actPrfCfgPath = path.Join(*dataDir, "conf", "samples", actPrfConfigDIR) - actPrfCfg, err = config.NewCGRConfigFromPath(actPrfCfgPath) - if err != nil { - t.Error(err) - } -} - -func testActionSInitDataDb(t *testing.T) { - if err := engine.InitDataDb(actPrfCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func testActionSResetStorDb(t *testing.T) { - if err := engine.InitStorDb(actPrfCfg); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func testActionSStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(actPrfCfgPath, *waitRater); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func testActionSRPCConn(t *testing.T) { - var err error - actSRPC, err = newRPCClient(actPrfCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func testActionSLoadFromFolder(t *testing.T) { - var reply string - acts := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutactions")} - if err := actSRPC.Call(utils.APIerSv1LoadTariffPlanFromFolder, acts, &reply); err != nil { - t.Error(err) - } - time.Sleep(100 * time.Millisecond) -} - -func testActionSGetActionProfile(t *testing.T) { - expected := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - FilterIDs: []string{}, - Weight: 10, - Schedule: utils.MetaASAP, - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: {"1001": {}, "1002": {}}, - }, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestBalance.Units", - Value: "10", - }}, - }, - { - ID: "SET_BALANCE_TEST_DATA", - Type: "*set_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestDataBalance.Type", - Value: "*data", - }}, - }, - { - ID: "TOPUP_TEST_DATA", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestDataBalance.Units", - Value: "1024", - }}, - }, - { - ID: "SET_BALANCE_TEST_VOICE", - Type: "*set_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestVoiceBalance.Type", - Value: "*voice", - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestVoiceBalance.Units", - Value: "15m15s", - }}, - }, - { - ID: "SET_BALANCE_TEST_FILTERS", - Type: "*set_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestVoiceBalance.Filters", - Value: "*string:~*req.CustomField:500", - }}, - }, - { - ID: "TOPUP_REM_VOICE", - Type: "*rem_balance", - Diktats: []*engine.APDiktat{{ - Path: "TestVoiceBalance2", - }}, - }, - }, - } - if *encoding == utils.MetaGOB { - expected.FilterIDs = nil - for i := range expected.Actions { - expected.Actions[i].FilterIDs = nil - } - } - var reply *engine.ActionProfile - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}}, &reply); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(expected, reply) { - t.Errorf("Expecting : %+v \n received: %+v", utils.ToJSON(expected), utils.ToJSON(reply)) - } -} - -func testActionSPing(t *testing.T) { - var resp string - if err := actSRPC.Call(utils.ActionSv1Ping, new(utils.CGREvent), &resp); err != nil { - t.Error(err) - } else if resp != utils.Pong { - t.Error("Unexpected reply returned", resp) - } -} - -func testActionSSettActionProfile(t *testing.T) { - actPrf = &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "tenant_test", - ID: "id_test", - Actions: []*engine.APAction{ - { - ID: "test_action_id", - Diktats: []*engine.APDiktat{{}}, - }, - { - ID: "test_action_id2", - Diktats: []*engine.APDiktat{{}}, - }, - }, - }, - APIOpts: map[string]interface{}{}, - } - var result string - expErr := utils.ErrNotFound.Error() - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &result); err == nil || err.Error() != expErr { - t.Errorf("Expected error: %v received: %v", expErr, err) - } - var reply string - if err := actSRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } - var reply2 *engine.ActionProfile - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &reply2); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, reply2) { - t.Errorf("Expecting : %+v, received: %+v", actPrf.ActionProfile, reply2) - } -} - -func testActionSGetActionProfileIDs(t *testing.T) { - - expected := []string{"id_test"} - var result []string - if err := actSRPC.Call(utils.APIerSv1GetActionProfileIDs, utils.PaginatorWithTenant{}, &result); err != nil { - t.Error(err) - } else if len(expected) != len(result) { - t.Errorf("Expecting : %+v, received: %+v", expected, result) - } - if err := actSRPC.Call(utils.APIerSv1GetActionProfileIDs, utils.PaginatorWithTenant{Tenant: "tenant_test"}, &result); err != nil { - t.Error(err) - } else if len(expected) != len(result) { - t.Errorf("Expecting : %+v, received: %+v", expected, result) - } - if err := actSRPC.Call(utils.APIerSv1GetActionProfileIDs, utils.PaginatorWithTenant{ - Tenant: "tenant_test", - Paginator: utils.Paginator{Limit: utils.IntPointer(1)}, - }, &result); err != nil { - t.Error(err) - } else if 1 != len(result) { - t.Errorf("Expecting : %+v, received: %+v", expected, result) - } - -} - -func testActionSGetActionProfileIDsCount(t *testing.T) { - var reply int - if err := actSRPC.Call(utils.APIerSv1GetActionProfileIDsCount, - &utils.TenantWithAPIOpts{Tenant: "tenant_test"}, &reply); err != nil { - t.Error(err) - } else if reply != 1 { - t.Errorf("Expecting: 1, received: %+v", reply) - } -} - -func testActionSUpdateActionProfile(t *testing.T) { - var reply string - actPrf.Weight = 2 - if err := actSRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } - var reply2 *engine.ActionProfile - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &reply2); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, reply2) { - t.Errorf("Expecting : %+v, received: %+v", actPrf.ActionProfile, reply2) - } -} - -func testActionSRemoveActionProfile(t *testing.T) { - var reply string - if err := actSRPC.Call(utils.APIerSv1RemoveActionProfile, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } - var reply2 *engine.ActionProfile - expErr := utils.ErrNotFound.Error() - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &reply2); err == nil || err.Error() != expErr { - t.Errorf("Expected error: %v received: %v", expErr, err) - } - if err := actSRPC.Call(utils.APIerSv1RemoveActionProfile, &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "tenant_test", ID: "id_test"}}, &reply2); err == nil || err.Error() != expErr { - t.Errorf("Expected error: %v received: %v", expErr, err) - } -} - -func testActionSKillEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func testActionSCacheTestGetNotFound(t *testing.T) { - var reply *utils.TenantIDWithAPIOpts - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, - &utils.TenantID{Tenant: "cgrates.org", ID: "ACTION_CACHE"}, &reply); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatal(err) - } -} - -func testActionSCacheTestGetFound(t *testing.T) { - var reply *utils.TenantIDWithAPIOpts - if err := actSRPC.Call(utils.APIerSv1GetActionProfile, - &utils.TenantID{Tenant: "cgrates.org", ID: "ACTION_CACHE"}, &reply); err != nil { - t.Fatal(err) - } -} - -func testActionSCacheTestSet(t *testing.T) { - actPrf = &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "ACTION_CACHE", - Actions: []*engine.APAction{ - { - ID: "ACTION_CACHE", - Diktats: []*engine.APDiktat{{}}, - }, - }, - }, - APIOpts: map[string]interface{}{ - utils.CacheOpt: utils.MetaNone, - }, - } - var reply string - if err := actSRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } -} - -func testActionSCacheReload(t *testing.T) { - cache := &utils.AttrReloadCacheWithAPIOpts{ - ArgsCache: map[string][]string{ - utils.ActionProfileIDs: {"cgrates.org:ACTION_CACHE"}, - }, - } - var reply string - if err := actSRPC.Call(utils.CacheSv1ReloadCache, cache, &reply); err != nil { - t.Error("Got error on CacheSv1.ReloadCache: ", err.Error()) - } else if reply != utils.OK { - t.Error("Calling CacheSv1.ReloadCache got reply: ", reply) - } -} diff --git a/apier/v1/api_interfaces.go b/apier/v1/api_interfaces.go index 8a0d277f7..5b5c892a7 100644 --- a/apier/v1/api_interfaces.go +++ b/apier/v1/api_interfaces.go @@ -259,14 +259,4 @@ type ReplicatorSv1Interface interface { GetIndexes(args *utils.GetIndexesArg, reply *map[string]utils.StringSet) error SetIndexes(args *utils.SetIndexesArg, reply *string) error RemoveIndexes(args *utils.GetIndexesArg, reply *string) error - - GetActionProfile(tntID *utils.TenantIDWithAPIOpts, reply *engine.ActionProfile) error - SetActionProfile(args *engine.ActionProfileWithAPIOpts, reply *string) error - RemoveActionProfile(args *utils.TenantIDWithAPIOpts, reply *string) error -} - -type ActionSv1Interface interface { - ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error - ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error - Ping(ign *utils.CGREvent, reply *string) error } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index f28a77103..a83be4a08 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -1884,44 +1884,6 @@ func (apierSv1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *st } } csvWriter.Flush() - case utils.MetaActionProfiles: - prfx := utils.ActionProfilePrefix - keys, err := apierSv1.DataManager.DataDB().GetKeysForPrefix(prfx) - if err != nil { - return err - } - if len(keys) == 0 { // if we don't find items we skip - continue - } - f, err := os.Create(path.Join(arg.Path, utils.ActionProfilesCsv)) - if err != nil { - return err - } - defer f.Close() - - csvWriter := csv.NewWriter(f) - csvWriter.Comma = utils.CSVSep - //write the header of the file - if err := csvWriter.Write(engine.ActionProfileMdls{}.CSVHeader()); err != nil { - return err - } - for _, key := range keys { - tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2) - rPrf, err := apierSv1.DataManager.GetActionProfile(tntID[0], tntID[1], - true, false, utils.NonTransactional) - if err != nil { - return err - } - for _, model := range engine.APItoModelTPActionProfile(engine.ActionProfileToAPI(rPrf)) { - if record, err := engine.CsvDump(model); err != nil { - return err - } else if err := csvWriter.Write(record); err != nil { - return err - } - } - } - csvWriter.Flush() - } } *reply = utils.OK diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index 32a4ff2bd..75dd36f00 100755 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -1275,48 +1275,3 @@ func (dS *DispatcherReplicatorSv1) SetIndexes(args *utils.SetIndexesArg, reply * func (dS *DispatcherReplicatorSv1) RemoveIndexes(args *utils.GetIndexesArg, reply *string) error { return dS.dS.ReplicatorSv1RemoveIndexes(args, reply) } - -// GetActionProfile . -func (dS *DispatcherReplicatorSv1) GetActionProfile(tntID *utils.TenantIDWithAPIOpts, reply *engine.ActionProfile) error { - return dS.dS.ReplicatorSv1GetActionProfile(tntID, reply) -} - -// SetActionProfile . -func (dS *DispatcherReplicatorSv1) SetActionProfile(args *engine.ActionProfileWithAPIOpts, reply *string) error { - return dS.dS.ReplicatorSv1SetActionProfile(args, reply) -} - -// RemoveActionProfile . -func (dS *DispatcherReplicatorSv1) RemoveActionProfile(args *utils.TenantIDWithAPIOpts, reply *string) error { - return dS.dS.ReplicatorSv1RemoveActionProfile(args, reply) -} - -func NewDispatcherActionSv1(dps *dispatchers.DispatcherService) *DispatcherActionSv1 { - return &DispatcherActionSv1{dR: dps} -} - -// Exports RPC from RLs -type DispatcherActionSv1 struct { - dR *dispatchers.DispatcherService -} - -// Ping implements ActionSv1Ping -func (dR *DispatcherActionSv1) Ping(args *utils.CGREvent, reply *string) error { - return dR.dR.ActionSv1Ping(args, reply) -} - -func (dR *DispatcherActionSv1) ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { - return dR.dR.ActionSv1ScheduleActions(args, rpl) -} -func (dR *DispatcherActionSv1) ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { - return dR.dR.ActionSv1ExecuteActions(args, rpl) -} - -func NewDispatcherAccountSv1(dps *dispatchers.DispatcherService) *DispatcherAccountSv1 { - return &DispatcherAccountSv1{dR: dps} -} - -// Exports RPC from RLs -type DispatcherAccountSv1 struct { - dR *dispatchers.DispatcherService -} diff --git a/apier/v1/filter_indexes.go b/apier/v1/filter_indexes.go index e73db799a..ce158ab42 100644 --- a/apier/v1/filter_indexes.go +++ b/apier/v1/filter_indexes.go @@ -61,8 +61,6 @@ func (apierSv1 *APIerSv1) RemoveFilterIndexes(arg *AttrRemFilterIndexes, reply * arg.ItemType = utils.CacheResourceFilterIndexes case utils.MetaChargers: arg.ItemType = utils.CacheChargerFilterIndexes - case utils.MetaActionProfiles: - arg.ItemType = utils.CacheActionProfilesFilterIndexes case utils.MetaDispatchers: if missing := utils.MissingStructFields(arg, []string{"Context"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) @@ -106,8 +104,6 @@ func (apierSv1 *APIerSv1) GetFilterIndexes(arg *AttrGetFilterIndexes, reply *[]s arg.ItemType = utils.CacheResourceFilterIndexes case utils.MetaChargers: arg.ItemType = utils.CacheChargerFilterIndexes - case utils.MetaActionProfiles: - arg.ItemType = utils.CacheActionProfilesFilterIndexes case utils.MetaDispatchers: if missing := utils.MissingStructFields(arg, []string{"Context"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) @@ -306,24 +302,6 @@ func (apierSv1 *APIerSv1) ComputeFilterIndexes(args *utils.ArgsComputeFilterInde return utils.APIErrorHandler(err) } } - //ActionProfile Indexes - if args.ActionS { - if args.ActionS, err = engine.ComputeIndexes(apierSv1.DataManager, tnt, args.Context, utils.CacheActionProfilesFilterIndexes, - nil, transactionID, func(tnt, id, ctx string) (*[]string, error) { - atp, e := apierSv1.DataManager.GetActionProfile(tnt, id, true, false, utils.NonTransactional) - if e != nil { - return nil, e - } - fltrIDs := make([]string, len(atp.FilterIDs)) - for i, fltrID := range atp.FilterIDs { - fltrIDs[i] = fltrID - } - return &fltrIDs, nil - - }); err != nil && err != utils.ErrNotFound { - return utils.APIErrorHandler(err) - } - } //ChargerProfile Indexes if args.ChargerS { if args.ChargerS, err = engine.ComputeIndexes(apierSv1.DataManager, tnt, args.Context, utils.CacheChargerFilterIndexes, @@ -391,13 +369,6 @@ func (apierSv1 *APIerSv1) ComputeFilterIndexes(args *utils.ArgsComputeFilterInde return } } - //ActionProfile Indexes - if args.ActionS { - if err = apierSv1.DataManager.SetIndexes(utils.CacheActionProfilesFilterIndexes, tnt, nil, true, transactionID); err != nil { - return - } - } - //AttributeProfile Indexes if args.AttributeS { if err = apierSv1.DataManager.SetIndexes(utils.CacheAttributeFilterIndexes, tntCtx, nil, true, transactionID); err != nil { @@ -487,22 +458,6 @@ func (apierSv1 *APIerSv1) ComputeFilterIndexIDs(args *utils.ArgsComputeFilterInd }); err != nil && err != utils.ErrNotFound { return utils.APIErrorHandler(err) } - //ActionProfile Indexes - if _, err = engine.ComputeIndexes(apierSv1.DataManager, tnt, args.Context, utils.CacheActionProfilesFilterIndexes, - &args.ActionProfileIDs, transactionID, func(tnt, id, ctx string) (*[]string, error) { - atp, e := apierSv1.DataManager.GetActionProfile(tnt, id, true, false, utils.NonTransactional) - if e != nil { - return nil, e - } - fltrIDs := make([]string, len(atp.FilterIDs)) - for i, fltrID := range atp.FilterIDs { - fltrIDs[i] = fltrID - } - return &fltrIDs, nil - }); err != nil && err != utils.ErrNotFound { - return utils.APIErrorHandler(err) - } - //AttributeProfile Indexes if _, err = engine.ComputeIndexes(apierSv1.DataManager, tnt, args.Context, utils.CacheAttributeFilterIndexes, &args.AttributeIDs, transactionID, func(tnt, id, ctx string) (*[]string, error) { diff --git a/apier/v1/filter_indexes_it_test.go b/apier/v1/filter_indexes_it_test.go index 153a22f21..92b1be8a9 100644 --- a/apier/v1/filter_indexes_it_test.go +++ b/apier/v1/filter_indexes_it_test.go @@ -72,12 +72,6 @@ var ( testV1FIdxSecondComputeRouteProfileIndexes, testV1FIdxRemoveRouteProfile, - testV1FIdxdxInitDataDb, - testV1FISetActionProfileIndexes, - testV1FIComputeActionProfileIndexes, - testVF1SetSecondActionProfile, - testVF1ComputeIDsActionProfileIndexes, - testV1FIRemoveActionProfile, testV1FIdxdxInitDataDb, testV1FIdxSetAttributeProfileIndexes, @@ -1145,359 +1139,6 @@ func testV1FIdxRemoveRouteProfile(t *testing.T) { } } -//ActionProfile -func testV1FISetActionProfileIndexes(t *testing.T) { - //set a new filter in db - filter = &engine.FilterWithAPIOpts{ - Filter: &engine.Filter{ - Tenant: tenant, - ID: "ACTION_FLTR", - Rules: []*engine.FilterRule{ - { - Type: utils.MetaString, - Element: "~*req.ToR", - Values: []string{"*sms", "*data", "~*req.Voice"}, - }, - }, - }, - } - var result string - if err := tFIdxRpc.Call(utils.APIerSv1SetFilter, filter, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected result returned", result) - } - - //there is not an actPrf in db, so we will get NOT_FOUND - var reply *engine.ActionProfile - if err := tFIdxRpc.Call(utils.APIerSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF"}}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - //set an actPrf in db, so we will get it without any problems - actPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: tenant, - ID: "ACT_PRF", - FilterIDs: []string{"*prefix:~*req.Account:1001|1002", "ACTION_FLTR"}, - Schedule: "* * * * *", - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: utils.MetaLog, - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - }, - } - if err := tFIdxRpc.Call(utils.APIerSv1SetActionProfile, actPrf, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - //get it from db and compare - if err := tFIdxRpc.Call(utils.APIerSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF"}}, - &reply); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(reply, actPrf.ActionProfile) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(actPrf.ActionProfile), utils.ToJSON(reply)) - } - - //get indexes to verify if these are indexed well - var indexes []string - expectedIDx := []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF", - "*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } - - //get indexes only for that inline actPRf filter (with Type *prefix) - expectedIDx = []string{"*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant, FilterType: utils.MetaPrefix}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } - - //get indexes only with Field ToR - expectedIDx = []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant, FilterField: "*req.ToR"}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } - - //get the indexes only with Value 1001 - expectedIDx = []string{"*prefix:*req.Account:1001:ACT_PRF"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant, FilterValue: "1001"}, - &indexes); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } -} - -func testV1FIComputeActionProfileIndexes(t *testing.T) { - //remove indexes from db - var result string - if err := tFIdxRpc.Call(utils.APIerSv1RemoveFilterIndexes, - &AttrRemFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected result returned", result) - } - - //nothing to get from db - var indexes []string - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } - - //compute them, to put indexes again in db for the right subsystem - if err := tFIdxRpc.Call(utils.APIerSv1ComputeFilterIndexes, - &utils.ArgsComputeFilterIndexes{ - Tenant: tenant, - ActionS: true, - }, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - expectedIDx := []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF", - "*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } -} - -func testVF1SetSecondActionProfile(t *testing.T) { - //second filter in db - filter = &engine.FilterWithAPIOpts{ - Filter: &engine.Filter{ - Tenant: tenant, - ID: "ACTION_FLTR2", - Rules: []*engine.FilterRule{ - { - Type: utils.MetaString, - Element: "~*req.OriginID", - Values: []string{"Dan1"}, - }, - }, - }, - } - var result string - if err := tFIdxRpc.Call(utils.APIerSv1SetFilter, filter, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - //set the second actPrf in db with our filter - actPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: tenant, - ID: "ACT_PRF2", - FilterIDs: []string{"ACTION_FLTR2"}, - Actions: []*engine.APAction{ - { - ID: "TORESET", - FilterIDs: []string{}, - Type: utils.MetaLog, - }, - }, - }, - } - if err := tFIdxRpc.Call(utils.APIerSv1SetActionProfile, actPrf, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - //get it from db and compare - var reply *engine.ActionProfile - if err := tFIdxRpc.Call(utils.APIerSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF2"}}, - &reply); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(reply, actPrf.ActionProfile) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(actPrf.ActionProfile), utils.ToJSON(reply)) - } - - //get indexes to verify if these are indexed well - var indexes []string - expectedIDx := []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF", - "*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF", "*string:*req.OriginID:Dan1:ACT_PRF2"} - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } -} - -func testVF1ComputeIDsActionProfileIndexes(t *testing.T) { - //remove indexes from db for both actPrf - var result string - if err := tFIdxRpc.Call(utils.APIerSv1RemoveFilterIndexes, - &AttrRemFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - var indexes []string - //nothing to get from db, as we removed them, - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } - - //firstly, compute indexes for "ACT_PRF" - if err := tFIdxRpc.Call(utils.APIerSv1ComputeFilterIndexIDs, - &utils.ArgsComputeFilterIndexIDs{ - Tenant: tenant, - ActionProfileIDs: []string{"ACT_PRF"}, - }, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - expectedIDx := []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF", - "*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF"} - //as we compute them, next we will try to get them again from db - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } - - //secondly, compute indexes for "ACT_PRF2" - if err := tFIdxRpc.Call(utils.APIerSv1ComputeFilterIndexIDs, - &utils.ArgsComputeFilterIndexIDs{ - Tenant: tenant, - ActionProfileIDs: []string{"ACT_PRF2"}, - }, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - - expectedIDx = []string{"*string:*req.ToR:*sms:ACT_PRF", "*string:*req.ToR:*data:ACT_PRF", - "*prefix:*req.Account:1001:ACT_PRF", "*prefix:*req.Account:1002:ACT_PRF", "*string:*req.OriginID:Dan1:ACT_PRF2"} - //as we compute them, next we will try to get them again from db - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err != nil { - t.Error(err) - } else { - sort.Strings(expectedIDx) - sort.Strings(indexes) - if !reflect.DeepEqual(indexes, expectedIDx) { - t.Errorf("Expected %+v, received %+v", expectedIDx, indexes) - } - } -} - -func testV1FIRemoveActionProfile(t *testing.T) { - //we will remove actionProfiles 1 by one(ACT_PRF) first - var result string - if err := tFIdxRpc.Call(utils.APIerSv1RemoveActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF"}}, - &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected result returned", result) - } - - var reply *engine.ActionProfile - //there is not an actPrf in database, so we will get NOT_FOUND - if err := tFIdxRpc.Call(utils.APIerSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF"}}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } - - //we will remove actionProfiles 1 by one(ACT_PRF2) second - if err := tFIdxRpc.Call(utils.APIerSv1RemoveActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF2"}}, - &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected result returned", result) - } - - //there is not an actPrf in database, so we will get NOT_FOUND - if err := tFIdxRpc.Call(utils.APIerSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: tenant, ID: "ACT_PRF2"}}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } - - //bcs both profiles are removed, there are not any indexes in db - var indexes []string - //there are no indexes in db, as we removed actprf from db - if err := tFIdxRpc.Call(utils.APIerSv1GetFilterIndexes, - &AttrGetFilterIndexes{ItemType: utils.MetaActionProfiles, Tenant: tenant}, - &indexes); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - //AttributeProfile Indexes func testV1FIdxSetAttributeProfileIndexes(t *testing.T) { var reply *engine.AttributeProfile diff --git a/apier/v1/full_remote_it_test.go b/apier/v1/full_remote_it_test.go index d6b61d1e2..b83ea93d9 100644 --- a/apier/v1/full_remote_it_test.go +++ b/apier/v1/full_remote_it_test.go @@ -56,7 +56,6 @@ var ( testFullRemoteITFilter, testFullRemoteITCharger, testFullRemoteITDispatcher, - testFullRemoteITAction, testFullRemoteITKillEngine, } ) @@ -584,63 +583,6 @@ func testFullRemoteITDispatcher(t *testing.T) { } } -func testFullRemoteITAction(t *testing.T) { - // verify for not found in internal - var reply *engine.ActionProfile - if err := fullRemInternalRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ACT_1"}}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Fatal(err) - } - - var replySet string - actPrf = &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "ACT_1", - Actions: []*engine.APAction{ - { - ID: "test_action_id", - Diktats: []*engine.APDiktat{{}}, - }, - { - ID: "test_action_id2", - Diktats: []*engine.APDiktat{{}}, - }, - }, - }, - APIOpts: map[string]interface{}{}, - } - // add a threshold profile in engine1 and verify it internal - if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &replySet); err != nil { - t.Error(err) - } else if replySet != utils.OK { - t.Error("Unexpected reply returned", replySet) - } - - if err := fullRemInternalRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ACT_1"}}, - &reply); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, reply) { - t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(actPrf.ActionProfile), utils.ToJSON(reply)) - } - // update the threshold profile and verify it to be updated - actPrf.FilterIDs = []string{"*string:~*req.Account:1001", "*string:~*req.Destination:1002"} - if err := fullRemEngineOneRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &replySet); err != nil { - t.Error(err) - } else if replySet != utils.OK { - t.Error("Unexpected reply returned", replySet) - } - if err := fullRemInternalRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ACT_1"}}, - &reply); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, reply) { - t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(actPrf.ActionProfile), utils.ToJSON(reply)) - } -} - func testFullRemoteITKillEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) diff --git a/apier/v1/precache_it_test.go b/apier/v1/precache_it_test.go index 700c5ab98..b89b33fb1 100644 --- a/apier/v1/precache_it_test.go +++ b/apier/v1/precache_it_test.go @@ -211,6 +211,7 @@ func testPrecacheGetCacheStatsAfterRestart(t *testing.T) { Items: 10, Groups: 1, }, +<<<<<<< HEAD utils.CacheThresholdProfiles: {Items: 7}, utils.CacheThresholds: {Items: 7}, utils.CacheTimings: {}, @@ -248,6 +249,48 @@ func testPrecacheGetCacheStatsAfterRestart(t *testing.T) { utils.CacheTBLTPDispatcherHosts: {}, utils.MetaAPIBan: {}, utils.CacheReplicationHosts: {}, +======= + utils.CacheThresholdProfiles: {Items: 7}, + utils.CacheThresholds: {Items: 7}, + utils.CacheTimings: {}, + utils.CacheDiameterMessages: {}, + utils.CacheClosedSessions: {}, + utils.CacheLoadIDs: {}, + utils.CacheRPCConnections: {}, + utils.CacheCDRIDs: {}, + utils.CacheRatingProfilesTmp: {}, + utils.CacheUCH: {}, + utils.CacheReverseFilterIndexes: {}, + utils.CacheAccounts: {}, + utils.CacheVersions: {}, + utils.CacheTBLTPTimings: {}, + utils.CacheTBLTPDestinations: {}, + utils.CacheTBLTPRates: {}, + utils.CacheTBLTPDestinationRates: {}, + utils.CacheTBLTPRatingPlans: {}, + utils.CacheTBLTPRatingProfiles: {}, + utils.CacheTBLTPSharedGroups: {}, + utils.CacheTBLTPActions: {}, + utils.CacheTBLTPActionPlans: {}, + utils.CacheTBLTPActionTriggers: {}, + utils.CacheTBLTPAccountActions: {}, + utils.CacheTBLTPResources: {}, + utils.CacheTBLTPStats: {}, + utils.CacheTBLTPThresholds: {}, + utils.CacheTBLTPFilters: {}, + utils.CacheSessionCostsTBL: {}, + utils.CacheCDRsTBL: {}, + utils.CacheTBLTPRoutes: {}, + utils.CacheTBLTPAttributes: {}, + utils.CacheTBLTPChargers: {}, + utils.CacheTBLTPDispatchers: {}, + utils.CacheTBLTPDispatcherHosts: {}, + utils.MetaAPIBan: {}, + utils.CacheTBLTPAccountProfiles: {}, + utils.CacheAccountProfiles: {}, + utils.CacheAccountProfilesFilterIndexes: {}, + utils.CacheReplicationHosts: {}, +>>>>>>> Removing ActionS } if *apiBan { (*expectedStats)[utils.MetaAPIBan] = <cache.CacheStats{Items: 254} diff --git a/apier/v1/replicator.go b/apier/v1/replicator.go index c6964b812..28a862d66 100644 --- a/apier/v1/replicator.go +++ b/apier/v1/replicator.go @@ -310,17 +310,6 @@ func (rplSv1 *ReplicatorSv1) GetDispatcherHost(tntID *utils.TenantIDWithAPIOpts, return nil } -// GetActionProfile is the remote method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) GetActionProfile(tntID *utils.TenantIDWithAPIOpts, reply *engine.ActionProfile) error { - engine.UpdateReplicationFilters(utils.ActionProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.APIOpts[utils.RemoteHostOpt])) - rcv, err := rplSv1.dm.DataDB().GetActionProfileDrv(tntID.Tenant, tntID.ID) - if err != nil { - return err - } - *reply = *rcv - return nil -} - // GetItemLoadIDs is the remote method coresponding to the dataDb driver method func (rplSv1 *ReplicatorSv1) GetItemLoadIDs(itemID *utils.StringWithAPIOpts, reply *map[string]int64) error { engine.UpdateReplicationFilters(utils.LoadIDPrefix, itemID.Arg, utils.IfaceAsString(itemID.APIOpts[utils.RemoteHostOpt])) @@ -639,19 +628,6 @@ func (rplSv1 *ReplicatorSv1) SetDispatcherHost(dpp *engine.DispatcherHostWithAPI return } -// SetActionProfile is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) SetActionProfile(acp *engine.ActionProfileWithAPIOpts, reply *string) (err error) { - if err = rplSv1.dm.DataDB().SetActionProfileDrv(acp.ActionProfile); err != nil { - return - } - if err = rplSv1.v1.CallCache(utils.IfaceAsString(acp.APIOpts[utils.CacheOpt]), - acp.Tenant, utils.CacheActionProfiles, acp.TenantID(), &acp.FilterIDs, nil, acp.APIOpts); err != nil { - return - } - *reply = utils.OK - return -} - // SetLoadIDs is the replication method coresponding to the dataDb driver method func (rplSv1 *ReplicatorSv1) SetLoadIDs(args *utils.LoadIDsWithAPIOpts, reply *string) (err error) { if err = rplSv1.dm.DataDB().SetLoadIDsDrv(args.LoadIDs); err != nil { @@ -956,19 +932,6 @@ func (rplSv1 *ReplicatorSv1) RemoveDispatcherProfile(args *utils.TenantIDWithAPI return } -// RemoveActionProfile is the replication method coresponding to the dataDb driver method -func (rplSv1 *ReplicatorSv1) RemoveActionProfile(args *utils.TenantIDWithAPIOpts, reply *string) (err error) { - if err = rplSv1.dm.DataDB().RemoveActionProfileDrv(args.Tenant, args.ID); err != nil { - return - } - if err = rplSv1.v1.CallCache(utils.IfaceAsString(args.APIOpts[utils.CacheOpt]), - args.Tenant, utils.CacheActionProfiles, args.TenantID.TenantID(), nil, nil, args.APIOpts); err != nil { - return - } - *reply = utils.OK - return -} - // RemoveDispatcherHost is the replication method coresponding to the dataDb driver method func (rplSv1 *ReplicatorSv1) RemoveDispatcherHost(args *utils.TenantIDWithAPIOpts, reply *string) (err error) { if err = rplSv1.dm.DataDB().RemoveDispatcherHostDrv(args.Tenant, args.ID); err != nil { diff --git a/apier/v1/tpactionprofiles.go b/apier/v1/tpactionprofiles.go deleted file mode 100644 index 3cd2bc9fa..000000000 --- a/apier/v1/tpactionprofiles.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -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 -*/ - -package v1 - -import ( - "github.com/cgrates/cgrates/utils" -) - -// SetTPActionProfile creates a new TPActionProfile within a tariff plan -func (apierSv1 *APIerSv1) SetTPActionProfile(attrs *utils.TPActionProfile, reply *string) error { - if missing := utils.MissingStructFields(attrs, []string{utils.TPid, utils.ID}); len(missing) != 0 { - return utils.NewErrMandatoryIeMissing(missing...) - } - if attrs.Tenant == utils.EmptyString { - attrs.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant - } - if err := apierSv1.StorDb.SetTPActionProfiles([]*utils.TPActionProfile{attrs}); err != nil { - return utils.NewErrServerError(err) - } - *reply = utils.OK - return nil -} - -// GetTPActionProfile queries specific TPActionProfile on tariff plan -func (apierSv1 *APIerSv1) GetTPActionProfile(attr *utils.TPTntID, reply *utils.TPActionProfile) error { - if missing := utils.MissingStructFields(attr, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) - } - if attr.Tenant == utils.EmptyString { - attr.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant - } - spp, err := apierSv1.StorDb.GetTPActionProfiles(attr.TPid, attr.Tenant, attr.ID) - if err != nil { - if err.Error() != utils.ErrNotFound.Error() { - err = utils.NewErrServerError(err) - } - return err - } - *reply = *spp[0] - return nil -} - -type AttrGetTPActionProfileIDs struct { - TPid string // Tariff plan id - utils.PaginatorWithSearch -} - -// GetTPActionProfileIDs queries TPActionProfiles identities on specific tariff plan. -func (apierSv1 *APIerSv1) GetTPActionProfileIDs(attrs *AttrGetTPActionProfileIDs, reply *[]string) error { - if missing := utils.MissingStructFields(attrs, []string{utils.TPid}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) - } - ids, err := apierSv1.StorDb.GetTpTableIds(attrs.TPid, utils.TBLTPActionProfiles, - utils.TPDistinctIds{"tenant", "id"}, nil, &attrs.PaginatorWithSearch) - if err != nil { - if err.Error() != utils.ErrNotFound.Error() { - err = utils.NewErrServerError(err) - } - return err - } - *reply = ids - return nil -} - -// RemoveTPActionProfile removes specific TPActionProfile on Tariff plan -func (apierSv1 *APIerSv1) RemoveTPActionProfile(attrs *utils.TPTntID, reply *string) error { - if missing := utils.MissingStructFields(attrs, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing - return utils.NewErrMandatoryIeMissing(missing...) - } - if attrs.Tenant == utils.EmptyString { - attrs.Tenant = apierSv1.Config.GeneralCfg().DefaultTenant - } - if err := apierSv1.StorDb.RemTpData(utils.TBLTPActionProfiles, attrs.TPid, - map[string]string{utils.TenantCfg: attrs.Tenant, utils.IDCfg: attrs.ID}); err != nil { - return utils.NewErrServerError(err) - } - *reply = utils.OK - return nil -} diff --git a/apier/v1/tpactionprofiles_it_test.go b/apier/v1/tpactionprofiles_it_test.go deleted file mode 100644 index 3769d539f..000000000 --- a/apier/v1/tpactionprofiles_it_test.go +++ /dev/null @@ -1,266 +0,0 @@ -// +build offline - -/* -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 -*/ - -package v1 - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "path" - "reflect" - "sort" - "strings" - "testing" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - tpActPrfCfgPath string - tpActPrfCfg *config.CGRConfig - tpActPrfRPC *rpc.Client - tpActPrf *utils.TPActionProfile - tpActPrfDelay int - tpActPrfConfigDIR string //run tests for specific configuration -) - -var sTestsTPActPrf = []func(t *testing.T){ - testTPActPrfInitCfg, - testTPActPrfResetStorDb, - testTPActPrfStartEngine, - testTPActPrfRPCConn, - testTPActPrfGetTPActPrfBeforeSet, - testTPActPrfSetTPActPrf, - testTPActPrfGetTPActPrfAfterSet, - testTPActPrfGetTPActPrfIDs, - testTPActPrfUpdateTPActPrf, - testTPActPrfGetTPActPrfAfterUpdate, - testTPActPrfRemTPActPrf, - testTPActPrfGetTPActPrfAfterRemove, - testTPActPrfKillEngine, -} - -//Test start here -func TestTPActPrfIT(t *testing.T) { - switch *dbType { - case utils.MetaInternal: - tpActPrfConfigDIR = "tutinternal" - case utils.MetaMySQL: - tpActPrfConfigDIR = "tutmysql" - case utils.MetaMongo: - tpActPrfConfigDIR = "tutmongo" - case utils.MetaPostgres: - t.SkipNow() - default: - t.Fatal("Unknown Database type") - } - for _, stest := range sTestsTPActPrf { - t.Run(tpActPrfConfigDIR, stest) - } -} - -func testTPActPrfInitCfg(t *testing.T) { - var err error - tpActPrfCfgPath = path.Join(*dataDir, "conf", "samples", tpActPrfConfigDIR) - tpActPrfCfg, err = config.NewCGRConfigFromPath(tpActPrfCfgPath) - if err != nil { - t.Error(err) - } - tpActPrfDelay = 1000 -} - -// Wipe out the cdr database -func testTPActPrfResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tpActPrfCfg); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func testTPActPrfStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(tpActPrfCfgPath, tpActPrfDelay); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func testTPActPrfRPCConn(t *testing.T) { - var err error - tpActPrfRPC, err = jsonrpc.Dial(utils.TCP, tpActPrfCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func testTPActPrfGetTPActPrfBeforeSet(t *testing.T) { - var reply *utils.TPActionProfile - if err := tpActPrfRPC.Call(utils.APIerSv1GetTPActionProfile, - &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "Attr1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testTPActPrfSetTPActPrf(t *testing.T) { - tpActPrf = &utils.TPActionProfile{ - TPid: "TP1", - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - Weight: 10, - Schedule: utils.MetaASAP, - Targets: []*utils.TPActionTarget{ - { - TargetType: utils.MetaAccounts, - TargetIDs: []string{"1001"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - sort.Strings(tpActPrf.FilterIDs) - var result string - if err := tpActPrfRPC.Call(utils.APIerSv1SetTPActionProfile, tpActPrf, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } -} - -func testTPActPrfGetTPActPrfAfterSet(t *testing.T) { - var reply *utils.TPActionProfile - if err := tpActPrfRPC.Call(utils.APIerSv1GetTPActionProfile, - &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}, &reply); err != nil { - t.Fatal(err) - } - sort.Strings(reply.FilterIDs) - if !reflect.DeepEqual(tpActPrf, reply) { - t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(tpActPrf), utils.ToJSON(reply)) - } -} - -func testTPActPrfGetTPActPrfIDs(t *testing.T) { - var result []string - expectedTPID := []string{"cgrates.org:ONE_TIME_ACT"} - if err := tpActPrfRPC.Call(utils.APIerSv1GetTPActionProfileIDs, - &AttrGetTPActionProfileIDs{TPid: "TP1"}, &result); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(expectedTPID, result) { - t.Errorf("Expecting: %+v, received: %+v", expectedTPID, result) - } -} - -func testTPActPrfUpdateTPActPrf(t *testing.T) { - tpActPrf.Actions = []*utils.TPAPAction{ - { - ID: "new_TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - } - var result string - if err := tpActPrfRPC.Call(utils.APIerSv1SetTPActionProfile, tpActPrf, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } -} - -func testTPActPrfGetTPActPrfAfterUpdate(t *testing.T) { - var reply *utils.TPActionProfile - revTPActPrf := &utils.TPActionProfile{ - TPid: "TP1", - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - Weight: 10, - Schedule: utils.MetaASAP, - Targets: []*utils.TPActionTarget{ - { - TargetType: utils.MetaAccounts, - TargetIDs: []string{"1001"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "new_TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - Value: "10", - }}, - }, - }, - } - sort.Strings(revTPActPrf.FilterIDs) - sort.Slice(revTPActPrf.Actions, func(i, j int) bool { - return strings.Compare(revTPActPrf.Actions[i].ID, revTPActPrf.Actions[j].ID) == -1 - }) - if err := tpActPrfRPC.Call(utils.APIerSv1GetTPActionProfile, - &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}, &reply); err != nil { - t.Fatal(err) - } - sort.Strings(reply.FilterIDs) - sort.Slice(reply.Actions, func(i, j int) bool { - return strings.Compare(reply.Actions[i].ID, reply.Actions[j].ID) == -1 - }) - if !reflect.DeepEqual(tpActPrf, reply) && !reflect.DeepEqual(revTPActPrf, reply) { - t.Errorf("Expecting : %+v, \n received: %+v", utils.ToJSON(tpActPrf), utils.ToJSON(reply)) - } -} - -func testTPActPrfRemTPActPrf(t *testing.T) { - var resp string - if err := tpActPrfRPC.Call(utils.APIerSv1RemoveTPActionProfile, - &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}, - &resp); err != nil { - t.Error(err) - } else if resp != utils.OK { - t.Error("Unexpected reply returned", resp) - } -} - -func testTPActPrfGetTPActPrfAfterRemove(t *testing.T) { - var reply *utils.TPActionProfile - if err := tpActPrfRPC.Call(utils.APIerSv1GetTPActionProfile, - &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}, - &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error(err) - } -} - -func testTPActPrfKillEngine(t *testing.T) { - if err := engine.KillEngine(tpActPrfDelay); err != nil { - t.Error(err) - } -} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index aa3fccab5..483f28af6 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -678,7 +678,6 @@ func main() { services.NewEventExporterService(cfg, filterSChan, connManager, server, internalEEsChan, anz, srvDep), services.NewSIPAgent(cfg, filterSChan, shdChan, connManager, srvDep), - services.NewActionService(cfg, dmService, cacheS, filterSChan, connManager, server, internalActionSChan, anz, srvDep), ) srvManager.StartServices() // Start FilterS diff --git a/config/config_json_test.go b/config/config_json_test.go index 798f11797..2b53bf96d 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -151,9 +151,6 @@ func TestCacheJsonCfg(t *testing.T) { utils.CacheDispatcherProfiles: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Precache: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, - utils.CacheActionProfiles: {Limit: utils.IntPointer(-1), - Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), - Precache: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, utils.CacheDispatcherHosts: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Precache: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, @@ -178,9 +175,6 @@ func TestCacheJsonCfg(t *testing.T) { utils.CacheDispatcherFilterIndexes: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, - utils.CacheActionProfilesFilterIndexes: {Limit: utils.IntPointer(-1), - Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), - Replicate: utils.BoolPointer(false)}, utils.CacheReverseFilterIndexes: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, @@ -298,9 +292,6 @@ func TestCacheJsonCfg(t *testing.T) { utils.CacheTBLTPDispatcherHosts: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, - utils.CacheTBLTPActionProfiles: {Limit: utils.IntPointer(-1), - Ttl: utils.StringPointer(""), Static_ttl: utils.BoolPointer(false), - Replicate: utils.BoolPointer(false)}, utils.MetaAPIBan: {Limit: utils.IntPointer(-1), Ttl: utils.StringPointer("2m"), Static_ttl: utils.BoolPointer(false), Replicate: utils.BoolPointer(false)}, @@ -451,10 +442,6 @@ func TestDfDataDbJsonCfg(t *testing.T) { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), }, - utils.MetaActionProfiles: { - Replicate: utils.BoolPointer(false), - Remote: utils.BoolPointer(false), - }, utils.MetaChargerProfiles: { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), @@ -587,10 +574,6 @@ func TestDfStorDBJsonCfg(t *testing.T) { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), }, - utils.CacheTBLTPActionProfiles: { - Replicate: utils.BoolPointer(false), - Remote: utils.BoolPointer(false), - }, utils.CacheCDRsTBL: { Replicate: utils.BoolPointer(false), Remote: utils.BoolPointer(false), @@ -1520,78 +1503,6 @@ func TestDfLoaderJsonCfg(t *testing.T) { Value: utils.StringPointer("~*req.4")}, }, }, - { - Type: utils.StringPointer(utils.MetaActionProfiles), - File_name: utils.StringPointer(utils.ActionProfilesCsv), - Fields: &[]*FcTemplateJsonCfg{ - {Tag: utils.StringPointer(utils.Tenant), - Path: utils.StringPointer(utils.Tenant), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.0"), - Mandatory: utils.BoolPointer(true)}, - {Tag: utils.StringPointer(utils.ID), - Path: utils.StringPointer(utils.ID), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.1"), - Mandatory: utils.BoolPointer(true)}, - {Tag: utils.StringPointer("FilterIDs"), - Path: utils.StringPointer("FilterIDs"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.2")}, - {Tag: utils.StringPointer("ActivationInterval"), - Path: utils.StringPointer("ActivationInterval"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.3")}, - {Tag: utils.StringPointer("Weight"), - Path: utils.StringPointer("Weight"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.4")}, - {Tag: utils.StringPointer("Schedule"), - Path: utils.StringPointer("Schedule"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.5")}, - {Tag: utils.StringPointer("TargetType"), - Path: utils.StringPointer("TargetType"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.6")}, - {Tag: utils.StringPointer("TargetIDs"), - Path: utils.StringPointer("TargetIDs"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.7")}, - {Tag: utils.StringPointer("ActionID"), - Path: utils.StringPointer("ActionID"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.8")}, - {Tag: utils.StringPointer("ActionFilterIDs"), - Path: utils.StringPointer("ActionFilterIDs"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.9")}, - {Tag: utils.StringPointer("ActionBlocker"), - Path: utils.StringPointer("ActionBlocker"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.10")}, - {Tag: utils.StringPointer("ActionTTL"), - Path: utils.StringPointer("ActionTTL"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.11")}, - {Tag: utils.StringPointer("ActionType"), - Path: utils.StringPointer("ActionType"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.12")}, - {Tag: utils.StringPointer("ActionOpts"), - Path: utils.StringPointer("ActionOpts"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.13")}, - {Tag: utils.StringPointer("ActionPath"), - Path: utils.StringPointer("ActionPath"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.14")}, - {Tag: utils.StringPointer("ActionValue"), - Path: utils.StringPointer("ActionValue"), - Type: utils.StringPointer(utils.MetaVariable), - Value: utils.StringPointer("~*req.15")}, - }, - }, }, }, } diff --git a/config/config_test.go b/config/config_test.go index cb50ff6fe..ecb53dc60 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -572,8 +572,6 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) { TTL: 0, StaticTTL: false, Precache: false}, utils.CacheDispatcherHosts: {Limit: -1, TTL: 0, StaticTTL: false, Precache: false}, - utils.CacheActionProfiles: {Limit: -1, - TTL: 0, StaticTTL: false, Precache: false}, utils.CacheResourceFilterIndexes: {Limit: -1, TTL: 0, StaticTTL: false, Precache: false}, utils.CacheStatFilterIndexes: {Limit: -1, @@ -588,8 +586,6 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) { TTL: 0, StaticTTL: false, Precache: false}, utils.CacheDispatcherFilterIndexes: {Limit: -1, TTL: 0, StaticTTL: false, Precache: false}, - utils.CacheActionProfilesFilterIndexes: {Limit: -1, - TTL: 0, StaticTTL: false, Precache: false}, utils.CacheReverseFilterIndexes: {Limit: -1, TTL: 0, StaticTTL: false, Precache: false}, utils.CacheDispatcherRoutes: {Limit: -1, @@ -666,8 +662,6 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) { TTL: 0, StaticTTL: false, Precache: false}, utils.CacheTBLTPDispatcherHosts: {Limit: -1, TTL: 0, StaticTTL: false, Precache: false}, - utils.CacheTBLTPActionProfiles: {Limit: -1, - TTL: 0, StaticTTL: false, Precache: false}, utils.MetaAPIBan: {Limit: -1, TTL: 2 * time.Minute, StaticTTL: false, Precache: false}, utils.CacheReplicationHosts: {Limit: 0, @@ -3262,94 +3256,6 @@ func TestCgrLoaderCfgITDefaults(t *testing.T) { }, }, }, - { - Type: utils.MetaActionProfiles, - Filename: utils.ActionProfilesCsv, - Fields: []*FCTemplate{ - {Tag: "Tenant", - Path: "Tenant", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "ID", - Path: "ID", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "FilterIDs", - Path: "FilterIDs", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.2", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActivationInterval", - Path: "ActivationInterval", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.3", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "Weight", - Path: "Weight", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.4", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "Schedule", - Path: "Schedule", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.5", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "TargetType", - Path: "TargetType", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.6", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "TargetIDs", - Path: "TargetIDs", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.7", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionID", - Path: "ActionID", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.8", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionFilterIDs", - Path: "ActionFilterIDs", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.9", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionBlocker", - Path: "ActionBlocker", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.10", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionTTL", - Path: "ActionTTL", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.11", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionType", - Path: "ActionType", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.12", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionOpts", - Path: "ActionOpts", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.13", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionPath", - Path: "ActionPath", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.14", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionValue", - Path: "ActionValue", - Type: utils.MetaVariable, - Value: NewRSRParsersMustCompile("~*req.15", utils.InfieldSep), - Layout: time.RFC3339}, - }, - }, { Type: utils.MetaAccountProfiles, Filename: utils.AccountProfilesCsv, diff --git a/console/actions.go b/console/actions.go deleted file mode 100644 index 2765a5c28..000000000 --- a/console/actions.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -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 -*/ - -package console - -import ( - v2 "github.com/cgrates/cgrates/apier/v2" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -func init() { - c := &CmdGetActions{ - name: "actions", - rpcMethod: utils.APIerSv2GetActions, - } - commands[c.Name()] = c - c.CommandExecuter = &CommandExecuter{c} -} - -// Commander implementation -type CmdGetActions struct { - name string - rpcMethod string - rpcParams *v2.AttrGetActions - *CommandExecuter -} - -func (self *CmdGetActions) Name() string { - return self.name -} - -func (self *CmdGetActions) RpcMethod() string { - return self.rpcMethod -} - -func (self *CmdGetActions) RpcParams(reset bool) interface{} { - if reset || self.rpcParams == nil { - self.rpcParams = &v2.AttrGetActions{} - } - return self.rpcParams -} - -func (self *CmdGetActions) PostprocessRpcParams() error { - return nil -} - -func (self *CmdGetActions) RpcResult() interface{} { - a := make(map[string]engine.Actions, 0) - return &a -} diff --git a/console/actions_remove.go b/console/actions_remove.go deleted file mode 100644 index a0a0d8348..000000000 --- a/console/actions_remove.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -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 -*/ - -package console - -import ( - "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/utils" -) - -func init() { - c := &CmdRemoveActions{ - name: "actions_remove", - rpcMethod: utils.APIerSv1RemoveActions, - } - commands[c.Name()] = c - c.CommandExecuter = &CommandExecuter{c} -} - -// Commander implementation -type CmdRemoveActions struct { - name string - rpcMethod string - rpcParams *v1.AttrRemoveActions - *CommandExecuter -} - -func (self *CmdRemoveActions) Name() string { - return self.name -} - -func (self *CmdRemoveActions) RpcMethod() string { - return self.rpcMethod -} - -func (self *CmdRemoveActions) RpcParams(reset bool) interface{} { - if reset || self.rpcParams == nil { - self.rpcParams = &v1.AttrRemoveActions{} - } - return self.rpcParams -} - -func (self *CmdRemoveActions) PostprocessRpcParams() error { - return nil -} - -func (self *CmdRemoveActions) RpcResult() interface{} { - var s string - return &s -} diff --git a/console/actions_remove_test.go b/console/actions_remove_test.go deleted file mode 100644 index ea4be2bbb..000000000 --- a/console/actions_remove_test.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -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 -*/ - -package console - -import ( - "reflect" - "strings" - "testing" - - v2 "github.com/cgrates/cgrates/apier/v2" - - "github.com/cgrates/cgrates/utils" -) - -func TestCmdActionsRemove(t *testing.T) { - // commands map is initiated in init function - command := commands["actions_remove"] - // verify if ApierSv1 object has method on it - m, ok := reflect.TypeOf(new(v2.APIerSv2)).MethodByName(strings.Split(command.RpcMethod(), utils.NestingSep)[1]) - if !ok { - t.Fatal("method not found") - } - if m.Type.NumIn() != 3 { // ApierSv1 is consider and we expect 3 inputs - t.Fatalf("invalid number of input parameters ") - } - // verify the type of input parameter - if ok := m.Type.In(1).AssignableTo(reflect.TypeOf(command.RpcParams(true))); !ok { - t.Fatalf("cannot assign input parameter") - } - // verify the type of output parameter - if ok := m.Type.In(2).AssignableTo(reflect.TypeOf(command.RpcResult())); !ok { - t.Fatalf("cannot assign output parameter") - } - // for coverage purpose - if err := command.PostprocessRpcParams(); err != nil { - t.Fatal(err) - } -} diff --git a/console/actions_test.go b/console/actions_test.go deleted file mode 100644 index d70a1e61c..000000000 --- a/console/actions_test.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -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 -*/ - -package console - -import ( - "reflect" - "strings" - "testing" - - v2 "github.com/cgrates/cgrates/apier/v2" - - "github.com/cgrates/cgrates/utils" -) - -func TestCmdActions(t *testing.T) { - // commands map is initiated in init function - command := commands["actions"] - // verify if ApierSv1 object has method on it - m, ok := reflect.TypeOf(new(v2.APIerSv2)).MethodByName(strings.Split(command.RpcMethod(), utils.NestingSep)[1]) - if !ok { - t.Fatal("method not found") - } - if m.Type.NumIn() != 3 { // ApierSv1 is consider and we expect 3 inputs - t.Fatalf("invalid number of input parameters ") - } - // verify the type of input parameter - if ok := m.Type.In(1).AssignableTo(reflect.TypeOf(command.RpcParams(true))); !ok { - t.Fatalf("cannot assign input parameter") - } - // verify the type of output parameter - if ok := m.Type.In(2).AssignableTo(reflect.TypeOf(command.RpcResult())); !ok { - t.Fatalf("cannot assign output parameter") - } - // for coverage purpose - if err := command.PostprocessRpcParams(); err != nil { - t.Fatal(err) - } -} diff --git a/dispatchers/actions.go b/dispatchers/actions.go deleted file mode 100644 index 532d234c4..000000000 --- a/dispatchers/actions.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -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 -*/ - -package dispatchers - -import "github.com/cgrates/cgrates/utils" - -func (dS *DispatcherService) ActionSv1Ping(args *utils.CGREvent, rpl *string) (err error) { - if args == nil { - args = new(utils.CGREvent) - } - args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant) - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ActionSv1Ping, args.Tenant, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), args.Time); err != nil { - return - } - } - return dS.Dispatch(args, utils.MetaActions, utils.ActionSv1Ping, args, rpl) -} - -func (dS *DispatcherService) ActionSv1ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { - if args == nil { - args = new(utils.ArgActionSv1ScheduleActions) - } - tnt := dS.cfg.GeneralCfg().DefaultTenant - if args.CGREvent != nil && args.CGREvent.Tenant != utils.EmptyString { - tnt = args.CGREvent.Tenant - } - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ActionSv1ScheduleActions, tnt, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), args.Time); err != nil { - return - } - } - return dS.Dispatch(args.CGREvent, utils.MetaActions, utils.ActionSv1ScheduleActions, args, rpl) -} - -func (dS *DispatcherService) ActionSv1ExecuteActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) (err error) { - if args == nil { - args = new(utils.ArgActionSv1ScheduleActions) - } - tnt := dS.cfg.GeneralCfg().DefaultTenant - if args.CGREvent != nil && args.CGREvent.Tenant != utils.EmptyString { - tnt = args.CGREvent.Tenant - } - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ActionSv1Ping, tnt, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), args.Time); err != nil { - return - } - } - return dS.Dispatch(args.CGREvent, utils.MetaActions, utils.ActionSv1Ping, args, rpl) -} diff --git a/dispatchers/actions_it_test.go b/dispatchers/actions_it_test.go deleted file mode 100644 index 7504bf693..000000000 --- a/dispatchers/actions_it_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build integration - -/* -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 -*/ - -package dispatchers - -import ( - "testing" - - "github.com/cgrates/cgrates/utils" -) - -var sTestsDspActPrf = []func(t *testing.T){ - testDspActPrfPing, -} - -//Test start here -func TestDspActionSIT(t *testing.T) { - var config1, config2, config3 string - switch *dbType { - case utils.MetaInternal: - t.SkipNow() - case utils.MetaMySQL: - config1 = "all_mysql" - config2 = "all2_mysql" - config3 = "dispatchers_mysql" - case utils.MetaMongo: - config1 = "all_mongo" - config2 = "all2_mongo" - config3 = "dispatchers_mongo" - case utils.MetaPostgres: - t.SkipNow() - default: - t.Fatal("Unknown Database type") - } - - dispDIR := "dispatchers" - if *encoding == utils.MetaGOB { - dispDIR += "_gob" - } - testDsp(t, sTestsDspActPrf, "TestDspActionSIT", config1, config2, config3, "tutorial", "oldtutorial", dispDIR) -} - -func testDspActPrfPing(t *testing.T) { - var reply string - if err := allEngine.RPC.Call(utils.ActionSv1Ping, new(utils.CGREvent), &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Received: %s", reply) - } - if err := dispEngine.RPC.Call(utils.ActionSv1Ping, &utils.CGREvent{ - Tenant: "cgrates.org", - APIOpts: map[string]interface{}{ - utils.OptsAPIKey: "actPrf12345", - }, - }, &reply); err != nil { - t.Error(err) - } else if reply != utils.Pong { - t.Errorf("Received: %s", reply) - } -} diff --git a/dispatchers/caches_it_test.go b/dispatchers/caches_it_test.go index c62f2cbd7..74a260187 100644 --- a/dispatchers/caches_it_test.go +++ b/dispatchers/caches_it_test.go @@ -237,8 +237,8 @@ func testDspChcPrecacheStatus(t *testing.T) { utils.CacheTBLTPDispatchers: utils.MetaReady, utils.CacheTBLTPDispatcherHosts: utils.MetaReady, utils.MetaAPIBan: utils.MetaReady, - utils.CacheTBLTPActionProfiles: utils.MetaReady, - utils.CacheReplicationHosts: utils.MetaReady, + + utils.CacheReplicationHosts: utils.MetaReady, } if err := dispEngine.RPC.Call(utils.CacheSv1PrecacheStatus, utils.AttrCacheIDsWithAPIOpts{ diff --git a/dispatchers/replicator.go b/dispatchers/replicator.go index 44a9aadc2..d1b9867b9 100644 --- a/dispatchers/replicator.go +++ b/dispatchers/replicator.go @@ -459,24 +459,6 @@ func (dS *DispatcherService) ReplicatorSv1GetDispatcherHost(args *utils.TenantID }, utils.MetaReplicator, utils.ReplicatorSv1GetDispatcherHost, args, reply) } -func (dS *DispatcherService) ReplicatorSv1GetActionProfile(args *utils.TenantIDWithAPIOpts, reply *engine.ActionProfile) (err error) { - tnt := dS.cfg.GeneralCfg().DefaultTenant - if args.TenantID != nil && args.TenantID.Tenant != utils.EmptyString { - tnt = args.TenantID.Tenant - } - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ReplicatorSv1GetActionProfile, tnt, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { - return - } - } - return dS.Dispatch(&utils.CGREvent{ - Tenant: tnt, - ID: args.ID, - APIOpts: args.APIOpts, - }, utils.MetaReplicator, utils.ReplicatorSv1GetActionProfile, args, reply) -} - func (dS *DispatcherService) ReplicatorSv1GetItemLoadIDs(args *utils.StringWithAPIOpts, rpl *map[string]int64) (err error) { if args == nil { args = new(utils.StringWithAPIOpts) @@ -834,23 +816,6 @@ func (dS *DispatcherService) ReplicatorSv1SetDispatcherProfile(args *engine.Disp }, utils.MetaReplicator, utils.ReplicatorSv1SetDispatcherProfile, args, rpl) } -func (dS *DispatcherService) ReplicatorSv1SetActionProfile(args *engine.ActionProfileWithAPIOpts, rpl *string) (err error) { - if args == nil { - args = &engine.ActionProfileWithAPIOpts{} - } - args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant) - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ReplicatorSv1SetActionProfile, args.Tenant, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { - return - } - } - return dS.Dispatch(&utils.CGREvent{ - Tenant: args.Tenant, - APIOpts: args.APIOpts, - }, utils.MetaReplicator, utils.ReplicatorSv1SetActionProfile, args, rpl) -} - func (dS *DispatcherService) ReplicatorSv1SetActionPlan(args *engine.SetActionPlanArgWithAPIOpts, rpl *string) (err error) { if args == nil { args = &engine.SetActionPlanArgWithAPIOpts{} @@ -1293,23 +1258,6 @@ func (dS *DispatcherService) ReplicatorSv1RemoveDispatcherHost(args *utils.Tenan }, utils.MetaReplicator, utils.ReplicatorSv1RemoveDispatcherHost, args, rpl) } -func (dS *DispatcherService) ReplicatorSv1RemoveActionProfile(args *utils.TenantIDWithAPIOpts, rpl *string) (err error) { - if args == nil { - args = &utils.TenantIDWithAPIOpts{} - } - args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant) - if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 { - if err = dS.authorize(utils.ReplicatorSv1RemoveActionProfile, args.Tenant, - utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil { - return - } - } - return dS.Dispatch(&utils.CGREvent{ - Tenant: args.Tenant, - APIOpts: args.APIOpts, - }, utils.MetaReplicator, utils.ReplicatorSv1RemoveActionProfile, args, rpl) -} - // ReplicatorSv1GetIndexes . func (dS *DispatcherService) ReplicatorSv1GetIndexes(args *utils.GetIndexesArg, reply *map[string]utils.StringSet) (err error) { if args == nil { diff --git a/dispatchers/replicator_it_test.go b/dispatchers/replicator_it_test.go index fadd6cd36..452ece0e0 100644 --- a/dispatchers/replicator_it_test.go +++ b/dispatchers/replicator_it_test.go @@ -53,7 +53,6 @@ var sTestsDspRpl = []func(t *testing.T){ testDspRplRatingPlan, testDspRplRatingProfile, testDspRplDestination, - testDspRplActionProfile, } //Test start here @@ -1467,63 +1466,3 @@ func testDspRplLoadIDs(t *testing.T) { // Start engine 1 allEngine.startEngine(t) } - -func testDspRplActionProfile(t *testing.T) { - // Set RateProfile - var replyStr string - rPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - }, - APIOpts: map[string]interface{}{ - utils.OptsAPIKey: "repl12345", - }, - } - if err := dispEngine.RPC.Call(utils.ReplicatorSv1SetActionProfile, rPrf, &replyStr); err != nil { - t.Error("Unexpected error when calling ReplicatorSv1.SetActionProfile: ", err) - } else if replyStr != utils.OK { - t.Error("Unexpected reply returned", replyStr) - } - // Get RateProfile - var reply *engine.ActionProfile - args := &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{ - Tenant: "cgrates.org", - ID: "RP1", - }, - APIOpts: map[string]interface{}{ - utils.OptsAPIKey: "repl12345", - }, - } - if err := dispEngine.RPC.Call(utils.ReplicatorSv1GetActionProfile, args, &reply); err != nil { - t.Error("Unexpected error when calling ReplicatorSv1.GetActionProfile: ", err) - } else if !reflect.DeepEqual(rPrf.ActionProfile, reply) { - t.Errorf("Expecting: %+v, received: %+v, ", rPrf.ActionProfile, reply) - } - // Stop engine 1 - allEngine.stopEngine(t) - - // Get RateProfile - if err := dispEngine.RPC.Call(utils.ReplicatorSv1GetActionProfile, args, &reply); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Expecting: %+v, received: %+v, ", utils.ErrNotFound, err) - } - - // Start engine 1 - allEngine.startEngine(t) - - // Remove RateProfile - if err := dispEngine.RPC.Call(utils.ReplicatorSv1RemoveActionProfile, args, &replyStr); err != nil { - t.Error(err) - } else if replyStr != utils.OK { - t.Error("Unexpected reply returned", replyStr) - } - - // Get RateProfile - if err := dispEngine.RPC.Call(utils.ReplicatorSv1GetActionProfile, args, &reply); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Expecting: %+v, received: %+v, ", utils.ErrNotFound, err) - } - -} diff --git a/engine/actionprofile.go b/engine/actionprofile.go deleted file mode 100644 index a20cc084e..000000000 --- a/engine/actionprofile.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 -*/ - -package engine - -import ( - "sort" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/utils" -) - -// ActionProfile represents the configuration of a Action profile -type ActionProfile struct { - Tenant string - ID string - FilterIDs []string - ActivationInterval *utils.ActivationInterval - Weight float64 - Schedule string - Targets map[string]utils.StringSet - - Actions []*APAction -} - -func (aP *ActionProfile) TenantID() string { - return utils.ConcatenatedKey(aP.Tenant, aP.ID) -} - -// ActionProfiles is a sortable list of ActionProfiles -type ActionProfiles []*ActionProfile - -// Sort is part of sort interface, sort based on Weight -func (aps ActionProfiles) Sort() { - sort.Slice(aps, func(i, j int) bool { return aps[i].Weight > aps[j].Weight }) -} - -// APAction defines action related information used within a ActionProfile -type APAction struct { - ID string // Action ID - FilterIDs []string // Action FilterIDs - Blocker bool // Blocker will stop further actions running in the chain - TTL time.Duration // Cancel Action if not executed within TTL - Type string // Type of Action - Opts map[string]interface{} // Extra options to pass depending on action type - Diktats []*APDiktat -} - -type APDiktat struct { - Path string // Path to execute - Value string // Value to execute on Path - - valRSR config.RSRParsers -} - -// RSRValues returns the Value as RSRParsers -func (dk *APDiktat) RSRValues(sep string) (v config.RSRParsers, err error) { - if dk.valRSR == nil { - dk.valRSR, err = config.NewRSRParsers(dk.Value, sep) - if err != nil { - return - } - } - return dk.valRSR, nil -} - -// ActionProfileWithAPIOpts is used in API calls - -type ActionProfileWithAPIOpts struct { - *ActionProfile - APIOpts map[string]interface{} -} diff --git a/engine/actionprofile_test.go b/engine/actionprofile_test.go deleted file mode 100644 index ca165d72d..000000000 --- a/engine/actionprofile_test.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -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 -*/ - -package engine - -import ( - "reflect" - "testing" - - "github.com/cgrates/cgrates/utils" -) - -func TestActionProfileSort(t *testing.T) { - testStruct := &ActionProfiles{ - { - Tenant: "test_tenantA", - ID: "test_idA", - Weight: 1, - }, - { - Tenant: "test_tenantB", - ID: "test_idB", - Weight: 2, - }, - { - Tenant: "test_tenantC", - ID: "test_idC", - Weight: 3, - }, - } - expStruct := &ActionProfiles{ - { - Tenant: "test_tenantC", - ID: "test_idC", - Weight: 3, - }, - - { - Tenant: "test_tenantB", - ID: "test_idB", - Weight: 2, - }, - { - Tenant: "test_tenantA", - ID: "test_idA", - Weight: 1, - }, - } - testStruct.Sort() - if !reflect.DeepEqual(expStruct, testStruct) { - t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expStruct), utils.ToJSON(testStruct)) - } -} diff --git a/engine/caches.go b/engine/caches.go index be591ef54..3e837c6ae 100644 --- a/engine/caches.go +++ b/engine/caches.go @@ -64,9 +64,6 @@ func init() { gob.Register(new(DispatcherHost)) gob.Register(new(DispatcherHostProfile)) gob.Register(new(DispatcherHostWithAPIOpts)) - // ActionProfiles - gob.Register(new(ActionProfile)) - gob.Register(new(ActionProfileWithAPIOpts)) // CDRs gob.Register(new(EventCost)) diff --git a/engine/datadbmock.go b/engine/datadbmock.go index 9ab998c38..377a4580b 100644 --- a/engine/datadbmock.go +++ b/engine/datadbmock.go @@ -382,18 +382,6 @@ func (dbM *DataDBMock) RemoveDispatcherHostDrv(string, string) error { return utils.ErrNotImplemented } -func (dbM *DataDBMock) GetActionProfileDrv(string, string) (*ActionProfile, error) { - return nil, utils.ErrNotImplemented -} - -func (dbM *DataDBMock) SetActionProfileDrv(*ActionProfile) error { - return utils.ErrNotImplemented -} - -func (dbM *DataDBMock) RemoveActionProfileDrv(string, string) error { - return utils.ErrNotImplemented -} - func (dbM *DataDBMock) SetVersions(vrs Versions, overwrite bool) (err error) { return utils.ErrNotImplemented } diff --git a/engine/datamanager.go b/engine/datamanager.go index 687f3b06b..4a84b0c4c 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -35,44 +35,41 @@ var ( utils.RouteFilterIndexes: {}, utils.ChargerFilterIndexes: {}, utils.DispatcherFilterIndexes: {}, - utils.ActionProfilesFilterIndexPrfx: {}, utils.ActionPlanIndexes: {}, utils.FilterIndexPrfx: {}, } cachePrefixMap = utils.StringSet{ - utils.DestinationPrefix: {}, - utils.ReverseDestinationPrefix: {}, - utils.RatingPlanPrefix: {}, - utils.RatingProfilePrefix: {}, - utils.ActionPrefix: {}, - utils.ActionPlanPrefix: {}, - utils.AccountActionPlansPrefix: {}, - utils.ActionTriggerPrefix: {}, - utils.SharedGroupPrefix: {}, - utils.ResourceProfilesPrefix: {}, - utils.TimingsPrefix: {}, - utils.ResourcesPrefix: {}, - utils.StatQueuePrefix: {}, - utils.StatQueueProfilePrefix: {}, - utils.ThresholdPrefix: {}, - utils.ThresholdProfilePrefix: {}, - utils.FilterPrefix: {}, - utils.RouteProfilePrefix: {}, - utils.AttributeProfilePrefix: {}, - utils.ChargerProfilePrefix: {}, - utils.DispatcherProfilePrefix: {}, - utils.DispatcherHostPrefix: {}, - utils.ActionProfilePrefix: {}, - utils.AttributeFilterIndexes: {}, - utils.ResourceFilterIndexes: {}, - utils.StatFilterIndexes: {}, - utils.ThresholdFilterIndexes: {}, - utils.RouteFilterIndexes: {}, - utils.ChargerFilterIndexes: {}, - utils.DispatcherFilterIndexes: {}, - utils.ActionProfilesFilterIndexPrfx: {}, - utils.FilterIndexPrfx: {}, - utils.MetaAPIBan: {}, // not realy a prefix as this is not stored in DB + utils.DestinationPrefix: {}, + utils.ReverseDestinationPrefix: {}, + utils.RatingPlanPrefix: {}, + utils.RatingProfilePrefix: {}, + utils.ActionPrefix: {}, + utils.ActionPlanPrefix: {}, + utils.AccountActionPlansPrefix: {}, + utils.ActionTriggerPrefix: {}, + utils.SharedGroupPrefix: {}, + utils.ResourceProfilesPrefix: {}, + utils.TimingsPrefix: {}, + utils.ResourcesPrefix: {}, + utils.StatQueuePrefix: {}, + utils.StatQueueProfilePrefix: {}, + utils.ThresholdPrefix: {}, + utils.ThresholdProfilePrefix: {}, + utils.FilterPrefix: {}, + utils.RouteProfilePrefix: {}, + utils.AttributeProfilePrefix: {}, + utils.ChargerProfilePrefix: {}, + utils.DispatcherProfilePrefix: {}, + utils.DispatcherHostPrefix: {}, + utils.AttributeFilterIndexes: {}, + utils.ResourceFilterIndexes: {}, + utils.StatFilterIndexes: {}, + utils.ThresholdFilterIndexes: {}, + utils.RouteFilterIndexes: {}, + utils.ChargerFilterIndexes: {}, + utils.DispatcherFilterIndexes: {}, + utils.FilterIndexPrfx: {}, + utils.MetaAPIBan: {}, // not realy a prefix as this is not stored in DB } ) @@ -217,9 +214,6 @@ func (dm *DataManager) CacheDataFromDB(prfx string, ids []string, mustBeCached b case utils.DispatcherHostPrefix: tntID := utils.NewTenantID(dataID) _, err = dm.GetDispatcherHost(tntID.Tenant, tntID.ID, false, true, utils.NonTransactional) - case utils.ActionProfilePrefix: - tntID := utils.NewTenantID(dataID) - _, err = dm.GetActionProfile(tntID.Tenant, tntID.ID, false, true, utils.NonTransactional) case utils.AttributeFilterIndexes: var tntCtx, idxKey string if tntCtx, idxKey, err = splitFilterIndex(dataID); err != nil { @@ -262,12 +256,6 @@ func (dm *DataManager) CacheDataFromDB(prfx string, ids []string, mustBeCached b return } _, err = dm.GetIndexes(utils.CacheDispatcherFilterIndexes, tntCtx, idxKey, false, true) - case utils.ActionProfilesFilterIndexPrfx: - var tntCtx, idxKey string - if tntCtx, idxKey, err = splitFilterIndex(dataID); err != nil { - return - } - _, err = dm.GetIndexes(utils.CacheActionProfilesFilterIndexes, tntCtx, idxKey, false, true) case utils.FilterIndexPrfx: idx := strings.LastIndexByte(dataID, utils.InInFieldSep[0]) if idx < 0 { @@ -3009,131 +2997,6 @@ func (dm *DataManager) SetLoadIDs(loadIDs map[string]int64) (err error) { return } -func (dm *DataManager) GetActionProfile(tenant, id string, cacheRead, cacheWrite bool, - transactionID string) (ap *ActionProfile, err error) { - tntID := utils.ConcatenatedKey(tenant, id) - if cacheRead { - if x, ok := Cache.Get(utils.CacheActionProfiles, tntID); ok { - if x == nil { - return nil, utils.ErrNotFound - } - return x.(*ActionProfile), nil - } - } - if dm == nil { - err = utils.ErrNoDatabaseConn - return - } - ap, err = dm.dataDB.GetActionProfileDrv(tenant, id) - if err != nil { - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionProfiles]; err == utils.ErrNotFound && itm.Remote { - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RmtConns, nil, - utils.ReplicatorSv1GetActionProfile, - &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: tenant, ID: id}, - APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, utils.EmptyString, - utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, - config.CgrConfig().GeneralCfg().NodeID)), - }, &ap); err == nil { - err = dm.dataDB.SetActionProfileDrv(ap) - } - } - if err != nil { - err = utils.CastRPCErr(err) - if err == utils.ErrNotFound && cacheWrite { - if errCh := Cache.Set(utils.CacheActionProfiles, tntID, nil, nil, - cacheCommit(transactionID), transactionID); errCh != nil { - return nil, errCh - } - - } - return nil, err - } - } - if cacheWrite { - if errCh := Cache.Set(utils.CacheActionProfiles, tntID, ap, nil, - cacheCommit(transactionID), transactionID); errCh != nil { - return nil, errCh - } - } - return -} - -func (dm *DataManager) SetActionProfile(ap *ActionProfile, withIndex bool) (err error) { - if dm == nil { - return utils.ErrNoDatabaseConn - } - if withIndex { - if brokenReference := dm.checkFilters(ap.Tenant, ap.FilterIDs); len(brokenReference) != 0 { - // if we get a broken filter do not set the profile - return fmt.Errorf("broken reference to filter: %+v for item with ID: %+v", - brokenReference, ap.TenantID()) - } - } - oldRpp, err := dm.GetActionProfile(ap.Tenant, ap.ID, true, false, utils.NonTransactional) - if err != nil && err != utils.ErrNotFound { - return err - } - if err = dm.DataDB().SetActionProfileDrv(ap); err != nil { - return err - } - if withIndex { - var oldFiltersIDs *[]string - if oldRpp != nil { - oldFiltersIDs = &oldRpp.FilterIDs - } - if err := updatedIndexes(dm, utils.CacheActionProfilesFilterIndexes, ap.Tenant, - utils.EmptyString, ap.ID, oldFiltersIDs, ap.FilterIDs, false); err != nil { - return err - } - } - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionProfiles]; itm.Replicate { - err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, - config.CgrConfig().DataDbCfg().RplFiltered, - utils.ActionProfilePrefix, ap.TenantID(), // this are used to get the host IDs from cache - utils.ReplicatorSv1SetActionProfile, - &ActionProfileWithAPIOpts{ - ActionProfile: ap, - APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, - config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)}) - } - return -} - -func (dm *DataManager) RemoveActionProfile(tenant, id string, - transactionID string, withIndex bool) (err error) { - if dm == nil { - return utils.ErrNoDatabaseConn - } - oldRpp, err := dm.GetActionProfile(tenant, id, true, false, utils.NonTransactional) - if err != nil && err != utils.ErrNotFound { - return err - } - if err = dm.DataDB().RemoveActionProfileDrv(tenant, id); err != nil { - return - } - if oldRpp == nil { - return utils.ErrNotFound - } - if withIndex { - if err = removeItemFromFilterIndex(dm, utils.CacheActionProfilesFilterIndexes, - tenant, utils.EmptyString, id, oldRpp.FilterIDs); err != nil { - return - } - } - if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionProfiles]; itm.Replicate { - replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, - config.CgrConfig().DataDbCfg().RplFiltered, - utils.ActionProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache - utils.ReplicatorSv1RemoveActionProfile, - &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: tenant, ID: id}, - APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, - config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)}) - } - return -} - // Reconnect reconnects to the DB when the config was changed func (dm *DataManager) Reconnect(marshaller string, newcfg *config.DataDbCfg) (err error) { d, err := NewDataDBConn(newcfg.Type, newcfg.Host, newcfg.Port, newcfg.Name, diff --git a/engine/libindex.go b/engine/libindex.go index ca6e3baf8..d2a913143 100644 --- a/engine/libindex.go +++ b/engine/libindex.go @@ -690,26 +690,6 @@ func UpdateFilterIndex(dm *DataManager, oldFlt, newFlt *Filter) (err error) { }); err != nil && err != utils.ErrNotFound { return utils.APIErrorHandler(err) } - case utils.CacheActionProfilesFilterIndexes: - if err = removeFilterIndexesForFilter(dm, idxItmType, newFlt.Tenant, //remove the indexes for the filter - removeIndexKeys, indx); err != nil { - return - } - idxSlice := indx.AsSlice() - if _, err = ComputeIndexes(dm, newFlt.Tenant, utils.EmptyString, idxItmType, // compute all the indexes for afected items - &idxSlice, utils.NonTransactional, func(tnt, id, ctx string) (*[]string, error) { - acp, e := dm.GetActionProfile(tnt, id, true, false, utils.NonTransactional) - if e != nil { - return nil, e - } - fltrIDs := make([]string, len(acp.FilterIDs)) - for i, fltrID := range acp.FilterIDs { - fltrIDs[i] = fltrID - } - return &fltrIDs, nil - }); err != nil && err != utils.ErrNotFound { - return utils.APIErrorHandler(err) - } case utils.CacheAttributeFilterIndexes: for itemID := range indx { var ap *AttributeProfile diff --git a/engine/libtest.go b/engine/libtest.go index a6c6c2fe4..16e5cabc5 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -559,43 +559,40 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats { utils.CacheTBLTPChargers: {}, utils.CacheTBLTPDispatchers: {}, utils.CacheTBLTPDispatcherHosts: {}, - utils.CacheTBLTPActionProfiles: {}, } } func GetDefaultEmptyArgCachePrefix() map[string][]string { return map[string][]string{ - utils.DestinationPrefix: nil, - utils.ReverseDestinationPrefix: nil, - utils.RatingPlanPrefix: nil, - utils.RatingProfilePrefix: nil, - utils.ActionPrefix: nil, - utils.ActionPlanPrefix: nil, - utils.AccountActionPlansPrefix: nil, - utils.ActionTriggerPrefix: nil, - utils.SharedGroupPrefix: nil, - utils.ResourceProfilesPrefix: nil, - utils.ResourcesPrefix: nil, - utils.StatQueuePrefix: nil, - utils.StatQueueProfilePrefix: nil, - utils.ThresholdPrefix: nil, - utils.ThresholdProfilePrefix: nil, - utils.FilterPrefix: nil, - utils.RouteProfilePrefix: nil, - utils.AttributeProfilePrefix: nil, - utils.ChargerProfilePrefix: nil, - utils.DispatcherProfilePrefix: nil, - utils.DispatcherHostPrefix: nil, - utils.ActionProfilePrefix: nil, - utils.TimingsPrefix: nil, - utils.AttributeFilterIndexes: nil, - utils.ResourceFilterIndexes: nil, - utils.StatFilterIndexes: nil, - utils.ThresholdFilterIndexes: nil, - utils.RouteFilterIndexes: nil, - utils.ChargerFilterIndexes: nil, - utils.DispatcherFilterIndexes: nil, - utils.ActionProfilesFilterIndexPrfx: nil, - utils.FilterIndexPrfx: nil, + utils.DestinationPrefix: nil, + utils.ReverseDestinationPrefix: nil, + utils.RatingPlanPrefix: nil, + utils.RatingProfilePrefix: nil, + utils.ActionPrefix: nil, + utils.ActionPlanPrefix: nil, + utils.AccountActionPlansPrefix: nil, + utils.ActionTriggerPrefix: nil, + utils.SharedGroupPrefix: nil, + utils.ResourceProfilesPrefix: nil, + utils.ResourcesPrefix: nil, + utils.StatQueuePrefix: nil, + utils.StatQueueProfilePrefix: nil, + utils.ThresholdPrefix: nil, + utils.ThresholdProfilePrefix: nil, + utils.FilterPrefix: nil, + utils.RouteProfilePrefix: nil, + utils.AttributeProfilePrefix: nil, + utils.ChargerProfilePrefix: nil, + utils.DispatcherProfilePrefix: nil, + utils.DispatcherHostPrefix: nil, + utils.TimingsPrefix: nil, + utils.AttributeFilterIndexes: nil, + utils.ResourceFilterIndexes: nil, + utils.StatFilterIndexes: nil, + utils.ThresholdFilterIndexes: nil, + utils.RouteFilterIndexes: nil, + utils.ChargerFilterIndexes: nil, + utils.DispatcherFilterIndexes: nil, + utils.FilterIndexPrfx: nil, } } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 146dee532..91f5464f5 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -106,9 +106,6 @@ func init() { if err := csvr.LoadDispatcherHosts(); err != nil { log.Print("error in LoadDispatcherHosts:", err) } - if err := csvr.LoadActionProfiles(); err != nil { - log.Print("error in LoadActionProfiles: ", err) - } if err := csvr.WriteToDatabase(false, false); err != nil { log.Print("error when writing into database ", err) } @@ -1395,94 +1392,6 @@ func TestLoadDispatcherProfiles(t *testing.T) { } } -func TestLoadActionProfiles(t *testing.T) { - expected := &utils.TPActionProfile{ - TPid: testTPID, - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - Weight: 10, - Schedule: utils.MetaASAP, - Targets: []*utils.TPActionTarget{ - { - TargetType: utils.MetaAccounts, - TargetIDs: []string{"1001", "1002"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "TOPUP", - TTL: "0s", - Type: "*add_balance", - Diktats: []*utils.TPAPDiktat{{ - Path: "*balance.TestBalance.Value", - Value: "10", - }}, - }, - { - ID: "SET_BALANCE_TEST_DATA", - TTL: "0s", - Type: "*set_balance", - Diktats: []*utils.TPAPDiktat{{ - Path: "*balance.TestDataBalance.Type", - Value: "*data", - }}, - }, - { - ID: "TOPUP_TEST_DATA", - TTL: "0s", - Type: "*add_balance", - Diktats: []*utils.TPAPDiktat{{ - Path: "*balance.TestDataBalance.Value", - Value: "1024", - }}, - }, - { - ID: "SET_BALANCE_TEST_VOICE", - TTL: "0s", - Type: "*set_balance", - Diktats: []*utils.TPAPDiktat{{ - Path: "*balance.TestVoiceBalance.Type", - Value: "*voice", - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - TTL: "0s", - Type: "*add_balance", - Diktats: []*utils.TPAPDiktat{{ - Path: "*balance.TestVoiceBalance.Value", - Value: "15m15s", - }, { - Path: "*balance.TestVoiceBalance2.Value", - Value: "15m15s", - }}, - }, - }, - } - - if len(csvr.actionProfiles) != 1 { - t.Fatalf("Failed to load ActionProfiles: %s", utils.ToJSON(csvr.actionProfiles)) - } - actPrfKey := utils.TenantID{ - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - } - sort.Slice(expected.Actions, func(i, j int) bool { - return false - }) - sort.Slice(expected.Targets[0].TargetIDs, func(i, j int) bool { - return expected.Targets[0].TargetIDs[i] < expected.Targets[0].TargetIDs[j] - }) - sort.Slice(csvr.actionProfiles[actPrfKey].Targets[0].TargetIDs, func(i, j int) bool { - return csvr.actionProfiles[actPrfKey].Targets[0].TargetIDs[i] < csvr.actionProfiles[actPrfKey].Targets[0].TargetIDs[j] - }) - - if !reflect.DeepEqual(csvr.actionProfiles[actPrfKey], expected) { - t.Errorf("Expecting: %+v,\n received: %+v", - utils.ToJSON(expected), utils.ToJSON(csvr.actionProfiles[actPrfKey])) - } -} - func TestLoadDispatcherHosts(t *testing.T) { eDispatcherHosts := &utils.TPDispatcherHost{ TPid: testTPID, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 6899d19d9..622f40e03 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -2866,257 +2866,3 @@ func DispatcherHostToAPI(dph *DispatcherHost) (tpDPH *utils.TPDispatcherHost) { }, } } - -type ActionProfileMdls []*ActionProfileMdl - -// CSVHeader return the header for csv fields as a slice of string -func (apm ActionProfileMdls) CSVHeader() (result []string) { - return []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, - utils.ActivationIntervalString, utils.Weight, utils.Schedule, utils.TargetType, - utils.TargetIDs, utils.ActionID, utils.ActionFilterIDs, utils.ActionBlocker, utils.ActionTTL, - utils.ActionType, utils.ActionOpts, utils.ActionPath, utils.ActionValue, - } -} - -func (tps ActionProfileMdls) AsTPActionProfile() (result []*utils.TPActionProfile) { - filterIDsMap := make(map[string]utils.StringSet) - targetIDsMap := make(map[string]map[string]utils.StringSet) - actPrfMap := make(map[string]*utils.TPActionProfile) - for _, tp := range tps { - tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() - aPrf, found := actPrfMap[tenID] - if !found { - aPrf = &utils.TPActionProfile{ - TPid: tp.Tpid, - Tenant: tp.Tenant, - ID: tp.ID, - } - } - if tp.FilterIDs != utils.EmptyString { - if _, has := filterIDsMap[tenID]; !has { - filterIDsMap[tenID] = make(utils.StringSet) - } - filterIDsMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) - } - if tp.ActivationInterval != utils.EmptyString { - aPrf.ActivationInterval = new(utils.TPActivationInterval) - aiSplt := strings.Split(tp.ActivationInterval, utils.InfieldSep) - if len(aiSplt) == 2 { - aPrf.ActivationInterval.ActivationTime = aiSplt[0] - aPrf.ActivationInterval.ExpiryTime = aiSplt[1] - } else if len(aiSplt) == 1 { - aPrf.ActivationInterval.ActivationTime = aiSplt[0] - } - } - if tp.Weight != 0 { - aPrf.Weight = tp.Weight - } - if tp.Schedule != utils.EmptyString { - aPrf.Schedule = tp.Schedule - } - if tp.TargetType != utils.EmptyString { - if _, has := targetIDsMap[tenID]; !has { - targetIDsMap[tenID] = make(map[string]utils.StringSet) - } - targetIDsMap[tenID][tp.TargetType] = utils.NewStringSet(strings.Split(tp.TargetIDs, utils.InfieldSep)) - } - - if tp.ActionID != utils.EmptyString { - var tpAAction *utils.TPAPAction - if lacts := len(aPrf.Actions); lacts == 0 || - aPrf.Actions[lacts-1].ID != tp.ActionID { - tpAAction = &utils.TPAPAction{ - ID: tp.ActionID, - Blocker: tp.ActionBlocker, - TTL: tp.ActionTTL, - Type: tp.ActionType, - Opts: tp.ActionOpts, - Diktats: []*utils.TPAPDiktat{{ - Path: tp.ActionPath, - Value: tp.ActionValue, - }}, - } - if tp.ActionFilterIDs != utils.EmptyString { - tpAAction.FilterIDs = utils.NewStringSet(strings.Split(tp.ActionFilterIDs, utils.InfieldSep)).AsSlice() - } - aPrf.Actions = append(aPrf.Actions, tpAAction) - } else { - aPrf.Actions[lacts-1].Diktats = append(aPrf.Actions[lacts-1].Diktats, &utils.TPAPDiktat{ - Path: tp.ActionPath, - Value: tp.ActionValue, - }) - } - } - actPrfMap[tenID] = aPrf - } - result = make([]*utils.TPActionProfile, len(actPrfMap)) - i := 0 - for tntID, th := range actPrfMap { - result[i] = th - result[i].FilterIDs = filterIDsMap[tntID].AsSlice() - for targetType, targetIDs := range targetIDsMap[tntID] { - result[i].Targets = append(result[i].Targets, &utils.TPActionTarget{TargetType: targetType, TargetIDs: targetIDs.AsSlice()}) - } - i++ - } - return -} - -func APItoModelTPActionProfile(tPrf *utils.TPActionProfile) (mdls ActionProfileMdls) { - if len(tPrf.Actions) == 0 { - return - } - for i, action := range tPrf.Actions { - mdl := &ActionProfileMdl{ - Tenant: tPrf.Tenant, - Tpid: tPrf.TPid, - ID: tPrf.ID, - } - if i == 0 { - mdl.FilterIDs = strings.Join(tPrf.FilterIDs, utils.InfieldSep) - - if tPrf.ActivationInterval != nil { - if tPrf.ActivationInterval.ActivationTime != utils.EmptyString { - mdl.ActivationInterval = tPrf.ActivationInterval.ActivationTime - } - if tPrf.ActivationInterval.ExpiryTime != utils.EmptyString { - mdl.ActivationInterval += utils.InfieldSep + tPrf.ActivationInterval.ExpiryTime - } - } - mdl.Weight = tPrf.Weight - mdl.Schedule = tPrf.Schedule - for _, target := range tPrf.Targets { - mdl.TargetType = target.TargetType - mdl.TargetIDs = strings.Join(target.TargetIDs, utils.InfieldSep) - } - } - mdl.ActionID = action.ID - mdl.ActionFilterIDs = strings.Join(action.FilterIDs, utils.InfieldSep) - - mdl.ActionBlocker = action.Blocker - mdl.ActionTTL = action.TTL - mdl.ActionType = action.Type - mdl.ActionOpts = action.Opts - for j, actD := range action.Diktats { - if j != 0 { - mdl = &ActionProfileMdl{ - Tenant: mdl.Tenant, - Tpid: mdl.Tpid, - ID: mdl.ID, - ActionID: mdl.ActionID, - ActionType: mdl.ActionType, - } - } - mdl.ActionPath = actD.Path - mdl.ActionValue = actD.Value - mdls = append(mdls, mdl) - } - } - return -} - -func APItoActionProfile(tpAp *utils.TPActionProfile, timezone string) (ap *ActionProfile, err error) { - ap = &ActionProfile{ - Tenant: tpAp.Tenant, - ID: tpAp.ID, - FilterIDs: make([]string, len(tpAp.FilterIDs)), - Weight: tpAp.Weight, - Schedule: tpAp.Schedule, - Targets: make(map[string]utils.StringSet), - Actions: make([]*APAction, len(tpAp.Actions)), - } - for i, stp := range tpAp.FilterIDs { - ap.FilterIDs[i] = stp - } - if tpAp.ActivationInterval != nil { - if ap.ActivationInterval, err = tpAp.ActivationInterval.AsActivationInterval(timezone); err != nil { - return - } - } - for _, target := range tpAp.Targets { - ap.Targets[target.TargetType] = utils.NewStringSet(target.TargetIDs) - } - for i, act := range tpAp.Actions { - actDs := make([]*APDiktat, len(act.Diktats)) - for j, actD := range act.Diktats { - actDs[j] = &APDiktat{ - Path: actD.Path, - Value: actD.Value, - } - } - ap.Actions[i] = &APAction{ - ID: act.ID, - FilterIDs: act.FilterIDs, - Blocker: act.Blocker, - Type: act.Type, - Diktats: actDs, - } - if ap.Actions[i].TTL, err = utils.ParseDurationWithNanosecs(act.TTL); err != nil { - return - } - if act.Opts != utils.EmptyString { - ap.Actions[i].Opts = make(map[string]interface{}) - for _, opt := range strings.Split(act.Opts, utils.InfieldSep) { // example of opts: key1:val1;key2:val2;key3:val3 - keyValSls := utils.SplitConcatenatedKey(opt) - if len(keyValSls) != 2 { - err = fmt.Errorf("malformed option for ActionProfile <%s> for action <%s>", ap.TenantID(), act.ID) - return - } - ap.Actions[i].Opts[keyValSls[0]] = keyValSls[1] - } - } - - } - return -} - -func ActionProfileToAPI(ap *ActionProfile) (tpAp *utils.TPActionProfile) { - tpAp = &utils.TPActionProfile{ - Tenant: ap.Tenant, - ID: ap.ID, - FilterIDs: make([]string, len(ap.FilterIDs)), - ActivationInterval: new(utils.TPActivationInterval), - Weight: ap.Weight, - Schedule: ap.Schedule, - Targets: make([]*utils.TPActionTarget, 0, len(ap.Targets)), - Actions: make([]*utils.TPAPAction, len(ap.Actions)), - } - for i, fli := range ap.FilterIDs { - tpAp.FilterIDs[i] = fli - } - if ap.ActivationInterval != nil { - if !ap.ActivationInterval.ActivationTime.IsZero() { - tpAp.ActivationInterval.ActivationTime = ap.ActivationInterval.ActivationTime.Format(time.RFC3339) - } - if !ap.ActivationInterval.ExpiryTime.IsZero() { - tpAp.ActivationInterval.ExpiryTime = ap.ActivationInterval.ExpiryTime.Format(time.RFC3339) - } - } - for targetType, targetIDs := range ap.Targets { - tpAp.Targets = append(tpAp.Targets, &utils.TPActionTarget{TargetType: targetType, TargetIDs: targetIDs.AsSlice()}) - } - for i, act := range ap.Actions { - actDs := make([]*utils.TPAPDiktat, len(act.Diktats)) - for j, actD := range act.Diktats { - actDs[j] = &utils.TPAPDiktat{ - Path: actD.Path, - Value: actD.Value, - } - } - - elems := make([]string, 0, len(act.Opts)) - for k, v := range act.Opts { - elems = append(elems, utils.ConcatenatedKey(k, utils.IfaceAsString(v))) - } - tpAp.Actions[i] = &utils.TPAPAction{ - ID: act.ID, - FilterIDs: act.FilterIDs, - Blocker: act.Blocker, - TTL: act.TTL.String(), - Type: act.Type, - Diktats: actDs, - Opts: strings.Join(elems, utils.InfieldSep), - } - } - return -} diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 99d81c2df..39706c84e 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -4867,379 +4867,6 @@ func TestThresholdMdlsCSVHeader(t *testing.T) { t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) } } -func TestActionProfileMdlsCSVHeader(t *testing.T) { - testStruct := ActionProfileMdls{ - { - Tpid: "test_tpid", - Tenant: "test_tenant", - }, - } - expStruct := []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, - utils.ActivationIntervalString, utils.Weight, utils.Schedule, utils.TargetType, - utils.TargetIDs, utils.ActionID, utils.ActionFilterIDs, utils.ActionBlocker, utils.ActionTTL, - utils.ActionType, utils.ActionOpts, utils.ActionPath, utils.ActionValue, - } - result := testStruct.CSVHeader() - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} - -func TestActionProfileMdlsAsTPActionProfileTimeLen1(t *testing.T) { - testStruct := ActionProfileMdls{ - { - Tpid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "*string:~*req.Subject:1001", - ActivationInterval: "2014-07-29T15:00:00Z", - Weight: 1, - Schedule: "test_schedule", - ActionID: "test_action_id", - ActionFilterIDs: "test_action_filter_ids", - }, - } - expStruct := []*utils.TPActionProfile{ - { - TPid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-29T15:00:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_ids"}, - Diktats: []*utils.TPAPDiktat{{}}, - }, - }, - }, - } - result := testStruct.AsTPActionProfile() - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting %s,\n Received %s", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} - -func TestActionProfileMdlsAsTPActionProfile(t *testing.T) { - testStruct := ActionProfileMdls{ - { - Tpid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "*string:~*req.Subject:1001", - ActivationInterval: "2014-07-29T15:00:00Z;2014-08-29T15:00:00Z", - Weight: 1, - Schedule: "test_schedule", - TargetType: utils.MetaAccounts, - TargetIDs: "test_account_id1;test_account_id2", - ActionID: "test_action_id", - ActionFilterIDs: "test_action_filter_ids", - }, - } - expStruct := []*utils.TPActionProfile{ - { - TPid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-29T15:00:00Z", - ExpiryTime: "2014-08-29T15:00:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{ - &utils.TPActionTarget{ - TargetType: utils.MetaAccounts, - TargetIDs: []string{"test_account_id1", "test_account_id2"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_ids"}, - Diktats: []*utils.TPAPDiktat{{}}, - }, - }, - }, - } - - result := testStruct.AsTPActionProfile() - sort.Slice(result[0].Targets[0].TargetIDs, func(i, j int) bool { - return result[0].Targets[0].TargetIDs[i] < result[0].Targets[0].TargetIDs[j] - }) - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} - -func TestAPItoModelTPActionProfileTPActionProfileNil(t *testing.T) { - testStruct := &utils.TPActionProfile{} - expStruct := ActionProfileMdls{} - expStruct = nil - result := APItoModelTPActionProfile(testStruct) - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} - -func TestAPItoModelTPActionProfileTPActionProfile(t *testing.T) { - testStruct := &utils.TPActionProfile{ - TPid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-29T15:00:00Z", - ExpiryTime: "2014-08-29T15:00:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{{ - TargetType: utils.MetaAccounts, - TargetIDs: []string{"test_account_id1", "test_account_id2"}, - }}, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*utils.TPAPDiktat{{}}, - }, - }, - } - - expStruct := ActionProfileMdls{{ - Tpid: "test_id", - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: "*string:~*req.Subject:1001;*string:~*req.Subject:1002", - ActivationInterval: "2014-07-29T15:00:00Z;2014-08-29T15:00:00Z", - Weight: 1, - Schedule: "test_schedule", - TargetType: utils.MetaAccounts, - TargetIDs: "test_account_id1;test_account_id2", - ActionID: "test_action_id", - ActionFilterIDs: "test_action_filter_id1;test_action_filter_id2", - }} - result := APItoModelTPActionProfile(testStruct) - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting %s,\n Received %s", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} - -func TestModelHelpersAPItoActionProfile(t *testing.T) { - testStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{ - &utils.TPActionTarget{ - TargetType: utils.MetaAccounts, - TargetIDs: []string{"test_account_id1", "test_account_id2"}, - }, - &utils.TPActionTarget{ - TargetType: utils.MetaResources, - TargetIDs: []string{"test_ID1", "test_ID2"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - Opts: "key1:val1;key2:val2", - }, - }, - } - - expStruct := &ActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), - ExpiryTime: time.Date(2014, 7, 15, 14, 25, 0, 0, time.UTC), - }, - Weight: 1, - Schedule: "test_schedule", - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.NewStringSet([]string{"test_account_id1", "test_account_id2"}), - utils.MetaResources: utils.NewStringSet([]string{"test_ID1", "test_ID2"}), - }, - Actions: []*APAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*APDiktat{{ - Path: "test_path", - }}, - Opts: map[string]interface{}{ - "key1": "val1", - "key2": "val2", - }, - }, - }, - } - result, _ := APItoActionProfile(testStruct, "") - sort.Strings(result.FilterIDs) - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) - } - -} - -func TestModelHelpersAPItoActionProfileError1(t *testing.T) { - testStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "cat", - ExpiryTime: "cat", - }, - Weight: 1, - Schedule: "test_schedule", - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - }, - }, - } - - _, err := APItoActionProfile(testStruct, "") - if err == nil || err.Error() != "Unsupported time format" { - t.Errorf("\nExpecting ,\n Received <%+v>", err) - } -} - -func TestModelHelpersAPItoActionProfileError3(t *testing.T) { - testStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - TTL: "cat", - }, - }, - } - - _, err := APItoActionProfile(testStruct, "") - if err == nil || err.Error() != "time: invalid duration \"cat\"" { - t.Errorf("\nExpecting ,\n Received <%+v>", err) - } -} - -func TestModelHelpersAPItoActionProfileError4(t *testing.T) { - testStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - Opts: "test_opt", - }, - }, - } - - _, err := APItoActionProfile(testStruct, "") - if err == nil || err.Error() != "malformed option for ActionProfile for action " { - t.Errorf("\nExpecting for action >,\n Received <%+v>", err) - } -} - -func TestModelHelpersActionProfileToAPI(t *testing.T) { - testStruct := &ActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.ActivationInterval{ - ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), - ExpiryTime: time.Date(2014, 7, 15, 14, 25, 0, 0, time.UTC), - }, - Weight: 1, - Schedule: "test_schedule", - Actions: []*APAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - TTL: time.Second, - Diktats: []*APDiktat{{ - Path: "test_path", - }}, - Opts: map[string]interface{}{ - "key1": "val1", - }, - }, - }, - } - expStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001", "*string:~*req.Subject:1002"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{}, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1", "test_action_filter_id2"}, - TTL: "1s", - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - Opts: "key1:val1", - }, - }, - } - result := ActionProfileToAPI(testStruct) - if !reflect.DeepEqual(result, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result)) - } -} func TestChargerMdlsCSVHeader(t *testing.T) { @@ -6145,75 +5772,3 @@ func TestModelHelpersCSVLoadErrorBool(t *testing.T) { t.Errorf("\nExpecting ,\n Received <%+v>", err) } } - -func TestModelHelpersActionProfileToAPICase2(t *testing.T) { - testStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{ - &utils.TPActionTarget{ - TargetType: utils.MetaAccounts, - TargetIDs: []string{"test_account_id1", "test_account_id2"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - Opts: "key1:val1", - }, - }, - } - - expStruct := &utils.TPActionProfile{ - Tenant: "cgrates.org", - ID: "RP1", - FilterIDs: []string{"*string:~*req.Subject:1001"}, - ActivationInterval: &utils.TPActivationInterval{ - ActivationTime: "2014-07-14T14:25:00Z", - ExpiryTime: "2014-07-15T14:25:00Z", - }, - Weight: 1, - Schedule: "test_schedule", - Targets: []*utils.TPActionTarget{ - &utils.TPActionTarget{ - TargetType: utils.MetaAccounts, - TargetIDs: []string{"test_account_id1", "test_account_id2"}, - }, - }, - Actions: []*utils.TPAPAction{ - { - ID: "test_action_id", - FilterIDs: []string{"test_action_filter_id1"}, - Diktats: []*utils.TPAPDiktat{{ - Path: "test_path", - }}, - Opts: "key1:val1", - TTL: "0s", - }, - }, - } - - result, err := APItoActionProfile(testStruct, "") - if err != nil { - t.Errorf("\nExpecting ,\n Received <%+v>", err) - } - result2 := ActionProfileToAPI(result) - sort.Strings(result2.FilterIDs) - sort.Strings(expStruct.FilterIDs) - sort.Strings(result2.Targets[0].TargetIDs) - sort.Strings(expStruct.Targets[0].TargetIDs) - if !reflect.DeepEqual(result2, expStruct) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ToJSON(expStruct), utils.ToJSON(result2)) - } -} diff --git a/engine/models.go b/engine/models.go index 508fc3e6e..ebaf0aa7f 100644 --- a/engine/models.go +++ b/engine/models.go @@ -509,30 +509,3 @@ type DispatcherHostMdl struct { func (DispatcherHostMdl) TableName() string { return utils.TBLTPDispatcherHosts } - -type ActionProfileMdl struct { - PK uint `gorm:"primary_key"` - Tpid string - Tenant string `index:"0" re:""` - ID string `index:"1" re:""` - FilterIDs string `index:"2" re:""` - ActivationInterval string `index:"3" re:""` - Weight float64 `index:"4" re:"\d+\.?\d*"` - Schedule string `index:"5" re:""` - TargetType string `index:"6" re:""` - TargetIDs string `index:"7" re:""` - ActionID string `index:"8" re:""` - ActionFilterIDs string `index:"9" re:""` - ActionBlocker bool `index:"10" re:""` - ActionTTL string `index:"11" re:""` - ActionType string `index:"12" re:""` - ActionOpts string `index:"13" re:""` - ActionPath string `index:"14" re:""` - ActionValue string `index:"15" re:""` - - CreatedAt time.Time -} - -func (ActionProfileMdl) TableName() string { - return utils.TBLTPActionProfiles -} diff --git a/engine/storage_csv.go b/engine/storage_csv.go index bcd5bafbf..7fbd2d61d 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -64,7 +64,6 @@ type CSVStorage struct { chargerProfilesFn []string dispatcherProfilesFn []string dispatcherHostsFn []string - actionProfilesFn []string } // NewCSVStorage creates a CSV storege that takes the data from the paths specified @@ -97,7 +96,6 @@ func NewCSVStorage(sep rune, chargerProfilesFn: chargerProfilesFn, dispatcherProfilesFn: dispatcherProfilesFn, dispatcherHostsFn: dispatcherHostsFn, - actionProfilesFn: actionProfilesFn, } } @@ -127,7 +125,6 @@ func NewFileCSVStorage(sep rune, dataPath string) *CSVStorage { chargersPaths := appendName(allFoldersPath, utils.ChargersCsv) dispatcherprofilesPaths := appendName(allFoldersPath, utils.DispatcherProfilesCsv) dispatcherhostsPaths := appendName(allFoldersPath, utils.DispatcherHostsCsv) - actionProfilesFn := appendName(allFoldersPath, utils.ActionProfilesCsv) return NewCSVStorage(sep, destinationsPaths, timingsPaths, @@ -149,7 +146,6 @@ func NewFileCSVStorage(sep rune, dataPath string) *CSVStorage { chargersPaths, dispatcherprofilesPaths, dispatcherhostsPaths, - actionProfilesFn, ) } @@ -239,7 +235,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { var chargersPaths []string var dispatcherprofilesPaths []string var dispatcherhostsPaths []string - var actionProfilesPaths []string for _, baseURL := range strings.Split(dataPath, utils.InfieldSep) { if !strings.HasSuffix(baseURL, utils.CSVSuffix) { @@ -263,7 +258,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { chargersPaths = append(chargersPaths, joinURL(baseURL, utils.ChargersCsv)) dispatcherprofilesPaths = append(dispatcherprofilesPaths, joinURL(baseURL, utils.DispatcherProfilesCsv)) dispatcherhostsPaths = append(dispatcherhostsPaths, joinURL(baseURL, utils.DispatcherHostsCsv)) - actionProfilesPaths = append(actionProfilesPaths, joinURL(baseURL, utils.ActionProfilesCsv)) continue } switch { @@ -307,9 +301,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { dispatcherprofilesPaths = append(dispatcherprofilesPaths, baseURL) case strings.HasSuffix(baseURL, utils.DispatcherHostsCsv): dispatcherhostsPaths = append(dispatcherhostsPaths, baseURL) - case strings.HasSuffix(baseURL, utils.ActionProfilesCsv): - actionProfilesPaths = append(actionProfilesPaths, baseURL) - } } @@ -334,7 +325,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage { chargersPaths, dispatcherprofilesPaths, dispatcherhostsPaths, - actionProfilesPaths, ) c.generator = func() csvReaderCloser { return &csvURL{} @@ -649,18 +639,6 @@ func (csvs *CSVStorage) GetTPDispatcherHosts(tpid, tenant, id string) ([]*utils. return tpDDHs.AsTPDispatcherHosts(), nil } -func (csvs *CSVStorage) GetTPActionProfiles(tpid, tenant, id string) ([]*utils.TPActionProfile, error) { - var tpDPPs ActionProfileMdls - if err := csvs.proccesData(ActionProfileMdl{}, csvs.actionProfilesFn, func(tp interface{}) { - dpp := tp.(ActionProfileMdl) - dpp.Tpid = tpid - tpDPPs = append(tpDPPs, &dpp) - }); err != nil { - return nil, err - } - return tpDPPs.AsTPActionProfile(), nil -} - func (csvs *CSVStorage) GetTpIds(colName string) ([]string, error) { return nil, utils.ErrNotImplemented } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index d98349b92..0f89290e7 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -129,9 +129,6 @@ type DataDB interface { GetDispatcherHostDrv(string, string) (*DispatcherHost, error) SetDispatcherHostDrv(*DispatcherHost) error RemoveDispatcherHostDrv(string, string) error - GetActionProfileDrv(string, string) (*ActionProfile, error) - SetActionProfileDrv(*ActionProfile) error - RemoveActionProfileDrv(string, string) error } type StorDB interface { @@ -181,7 +178,6 @@ type LoadReader interface { GetTPChargers(string, string, string) ([]*utils.TPChargerProfile, error) GetTPDispatcherProfiles(string, string, string) ([]*utils.TPDispatcherProfile, error) GetTPDispatcherHosts(string, string, string) ([]*utils.TPDispatcherHost, error) - GetTPActionProfiles(string, string, string) ([]*utils.TPActionProfile, error) } type LoadWriter interface { @@ -206,7 +202,6 @@ type LoadWriter interface { SetTPChargers([]*utils.TPChargerProfile) error SetTPDispatcherProfiles([]*utils.TPDispatcherProfile) error SetTPDispatcherHosts([]*utils.TPDispatcherHost) error - SetTPActionProfiles([]*utils.TPActionProfile) error } // NewMarshaler returns the marshaler type selected by mrshlerStr diff --git a/engine/storage_internal_datadb.go b/engine/storage_internal_datadb.go index 6e82d9fdd..9a73453ff 100644 --- a/engine/storage_internal_datadb.go +++ b/engine/storage_internal_datadb.go @@ -819,26 +819,6 @@ func (iDB *InternalDB) RemoveDispatcherHostDrv(tenant, id string) (err error) { return } -func (iDB *InternalDB) GetActionProfileDrv(tenant, id string) (ap *ActionProfile, err error) { - x, ok := Cache.Get(utils.CacheActionProfiles, utils.ConcatenatedKey(tenant, id)) - if !ok || x == nil { - return nil, utils.ErrNotFound - } - return x.(*ActionProfile), nil -} - -func (iDB *InternalDB) SetActionProfileDrv(ap *ActionProfile) (err error) { - Cache.SetWithoutReplicate(utils.CacheActionProfiles, ap.TenantID(), ap, nil, - cacheCommit(utils.NonTransactional), utils.NonTransactional) - return -} - -func (iDB *InternalDB) RemoveActionProfileDrv(tenant, id string) (err error) { - Cache.RemoveWithoutReplicate(utils.CacheActionProfiles, utils.ConcatenatedKey(tenant, id), - cacheCommit(utils.NonTransactional), utils.NonTransactional) - return -} - func (iDB *InternalDB) RemoveLoadIDsDrv() (err error) { return utils.ErrNotImplemented } diff --git a/engine/storage_internal_stordb.go b/engine/storage_internal_stordb.go index 1597f25be..d920245cf 100644 --- a/engine/storage_internal_stordb.go +++ b/engine/storage_internal_stordb.go @@ -563,28 +563,6 @@ func (iDB *InternalDB) GetTPDispatcherHosts(tpid, tenant, id string) (dpps []*ut return } -func (iDB *InternalDB) GetTPActionProfiles(tpid, tenant, id string) (tpPrfs []*utils.TPActionProfile, err error) { - key := tpid - if tenant != utils.EmptyString { - key += utils.ConcatenatedKeySep + tenant - } - if id != utils.EmptyString { - key += utils.ConcatenatedKeySep + id - } - ids := Cache.GetItemIDs(utils.CacheTBLTPActionProfiles, key) - for _, id := range ids { - x, ok := Cache.Get(utils.CacheTBLTPActionProfiles, id) - if !ok || x == nil { - return nil, utils.ErrNotFound - } - tpPrfs = append(tpPrfs, x.(*utils.TPActionProfile)) - } - if len(tpPrfs) == 0 { - return nil, utils.ErrNotFound - } - return -} - //implement LoadWriter interface func (iDB *InternalDB) RemTpData(table, tpid string, args map[string]string) (err error) { if table == utils.EmptyString { @@ -836,17 +814,6 @@ func (iDB *InternalDB) SetTPDispatcherHosts(dpps []*utils.TPDispatcherHost) (err return } -func (iDB *InternalDB) SetTPActionProfiles(tpPrfs []*utils.TPActionProfile) (err error) { - if len(tpPrfs) == 0 { - return nil - } - for _, tpPrf := range tpPrfs { - Cache.SetWithoutReplicate(utils.CacheTBLTPActionProfiles, utils.ConcatenatedKey(tpPrf.TPid, tpPrf.Tenant, tpPrf.ID), tpPrf, nil, - cacheCommit(utils.NonTransactional), utils.NonTransactional) - } - return -} - //implement CdrStorage interface func (iDB *InternalDB) SetCDR(cdr *CDR, allowUpdate bool) (err error) { if cdr.OrderID == 0 { diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index c57084b05..fe6176753 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -636,8 +636,13 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result, err = ms.getField2(sctx, ColCpp, utils.ChargerProfilePrefix, subject, tntID) case utils.DispatcherProfilePrefix: result, err = ms.getField2(sctx, ColDpp, utils.DispatcherProfilePrefix, subject, tntID) +<<<<<<< HEAD case utils.ActionProfilePrefix: result, err = ms.getField2(sctx, ColApp, utils.ActionProfilePrefix, subject, tntID) +======= + case utils.AccountProfilePrefix: + result, err = ms.getField2(sctx, ColAnp, utils.AccountProfilePrefix, subject, tntID) +>>>>>>> Removing ActionS case utils.DispatcherHostPrefix: result, err = ms.getField2(sctx, ColDph, utils.DispatcherHostPrefix, subject, tntID) case utils.AttributeFilterIndexes: @@ -656,6 +661,11 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er result, err = ms.getField3(sctx, ColIndx, utils.DispatcherFilterIndexes, "key") case utils.ActionPlanIndexes: result, err = ms.getField3(sctx, ColIndx, utils.ActionPlanIndexes, "key") +<<<<<<< HEAD +======= + case utils.AccountProfileFilterIndexPrfx: + result, err = ms.getField3(sctx, ColIndx, utils.AccountProfileFilterIndexPrfx, "key") +>>>>>>> Removing ActionS case utils.FilterIndexPrfx: result, err = ms.getField3(sctx, ColIndx, utils.FilterIndexPrfx, "key") default: @@ -706,8 +716,13 @@ func (ms *MongoStorage) HasDataDrv(category, subject, tenant string) (has bool, count, err = ms.getCol(ColDpp).CountDocuments(sctx, bson.M{"tenant": tenant, "id": subject}) case utils.DispatcherHostPrefix: count, err = ms.getCol(ColDph).CountDocuments(sctx, bson.M{"tenant": tenant, "id": subject}) +<<<<<<< HEAD case utils.ActionProfilePrefix: count, err = ms.getCol(ColApp).CountDocuments(sctx, bson.M{"tenant": tenant, "id": subject}) +======= + case utils.AccountProfilePrefix: + count, err = ms.getCol(ColAnp).CountDocuments(sctx, bson.M{"tenant": tenant, "id": subject}) +>>>>>>> Removing ActionS default: err = fmt.Errorf("unsupported category in HasData: %s", category) } @@ -1997,42 +2012,6 @@ func (ms *MongoStorage) RemoveLoadIDsDrv() (err error) { }) } -func (ms *MongoStorage) GetActionProfileDrv(tenant, id string) (ap *ActionProfile, err error) { - ap = new(ActionProfile) - err = ms.query(func(sctx mongo.SessionContext) (err error) { - cur := ms.getCol(ColApp).FindOne(sctx, bson.M{"tenant": tenant, "id": id}) - if err := cur.Decode(ap); err != nil { - ap = nil - if err == mongo.ErrNoDocuments { - return utils.ErrNotFound - } - return err - } - return nil - }) - return -} - -func (ms *MongoStorage) SetActionProfileDrv(ap *ActionProfile) (err error) { - return ms.query(func(sctx mongo.SessionContext) (err error) { - _, err = ms.getCol(ColApp).UpdateOne(sctx, bson.M{"tenant": ap.Tenant, "id": ap.ID}, - bson.M{"$set": ap}, - options.Update().SetUpsert(true), - ) - return err - }) -} - -func (ms *MongoStorage) RemoveActionProfileDrv(tenant, id string) (err error) { - return ms.query(func(sctx mongo.SessionContext) (err error) { - dr, err := ms.getCol(ColApp).DeleteOne(sctx, bson.M{"tenant": tenant, "id": id}) - if dr.DeletedCount == 0 { - return utils.ErrNotFound - } - return err - }) -} - // GetIndexesDrv retrieves Indexes from dataDB // the key is the tenant of the item or in case of context dependent profiles is a concatenatedKey between tenant and context // id is used as a concatenated key in case of filterIndexes the id will be filterType:fieldName:fieldVal diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go index aab8e70aa..f97dbbe22 100644 --- a/engine/storage_mongo_stordb.go +++ b/engine/storage_mongo_stordb.go @@ -1529,54 +1529,6 @@ func (ms *MongoStorage) SetTPDispatcherHosts(tpDPPs []*utils.TPDispatcherHost) ( }) } -func (ms *MongoStorage) GetTPActionProfiles(tpid, tenant, id string) ([]*utils.TPActionProfile, error) { - filter := bson.M{"tpid": tpid} - if id != "" { - filter["id"] = id - } - if tenant != "" { - filter["tenant"] = tenant - } - var results []*utils.TPActionProfile - err := ms.query(func(sctx mongo.SessionContext) (err error) { - cur, err := ms.getCol(utils.TBLTPActionProfiles).Find(sctx, filter) - if err != nil { - return err - } - for cur.Next(sctx) { - var tp utils.TPActionProfile - err := cur.Decode(&tp) - if err != nil { - return err - } - results = append(results, &tp) - } - if len(results) == 0 { - return utils.ErrNotFound - } - return cur.Close(sctx) - }) - return results, err -} - -func (ms *MongoStorage) SetTPActionProfiles(tpAps []*utils.TPActionProfile) (err error) { - if len(tpAps) == 0 { - return - } - return ms.query(func(sctx mongo.SessionContext) (err error) { - for _, tp := range tpAps { - _, err = ms.getCol(utils.TBLTPActionProfiles).UpdateOne(sctx, bson.M{"tpid": tp.TPid, "id": tp.ID}, - bson.M{"$set": tp}, - options.Update().SetUpsert(true), - ) - if err != nil { - return err - } - } - return nil - }) -} - func (ms *MongoStorage) GetVersions(itm string) (vrs Versions, err error) { fop := options.FindOne() if itm != "" { diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 7b2214085..67cc42cde 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -1247,30 +1247,6 @@ func (rs *RedisStorage) RemoveLoadIDsDrv() (err error) { return rs.Cmd(nil, redis_DEL, utils.LoadIDs) } -func (rs *RedisStorage) GetActionProfileDrv(tenant, id string) (ap *ActionProfile, err error) { - var values []byte - if err = rs.Cmd(&values, redis_GET, utils.ActionProfilePrefix+utils.ConcatenatedKey(tenant, id)); err != nil { - return - } else if len(values) == 0 { - err = utils.ErrNotFound - return - } - err = rs.ms.Unmarshal(values, &ap) - return -} - -func (rs *RedisStorage) SetActionProfileDrv(ap *ActionProfile) (err error) { - var result []byte - if result, err = rs.ms.Marshal(ap); err != nil { - return - } - return rs.Cmd(nil, redis_SET, utils.ActionProfilePrefix+utils.ConcatenatedKey(ap.Tenant, ap.ID), string(result)) -} - -func (rs *RedisStorage) RemoveActionProfileDrv(tenant, id string) (err error) { - return rs.Cmd(nil, redis_DEL, utils.ActionProfilePrefix+utils.ConcatenatedKey(tenant, id)) -} - // GetIndexesDrv retrieves Indexes from dataDB func (rs *RedisStorage) GetIndexesDrv(idxItmType, tntCtx, idxKey string) (indexes map[string]utils.StringSet, err error) { mp := make(map[string]string) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index f116f1915..e9d3cebae 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -728,27 +728,6 @@ func (sqls *SQLStorage) SetTPDispatcherHosts(tpDPPs []*utils.TPDispatcherHost) e return nil } -func (sqls *SQLStorage) SetTPActionProfiles(tpAps []*utils.TPActionProfile) error { - if len(tpAps) == 0 { - return nil - } - tx := sqls.db.Begin() - for _, tpAp := range tpAps { - // Remove previous - if err := tx.Where(&ActionProfileMdl{Tpid: tpAp.TPid, Tenant: tpAp.Tenant, ID: tpAp.ID}).Delete(ActionProfileMdl{}).Error; err != nil { - tx.Rollback() - return err - } - for _, mst := range APItoModelTPActionProfile(tpAp) { - if err := tx.Create(&mst).Error; err != nil { - tx.Rollback() - return err - } - } - } - tx.Commit() - return nil -} func (sqls *SQLStorage) SetSMCost(smc *SMCost) error { if smc.CostDetails == nil { return nil @@ -1572,26 +1551,6 @@ func (sqls *SQLStorage) GetTPDispatcherHosts(tpid, tenant, id string) ([]*utils. return arls, nil } -func (sqls *SQLStorage) GetTPActionProfiles(tpid, tenant, id string) ([]*utils.TPActionProfile, error) { - var dpps ActionProfileMdls - q := sqls.db.Where("tpid = ?", tpid) - - if len(id) != 0 { - q = q.Where("id = ?", id) - } - if len(tenant) != 0 { - q = q.Where("tenant = ?", tenant) - } - if err := q.Find(&dpps).Error; err != nil { - return nil, err - } - arls := dpps.AsTPActionProfile() - if len(arls) == 0 { - return arls, utils.ErrNotFound - } - return arls, nil -} - // GetVersions returns slice of all versions or a specific version if tag is specified func (sqls *SQLStorage) GetVersions(itm string) (vrs Versions, err error) { q := sqls.db.Model(&TBLVersion{}) diff --git a/engine/tpexporter.go b/engine/tpexporter.go index bd266bec1..e246644c1 100644 --- a/engine/tpexporter.go +++ b/engine/tpexporter.go @@ -320,18 +320,6 @@ func (tpExp *TPExporter) Run() error { toExportMap[utils.DispatcherHostsCsv] = append(toExportMap[utils.DispatcherHostsCsv], APItoModelTPDispatcherHost(sd)) } - storDataActionProfiles, err := tpExp.storDb.GetTPActionProfiles(tpExp.tpID, "", "") - if err != nil && err.Error() != utils.ErrNotFound.Error() { - utils.Logger.Warning(fmt.Sprintf("<%s> error: %s, when getting %s from stordb for export", utils.ApierS, err, utils.TpActionProfiles)) - withError = true - } - for _, sd := range storDataActionProfiles { - sdModels := APItoModelTPActionProfile(sd) - for _, sdModel := range sdModels { - toExportMap[utils.ActionProfilesCsv] = append(toExportMap[utils.ActionProfilesCsv], sdModel) - } - } - if len(toExportMap) == 0 { // if we don't have anything to export we return not found error return utils.ErrNotFound } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 13c8e15ac..a996bfc0a 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -60,7 +60,6 @@ var fileHandlers = map[string]func(*TPCSVImporter, string) error{ utils.ChargersCsv: (*TPCSVImporter).importChargerProfiles, utils.DispatcherProfilesCsv: (*TPCSVImporter).importDispatcherProfiles, utils.DispatcherHostsCsv: (*TPCSVImporter).importDispatcherHosts, - utils.ActionProfilesCsv: (*TPCSVImporter).importActionProfiles, } func (tpImp *TPCSVImporter) Run() error { @@ -358,14 +357,3 @@ func (tpImp *TPCSVImporter) importDispatcherHosts(fn string) error { } return tpImp.StorDb.SetTPDispatcherHosts(dpps) } - -func (tpImp *TPCSVImporter) importActionProfiles(fn string) error { - if tpImp.Verbose { - log.Printf("Processing file: <%s> ", fn) - } - rpps, err := tpImp.csvr.GetTPActionProfiles(tpImp.TPid, "", "") - if err != nil { - return err - } - return tpImp.StorDb.SetTPActionProfiles(rpps) -} diff --git a/engine/tpreader.go b/engine/tpreader.go index 9f4fc60a3..437f4478f 100644 --- a/engine/tpreader.go +++ b/engine/tpreader.go @@ -56,7 +56,6 @@ type TpReader struct { chargerProfiles map[utils.TenantID]*utils.TPChargerProfile dispatcherProfiles map[utils.TenantID]*utils.TPDispatcherProfile dispatcherHosts map[utils.TenantID]*utils.TPDispatcherHost - actionProfiles map[utils.TenantID]*utils.TPActionProfile resources []*utils.TenantID // IDs of resources which need creation based on resourceProfiles statQueues []*utils.TenantID // IDs of statQueues which need creation based on statQueueProfiles thresholds []*utils.TenantID // IDs of thresholds which need creation based on thresholdProfiles @@ -105,7 +104,6 @@ func (tpr *TpReader) Init() { tpr.chargerProfiles = make(map[utils.TenantID]*utils.TPChargerProfile) tpr.dispatcherProfiles = make(map[utils.TenantID]*utils.TPDispatcherProfile) tpr.dispatcherHosts = make(map[utils.TenantID]*utils.TPDispatcherHost) - tpr.actionProfiles = make(map[utils.TenantID]*utils.TPActionProfile) tpr.filters = make(map[utils.TenantID]*utils.TPFilterProfile) tpr.acntActionPlans = make(map[string][]string) } @@ -1283,26 +1281,6 @@ func (tpr *TpReader) LoadDispatcherHostsFiltered(tag string) (err error) { return nil } -func (tpr *TpReader) LoadActionProfiles() error { - return tpr.LoadActionProfilesFiltered("") -} - -func (tpr *TpReader) LoadActionProfilesFiltered(tag string) (err error) { - aps, err := tpr.lr.GetTPActionProfiles(tpr.tpid, "", tag) - if err != nil { - return err - } - mapActionProfiles := make(map[utils.TenantID]*utils.TPActionProfile) - for _, ap := range aps { - if err = verifyInlineFilterS(ap.FilterIDs); err != nil { - return - } - mapActionProfiles[utils.TenantID{Tenant: ap.Tenant, ID: ap.ID}] = ap - } - tpr.actionProfiles = mapActionProfiles - return nil -} - func (tpr *TpReader) LoadDispatcherHosts() error { return tpr.LoadDispatcherHostsFiltered("") } @@ -1368,9 +1346,6 @@ func (tpr *TpReader) LoadAll() (err error) { if err = tpr.LoadDispatcherHosts(); err != nil && err.Error() != utils.NotFoundCaps { return } - if err = tpr.LoadActionProfiles(); err != nil && err.Error() != utils.NotFoundCaps { - return - } return nil } @@ -1813,25 +1788,6 @@ func (tpr *TpReader) WriteToDatabase(verbose, disableReverse bool) (err error) { loadIDs[utils.CacheDispatcherHosts] = loadID } - if verbose { - log.Print("ActionProfiles:") - } - for _, tpAP := range tpr.actionProfiles { - var ap *ActionProfile - if ap, err = APItoActionProfile(tpAP, tpr.timezone); err != nil { - return - } - if err = tpr.dm.SetActionProfile(ap, true); err != nil { - return - } - if verbose { - log.Print("\t", ap.TenantID()) - } - } - if len(tpr.actionProfiles) != 0 { - loadIDs[utils.CacheActionProfiles] = loadID - } - if verbose { log.Print("Timings:") } @@ -1928,8 +1884,6 @@ func (tpr *TpReader) ShowStatistics() { log.Print("DispatcherProfiles: ", len(tpr.dispatcherProfiles)) // Dispatcher Hosts log.Print("DispatcherHosts: ", len(tpr.dispatcherHosts)) - // Action profiles - log.Print("ActionProfiles: ", len(tpr.actionProfiles)) } // GetLoadedIds returns the identities loaded for a specific category, useful for cache reloads @@ -2080,14 +2034,6 @@ func (tpr *TpReader) GetLoadedIds(categ string) ([]string, error) { i++ } return keys, nil - case utils.ActionProfilePrefix: - keys := make([]string, len(tpr.actionProfiles)) - i := 0 - for k := range tpr.actionProfiles { - keys[i] = k.TenantID() - i++ - } - return keys, nil } return nil, errors.New("Unsupported load category") } @@ -2311,19 +2257,6 @@ func (tpr *TpReader) RemoveFromDatabase(verbose, disableReverse bool) (err error } } - if verbose { - log.Print("ActionProfiles:") - } - for _, tpAp := range tpr.actionProfiles { - if err = tpr.dm.RemoveActionProfile(tpAp.Tenant, tpAp.ID, - utils.NonTransactional, true); err != nil { - return - } - if verbose { - log.Print("\t", utils.ConcatenatedKey(tpAp.Tenant, tpAp.ID)) - } - } - if verbose { log.Print("Timings:") } @@ -2427,9 +2360,6 @@ func (tpr *TpReader) RemoveFromDatabase(verbose, disableReverse bool) (err error if len(tpr.dispatcherHosts) != 0 { loadIDs[utils.CacheDispatcherHosts] = loadID } - if len(tpr.actionProfiles) != 0 { - loadIDs[utils.CacheActionProfiles] = loadID - } if len(tpr.timings) != 0 { loadIDs[utils.CacheTimings] = loadID } @@ -2465,7 +2395,6 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i chargerIDs, _ := tpr.GetLoadedIds(utils.ChargerProfilePrefix) dppIDs, _ := tpr.GetLoadedIds(utils.DispatcherProfilePrefix) dphIDs, _ := tpr.GetLoadedIds(utils.DispatcherHostPrefix) - actionPrfIDs, _ := tpr.GetLoadedIds(utils.ActionProfilePrefix) aps, _ := tpr.GetLoadedIds(utils.ActionPlanPrefix) //compose Reload Cache argument @@ -2493,7 +2422,6 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i utils.ChargerProfileIDs: chargerIDs, utils.DispatcherProfileIDs: dppIDs, utils.DispatcherHostIDs: dphIDs, - utils.ActionProfileIDs: actionPrfIDs, }, } @@ -2545,9 +2473,6 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i if len(dppIDs) != 0 { cacheIDs = append(cacheIDs, utils.CacheDispatcherFilterIndexes) } - if len(actionPrfIDs) != 0 { - cacheIDs = append(cacheIDs, utils.CacheActionProfilesFilterIndexes) - } if len(flrIDs) != 0 { cacheIDs = append(cacheIDs, utils.CacheReverseFilterIndexes) } diff --git a/engine/version.go b/engine/version.go index 6264c8a33..a264a21e1 100644 --- a/engine/version.go +++ b/engine/version.go @@ -163,7 +163,6 @@ func CurrentDataDBVersions() Versions { utils.Chargers: 2, utils.Dispatchers: 2, utils.LoadIDsVrs: 1, - utils.ActionProfiles: 1, } } @@ -194,7 +193,6 @@ func CurrentStorDBVersions() Versions { utils.TpRatingProfile: 1, utils.TpChargers: 1, utils.TpDispatchers: 1, - utils.TpActionProfiles: 1, } } diff --git a/engine/version_test.go b/engine/version_test.go index ff81dec90..2be20b797 100644 --- a/engine/version_test.go +++ b/engine/version_test.go @@ -92,7 +92,7 @@ func TestCurrentDBVersions(t *testing.T) { utils.Timing: 1, utils.RQF: 5, utils.Resource: 1, utils.Subscribers: 1, utils.Destinations: 1, utils.ReverseDestinations: 1, utils.RatingPlan: 1, utils.RatingProfile: 1, utils.Chargers: 2, - utils.Dispatchers: 2, utils.LoadIDsVrs: 1, utils.ActionProfiles: 1, + utils.Dispatchers: 2, utils.LoadIDsVrs: 1, } expVersStorDB := Versions{ utils.CostDetails: 2, utils.SessionSCosts: 3, utils.CDRs: 2, @@ -103,7 +103,6 @@ func TestCurrentDBVersions(t *testing.T) { utils.TpResources: 1, utils.TpRates: 1, utils.TpTiming: 1, utils.TpResource: 1, utils.TpDestinations: 1, utils.TpRatingPlan: 1, utils.TpRatingProfile: 1, utils.TpChargers: 1, utils.TpDispatchers: 1, - utils.TpActionProfiles: 1, } if vrs := CurrentDBVersions(utils.Mongo, true); !reflect.DeepEqual(expVersDataDB, vrs) { t.Errorf("Expectred %+v, received %+v", expVersDataDB, vrs) diff --git a/engine/z_filterindexer_it_test.go b/engine/z_filterindexer_it_test.go index f7325b31d..5f6a4934b 100644 --- a/engine/z_filterindexer_it_test.go +++ b/engine/z_filterindexer_it_test.go @@ -68,7 +68,6 @@ var sTests = []func(t *testing.T){ testITDispatcherProfileIndexes, testITFlush, testITIsDBEmpty, - testITActionProfileIndexes, testITFlush, testITIsDBEmpty, testITTestStoreFilterIndexesWithTransID2, @@ -1419,168 +1418,6 @@ func testITDispatcherProfileIndexes(t *testing.T) { } } -func testITActionProfileIndexes(t *testing.T) { - fltr1 := &Filter{ - Tenant: "itsyscom", - ID: "ACTPRF_FLTR1", - Rules: []*FilterRule{{Type: utils.MetaString, Element: "~*req.Destination", Values: []string{"ACC1", "ACC2", "~*req.Account"}}}, - } - fltr2 := &Filter{ - Tenant: "itsyscom", - ID: "ACTPRF_FLTR2", - Rules: []*FilterRule{{Type: utils.MetaString, Element: "20m", Values: []string{"USAGE", "~*opts.Debited", "~*req.Usage"}}}, - } - if err := dataManager.SetFilter(fltr1, true); err != nil { - t.Error(err) - } else if err := dataManager.SetFilter(fltr2, true); err != nil { - t.Error(err) - } - - actPrf1 := &ActionProfile{ - Tenant: "itsyscom", - ID: "ACTPRF1", - FilterIDs: []string{"ACTPRF_FLTR1", "*prefix:~*req.Destination:123"}, - } - actPrf2 := &ActionProfile{ - Tenant: "itsyscom", - ID: "ACTPRF2", - FilterIDs: []string{"ACTPRF_FLTR2"}, - } - if err := dataManager.SetActionProfile(actPrf1, true); err != nil { - t.Error(err) - } else if err := dataManager.SetActionProfile(actPrf2, true); err != nil { - t.Error(err) - } - - expIdx := map[string]utils.StringSet{ - "*string:*req.Destination:ACC1": { - "ACTPRF1": struct{}{}, - }, - "*string:*req.Destination:ACC2": { - "ACTPRF1": struct{}{}, - }, - "*prefix:*req.Destination:123": { - "ACTPRF1": struct{}{}, - }, - "*string:*opts.Debited:20m": { - "ACTPRF2": struct{}{}, - }, - "*string:*req.Usage:20m": { - "ACTPRF2": struct{}{}, - }, - } - if rcvIdx, err := dataManager.GetIndexes(utils.CacheActionProfilesFilterIndexes, - "itsyscom", utils.EmptyString, false, false); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - - expIdx = map[string]utils.StringSet{ - "*string:*req.Destination:ACC1": { - "ACTPRF1": struct{}{}, - }, - } - if rcvIdx, err := dataManager.GetIndexes(utils.CacheActionProfilesFilterIndexes, - "itsyscom", "*string:*req.Destination:ACC1", false, false); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - - // we will update the filter - fltr1 = &Filter{ - Tenant: "itsyscom", - ID: "ACTPRF_FLTR1", - Rules: []*FilterRule{{Type: utils.MetaString, Element: "~*req.ToR", Values: []string{"*voice", "~*req.Account"}}}, - } - fltr2 = &Filter{ - Tenant: "itsyscom", - ID: "ACTPRF_FLTR2", - Rules: []*FilterRule{{Type: utils.MetaString, Element: "~*req.CGRID", Values: []string{"CHANGED_ID_1", "~*req.Account"}}}, - } - - if err := dataManager.SetFilter(fltr1, true); err != nil { - t.Error(err) - } else if err := dataManager.SetFilter(fltr2, true); err != nil { - t.Error(err) - } - - actPrf1 = &ActionProfile{ - Tenant: "itsyscom", - ID: "CHANGED_ACTPRF1", - FilterIDs: []string{"ACTPRF_FLTR1", "*prefix:~*req.Destination:123"}, - } - actPrf2 = &ActionProfile{ - Tenant: "itsyscom", - ID: "CHANGED_ACTPRF2", - FilterIDs: []string{"ACTPRF_FLTR2"}, - } - if err := dataManager.SetActionProfile(actPrf1, true); err != nil { - t.Error(err) - } else if err := dataManager.SetActionProfile(actPrf2, true); err != nil { - t.Error(err) - } - - expIdx = map[string]utils.StringSet{ - "*string:*req.ToR:*voice": { - "ACTPRF1": struct{}{}, - "CHANGED_ACTPRF1": struct{}{}, - }, - "*string:*req.CGRID:CHANGED_ID_1": { - "ACTPRF2": struct{}{}, - "CHANGED_ACTPRF2": struct{}{}, - }, - "*prefix:*req.Destination:123": { - "ACTPRF1": struct{}{}, - "CHANGED_ACTPRF1": struct{}{}, - }, - } - if rcvIdx, err := dataManager.GetIndexes(utils.CacheActionProfilesFilterIndexes, - "itsyscom", utils.EmptyString, false, false); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - - //here we will get the reverse indexes - expIdx = map[string]utils.StringSet{ - utils.CacheActionProfilesFilterIndexes: { - "ACTPRF1": struct{}{}, - "CHANGED_ACTPRF1": struct{}{}, - }, - } - if rcvIdx, err := dataManager.GetIndexes(utils.CacheReverseFilterIndexes, - "itsyscom:ACTPRF_FLTR1", utils.EmptyString, false, false); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - - expIdx = map[string]utils.StringSet{ - utils.CacheActionProfilesFilterIndexes: { - "ACTPRF2": struct{}{}, - "CHANGED_ACTPRF2": struct{}{}, - }, - } - if rcvIdx, err := dataManager.GetIndexes(utils.CacheReverseFilterIndexes, - "itsyscom:ACTPRF_FLTR2", utils.EmptyString, false, false); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - - //invalid tnt:context or index key - expIdx = nil - if rcvIdx, err := dataManager.GetIndexes(utils.CacheActionProfilesFilterIndexes, - "itsyscom", "*string:*req.Destination:ACC7", false, false); err == nil || err != utils.ErrNotFound { - t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err) - } else if !reflect.DeepEqual(rcvIdx, expIdx) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expIdx), utils.ToJSON(rcvIdx)) - } - -} - func testITTestStoreFilterIndexesWithTransID2(t *testing.T) { idxes := map[string]utils.StringSet{ "*string:Event:Event1": { diff --git a/engine/z_onstor_it_test.go b/engine/z_onstor_it_test.go index e82a24074..91348ecea 100644 --- a/engine/z_onstor_it_test.go +++ b/engine/z_onstor_it_test.go @@ -75,7 +75,6 @@ var ( testOnStorITTestAttributeSubstituteIface, testOnStorITChargerProfile, testOnStorITDispatcherProfile, - testOnStorITActionProfile, //testOnStorITCacheActionTriggers, //testOnStorITCRUDActionTriggers, } @@ -2152,79 +2151,3 @@ func testOnStorITDispatcherProfile(t *testing.T) { t.Error(rcvErr) } } - -func testOnStorITActionProfile(t *testing.T) { - actPrf := &ActionProfile{ - Tenant: "cgrates.org", - ID: "TEST_ID1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 20, - Schedule: utils.MetaASAP, - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.NewStringSet([]string{"acc1", "acc2", "acc3"}), - }, - Actions: []*APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*APDiktat{{ - Path: "~*balance.TestBalance.Value", - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*APDiktat{{ - Path: "~*balance.TestVoiceBalance.Value", - }}, - }, - }, - } - - //empty in database - if _, err := onStor.GetActionProfile("cgrates.org", "TEST_ID1", - true, false, utils.NonTransactional); err != utils.ErrNotFound { - t.Error(err) - } - - //get from database - if err := onStor.SetActionProfile(actPrf, false); err != nil { - t.Error(err) - } - if rcv, err := onStor.GetActionProfile("cgrates.org", "TEST_ID1", - true, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, actPrf) { - t.Errorf("Expecting: %v, received: %v", actPrf, rcv) - } - - //craft akeysFromPrefix - expectedKey := []string{"acp_cgrates.org:TEST_ID1"} - if rcv, err := onStor.DataDB().GetKeysForPrefix(utils.ActionProfilePrefix); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(expectedKey, rcv) { - t.Errorf("Expecting: %v, received: %v", expectedKey, rcv) - } - - //updateFilters - actPrf.FilterIDs = []string{"*prefix:~*req.Destination:10"} - if err := onStor.SetActionProfile(actPrf, false); err != nil { - t.Error(err) - } else if rcv, err := onStor.GetActionProfile("cgrates.org", "TEST_ID1", - false, false, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(actPrf, rcv) { - t.Errorf("Expecting: %v, received: %v", actPrf, rcv) - } - - //remove from database - if err := onStor.RemoveActionProfile("cgrates.org", "TEST_ID1", - utils.NonTransactional, false); err != nil { - t.Error(err) - } else if _, err := onStor.GetActionProfile("cgrates.org", "TEST_ID1", - false, false, utils.NonTransactional); err != utils.ErrNotFound { - t.Error(err) - } -} diff --git a/engine/z_stordb_it_test.go b/engine/z_stordb_it_test.go index 8145fc555..4ea831fae 100644 --- a/engine/z_stordb_it_test.go +++ b/engine/z_stordb_it_test.go @@ -44,7 +44,6 @@ var sTestsStorDBit = []func(t *testing.T){ testStorDBitFlush, testStorDBitIsDBEmpty, testStorDBitCRUDVersions, - testStorDBitCRUDTPActionProfiles, testStorDBitCRUDTPDispatcherProfiles, testStorDBitCRUDTPDispatcherHosts, testStorDBitCRUDTPFilters, @@ -147,80 +146,6 @@ func testStorDBitIsDBEmpty(t *testing.T) { } } -func testStorDBitCRUDTPActionProfiles(t *testing.T) { - //READ - if _, err := storDB.GetTPActionProfiles("sub_ID1", utils.EmptyString, "TEST_ID1"); err != utils.ErrNotFound { - t.Error(err) - } - - //WRITE - var actPrf = []*utils.TPActionProfile{ - { - Tenant: "cgrates.org", - TPid: "TEST_ID1", - ID: "sub_id1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 20, - Schedule: utils.MetaASAP, - Actions: []*utils.TPAPAction{ - { - ID: "TOPUP", - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - }}, - }, - }, - }, - { - Tenant: "cgrates.org", - TPid: "TEST_ID1", - ID: "sub_id2", - FilterIDs: []string{"*string:~*req.Destination:10"}, - Weight: 10, - Schedule: utils.MetaASAP, - Actions: []*utils.TPAPAction{ - { - ID: "TOPUP", - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - }}, - }, - }, - }, - } - if err := storDB.SetTPActionProfiles(actPrf); err != nil { - t.Error("Unable to set TPActionProfile") - } - - //READ - if rcv, err := storDB.GetTPActionProfiles(actPrf[0].TPid, utils.EmptyString, utils.EmptyString); err != nil { - t.Error(err) - } else if !(reflect.DeepEqual(rcv[0], actPrf[0]) || reflect.DeepEqual(rcv[1], actPrf[0])) { - t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", utils.ToJSON(actPrf[0]), utils.ToJSON(rcv[0]), utils.ToJSON(rcv[1])) - } - - //UPDATE AND READ - actPrf[0].FilterIDs = []string{"*string:~*req.Account:1007"} - actPrf[1].Weight = 20 - if err := storDB.SetTPActionProfiles(actPrf); err != nil { - t.Error(err) - } else if rcv, err := storDB.GetTPActionProfiles(actPrf[0].TPid, - utils.EmptyString, utils.EmptyString); err != nil { - t.Error(err) - } else if !(reflect.DeepEqual(rcv[0], actPrf[0]) || reflect.DeepEqual(rcv[1], actPrf[0])) { - t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", utils.ToJSON(actPrf[0]), utils.ToJSON(rcv[0]), utils.ToJSON(rcv[1])) - } - - //REMOVE AND READ - if err := storDB.RemTpData(utils.EmptyString, actPrf[0].TPid, nil); err != nil { - t.Error(err) - } else if _, err := storDB.GetTPActionProfiles(actPrf[0].TPid, utils.EmptyString, utils.EmptyString); err != utils.ErrNotFound { - t.Error(err) - } -} - func testStorDBitCRUDTPDispatcherProfiles(t *testing.T) { //READ if _, err := storDB.GetTPDispatcherProfiles("TP1", utils.EmptyString, utils.EmptyString); err != utils.ErrNotFound { diff --git a/general_tests/accountactions_it_test.go b/general_tests/accountactions_it_test.go deleted file mode 100644 index 6ad3e6588..000000000 --- a/general_tests/accountactions_it_test.go +++ /dev/null @@ -1,300 +0,0 @@ -// +build integration - -/* -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 -*/ - -package general_tests - -import ( - "net/rpc" - "path" - "reflect" - "strconv" - "testing" - "time" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var ( - accPrfCfgPath string - accPrfCfg *config.CGRConfig - accSRPC *rpc.Client - accPrfConfigDIR string //run tests for specific configuration - - sTestsAccPrf = []func(t *testing.T){ - testAccActionsInitCfg, - testAccActionsInitDataDb, - testAccActionsResetStorDb, - testAccActionsStartEngine, - testAccActionsRPCConn, - testAccActionsSetActionProfile, - testAccActionsExecuteAction, - testAccActionsSetActionProfile, - testAccActionsExecuteAction2, - testAccActionsSetActionProfile2, - testAccActionsExecuteAction3, - testAccActionsKillEngine, - } -) - -//Test start here -func TestAccActionsIT(t *testing.T) { - switch *dbType { - case utils.MetaInternal: - accPrfConfigDIR = "tutinternal" - case utils.MetaMySQL: - accPrfConfigDIR = "tutmysql" - case utils.MetaMongo: - accPrfConfigDIR = "tutmongo" - case utils.MetaPostgres: - t.SkipNow() - default: - t.Fatal("Unknown Database type") - } - for _, stest := range sTestsAccPrf { - t.Run(accPrfConfigDIR, stest) - } -} - -func testAccActionsInitCfg(t *testing.T) { - var err error - accPrfCfgPath = path.Join(*dataDir, "conf", "samples", accPrfConfigDIR) - if accPrfCfg, err = config.NewCGRConfigFromPath(accPrfCfgPath); err != nil { - t.Error(err) - } -} - -func testAccActionsInitDataDb(t *testing.T) { - if err := engine.InitDataDb(accPrfCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func testAccActionsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(accPrfCfg); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func testAccActionsStartEngine(t *testing.T) { - if _, err := engine.StopStartEngine(accPrfCfgPath, *waitRater); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func testAccActionsRPCConn(t *testing.T) { - var err error - accSRPC, err = newRPCClient(accPrfCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -func testAccActionsSetActionProfile(t *testing.T) { - actPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "CREATE_ACC", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 0, - Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}}, - Schedule: utils.MetaASAP, - Actions: []*engine.APAction{ - { - ID: "SET_NEW_BAL", - FilterIDs: []string{"*exists:*opts.BAL_NEW:"}, - Type: utils.MetaSetBalance, - Diktats: []*engine.APDiktat{ - { - Path: "*account.ThresholdIDs", - Value: utils.MetaNone, - }, - { - Path: "*balance.MONETARY.Type", - Value: utils.MetaConcrete, - }, - { - Path: "*balance.MONETARY.Units", - Value: "1048576", - }, - { - Path: "*balance.MONETARY.Weights", - Value: "`;0`", - }, - { - Path: "*balance.MONETARY.CostIncrements", - Value: "`*string:~*req.ToR:*data;1024;0;0.01`", - }, - }, - }, - { - ID: "SET_ADD_BAL", - FilterIDs: []string{"*exists:*opts.BAL_ADD:"}, - Type: utils.MetaAddBalance, - Diktats: []*engine.APDiktat{ - { - Path: "*balance.VOICE.Type", - Value: utils.MetaAbstract, - }, - { - Path: "*balance.VOICE.Units", - Value: strconv.FormatInt((3 * time.Hour).Nanoseconds(), 10), - }, - { - Path: "*balance.VOICE.FilterIDs", - Value: "`*string:~*req.ToR:*voice`", - }, - { - Path: "*balance.VOICE.Weights", - Value: "`;2`", - }, - { - Path: "*balance.VOICE.CostIncrements", - Value: "`*string:~*req.ToR:*voice;1000000000;0;0.01`", - }, - }, - }, - }, - }, - APIOpts: map[string]interface{}{}, - } - var reply string - if err := accSRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } - var result *engine.ActionProfile - if err := accSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: actPrf.Tenant, ID: actPrf.ID}}, &result); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, result) { - t.Errorf("Expecting : %+v, received: %+v", actPrf.ActionProfile, result) - } -} - -func testAccActionsExecuteAction(t *testing.T) { - var reply string - if err := accSRPC.Call(utils.ActionSv1ExecuteActions, &utils.ArgActionSv1ScheduleActions{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - Event: map[string]interface{}{ - "Account": 1001, - }, - APIOpts: map[string]interface{}{ - "BAL_NEW": true, - "BAL_ADD": true, - }, - }, - }, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } -} - -func testAccActionsExecuteAction2(t *testing.T) { - var reply string - if err := accSRPC.Call(utils.ActionSv1ExecuteActions, &utils.ArgActionSv1ScheduleActions{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - Event: map[string]interface{}{ - "Account": 1001, - }, - APIOpts: map[string]interface{}{ - "BAL_NEW": true, - "BAL_ADD": true, - }, - }, - ActionProfileIDs: []string{"CREATE_ACC"}, - }, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } -} - -func testAccActionsSetActionProfile2(t *testing.T) { - actPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "REM_ACC", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 0, - Targets: map[string]utils.StringSet{utils.MetaAccounts: {"1001": {}}}, - Schedule: utils.MetaASAP, - Actions: []*engine.APAction{ - { - ID: "REM_BAL", - Type: utils.MetaRemBalance, - Diktats: []*engine.APDiktat{ - { - Path: "MONETARY", - }, - { - Path: "VOICE", - }, - }, - }, - }, - }, - APIOpts: map[string]interface{}{}, - } - var reply string - if err := accSRPC.Call(utils.APIerSv1SetActionProfile, actPrf, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } - var result *engine.ActionProfile - if err := accSRPC.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: actPrf.Tenant, ID: actPrf.ID}}, &result); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(actPrf.ActionProfile, result) { - t.Errorf("Expecting : %+v, received: %+v", actPrf.ActionProfile, result) - } -} - -func testAccActionsExecuteAction3(t *testing.T) { - var reply string - if err := accSRPC.Call(utils.ActionSv1ExecuteActions, &utils.ArgActionSv1ScheduleActions{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - Event: map[string]interface{}{ - "Account": 1001, - }, - }, - ActionProfileIDs: []string{"REM_ACC"}, - }, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error("Unexpected reply returned", reply) - } -} - -func testAccActionsKillEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} diff --git a/general_tests/export_it_test.go b/general_tests/export_it_test.go index 388b436a6..ea6ebc9b6 100644 --- a/general_tests/export_it_test.go +++ b/general_tests/export_it_test.go @@ -59,7 +59,6 @@ var ( testExpVerifyResources, testExpVerifyStats, testExpVerifyRoutes, - testExpVerifyActionProfiles, testExpCleanFiles, testExpStopCgrEngine, } @@ -362,90 +361,6 @@ func testExpVerifyRoutes(t *testing.T) { } } -func testExpVerifyActionProfiles(t *testing.T) { - var reply *engine.ActionProfile - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - FilterIDs: []string{}, - Weight: 10, - Schedule: utils.MetaASAP, - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: {"1001": {}, "1002": {}}, - }, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - Type: utils.MetaAddBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestBalance" + utils.NestingSep + utils.Units, - Value: "10", - }}, - }, - - { - ID: "SET_BALANCE_TEST_DATA", - Type: utils.MetaSetBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Type, - Value: utils.MetaData, - }}, - }, - { - ID: "TOPUP_TEST_DATA", - Type: utils.MetaAddBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestDataBalance" + utils.NestingSep + utils.Units, - Value: "1024", - }}, - }, - { - ID: "SET_BALANCE_TEST_VOICE", - Type: utils.MetaSetBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Type, - Value: utils.MetaVoice, - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - Type: utils.MetaAddBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Units, - Value: "15m15s", - }}, - }, - { - ID: "SET_BALANCE_TEST_FILTERS", - Type: utils.MetaSetBalance, - Diktats: []*engine.APDiktat{{ - Path: utils.MetaBalance + utils.NestingSep + "TestVoiceBalance" + utils.NestingSep + utils.Filters, - Value: "*string:~*req.CustomField:500", - }}, - }, - { - ID: "TOPUP_REM_VOICE", - Type: utils.MetaRemBalance, - Diktats: []*engine.APDiktat{{ - Path: "TestVoiceBalance2", - }}, - }, - }, - } - if *encoding == utils.MetaGOB { - actPrf.FilterIDs = nil - for _, act := range actPrf.Actions { - act.FilterIDs = nil - } - } - if err := expRpc.Call(utils.APIerSv1GetActionProfile, &utils.TenantIDWithAPIOpts{ - TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ONE_TIME_ACT"}}, &reply); err != nil { - t.Fatal(err) - } else if !reflect.DeepEqual(actPrf, reply) { - t.Errorf("Expecting : %+v \n received: %+v", utils.ToJSON(actPrf), utils.ToJSON(reply)) - } -} - func testExpCleanFiles(t *testing.T) { if err := os.RemoveAll("/tmp/tp/"); err != nil { t.Error(err) diff --git a/general_tests/filtered_replication_it_test.go b/general_tests/filtered_replication_it_test.go index 2d82dbbdd..a91f84768 100644 --- a/general_tests/filtered_replication_it_test.go +++ b/general_tests/filtered_replication_it_test.go @@ -64,7 +64,6 @@ var ( testFltrRplChargerProfile, testFltrRplDispatcherProfile, testFltrRplDispatcherHost, - testFltrRplActionProfile, testFltrRplAccount, testFltrRplDestination, @@ -1338,110 +1337,6 @@ func testFltrRplDispatcherHost(t *testing.T) { } } -func testFltrRplActionProfile(t *testing.T) { - acID := "ATTR1" - acPrf := &engine.ActionProfileWithAPIOpts{ - ActionProfile: &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: acID, - Actions: []*engine.APAction{ - { - ID: "test_action_id", - Diktats: []*engine.APDiktat{{}}, - }, - }, - Weight: 10, - }, - } - var result string - var replyPrfl *engine.ActionProfile - var rplyIDs []string - // empty - if err := fltrRplEngine1RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - if err := fltrRplEngine2RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - - if err := fltrRplInternalRPC.Call(utils.APIerSv1SetActionProfile, acPrf, &result); err != nil { - t.Fatal(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - if err := fltrRplInternalRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: acID}}, &replyPrfl); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(acPrf.ActionProfile, replyPrfl) { - t.Errorf("Expecting : %s, received: %s", utils.ToJSON(acPrf.ActionProfile), utils.ToJSON(replyPrfl)) - } - replyPrfl = nil - - if err := fltrRplEngine1RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - if err := fltrRplEngine2RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - - if err := fltrRplEngine1RPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: acID}}, &replyPrfl); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(acPrf.ActionProfile, replyPrfl) { - t.Errorf("Expecting : %s, received: %s", utils.ToJSON(acPrf.ActionProfile), utils.ToJSON(replyPrfl)) - } - replyPrfl = nil - acPrf.Weight = 15 - if err := fltrRplInternalRPC.Call(utils.APIerSv1SetActionProfile, acPrf, &result); err != nil { - t.Fatal(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - if err := fltrRplInternalRPC.Call(utils.APIerSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: acID}}, &replyPrfl); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(acPrf.ActionProfile, replyPrfl) { - t.Errorf("Expecting : %s, received: %s", utils.ToJSON(acPrf.ActionProfile), utils.ToJSON(replyPrfl)) - } - replyPrfl = nil - - // use replicator to see if the attribute was changed in the DB - if err := fltrRplEngine1RPC.Call(utils.ReplicatorSv1GetActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: acID}}, &replyPrfl); err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(acPrf.ActionProfile, replyPrfl) { - t.Errorf("Expecting : %s, received: %s", utils.ToJSON(acPrf.ActionProfile), utils.ToJSON(replyPrfl)) - } - - if err := fltrRplEngine2RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - - if err := fltrRplInternalRPC.Call(utils.APIerSv1RemoveActionProfile, - utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: acID}}, &result); err != nil { - t.Error(err) - } else if result != utils.OK { - t.Error("Unexpected reply returned", result) - } - if err := fltrRplEngine1RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } - if err := fltrRplEngine2RPC.Call(utils.APIerSv1GetActionProfileIDs, &utils.PaginatorWithTenant{}, &rplyIDs); err == nil || - err.Error() != utils.ErrNotFound.Error() { - t.Fatalf("Unexpected error: %v", err) - } -} - func testFltrRplAccount(t *testing.T) { acID := "ATTR1" attrPrf := &v2.AttrSetAccount{Tenant: "cgrates.org", Account: acID, ExtraOptions: map[string]bool{utils.Disabled: true}} diff --git a/loaders/loader.go b/loaders/loader.go index 39affbd02..b1f6a2134 100644 --- a/loaders/loader.go +++ b/loaders/loader.go @@ -574,36 +574,6 @@ func (ldr *Loader) storeLoadedData(loaderType string, cacheArgs[utils.DispatcherHostIDs] = ids } } - case utils.MetaActionProfiles: - cacheIDs = []string{utils.CacheActionProfilesFilterIndexes} - for _, lDataSet := range lds { - acpsModels := make(engine.ActionProfileMdls, len(lDataSet)) - for i, ld := range lDataSet { - acpsModels[i] = new(engine.ActionProfileMdl) - if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil { - return - } - } - - for _, tpAcp := range acpsModels.AsTPActionProfile() { - acp, err := engine.APItoActionProfile(tpAcp, ldr.timezone) - if err != nil { - return err - } - if ldr.dryRun { - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfile: %s", - utils.LoaderS, ldr.ldrID, utils.ToJSON(acp))) - continue - } - // get IDs so we can reload in cache - ids = append(ids, acp.TenantID()) - if err := ldr.dm.SetActionProfile(acp, true); err != nil { - return err - } - cacheArgs[utils.ActionProfileIDs] = ids - } - } } if len(ldr.cacheConns) != 0 { @@ -895,24 +865,6 @@ func (ldr *Loader) removeLoadedData(loaderType string, lds map[string][]LoaderDa cacheArgs[utils.DispatcherHostIDs] = ids } } - case utils.MetaActionProfiles: - cacheIDs = []string{utils.CacheActionProfiles, utils.CacheActionProfilesFilterIndexes} - for tntID := range lds { - if ldr.dryRun { - utils.Logger.Info( - fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfileID: %s", - utils.LoaderS, ldr.ldrID, tntID)) - } else { - tntIDStruct := utils.NewTenantID(tntID) - // get IDs so we can reload in cache - ids = append(ids, tntID) - if err := ldr.dm.RemoveActionProfile(tntIDStruct.Tenant, - tntIDStruct.ID, utils.NonTransactional, true); err != nil { - return err - } - cacheArgs[utils.ActionProfileIDs] = ids - } - } } if len(ldr.cacheConns) != 0 { diff --git a/loaders/loader_it_test.go b/loaders/loader_it_test.go index d9871f82e..bb6d4b22e 100644 --- a/loaders/loader_it_test.go +++ b/loaders/loader_it_test.go @@ -20,7 +20,6 @@ along with this program. If not, see package loaders import ( - "encoding/csv" "fmt" "io" "net/rpc" @@ -51,11 +50,6 @@ var ( testLoaderStartEngine, testLoaderRPCConn, testLoaderPopulateData, - testLoadFromFilesCsvActionProfile, - testLoadFromFilesCsvActionProfileOpenError, - testProcessFolderRemoveContent, - testLoadFromFilesCsvActionProfileLockFolderError, - testLoaderMoveFiles, testLoaderMoveFilesMatchingFiles, testLoaderMoveFilesRenameError, testProcessFile, @@ -417,277 +411,6 @@ func testLoaderVerifyOutDirForCustomSep(t *testing.T) { } } -func testLoadFromFilesCsvActionProfile(t *testing.T) { - flPath := "/tmp/TestLoadFromFilesCsvActionProfile" - if err := os.MkdirAll(flPath, 0777); err != nil { - t.Error(err) - } - newFile, err := os.Create(path.Join(flPath, "ActionProfiles.csv")) - if err != nil { - t.Error(err) - } - newFile.Write([]byte(` -#Tenant[0],ID[1] -cgrates.org,SET_ACTPROFILE_3 -`)) - content, err := os.ReadFile(path.Join(flPath, "ActionProfiles.csv")) - if err != nil { - t.Error(err) - } - newFile.Close() - - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - tpInDir: flPath, - tpOutDir: utils.EmptyString, - lockFilename: "ActionProfiles.csv", - fieldSep: ",", - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "TenantID", - Path: "Tenant", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true}, - {Tag: "ProfileID", - Path: "ID", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true}, - }, - } - - rdr := io.NopCloser(strings.NewReader(string(content))) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err != nil { - t.Error(err) - } - expACtPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "SET_ACTPROFILE_3", - FilterIDs: []string{}, - Targets: map[string]utils.StringSet{}, - Actions: []*engine.APAction{}, - } - if rcv, err := ldr.dm.GetActionProfile(expACtPrf.Tenant, expACtPrf.ID, - true, true, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(expACtPrf, rcv) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(expACtPrf), utils.ToJSON(rcv)) - } - - //checking the error by adding a caching method - ldr.connMgr = engine.NewConnManager(config.NewDefaultCGRConfig(), nil) - ldr.cacheConns = []string{utils.MetaInternal} - rdr = io.NopCloser(strings.NewReader(string(content))) - csvRdr = csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - expected := "UNSUPPORTED_SERVICE_METHOD" - if err := ldr.ProcessFolder(utils.MetaReload, utils.MetaStore, true); err == nil || err.Error() != expected { - t.Error(err) - } - - if err = os.RemoveAll(flPath); err != nil { - t.Fatal(err) - } -} - -func testLoadFromFilesCsvActionProfileOpenError(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - tpInDir: "/tmp/testLoadFromFilesCsvActionProfileOpenError", - timezone: "UTC", - } - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - }, - }, - } - expectedErr := "open /tmp/testLoadFromFilesCsvActionProfileOpenError/ActionProfiles.csv: not a directory" - if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err == nil || err.Error() != expectedErr { - t.Errorf("Expected %+v, received %+v", expectedErr, err) - } - - //if stopOnError is on true, the error is avoided,but instead will get a logger.warning message - if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, false); err != nil { - t.Error(err) - } -} - -func testProcessFolderRemoveContent(t *testing.T) { - flPath := "/tmp/TestLoadFromFilesCsvActionProfile" - if err := os.MkdirAll(flPath, 0777); err != nil { - t.Error(err) - } - newFile, err := os.Create(path.Join(flPath, "ActionProfiles.csv")) - if err != nil { - t.Error(err) - } - newFile.Write([]byte(` -#Tenant[0],ID[1] -cgrates.org,SET_ACTPROFILE_3 -`)) - content, err := os.ReadFile(path.Join(flPath, "ActionProfiles.csv")) - if err != nil { - t.Error(err) - } - newFile.Close() - - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - tpInDir: flPath, - tpOutDir: utils.EmptyString, - lockFilename: "ActionProfiles.csv", - fieldSep: ",", - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "TenantID", - Path: "Tenant", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true}, - {Tag: "ProfileID", - Path: "ID", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true}, - }, - } - - rdr := io.NopCloser(strings.NewReader(string(content))) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - expACtPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "SET_ACTPROFILE_3", - FilterIDs: []string{}, - Targets: map[string]utils.StringSet{}, - Actions: []*engine.APAction{}, - } - if err := ldr.dm.SetActionProfile(expACtPrf, true); err != nil { - t.Error(err) - } - if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaRemove, true); err != nil { - t.Error(err) - } - //nothing to get from database - if _, err := ldr.dm.GetActionProfile(expACtPrf.Tenant, expACtPrf.ID, - true, true, utils.NonTransactional); err != utils.ErrNotFound { - t.Error(err) - } - - //checking the error by adding a caching method - ldr.cacheConns = []string{utils.MetaInternal} - rdr = io.NopCloser(strings.NewReader(string(content))) - csvRdr = csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - if err := ldr.dm.SetActionProfile(expACtPrf, true); err != nil { - t.Error(err) - } - if err := ldr.ProcessFolder(utils.MetaReload, utils.MetaRemove, true); err != utils.ErrNotFound { - t.Error(err) - } -} - -func testLoadFromFilesCsvActionProfileLockFolderError(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - }, - }, - } - expectedErr := "open : no such file or directory" - if err := ldr.ProcessFolder(utils.EmptyString, utils.MetaStore, true); err == nil || err.Error() != expectedErr { - t.Errorf("Expected %+v, received %+v", expectedErr, err) - } -} - -func testLoaderMoveFiles(t *testing.T) { - flPath := "/tmp/TestLoadFromFilesCsvActionProfile" - if err := os.MkdirAll(flPath, 0777); err != nil { - t.Error(err) - } - newFile, err := os.Create(path.Join(flPath, "ActionProfiles.csv")) - if err != nil { - t.Error(err) - } - newFile.Close() - - ldr := &Loader{ - tpInDir: flPath, - tpOutDir: "/tmp", - } - if err := ldr.moveFiles(); err != nil { - t.Error(err) - } - - if err := os.Remove("/tmp/ActionProfiles.csv"); err != nil { - t.Error(err) - } else if err := os.Remove("/tmp/TestLoadFromFilesCsvActionProfile"); err != nil { - t.Error(err) - } -} - func testLoaderMoveFilesMatchingFiles(t *testing.T) { flPath := "/tmp/TestLoaderMoveFilesMatchingFiles" ldr := &Loader{ diff --git a/loaders/loader_test.go b/loaders/loader_test.go index 1f95aa392..847bbe914 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -1507,203 +1507,12 @@ func TestNewLoaderWithMultiFiles(t *testing.T) { utils.RoutesCsv: {}, utils.StatsCsv: {}, utils.ThresholdsCsv: {}, - utils.ActionProfilesCsv: {}, } if !reflect.DeepEqual(expected, openRdrs) { t.Errorf("Expected %s,received %s", utils.ToJSON(expected), utils.ToJSON(openRdrs)) } } -func TestLoaderActionProfile(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestLoaderProcessContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "Tenant", - Path: "Tenant", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "ID", - Path: "ID", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "FilterIDs", - Path: "FilterIDs", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.2", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActivationInterval", - Path: "ActivationInterval", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.3", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "Weight", - Path: "Weight", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.4", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "Schedule", - Path: "Schedule", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.5", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "TargetType", - Path: "TargetType", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.6", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "TargetIDs", - Path: "TargetIDs", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.7", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionID", - Path: "ActionID", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.8", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionFilterIDs", - Path: "ActionFilterIDs", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.9", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionBlocker", - Path: "ActionBlocker", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.10", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionTTL", - Path: "ActionTTL", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.11", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionType", - Path: "ActionType", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.12", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionOpts", - Path: "ActionOpts", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.13", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionPath", - Path: "ActionPath", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.14", utils.InfieldSep), - Layout: time.RFC3339}, - {Tag: "ActionValue", - Path: "ActionValue", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.15", utils.InfieldSep), - Layout: time.RFC3339}, - }, - } - rdr := io.NopCloser(strings.NewReader(engine.ActionProfileCSVContent)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{fileName: utils.ActionProfilesCsv, - rdr: rdr, csvRdr: csvRdr}}, - } - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err != nil { - t.Error(err) - } - if len(ldr.bufLoaderData) != 0 { - t.Errorf("wrong buffer content: %+v", ldr.bufLoaderData) - } - - expected := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "ONE_TIME_ACT", - FilterIDs: []string{}, - Weight: 10, - Schedule: utils.MetaASAP, - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.NewStringSet([]string{"1001", "1002"}), - }, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestBalance.Value", - Value: "10", - }}, - }, - { - ID: "SET_BALANCE_TEST_DATA", - Type: "*set_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestDataBalance.Type", - Value: "*data", - }}, - }, - { - ID: "TOPUP_TEST_DATA", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestDataBalance.Value", - Value: "1024", - }}, - }, - { - ID: "SET_BALANCE_TEST_VOICE", - Type: "*set_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestVoiceBalance.Type", - Value: "*voice", - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - Type: "*add_balance", - Diktats: []*engine.APDiktat{{ - Path: "*balance.TestVoiceBalance.Value", - Value: "15m15s", - }, { - Path: "*balance.TestVoiceBalance2.Value", - Value: "15m15s", - }}, - }, - }, - } - - aps, err := ldr.dm.GetActionProfile("cgrates.org", "ONE_TIME_ACT", - true, false, utils.NonTransactional) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(expected, aps) { - t.Errorf("expecting: %s, received: %s", - utils.ToJSON(expected), utils.ToJSON(aps)) - } - - //cannot set ActionProfile when dryrun is true - ldr.dryRun = true - rdr = io.NopCloser(strings.NewReader(engine.ActionProfileCSVContent)) - csvRdr = csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{fileName: utils.ActionProfilesCsv, - rdr: rdr, csvRdr: csvRdr}}, - } - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err != nil { - t.Error(err) - } -} - func TestLoaderWrongCsv(t *testing.T) { data := engine.NewInternalDB(nil, nil, true) ldr := &Loader{ @@ -1713,7 +1522,7 @@ func TestLoaderWrongCsv(t *testing.T) { timezone: "UTC", } ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { + utils.MetaAttributeProfiles: { {Tag: "Tenant", Path: "Tenant", Type: utils.MetaVariable, @@ -1807,16 +1616,16 @@ cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance. rdr := io.NopCloser(strings.NewReader(newCSVContentMiss)) csvRdr := csv.NewReader(rdr) ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, + utils.MetaAttributeProfiles: { + utils.AttributesCsv: &openedCSVFile{ + fileName: utils.AttributesCsv, rdr: rdr, csvRdr: csvRdr, }, }, } expectedErr := "invalid syntax" - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || !strings.Contains(err.Error(), expectedErr) { + if err := ldr.processContent(utils.MetaAttributeProfiles, utils.EmptyString); err == nil || !strings.Contains(err.Error(), expectedErr) { t.Errorf("Expected %+q, received %+q", expectedErr, err) } @@ -1832,103 +1641,20 @@ cgrates.org,ONE_TIME_ACT,,,,,,TOPUP_TEST_VOICE,,false,0s,*add_balance,,*balance. rdr = io.NopCloser(strings.NewReader(newCSVContent)) csvRdr = csv.NewReader(rdr) ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, + utils.MetaAttributeProfiles: { + utils.AttributesCsv: &openedCSVFile{ + fileName: utils.AttributesCsv, rdr: rdr, csvRdr: csvRdr, }, }, } expectedErr = "invalid syntax" - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || !strings.Contains(err.Error(), expectedErr) { + if err := ldr.processContent(utils.MetaAttributeProfiles, utils.EmptyString); err == nil || !strings.Contains(err.Error(), expectedErr) { t.Errorf("Expected %+q, received %+q", expectedErr, err) } } -func TestLoaderActionProfileAsStructErrType(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestLoaderActionProfileAsStructErrType", - bufLoaderData: map[string][]LoaderData{}, - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "Tenant", - Path: "Tenant", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "ID", - Path: "ID", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - {Tag: "ActionBlocker", - Path: "ActionBlocker", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.2", utils.InfieldSep), - Layout: time.RFC3339}, - }, - } - actPrfCsv := ` -#Tenant,ID,ActionBlocker -cgrates.org,12,NOT_A_BOOLEAN -` - rdr := io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{fileName: utils.ActionProfilesCsv, - rdr: rdr, csvRdr: csvRdr}}, - } - expErr := `strconv.ParseBool: parsing "NOT_A_BOOLEAN": invalid syntax` - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expErr { - t.Errorf("Expected %+v, received %+v", expErr, err) - } -} - -func TestLoaderActionProfileAsStructErrTConversion(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestLoaderActionProfileAsStructErrType", - bufLoaderData: map[string][]LoaderData{}, - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "ActivationInterval", - Path: "ActivationInterval", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true, - Layout: time.RFC3339}, - }, - } - actPrfCsv := ` -#ActivationInterval -* * * * * * -` - rdr := io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{fileName: utils.ActionProfilesCsv, - rdr: rdr, csvRdr: csvRdr}}, - } - expErr := `Unsupported time format` - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expErr { - t.Errorf("Expected %+v, received %+v", expErr, err) - } -} - func TestLoaderAttributesAsStructErrType(t *testing.T) { data := engine.NewInternalDB(nil, nil, true) ldr := &Loader{ @@ -3385,190 +3111,6 @@ func TestProcessContentEmptyDataBase(t *testing.T) { } } -func TestRemoveActionProfileContent(t *testing.T) { - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "TenantID", - Path: "Tenant", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true}, - {Tag: "ProfileID", - Path: "ID", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true}, - }, - } - actPrfCsv := ` -#Tenant[0],ID[1] -cgrates.org,REM_ACTPROFILE_1 -` - //cannot set ActionProfile when dataManager is nil - ldr.dm = nil - rdr := io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - expected := "NO_DATA_BASE_CONNECTION" - if err := ldr.processContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expected { - t.Errorf("Expected %+v, received %+v", expected, err) - } - - //set dataManager - ldr.dm = engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) - actRtPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "REM_ACTPROFILE_1", - } - if err := ldr.dm.SetActionProfile(actRtPrf, true); err != nil { - t.Error(err) - } else if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err != nil { - t.Error(err) - } - - //nothing to remove from database - if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err != utils.ErrNotFound { - t.Error(err) - } - - //cannot remove DispatcherHosts when dryrun is true - ldr.dryRun = true - rdr = io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr = csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err != nil { - t.Error(err) - } -} - -func TestRemoveContentError1(t *testing.T) { - //use actionProfile to generate an error by giving a wrong csv - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "TenantID", - Path: "Tenant", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true}, - {Tag: "ProfileID", - Path: "ID", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true}, - }, - } - //wrong start at the beginning of csv - actPrfCsv := ` -//Tenant[0] -cgrates.org,REM_ACTPROFILE_s -` - rdr := io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - actRtPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "REM_ACTPROFILE_s", - } - expectedErr := "NOT_FOUND" - if err := ldr.dm.SetActionProfile(actRtPrf, true); err != nil { - t.Error(err) - } else if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expectedErr { - t.Errorf("Expected %+v, received %+v", expectedErr, err) - } -} - -func TestRemoveContentError2(t *testing.T) { - //use actionProfile to generate an error by giving a wrong csv - data := engine.NewInternalDB(nil, nil, true) - ldr := &Loader{ - ldrID: "TestRemoveActionProfileContent", - bufLoaderData: make(map[string][]LoaderData), - dm: engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil), - timezone: "UTC", - } - ldr.dataTpls = map[string][]*config.FCTemplate{ - utils.MetaActionProfiles: { - {Tag: "TenantID", - Path: "Tenant", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.0", utils.InfieldSep), - Mandatory: true}, - {Tag: "ProfileID", - Path: "ID", - Type: utils.MetaComposed, - Value: config.NewRSRParsersMustCompile("~*req.1", utils.InfieldSep), - Mandatory: true}, - }, - } - //wrong start at the beginning of csv - actPrfCsv := ` -Tenant[0],ID[1] -cgrates.org,REM_ACTPROFILE_s -` - rdr := io.NopCloser(strings.NewReader(actPrfCsv)) - csvRdr := csv.NewReader(rdr) - csvRdr.Comment = '#' - ldr.rdrs = map[string]map[string]*openedCSVFile{ - utils.MetaActionProfiles: { - utils.ActionProfilesCsv: &openedCSVFile{ - fileName: utils.ActionProfilesCsv, - rdr: rdr, - csvRdr: csvRdr, - }, - }, - } - actRtPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "REM_ACTPROFILE_s", - } - expectedErr := "NOT_FOUND" - if err := ldr.dm.SetActionProfile(actRtPrf, true); err != nil { - t.Error(err) - } else if err := ldr.removeContent(utils.MetaActionProfiles, utils.EmptyString); err == nil || err.Error() != expectedErr { - t.Errorf("Expected %+v, received %+v", expectedErr, err) - } -} - func TestLoaderListenAndServe(t *testing.T) { ldr := &Loader{} stopChan := make(chan struct{}, 1) diff --git a/migrator/action_profiles.go b/migrator/action_profiles.go deleted file mode 100644 index 39dee5333..000000000 --- a/migrator/action_profiles.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -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 -*/ - -package migrator - -import ( - "fmt" - "strings" - - "github.com/cgrates/cgrates/engine" - - "github.com/cgrates/cgrates/utils" -) - -func (m *Migrator) migrateCurrentActionProfiles() (err error) { - var ids []string - ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.ActionProfilePrefix) - if err != nil { - return err - } - for _, id := range ids { - tntID := strings.SplitN(strings.TrimPrefix(id, utils.ActionProfilePrefix), utils.InInFieldSep, 2) - if len(tntID) < 2 { - return fmt.Errorf("Invalid key <%s> when migrating from action profiles", id) - } - ap, err := m.dmIN.DataManager().GetActionProfile(tntID[0], tntID[1], false, false, utils.NonTransactional) - if err != nil { - return err - } - if ap == nil || m.dryRun { - continue - } - if err := m.dmOut.DataManager().SetActionProfile(ap, true); err != nil { - return err - } - if err := m.dmIN.DataManager().RemoveActionProfile(tntID[0], tntID[1], utils.NonTransactional, false); err != nil { - return err - } - m.stats[utils.ActionProfiles]++ - } - return -} - -func (m *Migrator) migrateActionProfiles() (err error) { - var vrs engine.Versions - current := engine.CurrentDataDBVersions() - if vrs, err = m.getVersions(utils.ActionProfiles); err != nil { - return - } - migrated := true - for { - version := vrs[utils.ActionProfiles] - for { - switch version { - default: - return fmt.Errorf("Unsupported version %v", version) - case current[utils.ActionProfiles]: - migrated = false - if m.sameDataDB { - break - } - if err = m.migrateCurrentActionProfiles(); err != nil { - return - } - } - if version == current[utils.ActionProfiles] || err == utils.ErrNoMoreData { - break - } - } - if err == utils.ErrNoMoreData || !migrated { - break - } - m.stats[utils.ActionProfiles]++ - } - //All done, update version with current one - if err = m.setVersions(utils.ActionProfiles); err != nil { - return - } - return m.ensureIndexesDataDB(engine.ColApp) -} diff --git a/migrator/actionprofiles_it_test.go b/migrator/actionprofiles_it_test.go deleted file mode 100644 index 630a23a4c..000000000 --- a/migrator/actionprofiles_it_test.go +++ /dev/null @@ -1,256 +0,0 @@ -// +build integration - -/* -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 -*/ - -package migrator - -import ( - "log" - "path" - "reflect" - "testing" - - "github.com/cgrates/cgrates/engine" - - "github.com/cgrates/cgrates/utils" - - "github.com/cgrates/cgrates/config" -) - -var ( - actPrfPathIn string - actPrfPathOut string - actPrfCfgIn *config.CGRConfig - actPrfCfgOut *config.CGRConfig - actPrfMigrator *Migrator - actPrfAction string -) - -var sTestsActPrfIT = []func(t *testing.T){ - testActPrfITConnect, - testActPrfITFlush, - testActPrfMigrateAndMove, -} - -func TestActPrfITMove1(t *testing.T) { - var err error - actPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo") - actPrfCfgIn, err = config.NewCGRConfigFromPath(actPrfPathIn) - if err != nil { - t.Fatal(err) - } - actPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql") - actPrfCfgOut, err = config.NewCGRConfigFromPath(actPrfPathOut) - if err != nil { - t.Fatal(err) - } - actPrfAction = utils.Move - for _, stest := range sTestsActPrfIT { - t.Run("TestActPrfITMove1", stest) - } - actPrfMigrator.Close() -} - -func TestActPrfITMove2(t *testing.T) { - var err error - actPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql") - actPrfCfgIn, err = config.NewCGRConfigFromPath(actPrfPathIn) - if err != nil { - t.Error(err) - } - actPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo") - actPrfCfgOut, err = config.NewCGRConfigFromPath(actPrfPathOut) - if err != nil { - t.Error(err) - } - actPrfAction = utils.Move - for _, stest := range sTestsActPrfIT { - t.Run("TestActPrfITMove2", stest) - } - actPrfMigrator.Close() -} - -func TestActPrfITMoveEncoding(t *testing.T) { - var err error - actPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo") - actPrfCfgIn, err = config.NewCGRConfigFromPath(actPrfPathIn) - if err != nil { - t.Error(err) - } - actPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson") - actPrfCfgOut, err = config.NewCGRConfigFromPath(actPrfPathOut) - if err != nil { - t.Error(err) - } - actPrfAction = utils.Move - for _, stest := range sTestsActPrfIT { - t.Run("TestActPrfITMove2", stest) - } - actPrfMigrator.Close() -} - -func TestActPrfITMoveEncoding2(t *testing.T) { - var err error - actPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql") - actPrfCfgIn, err = config.NewCGRConfigFromPath(actPrfPathIn) - if err != nil { - t.Error(err) - } - actPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson") - actPrfCfgOut, err = config.NewCGRConfigFromPath(actPrfPathOut) - if err != nil { - t.Error(err) - } - actPrfAction = utils.Move - for _, stest := range sTestsActPrfIT { - t.Run("TestActPrfITMove2", stest) - } - actPrfMigrator.Close() -} - -func testActPrfITConnect(t *testing.T) { - dataDBIn, err := NewMigratorDataDB(actPrfCfgIn.DataDbCfg().Type, - actPrfCfgIn.DataDbCfg().Host, actPrfCfgIn.DataDbCfg().Port, - actPrfCfgIn.DataDbCfg().Name, actPrfCfgIn.DataDbCfg().User, - actPrfCfgIn.DataDbCfg().Password, actPrfCfgIn.GeneralCfg().DBDataEncoding, - config.CgrConfig().CacheCfg(), actPrfCfgIn.DataDbCfg().Opts) - if err != nil { - log.Fatal(err) - } - dataDBOut, err := NewMigratorDataDB(actPrfCfgOut.DataDbCfg().Type, - actPrfCfgOut.DataDbCfg().Host, actPrfCfgOut.DataDbCfg().Port, - actPrfCfgOut.DataDbCfg().Name, actPrfCfgOut.DataDbCfg().User, - actPrfCfgOut.DataDbCfg().Password, actPrfCfgOut.GeneralCfg().DBDataEncoding, - config.CgrConfig().CacheCfg(), actPrfCfgOut.DataDbCfg().Opts) - if err != nil { - log.Fatal(err) - } - if reflect.DeepEqual(actPrfPathIn, actPrfPathOut) { - actPrfMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil, - false, true, false, false) - } else { - actPrfMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil, - false, false, false, false) - } - if err != nil { - log.Fatal(err) - } -} - -func testActPrfITFlush(t *testing.T) { - //dmIn - if err := actPrfMigrator.dmIN.DataManager().DataDB().Flush(utils.EmptyString); err != nil { - t.Error(err) - } - if isEmpty, err := actPrfMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil { - t.Error(err) - } else if !isEmpty { - t.Errorf("Expecting: true got :%+v", isEmpty) - } - if err := engine.SetDBVersions(actPrfMigrator.dmIN.DataManager().DataDB()); err != nil { - t.Error(err) - } - - //dmOut - if err := actPrfMigrator.dmOut.DataManager().DataDB().Flush(utils.EmptyString); err != nil { - t.Error(err) - } - if isEMpty, err := actPrfMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil { - t.Error(err) - } else if !isEMpty { - t.Error(err) - } - if err := engine.SetDBVersions(actPrfMigrator.dmOut.DataManager().DataDB()); err != nil { - t.Error(err) - } -} - -func testActPrfMigrateAndMove(t *testing.T) { - actPrf := &engine.ActionProfile{ - Tenant: "cgrates.org", - ID: "TEST_ID1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 20, - Schedule: utils.MetaASAP, - Targets: map[string]utils.StringSet{ - utils.MetaAccounts: utils.NewStringSet([]string{"acc1", "acc2"}), - }, - Actions: []*engine.APAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestBalance.Value", - }}, - }, - { - ID: "TOPUP_TEST_VOICE", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*engine.APDiktat{{ - Path: "~*balance.TestVoiceBalance.Value", - }}, - }, - }, - } - switch actPrfAction { - case utils.Migrate: // for the moment only one version of actions profiles exists - case utils.Move: - //set, get and migrate - if err := actPrfMigrator.dmIN.DataManager().SetActionProfile(actPrf, true); err != nil { - t.Error(err) - } - currentVersion := engine.CurrentDataDBVersions() - err := actPrfMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false) - if err != nil { - t.Error("Error when setting version for ActionPrf", err.Error()) - } - - _, err = actPrfMigrator.dmOut.DataManager().GetActionProfile(actPrf.Tenant, actPrf.ID, - false, false, utils.NonTransactional) - if err != utils.ErrNotFound { - t.Error(err) - } - - err, _ = actPrfMigrator.Migrate([]string{utils.MetaActionProfiles}) - if err != nil { - t.Error("Error when migrating ActPrf", err.Error()) - } - //compared with dmOut - receivedACtPrf, err := actPrfMigrator.dmOut.DataManager().GetActionProfile(actPrf.Tenant, actPrf.ID, - false, false, utils.NonTransactional) - if err != nil { - t.Error(err) - } - if !reflect.DeepEqual(receivedACtPrf, actPrf) { - t.Errorf("Expected %+v, received %+v", utils.ToJSON(actPrf), utils.ToJSON(receivedACtPrf)) - } - - //compared with dmIn(should be empty) - _, err = actPrfMigrator.dmIN.DataManager().GetActionProfile(actPrf.Tenant, actPrf.ID, - false, false, utils.NonTransactional) - if err != utils.ErrNotFound { - t.Error(err) - } - if actPrfMigrator.stats[utils.ActionProfiles] != 1 { - t.Errorf("Expected 1, received: %v", actPrfMigrator.stats[utils.ActionProfiles]) - } - } -} diff --git a/migrator/migrator.go b/migrator/migrator.go index 04d9cd168..549a184c3 100755 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -133,8 +133,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) { err = m.migrateRatingPlans() case utils.MetaRatingProfiles: err = m.migrateRatingProfiles() - case utils.MetaActionProfiles: - err = m.migrateActionProfiles() case utils.MetaDestinations: err = m.migrateDestinations() case utils.MetaReverseDestinations: @@ -180,8 +178,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) { err = m.migrateTPsharedgroups() case utils.MetaTpRatingProfiles: err = m.migrateTPratingprofiles() - case utils.MetaTpActionProfiles: - err = m.migrateTPActionProfiles() case utils.MetaTpResources: err = m.migrateTPresources() case utils.MetaTpRates: diff --git a/migrator/tp_action_profile.go b/migrator/tp_action_profile.go deleted file mode 100644 index 3be9fd46b..000000000 --- a/migrator/tp_action_profile.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -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 -*/ - -package migrator - -import ( - "github.com/cgrates/cgrates/engine" - - "github.com/cgrates/cgrates/utils" -) - -func (m *Migrator) migrateCurrentTPActionProfiles() (err error) { - tpIds, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPActionProfiles) - if err != nil { - return err - } - - for _, tpid := range tpIds { - ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPActionProfiles, - utils.TPDistinctIds{"id"}, map[string]string{}, nil) - if err != nil { - return err - } - - for _, id := range ids { - actionProfiles, err := m.storDBIn.StorDB().GetTPActionProfiles(tpid, utils.EmptyString, id) - if err != nil { - return err - } - if actionProfiles == nil || m.dryRun { - continue - } - if err := m.storDBOut.StorDB().SetTPActionProfiles(actionProfiles); err != nil { - return err - } - for _, actionProfile := range actionProfiles { - if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPActionProfiles, actionProfile.TPid, - map[string]string{"id": actionProfile.ID}); err != nil { - return err - } - } - m.stats[utils.TpActionProfiles]++ - } - } - return -} - -func (m *Migrator) migrateTPActionProfiles() (err error) { - var vrs engine.Versions - current := engine.CurrentStorDBVersions() - if vrs, err = m.getVersions(utils.TpActionProfiles); err != nil { - return - } - switch vrs[utils.TpActionProfiles] { - case current[utils.TpActionProfiles]: - if m.sameStorDB { - break - } - if err := m.migrateCurrentTPActionProfiles(); err != nil { - return err - } - } - return m.ensureIndexesStorDB(utils.TBLTPActionProfiles) -} diff --git a/migrator/tp_action_profile_it_test.go b/migrator/tp_action_profile_it_test.go deleted file mode 100644 index 4a4c30860..000000000 --- a/migrator/tp_action_profile_it_test.go +++ /dev/null @@ -1,167 +0,0 @@ -// +build integration - -/* -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 -*/ -package migrator - -import ( - "path" - "reflect" - "testing" - - "github.com/cgrates/cgrates/engine" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/utils" -) - -var ( - tpActPrfPathIn string - tpActPrfPathOut string - tpActPrfCfgIn *config.CGRConfig - tpActPrfCfgOut *config.CGRConfig - tpActPrfMigrator *Migrator - actPrf []*utils.TPActionProfile -) - -var sTestTpActPrfIT = []func(t *testing.T){ - testTpActPrfConnect, - testTpActPrfFlush, - testTpACtPrfPopulate, - testTpACtPrfMove, - testTpACtPrfCheckData, -} - -func TestTpActPrfMove(t *testing.T) { - for _, tests := range sTestTpActPrfIT { - t.Run("TestTpActPrfMove", tests) - } - tpActPrfMigrator.Close() -} - -func testTpActPrfConnect(t *testing.T) { - var err error - tpActPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo") - tpActPrfCfgIn, err = config.NewCGRConfigFromPath(tpActPrfPathIn) - if err != nil { - t.Fatal(err) - } - tpActPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql") - tpActPrfCfgOut, err = config.NewCGRConfigFromPath(tpActPrfPathOut) - if err != nil { - t.Fatal(err) - } - storDBIn, err := NewMigratorStorDB(tpActPrfCfgIn.StorDbCfg().Type, - tpActPrfCfgIn.StorDbCfg().Host, tpActPrfCfgIn.StorDbCfg().Port, - tpActPrfCfgIn.StorDbCfg().Name, tpActPrfCfgIn.StorDbCfg().User, - tpActPrfCfgIn.StorDbCfg().Password, tpActPrfCfgIn.GeneralCfg().DBDataEncoding, - tpActPrfCfgIn.StorDbCfg().StringIndexedFields, tpActPrfCfgIn.StorDbCfg().PrefixIndexedFields, - tpActPrfCfgIn.StorDbCfg().Opts) - if err != nil { - t.Error(err) - } - storDBOut, err := NewMigratorStorDB(tpActPrfCfgOut.StorDbCfg().Type, - tpActPrfCfgOut.StorDbCfg().Host, tpActPrfCfgOut.StorDbCfg().Port, - tpActPrfCfgOut.StorDbCfg().Name, tpActPrfCfgOut.StorDbCfg().User, - tpActPrfCfgOut.StorDbCfg().Password, tpActPrfCfgOut.GeneralCfg().DBDataEncoding, - tpActPrfCfgOut.StorDbCfg().StringIndexedFields, tpActPrfCfgOut.StorDbCfg().PrefixIndexedFields, - tpActPrfCfgOut.StorDbCfg().Opts) - if err != nil { - t.Error(err) - } - - tpActPrfMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, - false, false, false, false) - if err != nil { - t.Fatal(err) - } -} - -func testTpActPrfFlush(t *testing.T) { - if err := tpActPrfMigrator.storDBIn.StorDB().Flush( - path.Join(tpActPrfCfgIn.DataFolderPath, "storage", tpActPrfCfgIn.StorDbCfg().Type)); err != nil { - t.Error(err) - } - if err := tpActPrfMigrator.storDBOut.StorDB().Flush( - path.Join(tpActPrfCfgOut.DataFolderPath, "storage", tpActPrfCfgOut.StorDbCfg().Type)); err != nil { - t.Error(err) - } -} - -func testTpACtPrfPopulate(t *testing.T) { - actPrf = []*utils.TPActionProfile{ - { - Tenant: "cgrates.org", - TPid: "TEST_ID1", - ID: "sub_id1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 20, - Schedule: utils.MetaASAP, - Actions: []*utils.TPAPAction{ - { - ID: "TOPUP", - FilterIDs: []string{}, - Type: "*topup", - Diktats: []*utils.TPAPDiktat{{ - Path: "~*balance.TestBalance.Value", - }}, - }, - }, - }, - } - //empty in database - if _, err := tpActPrfMigrator.storDBIn.StorDB().GetTPActionProfiles(actPrf[0].TPid, - utils.EmptyString, actPrf[0].ID); err != utils.ErrNotFound { - t.Error(err) - } - - //set an TPActionProfile in database - if err := tpActPrfMigrator.storDBIn.StorDB().SetTPActionProfiles(actPrf); err != nil { - t.Error(err) - } - currVersion := engine.CurrentStorDBVersions() - err := tpActPrfMigrator.storDBIn.StorDB().SetVersions(currVersion, false) - if err != nil { - t.Error(err) - } -} - -func testTpACtPrfMove(t *testing.T) { - err, _ := tpActPrfMigrator.Migrate([]string{utils.MetaTpActionProfiles}) - if err != nil { - t.Error("Error when migrating TpActionProfile ", err.Error()) - } -} - -func testTpACtPrfCheckData(t *testing.T) { - rcv, err := tpActPrfMigrator.storDBOut.StorDB().GetTPActionProfiles(actPrf[0].TPid, - utils.EmptyString, actPrf[0].ID) - if err != nil { - t.Error("Error when getting TPActionProfile from database", err) - } - actPrf[0].Actions[0].FilterIDs = nil // because of converting and empty string into a slice - if !reflect.DeepEqual(rcv[0], actPrf[0]) { - t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(actPrf[0]), utils.ToJSON(rcv[0])) - } - - _, err = tpActPrfMigrator.storDBIn.StorDB().GetTPActionProfiles(actPrf[0].TPid, - utils.EmptyString, actPrf[0].ID) - if err != utils.ErrNotFound { - t.Error(err) - } -} diff --git a/services/actions.go b/services/actions.go deleted file mode 100644 index f55c7c0db..000000000 --- a/services/actions.go +++ /dev/null @@ -1,139 +0,0 @@ -/* -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 -*/ - -package services - -import ( - "fmt" - "sync" - - "github.com/cgrates/cgrates/actions" - - v1 "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/cores" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/servmanager" - "github.com/cgrates/cgrates/utils" - "github.com/cgrates/rpcclient" -) - -// NewActionService returns the Action Service -func NewActionService(cfg *config.CGRConfig, dm *DataDBService, - cacheS *engine.CacheS, filterSChan chan *engine.FilterS, - connMgr *engine.ConnManager, - server *cores.Server, internalChan chan rpcclient.ClientConnector, - anz *AnalyzerService, srvDep map[string]*sync.WaitGroup) servmanager.Service { - return &ActionService{ - connChan: internalChan, - connMgr: connMgr, - cfg: cfg, - dm: dm, - cacheS: cacheS, - filterSChan: filterSChan, - server: server, - anz: anz, - srvDep: srvDep, - rldChan: make(chan struct{}, 1), - } -} - -// ActionService implements Service interface -type ActionService struct { - sync.RWMutex - cfg *config.CGRConfig - dm *DataDBService - cacheS *engine.CacheS - filterSChan chan *engine.FilterS - connMgr *engine.ConnManager - server *cores.Server - - rldChan chan struct{} - stopChan chan struct{} - - acts *actions.ActionS - rpc *v1.ActionSv1 // useful on restart - connChan chan rpcclient.ClientConnector // publish the internal Subsystem when available - anz *AnalyzerService - srvDep map[string]*sync.WaitGroup -} - -// Start should handle the service start -func (acts *ActionService) Start() (err error) { - if acts.IsRunning() { - return utils.ErrServiceAlreadyRunning - } - - <-acts.cacheS.GetPrecacheChannel(utils.CacheActionProfiles) - <-acts.cacheS.GetPrecacheChannel(utils.CacheActionProfilesFilterIndexes) - - filterS := <-acts.filterSChan - acts.filterSChan <- filterS - dbchan := acts.dm.GetDMChan() - datadb := <-dbchan - dbchan <- datadb - - acts.Lock() - defer acts.Unlock() - acts.acts = actions.NewActionS(acts.cfg, filterS, datadb, acts.connMgr) - acts.stopChan = make(chan struct{}) - go acts.acts.ListenAndServe(acts.stopChan, acts.rldChan) - - utils.Logger.Info(fmt.Sprintf("<%s> starting <%s> subsystem", utils.CoreS, utils.ActionS)) - acts.rpc = v1.NewActionSv1(acts.acts) - if !acts.cfg.DispatcherSCfg().Enabled { - acts.server.RpcRegister(acts.rpc) - } - acts.connChan <- acts.anz.GetInternalCodec(acts.rpc, utils.ActionS) - return -} - -// Reload handles the change of config -func (acts *ActionService) Reload() (err error) { - acts.rldChan <- struct{}{} - return // for the moment nothing to reload -} - -// Shutdown stops the service -func (acts *ActionService) Shutdown() (err error) { - acts.Lock() - defer acts.Unlock() - close(acts.stopChan) - acts.acts.Shutdown() - acts.acts = nil - acts.rpc = nil - <-acts.connChan - return -} - -// IsRunning returns if the service is running -func (acts *ActionService) IsRunning() bool { - acts.RLock() - defer acts.RUnlock() - return acts != nil && acts.acts != nil -} - -// ServiceName returns the service name -func (acts *ActionService) ServiceName() string { - return utils.ActionS -} - -// ShouldRun returns if the service should be running -func (acts *ActionService) ShouldRun() bool { - return acts.cfg.ActionSCfg().Enabled -} diff --git a/services/actions_it_test.go b/services/actions_it_test.go deleted file mode 100644 index 3a4219c0f..000000000 --- a/services/actions_it_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// +build integration - -/* -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 -*/ -package services - -import ( - "path" - "sync" - "testing" - "time" - - "github.com/cgrates/rpcclient" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/cores" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/servmanager" - "github.com/cgrates/cgrates/utils" -) - -func TestActionSReload(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - - utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID) - utils.Logger.SetLogLevel(7) - - shdChan := utils.NewSyncedChan() - shdWg := new(sync.WaitGroup) - chS := engine.NewCacheS(cfg, nil, nil) - filterSChan := make(chan *engine.FilterS, 1) - filterSChan <- nil - close(chS.GetPrecacheChannel(utils.CacheActionProfiles)) - close(chS.GetPrecacheChannel(utils.CacheActionProfilesFilterIndexes)) - server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) - srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} - db := NewDataDBService(cfg, nil, srvDep) - actRPC := make(chan rpcclient.ClientConnector, 1) - anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) - actS := NewActionService(cfg, db, chS, filterSChan, nil, server, actRPC, anz, srvDep) - engine.NewConnManager(cfg, nil) - srvMngr.AddServices(actS, - NewLoaderService(cfg, db, filterSChan, server, make(chan rpcclient.ClientConnector, 1), nil, anz, srvDep), db) - if err := srvMngr.StartServices(); err != nil { - t.Error(err) - } - if actS.IsRunning() { - t.Errorf("Expected service to be down") - } - if db.IsRunning() { - t.Errorf("Expected service to be down") - } - - var reply string - if err := cfg.V1ReloadConfig(&config.ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo"), - Section: config.ActionSJson, - }, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Errorf("Expecting OK ,received %s", reply) - } - select { - case d := <-actRPC: - actRPC <- d - case <-time.After(time.Second): - t.Fatal("It took to long to reload the cache") - } - if !actS.IsRunning() { - t.Errorf("Expected service to be running") - } - if !db.IsRunning() { - t.Errorf("Expected service to be running") - } - err := actS.Start() - if err == nil || err != utils.ErrServiceAlreadyRunning { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ErrServiceAlreadyRunning, err) - } - err = actS.Reload() - if err != nil { - t.Errorf("\nExpecting ,\n Received <%+v>", err) - } - cfg.ActionSCfg().Enabled = false - cfg.GetReloadChan(config.ActionSJson) <- struct{}{} - time.Sleep(10 * time.Millisecond) - - if actS.IsRunning() { - t.Errorf("Expected service to be down") - } - - shdChan.CloseOnce() - time.Sleep(10 * time.Millisecond) - -} diff --git a/services/actions_test.go b/services/actions_test.go deleted file mode 100644 index df2df448e..000000000 --- a/services/actions_test.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -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 -*/ -package services - -import ( - "reflect" - "sync" - "testing" - - "github.com/cgrates/cgrates/actions" - - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/cores" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" - "github.com/cgrates/rpcclient" -) - -//TestActionSCoverage for cover testing -func TestActionSCoverage(t *testing.T) { - cfg := config.NewDefaultCGRConfig() - shdChan := utils.NewSyncedChan() - chS := engine.NewCacheS(cfg, nil, nil) - filterSChan := make(chan *engine.FilterS, 1) - filterSChan <- nil - server := cores.NewServer(nil) - srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} - db := NewDataDBService(cfg, nil, srvDep) - actRPC := make(chan rpcclient.ClientConnector, 1) - anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) - actS := NewActionService(cfg, db, - chS, filterSChan, nil, server, actRPC, - anz, srvDep) - if actS == nil { - t.Errorf("\nExpecting ,\n Received <%+v>", utils.ToJSON(actS)) - } - //initialises an empty chan to call the reload function - testChan := make(chan struct{}) - //populates actRPC with something in order to call the close function - actRPC <- chS - actS2 := &ActionService{ - cfg: cfg, - dm: db, - cacheS: chS, - filterSChan: filterSChan, - server: server, - rldChan: testChan, - stopChan: make(chan struct{}, 1), - connChan: actRPC, - anz: anz, - srvDep: srvDep, - } - if actS2.IsRunning() { - t.Errorf("Expected service to be down") - } - actS2.acts = actions.NewActionS(cfg, &engine.FilterS{}, &engine.DataManager{}, nil) - if !actS2.IsRunning() { - t.Errorf("Expected service to be running") - } - serviceName := actS2.ServiceName() - if !reflect.DeepEqual(serviceName, utils.ActionS) { - t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ActionS, serviceName) - } - shouldRun := actS2.ShouldRun() - if !reflect.DeepEqual(shouldRun, false) { - t.Errorf("\nExpecting ,\n Received <%+v>", shouldRun) - } -} diff --git a/services/datadb_it_test.go b/services/datadb_it_test.go index a3cbfbe79..053152562 100644 --- a/services/datadb_it_test.go +++ b/services/datadb_it_test.go @@ -176,9 +176,6 @@ func TestDataDBReload(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } if !reflect.DeepEqual(oldcfg, db.oldDBCfg) { @@ -239,7 +236,6 @@ func TestDataDBReloadBadType(t *testing.T) { utils.Chargers: 2, utils.Dispatchers: 2, utils.LoadIDsVrs: 1, - utils.ActionProfiles: 1, }, true) if err != nil { t.Fatal(err) @@ -347,9 +343,6 @@ func TestDataDBReloadBadType(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } cfg.DataDbCfg().Type = "dbtype" @@ -473,9 +466,6 @@ func TestDataDBReloadErrorMarsheler(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } @@ -526,7 +516,6 @@ func TestDataDBStartVersion(t *testing.T) { utils.Chargers: 2, utils.Dispatchers: 2, utils.LoadIDsVrs: 1, - utils.ActionProfiles: 1, }, true) if err != nil { t.Fatal(err) @@ -588,7 +577,6 @@ func TestDataDBReloadCastError(t *testing.T) { utils.Chargers: 2, utils.Dispatchers: 2, utils.LoadIDsVrs: 1, - utils.ActionProfiles: 1, }, true) if err != nil { t.Fatal(err) @@ -696,9 +684,6 @@ func TestDataDBReloadCastError(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } @@ -752,7 +737,6 @@ func TestDataDBReloadIfaceAsDurationError(t *testing.T) { utils.Chargers: 2, utils.Dispatchers: 2, utils.LoadIDsVrs: 1, - utils.ActionProfiles: 1, }, true) if err != nil { t.Fatal(err) @@ -860,9 +844,6 @@ func TestDataDBReloadIfaceAsDurationError(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } cfg.DataDbCfg().Opts[utils.QueryTimeoutCfg] = true @@ -1005,9 +986,6 @@ func TestDataDBReloadError(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } data := engine.NewInternalDB(nil, nil, true) diff --git a/services/datadb_test.go b/services/datadb_test.go index 8d66fbbd5..a5108d209 100644 --- a/services/datadb_test.go +++ b/services/datadb_test.go @@ -141,9 +141,6 @@ func TestDataDBCoverage(t *testing.T) { utils.MetaIndexes: { Replicate: false, Remote: false}, - utils.MetaActionProfiles: { - Replicate: false, - Remote: false}, }, } db.oldDBCfg = oldcfg diff --git a/services/dispatchers.go b/services/dispatchers.go index 4964c98fe..0438550d7 100644 --- a/services/dispatchers.go +++ b/services/dispatchers.go @@ -145,12 +145,6 @@ func (dspS *DispatcherService) Start() (err error) { dspS.server.RpcRegisterName(utils.CDRsV2, v2.NewDispatcherSCDRsV2(dspS.dspS)) - dspS.server.RpcRegisterName(utils.ActionSv1, - v1.NewDispatcherActionSv1(dspS.dspS)) - - dspS.server.RpcRegisterName(utils.AccountSv1, - v1.NewDispatcherAccountSv1(dspS.dspS)) - dspS.connChan <- dspS.anz.GetInternalCodec(dspS.dspS, utils.DispatcherS) return diff --git a/services/stordb_it_test.go b/services/stordb_it_test.go index 85098cc8c..9fc3317d9 100644 --- a/services/stordb_it_test.go +++ b/services/stordb_it_test.go @@ -197,7 +197,6 @@ func TestStorDBReloadVersion1(t *testing.T) { utils.TpRatingProfile: 1, utils.TpChargers: 1, utils.TpDispatchers: 1, - utils.TpActionProfiles: 1, }, true) utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID) @@ -276,7 +275,6 @@ func TestStorDBReloadVersion2(t *testing.T) { utils.TpRatingProfile: 1, utils.TpChargers: 1, utils.TpDispatchers: 1, - utils.TpActionProfiles: 1, }, true) utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID) @@ -352,7 +350,6 @@ func TestStorDBReloadVersion3(t *testing.T) { utils.TpRatingProfile: 1, utils.TpChargers: 1, utils.TpDispatchers: 1, - utils.TpActionProfiles: 1, }, true) utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID) diff --git a/utils/apitpdata.go b/utils/apitpdata.go index e804303e5..f32ede6dc 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -23,8 +23,6 @@ import ( "sort" "strings" "time" - - "github.com/ericlagergren/decimal" ) // Used to extract ids from stordb @@ -1453,69 +1451,3 @@ type ArgExportCDRs struct { Verbose bool // verbose is used to inform the user about the positive and negative exported cdrs RPCCDRsFilter } - -// ArgsCostForEvent arguments used for process event -type ArgsCostForEvent struct { - RateProfileIDs []string - *CGREvent -} - -// StartTime returns the event time used to check active rate profiles -func (args *ArgsCostForEvent) StartTime(tmz string) (sTime time.Time, err error) { - if tIface, has := args.APIOpts[OptsRatesStartTime]; has { - return IfaceAsTime(tIface, tmz) - } - return time.Now(), nil -} - -// usage returns the event time used to check active rate profiles -func (args *ArgsCostForEvent) Usage() (usage *decimal.Big, err error) { - // first search for the usage in opts - if uIface, has := args.APIOpts[OptsRatesUsage]; has { - return IfaceAsBig(uIface) - } - // if the usage is not present in opts search in event - if uIface, has := args.Event[Usage]; has { - return IfaceAsBig(uIface) - } - // if the usage is not found in the event populate with default value and overwrite the NOT_FOUND error with nil - return decimal.New(int64(time.Minute), 0), nil -} - -type TPActionProfile struct { - TPid string - Tenant string - ID string - FilterIDs []string - ActivationInterval *TPActivationInterval - Weight float64 - Schedule string - Targets []*TPActionTarget - Actions []*TPAPAction -} - -type TPActionTarget struct { - TargetType string - TargetIDs []string -} - -type TPAPAction struct { - ID string - FilterIDs []string - Blocker bool - TTL string - Type string - Opts string - Diktats []*TPAPDiktat -} - -type TPAPDiktat struct { - Path string - Value string -} - -// ArgActionSv1ScheduleActions is used in ActionSv1 methods -type ArgActionSv1ScheduleActions struct { - *CGREvent - ActionProfileIDs []string -} diff --git a/utils/consts.go b/utils/consts.go index ce3d33837..925831351 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -51,7 +51,7 @@ var ( CacheRatingProfiles, CacheActions, CacheActionTriggers, CacheSharedGroups, CacheTimings, CacheResourceProfiles, CacheResources, CacheEventResources, CacheStatQueueProfiles, CacheStatQueues, CacheThresholdProfiles, CacheThresholds, CacheFilters, CacheRouteProfiles, CacheAttributeProfiles, - CacheChargerProfiles, CacheActionProfiles, CacheDispatcherProfiles, CacheDispatcherHosts, + CacheChargerProfiles, CacheDispatcherProfiles, CacheDispatcherHosts, CacheResourceFilterIndexes, CacheStatFilterIndexes, CacheThresholdFilterIndexes, CacheRouteFilterIndexes, CacheAttributeFilterIndexes, CacheChargerFilterIndexes, CacheDispatcherFilterIndexes, CacheLoadIDs, CacheRatingProfilesTmp, CacheReverseFilterIndexes, @@ -123,7 +123,6 @@ var ( CacheAttributeProfiles: CacheAttributeFilterIndexes, CacheChargerProfiles: CacheChargerFilterIndexes, CacheDispatcherProfiles: CacheDispatcherFilterIndexes, - CacheActionProfiles: CacheActionProfilesFilterIndexes, CacheFilters: CacheReverseFilterIndexes, // CacheRates: CacheRateFilterIndexes, } @@ -157,7 +156,6 @@ var ( TBLTPChargers: CacheTBLTPChargers, TBLTPDispatchers: CacheTBLTPDispatchers, TBLTPDispatcherHosts: CacheTBLTPDispatcherHosts, - TBLTPActionProfiles: CacheTBLTPActionProfiles, } // ProtectedSFlds are the fields that sessions should not alter ProtectedSFlds = NewStringSet([]string{CGRID, OriginHost, OriginID, Usage}) @@ -183,7 +181,6 @@ var ( ChargerProfileIDs: ChargerProfilePrefix, DispatcherProfileIDs: DispatcherProfilePrefix, DispatcherHostIDs: DispatcherHostPrefix, - ActionProfileIDs: ActionProfilePrefix, TimingIDs: TimingsPrefix, AttributeFilterIndexIDs: AttributeFilterIndexes, @@ -377,7 +374,6 @@ const ( AttributeProfilePrefix = "alp_" ChargerProfilePrefix = "cpp_" DispatcherProfilePrefix = "dpp_" - ActionProfilePrefix = "acp_" DispatcherHostPrefix = "dph_" ThresholdProfilePrefix = "thp_" StatQueuePrefix = "stq_" @@ -535,7 +531,6 @@ const ( Filters = "Filters" DispatcherProfiles = "DispatcherProfiles" DispatcherHosts = "DispatcherHosts" - ActionProfiles = "ActionProfiles" MetaEveryMinute = "*every_minute" MetaHourly = "*hourly" ID = "ID" @@ -970,7 +965,6 @@ const ( MetaThresholds = "*thresholds" MetaRoutes = "*routes" MetaAttributes = "*attributes" - MetaActionProfiles = "*action_profiles" MetaLoadIDs = "*load_ids" ) @@ -1095,7 +1089,6 @@ const ( MetaTpStats = "*tp_stats" MetaTpSharedGroups = "*tp_shared_groups" MetaTpRatingProfiles = "*tp_rating_profiles" - MetaTpActionProfiles = "*tp_action_profiles" MetaTpResources = "*tp_resources" MetaTpRates = "*tp_rates" MetaTpTimings = "*tp_timings" @@ -1138,7 +1131,6 @@ const ( TpDispatchers = "TpDispatchers" TpDispatcherProfiles = "TpDispatcherProfiles" TpDispatcherHosts = "TpDispatcherHosts" - TpActionProfiles = "TpActionProfiles" ) // Dispatcher Const @@ -1227,7 +1219,6 @@ const ( ReplicatorSv1GetAttributeProfile = "ReplicatorSv1.GetAttributeProfile" ReplicatorSv1GetChargerProfile = "ReplicatorSv1.GetChargerProfile" ReplicatorSv1GetDispatcherProfile = "ReplicatorSv1.GetDispatcherProfile" - ReplicatorSv1GetActionProfile = "ReplicatorSv1.GetActionProfile" ReplicatorSv1GetDispatcherHost = "ReplicatorSv1.GetDispatcherHost" ReplicatorSv1GetItemLoadIDs = "ReplicatorSv1.GetItemLoadIDs" ReplicatorSv1SetThresholdProfile = "ReplicatorSv1.SetThresholdProfile" @@ -1252,7 +1243,6 @@ const ( ReplicatorSv1SetAttributeProfile = "ReplicatorSv1.SetAttributeProfile" ReplicatorSv1SetChargerProfile = "ReplicatorSv1.SetChargerProfile" ReplicatorSv1SetDispatcherProfile = "ReplicatorSv1.SetDispatcherProfile" - ReplicatorSv1SetActionProfile = "ReplicatorSv1.SetActionProfile" ReplicatorSv1SetDispatcherHost = "ReplicatorSv1.SetDispatcherHost" ReplicatorSv1SetLoadIDs = "ReplicatorSv1.SetLoadIDs" ReplicatorSv1RemoveThreshold = "ReplicatorSv1.RemoveThreshold" @@ -1276,7 +1266,6 @@ const ( ReplicatorSv1RemoveAttributeProfile = "ReplicatorSv1.RemoveAttributeProfile" ReplicatorSv1RemoveChargerProfile = "ReplicatorSv1.RemoveChargerProfile" ReplicatorSv1RemoveDispatcherProfile = "ReplicatorSv1.RemoveDispatcherProfile" - ReplicatorSv1RemoveActionProfile = "ReplicatorSv1.RemoveActionProfile" ReplicatorSv1RemoveDispatcherHost = "ReplicatorSv1.RemoveDispatcherHost" ReplicatorSv1GetIndexes = "ReplicatorSv1.GetIndexes" ReplicatorSv1SetIndexes = "ReplicatorSv1.SetIndexes" @@ -1768,15 +1757,6 @@ const ( EeSv1ProcessEvent = "EeSv1.ProcessEvent" ) -// ActionProfile APIs -const ( - APIerSv1SetActionProfile = "APIerSv1.SetActionProfile" - APIerSv1GetActionProfile = "APIerSv1.GetActionProfile" - APIerSv1GetActionProfileIDs = "APIerSv1.GetActionProfileIDs" - APIerSv1GetActionProfileIDsCount = "APIerSv1.GetActionProfileIDsCount" - APIerSv1RemoveActionProfile = "APIerSv1.RemoveActionProfile" -) - //cgr_ variables const ( CGRAccount = "cgr_account" @@ -1816,7 +1796,6 @@ const ( ChargersCsv = "Chargers.csv" DispatcherProfilesCsv = "DispatcherProfiles.csv" DispatcherHostsCsv = "DispatcherHosts.csv" - ActionProfilesCsv = "ActionProfiles.csv" ) // Table Name @@ -1845,7 +1824,6 @@ const ( OldSMCosts = "sm_costs" TBLTPDispatchers = "tp_dispatcher_profiles" TBLTPDispatcherHosts = "tp_dispatcher_hosts" - TBLTPActionProfiles = "tp_action_profiles" ) // Cache Name @@ -1928,16 +1906,15 @@ const ( // Prefix for indexing const ( - ResourceFilterIndexes = "rfi_" - StatFilterIndexes = "sfi_" - ThresholdFilterIndexes = "tfi_" - AttributeFilterIndexes = "afi_" - ChargerFilterIndexes = "cfi_" - DispatcherFilterIndexes = "dfi_" - ActionPlanIndexes = "api_" - RouteFilterIndexes = "rti_" - ActionProfilesFilterIndexPrfx = "aci_" - FilterIndexPrfx = "fii_" + ResourceFilterIndexes = "rfi_" + StatFilterIndexes = "sfi_" + ThresholdFilterIndexes = "tfi_" + AttributeFilterIndexes = "afi_" + ChargerFilterIndexes = "cfi_" + DispatcherFilterIndexes = "dfi_" + ActionPlanIndexes = "api_" + RouteFilterIndexes = "rti_" + FilterIndexPrfx = "fii_" ) // Agents @@ -2567,7 +2544,6 @@ const ( DispatcherProfileIDs = "DispatcherProfileIDs" DispatcherHostIDs = "DispatcherHostIDs" DispatcherRoutesIDs = "DispatcherRoutesIDs" - ActionProfileIDs = "ActionProfileIDs" TimingIDs = "TimingIDs" AttributeFilterIndexIDs = "AttributeFilterIndexIDs" ResourceFilterIndexIDs = "ResourceFilterIndexIDs"