diff --git a/apier/v1/api_interfaces.go b/apier/v1/api_interfaces.go
index 110a6bc8e..1527a7e9f 100644
--- a/apier/v1/api_interfaces.go
+++ b/apier/v1/api_interfaces.go
@@ -86,7 +86,6 @@ type SessionSv1Interface interface {
ProcessCDR(cgrEv *utils.CGREvent, rply *string) error
ProcessMessage(args *sessions.V1ProcessMessageArgs, rply *sessions.V1ProcessMessageReply) error
ProcessEvent(args *sessions.V1ProcessEventArgs, rply *sessions.V1ProcessEventReply) error
- GetCost(args *sessions.V1ProcessEventArgs, rply *sessions.V1GetCostReply) error
GetActiveSessions(args *utils.SessionFilter, rply *[]*sessions.ExternalSession) error
GetActiveSessionsCount(args *utils.SessionFilter, rply *int) error
ForceDisconnect(args *utils.SessionFilter, rply *string) error
@@ -102,16 +101,6 @@ type SessionSv1Interface interface {
STIRIdentity(args *sessions.V1STIRIdentityArgs, reply *string) error
}
-type ResponderInterface interface {
- GetCost(arg *engine.CallDescriptorWithAPIOpts, reply *engine.CallCost) (err error)
- Debit(arg *engine.CallDescriptorWithAPIOpts, reply *engine.CallCost) (err error)
- MaxDebit(arg *engine.CallDescriptorWithAPIOpts, reply *engine.CallCost) (err error)
- RefundRounding(arg *engine.CallDescriptorWithAPIOpts, reply *float64) (err error)
- GetMaxSessionTime(arg *engine.CallDescriptorWithAPIOpts, reply *time.Duration) (err error)
- Shutdown(arg *utils.TenantWithAPIOpts, reply *string) (err error)
- Ping(ign *utils.CGREvent, reply *string) error
-}
-
type CacheSv1Interface interface {
GetItemIDs(args *utils.ArgsGetCacheItemIDsWithAPIOpts, reply *[]string) error
HasItem(args *utils.ArgsGetCacheItemWithAPIOpts, reply *bool) error
@@ -149,16 +138,12 @@ type CDRsV1Interface interface {
ProcessEvent(arg *engine.ArgV1ProcessEvent, reply *string) error
ProcessExternalCDR(cdr *engine.ExternalCDRWithAPIOpts, reply *string) error
RateCDRs(arg *engine.ArgRateCDRs, reply *string) error
- StoreSessionCost(attr *engine.AttrCDRSStoreSMCost, reply *string) error
GetCDRsCount(args *utils.RPCCDRsFilterWithAPIOpts, reply *int64) error
GetCDRs(args *utils.RPCCDRsFilterWithAPIOpts, reply *[]*engine.CDR) error
Ping(ign *utils.CGREvent, reply *string) error
}
type ServiceManagerV1Interface interface {
- StartService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error
- StopService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error
- ServiceStatus(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error
Ping(ign *utils.CGREvent, reply *string) error
}
@@ -214,7 +199,6 @@ type ReplicatorSv1Interface interface {
SetTiming(tm *utils.TPTimingWithAPIOpts, reply *string) error
SetResource(rs *engine.ResourceWithAPIOpts, reply *string) error
SetResourceProfile(rs *engine.ResourceProfileWithAPIOpts, reply *string) error
- SetActions(args *engine.SetActionsArgsWithAPIOpts, reply *string) error
SetRouteProfile(sp *engine.RouteProfileWithAPIOpts, reply *string) error
SetAttributeProfile(ap *engine.AttributeProfileWithAPIOpts, reply *string) error
SetChargerProfile(cp *engine.ChargerProfileWithAPIOpts, reply *string) error
diff --git a/apier/v1/apier.go b/apier/v1/apier.go
index 164f3ff20..7e66b8e40 100644
--- a/apier/v1/apier.go
+++ b/apier/v1/apier.go
@@ -25,7 +25,6 @@ import (
"path"
"strconv"
"strings"
- "time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
@@ -551,75 +550,6 @@ func (apierSv1 *APIerSv1) GetLoadHistory(attrs *utils.Paginator, reply *[]*utils
return nil
}
-type AttrRemoveActions struct {
- ActionIDs []string
-}
-
-func (apierSv1 *APIerSv1) RemoveActions(attr *AttrRemoveActions, reply *string) error {
- if attr.ActionIDs == nil {
- err := utils.ErrNotFound
- *reply = err.Error()
- return err
- }
- // The check could lead to very long execution time. So we decided to leave it at the user's risck.'
- /*
- stringMap := utils.NewStringMap(attr.ActionIDs...)
- keys, err := apiv1.DataManager.DataDB().GetKeysForPrefix(utils.ActionTriggerPrefix, true)
- if err != nil {
- *reply = err.Error()
- return err
- }
- for _, key := range keys {
- getAttrs, err := apiv1.DataManager.DataDB().GetActionTriggers(key[len(utils.ActionTriggerPrefix):])
- if err != nil {
- *reply = err.Error()
- return err
- }
- for _, atr := range getAttrs {
- if _, found := stringMap[atr.ActionsID]; found {
- // found action trigger referencing action; abort
- err := fmt.Errorf("action %s refenced by action trigger %s", atr.ActionsID, atr.ID)
- *reply = err.Error()
- return err
- }
- }
- }
- allAplsMap, err := apiv1.DataManager.GetAllActionPlans()
- if err != nil && err != utils.ErrNotFound {
- *reply = err.Error()
- return err
- }
- for _, apl := range allAplsMap {
- for _, atm := range apl.ActionTimings {
- if _, found := stringMap[atm.ActionsID]; found {
- err := fmt.Errorf("action %s refenced by action plan %s", atm.ActionsID, apl.Id)
- *reply = err.Error()
- return err
- }
- }
- }
- */
- for _, aID := range attr.ActionIDs {
- if err := apierSv1.DataManager.RemoveActions(aID, utils.NonTransactional); err != nil {
- *reply = err.Error()
- return err
- }
- }
- //CacheReload
- if err := apierSv1.ConnMgr.Call(apierSv1.Config.ApierCfg().CachesConns, nil,
- utils.CacheSv1ReloadCache, utils.AttrReloadCacheWithAPIOpts{
- ArgsCache: map[string][]string{utils.ActionIDs: attr.ActionIDs},
- }, reply); err != nil {
- return err
- }
- //generate a loadID for CacheActions and store it in database
- if err := apierSv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheActions: time.Now().UnixNano()}); err != nil {
- return utils.APIErrorHandler(err)
- }
- *reply = utils.OK
- return nil
-}
-
type ArgsReplyFailedPosts struct {
FailedRequestsInDir *string // if defined it will be our source of requests to be replayed
FailedRequestsOutDir *string // if defined it will become our destination for files failing to be replayed, *none to be discarded
@@ -707,21 +637,6 @@ func (apierSv1 *APIerSv1) GetLoadTimes(args *LoadTimeArgs, reply *map[string]str
return
}
-func (apierSv1 *APIerSv1) ComputeActionPlanIndexes(_ string, reply *string) (err error) {
- if apierSv1.DataManager.DataDB().GetStorageType() != utils.Redis {
- return utils.ErrNotImplemented
- }
- redisDB, can := apierSv1.DataManager.DataDB().(*engine.RedisStorage)
- if !can {
- return fmt.Errorf("Storage type %s could not be cated to <*engine.RedisStorage>", apierSv1.DataManager.DataDB().GetStorageType())
- }
- if err = redisDB.RebbuildActionPlanKeys(); err != nil {
- return err
- }
- *reply = utils.OK
- return nil
-}
-
// ListenAndServe listen for storbd reload
func (apierSv1 *APIerSv1) ListenAndServe(stopChan chan struct{}) {
utils.Logger.Info(fmt.Sprintf("<%s> starting <%s> subsystem", utils.CoreS, utils.ApierS))
diff --git a/apier/v1/cdrs.go b/apier/v1/cdrs.go
index 613b7c9e6..b2075cf45 100644
--- a/apier/v1/cdrs.go
+++ b/apier/v1/cdrs.go
@@ -23,32 +23,6 @@ import (
"github.com/cgrates/cgrates/utils"
)
-// Retrieves the callCost out of CGR logDb
-func (apierSv1 *APIerSv1) GetEventCost(attrs *utils.AttrGetCallCost, reply *engine.EventCost) error {
- if attrs.CgrId == utils.EmptyString {
- return utils.NewErrMandatoryIeMissing("CgrId")
- }
- if attrs.RunId == utils.EmptyString {
- attrs.RunId = utils.MetaDefault
- }
- cdrFltr := &utils.CDRsFilter{
- CGRIDs: []string{attrs.CgrId},
- RunIDs: []string{attrs.RunId},
- }
- if cdrs, _, err := apierSv1.CdrDb.GetCDRs(cdrFltr, false); err != nil {
- if err != utils.ErrNotFound {
- err = utils.NewErrServerError(err)
- }
- return err
- } else if len(cdrs) == 0 ||
- cdrs[0].CostDetails == nil { // to avoid nil pointer dereference
- return utils.ErrNotFound
- } else {
- *reply = *cdrs[0].CostDetails
- }
- return nil
-}
-
// Retrieves CDRs based on the filters
func (apierSv1 *APIerSv1) GetCDRs(attrs *utils.AttrGetCdrs, reply *[]*engine.ExternalCDR) error {
cdrsFltr, err := attrs.AsCDRsFilter(apierSv1.Config.GeneralCfg().DefaultTimezone)
@@ -109,11 +83,6 @@ func (cdrSv1 *CDRsV1) RateCDRs(arg *engine.ArgRateCDRs, reply *string) error {
return cdrSv1.CDRs.V1RateCDRs(arg, reply)
}
-// StoreSMCost will store
-func (cdrSv1 *CDRsV1) StoreSessionCost(attr *engine.AttrCDRSStoreSMCost, reply *string) error {
- return cdrSv1.CDRs.V1StoreSessionCost(attr, reply)
-}
-
func (cdrSv1 *CDRsV1) GetCDRsCount(args *utils.RPCCDRsFilterWithAPIOpts, reply *int64) error {
return cdrSv1.CDRs.V1CountCDRs(args, reply)
}
diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go
index 67606424b..cc3d9485a 100755
--- a/apier/v1/dispatcher.go
+++ b/apier/v1/dispatcher.go
@@ -467,12 +467,6 @@ func (dS *DispatcherSessionSv1) ProcessEvent(args *sessions.V1ProcessEventArgs,
return dS.dS.SessionSv1ProcessEvent(args, reply)
}
-// GetCost implements SessionSv1GetCost
-func (dS *DispatcherSessionSv1) GetCost(args *sessions.V1ProcessEventArgs,
- reply *sessions.V1GetCostReply) (err error) {
- return dS.dS.SessionSv1GetCost(args, reply)
-}
-
// TerminateSession implements SessionSv1TerminateSession
func (dS *DispatcherSessionSv1) TerminateSession(args *sessions.V1TerminateSessionArgs,
reply *string) (err error) {
@@ -709,10 +703,6 @@ func (dS *DispatcherSCDRsV1) GetCDRsCount(args *utils.RPCCDRsFilterWithAPIOpts,
return dS.dS.CDRsV1GetCDRsCount(args, reply)
}
-func (dS *DispatcherSCDRsV1) StoreSessionCost(args *engine.AttrCDRSStoreSMCost, reply *string) error {
- return dS.dS.CDRsV1StoreSessionCost(args, reply)
-}
-
func (dS *DispatcherSCDRsV1) RateCDRs(args *engine.ArgRateCDRs, reply *string) error {
return dS.dS.CDRsV1RateCDRs(args, reply)
}
@@ -742,15 +732,6 @@ type DispatcherSServiceManagerV1 struct {
func (dS *DispatcherSServiceManagerV1) Ping(args *utils.CGREvent, reply *string) error {
return dS.dS.ServiceManagerV1Ping(args, reply)
}
-func (dS *DispatcherSServiceManagerV1) StartService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error {
- return dS.dS.ServiceManagerV1StartService(*args, reply)
-}
-func (dS *DispatcherSServiceManagerV1) StopService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error {
- return dS.dS.ServiceManagerV1StopService(*args, reply)
-}
-func (dS *DispatcherSServiceManagerV1) ServiceStatus(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) error {
- return dS.dS.ServiceManagerV1ServiceStatus(*args, reply)
-}
func NewDispatcherConfigSv1(dps *dispatchers.DispatcherService) *DispatcherConfigSv1 {
return &DispatcherConfigSv1{dS: dps}
@@ -952,11 +933,6 @@ func (dS *DispatcherReplicatorSv1) SetResourceProfile(args *engine.ResourceProfi
return dS.dS.ReplicatorSv1SetResourceProfile(args, reply)
}
-// SetActions
-func (dS *DispatcherReplicatorSv1) SetActions(args *engine.SetActionsArgsWithAPIOpts, reply *string) error {
- return dS.dS.ReplicatorSv1SetActions(args, reply)
-}
-
// SetRouteProfile
func (dS *DispatcherReplicatorSv1) SetRouteProfile(args *engine.RouteProfileWithAPIOpts, reply *string) error {
return dS.dS.ReplicatorSv1SetRouteProfile(args, reply)
diff --git a/apier/v1/servicemanager.go b/apier/v1/servicemanager.go
index f238a9505..44c4b2600 100644
--- a/apier/v1/servicemanager.go
+++ b/apier/v1/servicemanager.go
@@ -19,7 +19,6 @@ along with this program. If not, see
package v1
import (
- "github.com/cgrates/cgrates/dispatchers"
"github.com/cgrates/cgrates/servmanager"
"github.com/cgrates/cgrates/utils"
)
@@ -32,18 +31,6 @@ type ServiceManagerV1 struct {
sm *servmanager.ServiceManager // Need to have them capitalize so we can export in V2
}
-func (servManager *ServiceManagerV1) StartService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) (err error) {
- return servManager.sm.V1StartService(args.ArgStartService, reply)
-}
-
-func (servManager *ServiceManagerV1) StopService(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) (err error) {
- return servManager.sm.V1StopService(args.ArgStartService, reply)
-}
-
-func (servManager *ServiceManagerV1) ServiceStatus(args *dispatchers.ArgStartServiceWithAPIOpts, reply *string) (err error) {
- return servManager.sm.V1ServiceStatus(args.ArgStartService, reply)
-}
-
// Ping return pong if the service is active
func (servManager *ServiceManagerV1) Ping(ign *utils.CGREvent, reply *string) error {
*reply = utils.Pong
diff --git a/apier/v1/sessions.go b/apier/v1/sessions.go
index ad91ae189..713396dcb 100644
--- a/apier/v1/sessions.go
+++ b/apier/v1/sessions.go
@@ -87,11 +87,6 @@ func (ssv1 *SessionSv1) ProcessEvent(args *sessions.V1ProcessEventArgs,
return ssv1.sS.BiRPCv1ProcessEvent(nil, args, rply)
}
-func (ssv1 *SessionSv1) GetCost(args *sessions.V1ProcessEventArgs,
- rply *sessions.V1GetCostReply) error {
- return ssv1.sS.BiRPCv1GetCost(nil, args, rply)
-}
-
func (ssv1 *SessionSv1) GetActiveSessions(args *utils.SessionFilter,
rply *[]*sessions.ExternalSession) error {
return ssv1.sS.BiRPCv1GetActiveSessions(nil, args, rply)
diff --git a/apier/v1/sessionsbirpc.go b/apier/v1/sessionsbirpc.go
index fd86b2c9c..058c1eaff 100644
--- a/apier/v1/sessionsbirpc.go
+++ b/apier/v1/sessionsbirpc.go
@@ -44,7 +44,6 @@ func (ssv1 *SessionSv1) Handlers() map[string]interface{} {
utils.SessionSv1ProcessCDR: ssv1.BiRPCv1ProcessCDR,
utils.SessionSv1ProcessMessage: ssv1.BiRPCv1ProcessMessage,
utils.SessionSv1ProcessEvent: ssv1.BiRPCv1ProcessEvent,
- utils.SessionSv1GetCost: ssv1.BiRPCv1GetCost,
utils.SessionSv1ForceDisconnect: ssv1.BiRPCv1ForceDisconnect,
utils.SessionSv1RegisterInternalBiJSONConn: ssv1.BiRPCv1RegisterInternalBiJSONConn,
@@ -175,17 +174,6 @@ func (ssv1 *SessionSv1) BiRPCv1ProcessEvent(clnt *rpc2.Client, args *sessions.V1
return ssv1.sS.BiRPCv1ProcessEvent(clnt, args, rply)
}
-func (ssv1 *SessionSv1) BiRPCv1GetCost(clnt *rpc2.Client, args *sessions.V1ProcessEventArgs,
- rply *sessions.V1GetCostReply) (err error) {
- if ssv1.caps.IsLimited() {
- if err = ssv1.caps.Allocate(); err != nil {
- return
- }
- defer ssv1.caps.Deallocate()
- }
- return ssv1.sS.BiRPCv1GetCost(clnt, args, rply)
-}
-
func (ssv1 *SessionSv1) BiRPCv1GetActiveSessions(clnt *rpc2.Client, args *utils.SessionFilter,
rply *[]*sessions.ExternalSession) (err error) {
if ssv1.caps.IsLimited() {
diff --git a/apier/v1/tpactions.go b/apier/v1/tpactions.go
deleted file mode 100644
index fcdacc1c9..000000000
--- a/apier/v1/tpactions.go
+++ /dev/null
@@ -1,91 +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"
-)
-
-// SetTPActions creates a new Actions profile within a tariff plan
-func (apierSv1 *APIerSv1) SetTPActions(attrs *utils.TPActions, reply *string) error {
- if missing := utils.MissingStructFields(attrs, []string{utils.TPid, utils.ID, utils.Actions}); len(missing) != 0 {
- return utils.NewErrMandatoryIeMissing(missing...)
- }
- if err := apierSv1.StorDb.SetTPActions([]*utils.TPActions{attrs}); err != nil {
- return utils.NewErrServerError(err)
- }
- *reply = utils.OK
- return nil
-}
-
-type AttrGetTPActions struct {
- TPid string // Tariff plan id
- ID string // Actions id
-}
-
-// GetTPActions queries specific Actions profile on tariff plan
-func (apierSv1 *APIerSv1) GetTPActions(attrs *AttrGetTPActions, reply *utils.TPActions) error {
- if missing := utils.MissingStructFields(attrs, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing
- return utils.NewErrMandatoryIeMissing(missing...)
- }
- as, err := apierSv1.StorDb.GetTPActions(attrs.TPid, attrs.ID)
- if err != nil {
- if err.Error() != utils.ErrNotFound.Error() {
- err = utils.NewErrServerError(err)
- }
- return err
- }
- *reply = *as[0]
- return nil
-}
-
-type AttrGetTPActionIds struct {
- TPid string // Tariff plan id
- utils.PaginatorWithSearch
-}
-
-// GetTPActionIds queries Actions identities on specific tariff plan.
-func (apierSv1 *APIerSv1) GetTPActionIds(attrs *AttrGetTPActionIds, 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.TBLTPActions,
- utils.TPDistinctIds{utils.TagCfg}, nil, &attrs.PaginatorWithSearch)
- if err != nil {
- if err.Error() != utils.ErrNotFound.Error() {
- err = utils.NewErrServerError(err)
- }
- return err
- }
- *reply = ids
- return nil
-}
-
-// RemoveTPActions removes specific Actions on Tariff plan
-func (apierSv1 *APIerSv1) RemoveTPActions(attrs *AttrGetTPActions, reply *string) error {
- if missing := utils.MissingStructFields(attrs, []string{utils.TPid, utils.ID}); len(missing) != 0 { //Params missing
- return utils.NewErrMandatoryIeMissing(missing...)
- }
- if err := apierSv1.StorDb.RemTpData(utils.TBLTPActions,
- attrs.TPid, map[string]string{utils.TagCfg: attrs.ID}); err != nil {
- return utils.NewErrServerError(err)
- }
- *reply = utils.OK
- return nil
-}
diff --git a/apier/v1/tpactions_it_test.go b/apier/v1/tpactions_it_test.go
deleted file mode 100644
index 431ef6139..000000000
--- a/apier/v1/tpactions_it_test.go
+++ /dev/null
@@ -1,311 +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"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpActionCfgPath string
- tpActionCfg *config.CGRConfig
- tpActionRPC *rpc.Client
- tpActions *utils.TPActions
- tpActionDelay int
- tpActionConfigDIR string //run tests for specific configuration
-
-)
-
-var sTestsTPActions = []func(t *testing.T){
- testTPActionsInitCfg,
- testTPActionsResetStorDb,
- testTPActionsStartEngine,
- testTPActionsRpcConn,
- testTPActionsGetTPActionBeforeSet,
- testTPActionsSetTPAction,
- testTPActionsGetTPActionAfterSet,
- testTPActionsGetTPActionIds,
- testTPActionsUpdateTPAction,
- testTPActionsGetTPActionAfterUpdate,
- testTPActionsRemTPAction,
- testTPActionsGetTPActionAfterRemove,
- testTPActionsKillEngine,
-}
-
-//Test start here
-func TestTPActionsIT(t *testing.T) {
- switch *dbType {
- case utils.MetaInternal:
- tpActionConfigDIR = "tutinternal"
- case utils.MetaMySQL:
- tpActionConfigDIR = "tutmysql"
- case utils.MetaMongo:
- tpActionConfigDIR = "tutmongo"
- case utils.MetaPostgres:
- tpActionConfigDIR = "tutpostgres"
- default:
- t.Fatal("Unknown Database type")
- }
- for _, stest := range sTestsTPActions {
- t.Run(tpActionConfigDIR, stest)
- }
-}
-
-func testTPActionsInitCfg(t *testing.T) {
- var err error
- tpActionCfgPath = path.Join(*dataDir, "conf", "samples", tpActionConfigDIR)
- tpActionCfg, err = config.NewCGRConfigFromPath(tpActionCfgPath)
- if err != nil {
- t.Error(err)
- }
- switch tpActionConfigDIR {
- case "tutmongo": // Mongo needs more time to reset db, need to investigate
- tpActionDelay = 2000
- default:
- tpActionDelay = 1000
- }
-}
-
-// Wipe out the cdr database
-func testTPActionsResetStorDb(t *testing.T) {
- if err := engine.InitStorDb(tpActionCfg); err != nil {
- t.Fatal(err)
- }
-}
-
-// Start CGR Engine
-func testTPActionsStartEngine(t *testing.T) {
- if _, err := engine.StopStartEngine(tpActionCfgPath, tpActionDelay); err != nil {
- t.Fatal(err)
- }
-}
-
-// Connect rpc client to rater
-func testTPActionsRpcConn(t *testing.T) {
- var err error
- tpActionRPC, err = jsonrpc.Dial(utils.TCP, tpActionCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func testTPActionsGetTPActionBeforeSet(t *testing.T) {
- var reply *utils.TPActionPlan
- if err := tpActionRPC.Call(utils.APIerSv1GetTPActions,
- &AttrGetTPActions{TPid: "TPAcc", ID: "ID"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Error(err)
- }
-}
-
-func testTPActionsSetTPAction(t *testing.T) {
- tpActions = &utils.TPActions{
- TPid: "TPAcc",
- ID: "ID",
- Actions: []*utils.TPAction{
- &utils.TPAction{
- Identifier: "*topup_reset",
- BalanceId: "BalID",
- BalanceUuid: "BalUuid",
- BalanceType: "*data",
- Units: "10",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "DST_1002",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "10",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 10,
- },
- &utils.TPAction{
- Identifier: "*log",
- BalanceId: "BalID",
- BalanceUuid: "BalUuid",
- BalanceType: "*monetary",
- Units: "120",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "*any",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "11",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 11,
- },
- },
- }
- var result string
- if err := tpActionRPC.Call(utils.APIerSv1SetTPActions, tpActions, &result); err != nil {
- t.Error(err)
- } else if result != utils.OK {
- t.Error("Unexpected reply returned", result)
- }
-}
-
-func testTPActionsGetTPActionAfterSet(t *testing.T) {
- var reply *utils.TPActions
- if err := tpActionRPC.Call(utils.APIerSv1GetTPActions,
- &AttrGetTPActions{TPid: "TPAcc", ID: "ID"}, &reply); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(tpActions.TPid, reply.TPid) {
- t.Errorf("Expecting : %+v, received: %+v", tpActions.TPid, reply.TPid)
- } else if !reflect.DeepEqual(tpActions.ID, reply.ID) {
- t.Errorf("Expecting : %+v, received: %+v", tpActions.ID, reply.ID)
- } else if !reflect.DeepEqual(len(tpActions.Actions), len(reply.Actions)) {
- t.Errorf("Expecting : %+v, received: %+v", len(tpActions.Actions), len(reply.Actions))
- }
-}
-
-func testTPActionsGetTPActionIds(t *testing.T) {
- var result []string
- expectedTPID := []string{"ID"}
- if err := tpActionRPC.Call(utils.APIerSv1GetTPActionIds,
- &AttrGetTPActionIds{TPid: "TPAcc"}, &result); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expectedTPID, result) {
- t.Errorf("Expecting: %+v, received: %+v", expectedTPID, result)
- }
-}
-
-func testTPActionsUpdateTPAction(t *testing.T) {
- tpActions.Actions = []*utils.TPAction{
- &utils.TPAction{
- Identifier: "*topup_reset",
- BalanceId: "BalID",
- BalanceUuid: "BalUuid",
- BalanceType: "*data",
- Units: "10",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "DST_1002",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "10",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 10,
- },
- &utils.TPAction{
- Identifier: "*log",
- BalanceId: "BalID",
- BalanceUuid: "BalUuid",
- BalanceType: "*monetary",
- Units: "120",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "*any",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "11",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 11,
- },
- &utils.TPAction{
- Identifier: "*topup",
- BalanceId: "BalID",
- BalanceUuid: "BalUuid",
- BalanceType: "*voice",
- Units: "102400",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "*any",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "20",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 11,
- },
- }
- var result string
- if err := tpActionRPC.Call(utils.APIerSv1SetTPActions, tpActions, &result); err != nil {
- t.Error(err)
- } else if result != utils.OK {
- t.Error("Unexpected reply returned", result)
- }
-
-}
-
-func testTPActionsGetTPActionAfterUpdate(t *testing.T) {
- var reply *utils.TPActions
- if err := tpActionRPC.Call(utils.APIerSv1GetTPActions,
- &AttrGetTPActions{TPid: "TPAcc", ID: "ID"}, &reply); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(tpActions.TPid, reply.TPid) {
- t.Errorf("Expecting : %+v, received: %+v", tpActions.TPid, reply.TPid)
- } else if !reflect.DeepEqual(tpActions.ID, reply.ID) {
- t.Errorf("Expecting : %+v, received: %+v", tpActions.ID, reply.ID)
- } else if !reflect.DeepEqual(len(tpActions.Actions), len(reply.Actions)) {
- t.Errorf("Expecting : %+v, received: %+v", len(tpActions.Actions), len(reply.Actions))
- }
-
-}
-
-func testTPActionsRemTPAction(t *testing.T) {
- var resp string
- if err := tpActionRPC.Call(utils.APIerSv1RemoveTPActions,
- &AttrGetTPActions{TPid: "TPAcc", ID: "ID"}, &resp); err != nil {
- t.Error(err)
- } else if resp != utils.OK {
- t.Error("Unexpected reply returned", resp)
- }
-
-}
-
-func testTPActionsGetTPActionAfterRemove(t *testing.T) {
- var reply *utils.TPActionPlan
- if err := tpActionRPC.Call(utils.APIerSv1GetTPActions,
- &AttrGetTPActions{TPid: "TPAcc", ID: "ID"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Error(err)
- }
-}
-
-func testTPActionsKillEngine(t *testing.T) {
- if err := engine.KillEngine(tpActionDelay); err != nil {
- t.Error(err)
- }
-}
diff --git a/apier/v2/apier.go b/apier/v2/apier.go
index 281dd022b..f42b65dc1 100644
--- a/apier/v2/apier.go
+++ b/apier/v2/apier.go
@@ -102,22 +102,6 @@ func (apiv2 *APIerSv2) LoadTariffPlanFromFolder(attrs *utils.AttrLoadTpFromFolde
return nil
}
-type AttrGetActionsCount struct{}
-
-// GetActionsCount sets in reply var the total number of actions registered for the received tenant
-// returns ErrNotFound in case of 0 actions
-func (apiv2 *APIerSv2) GetActionsCount(attr *AttrGetActionsCount, reply *int) (err error) {
- var actionKeys []string
- if actionKeys, err = apiv2.DataManager.DataDB().GetKeysForPrefix(utils.ActionPrefix); err != nil {
- return err
- }
- *reply = len(actionKeys)
- if len(actionKeys) == 0 {
- return utils.ErrNotFound
- }
- return nil
-}
-
type AttrGetDestinations struct {
DestinationIDs []string
}
diff --git a/apier/v2/cdrs.go b/apier/v2/cdrs.go
index 7558b9430..a5f53f25a 100644
--- a/apier/v2/cdrs.go
+++ b/apier/v2/cdrs.go
@@ -68,10 +68,6 @@ type CDRsV2 struct {
v1.CDRsV1
}
-func (cdrSv2 *CDRsV2) StoreSessionCost(args *engine.ArgsV2CDRSStoreSMCost, reply *string) error {
- return cdrSv2.CDRs.V2StoreSessionCost(args, reply)
-}
-
// ProcessEvent will process an Event based on the flags attached
func (cdrSv2 *CDRsV2) ProcessEvent(arg *engine.ArgV1ProcessEvent, evs *[]*utils.EventWithFlags) error {
return cdrSv2.CDRs.V2ProcessEvent(arg, evs)
diff --git a/apier/v2/dispatcher.go b/apier/v2/dispatcher.go
index 705af186d..0b28cbaa7 100644
--- a/apier/v2/dispatcher.go
+++ b/apier/v2/dispatcher.go
@@ -33,10 +33,6 @@ type DispatcherSCDRsV2 struct {
dS *dispatchers.DispatcherService
}
-func (dS *DispatcherSCDRsV2) StoreSessionCost(args *engine.ArgsV2CDRSStoreSMCost, reply *string) error {
- return dS.dS.CDRsV2StoreSessionCost(args, reply)
-}
-
func (dS *DispatcherSCDRsV2) ProcessEvent(args *engine.ArgV1ProcessEvent, reply *[]*utils.EventWithFlags) error {
return dS.dS.CDRsV2ProcessEvent(args, reply)
}
diff --git a/build.sh b/build.sh
index 5ec824b60..4659951e2 100755
--- a/build.sh
+++ b/build.sh
@@ -18,7 +18,5 @@ go install -ldflags "-X 'github.com/cgrates/cgrates/utils.GitLastLog=$GIT_LAST_L
cc=$?
go install -ldflags "-X 'github.com/cgrates/cgrates/utils.GitLastLog=$GIT_LAST_LOG'" github.com/cgrates/cgrates/cmd/cgr-migrator
cm=$?
-go install -ldflags "-X 'github.com/cgrates/cgrates/utils.GitLastLog=$GIT_LAST_LOG'" github.com/cgrates/cgrates/cmd/cgr-tester
-ct=$?
-exit $cr || $cl || $cc || $cm || $ct
+exit $cr || $cl || $cc || $cm
diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go
index e56373050..87a4a1ad3 100644
--- a/cmd/cgr-engine/cgr-engine.go
+++ b/cmd/cgr-engine/cgr-engine.go
@@ -491,7 +491,6 @@ func main() {
internalStatSChan := make(chan rpcclient.ClientConnector, 1)
internalResourceSChan := make(chan rpcclient.ClientConnector, 1)
internalRouteSChan := make(chan rpcclient.ClientConnector, 1)
- internalSchedulerSChan := make(chan rpcclient.ClientConnector, 1)
internalRALsChan := make(chan rpcclient.ClientConnector, 1)
internalResponderChan := make(chan rpcclient.ClientConnector, 1)
internalAPIerSv1Chan := make(chan rpcclient.ClientConnector, 1)
@@ -515,7 +514,6 @@ func main() {
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaLoaders): internalLoaderSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources): internalResourceSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder): internalResponderChan,
- utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler): internalSchedulerSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS): internalSessionSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats): internalStatSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes): internalRouteSChan,
@@ -523,10 +521,8 @@ func main() {
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaServiceManager): internalServeManagerChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaConfig): internalConfigChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCore): internalCoreSv1Chan,
- utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRALs): internalRALsChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs): internalEEsChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRateS): internalRateSChan,
- utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions): internalActionSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaDispatchers): internalDispatcherSChan,
utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts): internalAccountSChan,
diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go
index a297f7ba4..789005c2b 100755
--- a/cmd/cgr-loader/cgr-loader.go
+++ b/cmd/cgr-loader/cgr-loader.go
@@ -109,7 +109,7 @@ var (
toStorDB = cgrLoaderFlags.Bool(utils.ToStorDBcgr, false, "Import the tariff plan from files to storDb")
cacheSAddress = cgrLoaderFlags.String(utils.CacheSAddress, dfltCfg.LoaderCgrCfg().CachesConns[0],
"CacheS component to contact for cache reloads, empty to disable automatic cache reloads")
- schedulerAddress = cgrLoaderFlags.String(utils.SchedulerAddress, dfltCfg.LoaderCgrCfg().SchedulerConns[0], "")
+ schedulerAddress = cgrLoaderFlags.String(utils.SchedulerAddress, dfltCfg.LoaderCgrCfg().ActionSConns[0], "")
rpcEncoding = cgrLoaderFlags.String(utils.RpcEncodingCgr, rpcclient.JSONrpc, "RPC encoding used <*gob|*json>")
)
@@ -237,11 +237,11 @@ func loadConfig() (ldrCfg *config.CGRConfig) {
}
}
- if *schedulerAddress != dfltCfg.LoaderCgrCfg().SchedulerConns[0] {
+ if *schedulerAddress != dfltCfg.LoaderCgrCfg().ActionSConns[0] {
if *schedulerAddress == utils.EmptyString {
- ldrCfg.LoaderCgrCfg().SchedulerConns = []string{}
+ ldrCfg.LoaderCgrCfg().ActionSConns = []string{}
} else {
- ldrCfg.LoaderCgrCfg().SchedulerConns = []string{*schedulerAddress}
+ ldrCfg.LoaderCgrCfg().ActionSConns = []string{*schedulerAddress}
if _, has := ldrCfg.RPCConns()[*schedulerAddress]; !has {
ldrCfg.RPCConns()[*schedulerAddress] = &config.RPCConn{
Strategy: rpcclient.PoolFirst,
@@ -363,7 +363,7 @@ func main() {
if tpReader, err = engine.NewTpReader(dataDB, loader,
ldrCfg.LoaderCgrCfg().TpID, ldrCfg.GeneralCfg().DefaultTimezone,
ldrCfg.LoaderCgrCfg().CachesConns,
- ldrCfg.LoaderCgrCfg().SchedulerConns, false); err != nil {
+ ldrCfg.LoaderCgrCfg().ActionSConns, false); err != nil {
log.Fatal(err)
}
if err = tpReader.LoadAll(); err != nil {
@@ -393,7 +393,7 @@ func main() {
log.Fatal("Could not reload cache: ", err)
}
- if len(ldrCfg.LoaderCgrCfg().SchedulerConns) != 0 {
+ if len(ldrCfg.LoaderCgrCfg().ActionSConns) != 0 {
if err = tpReader.ReloadScheduler(*verbose); err != nil {
log.Fatal("Could not reload scheduler: ", err)
}
diff --git a/cmd/cgr-loader/cgr-loader_it_test.go b/cmd/cgr-loader/cgr-loader_it_test.go
index 75479cb26..300bbf5cf 100644
--- a/cmd/cgr-loader/cgr-loader_it_test.go
+++ b/cmd/cgr-loader/cgr-loader_it_test.go
@@ -143,8 +143,8 @@ func TestLoadConfig(t *testing.T) {
if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().CachesConns, []string{}) {
t.Errorf("Expected %v received %v", []string{}, ldrCfg.LoaderCgrCfg().CachesConns)
}
- if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().SchedulerConns, []string{}) {
- t.Errorf("Expected %v received %v", []string{}, ldrCfg.LoaderCgrCfg().SchedulerConns)
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().ActionSConns, []string{}) {
+ t.Errorf("Expected %v received %v", []string{}, ldrCfg.LoaderCgrCfg().ActionSConns)
}
*cacheSAddress = "127.0.0.1"
*schedulerAddress = "127.0.0.2"
@@ -155,8 +155,8 @@ func TestLoadConfig(t *testing.T) {
t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().CachesConns)
}
expAddrs = []string{"127.0.0.2"}
- if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().SchedulerConns, expAddrs) {
- t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().SchedulerConns)
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().ActionSConns, expAddrs) {
+ t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().ActionSConns)
}
expaddr := config.RPCConns{
utils.MetaBiJSONLocalHost: {
diff --git a/cmd/cgr-tester/cdr_repl/post_server.py b/cmd/cgr-tester/cdr_repl/post_server.py
deleted file mode 100644
index 738edd875..000000000
--- a/cmd/cgr-tester/cdr_repl/post_server.py
+++ /dev/null
@@ -1,46 +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
-*/
-"""
-from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
-import SocketServer
-
-class S(BaseHTTPRequestHandler):
- def _set_headers(self):
- self.send_response(200)
- self.send_header('Content-type', 'text/html')
- self.end_headers()
-
- def do_POST(self):
- # Doesn't do anything with posted data
- self._set_headers()
- print(self)
- #self.wfile.write("
POST!
")
-
-def run(server_class=HTTPServer, handler_class=S, port=80):
- server_address = ('', port)
- httpd = server_class(server_address, handler_class)
- print('Starting httpd...')
- httpd.serve_forever()
-
-if __name__ == "__main__":
- from sys import argv
-
- if len(argv) == 2:
- run(port=int(argv[1]))
- else:
- run(port=12080)
diff --git a/cmd/cgr-tester/cdr_repl/process_cdr.go b/cmd/cgr-tester/cdr_repl/process_cdr.go
deleted file mode 100644
index 735064d5f..000000000
--- a/cmd/cgr-tester/cdr_repl/process_cdr.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 main
-
-import (
- "flag"
- "fmt"
- "log"
- "path"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
- "github.com/cgrates/rpcclient"
-)
-
-var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
-
-func main() {
- flag.Parse()
- var err error
- var cdrsMasterRpc *rpcclient.RPCClient
- var cdrsMasterCfgPath string
- var cdrsMasterCfg *config.CGRConfig
- cdrsMasterCfgPath = path.Join(*dataDir, "conf", "samples", "cdrsreplicationmaster")
- if cdrsMasterCfg, err = config.NewCGRConfigFromPath(cdrsMasterCfgPath); err != nil {
- log.Fatal("Got config error: ", err.Error())
- }
- cdrsMasterRpc, err = rpcclient.NewRPCClient(utils.TCP, cdrsMasterCfg.ListenCfg().RPCJSONListen, false, "", "", "", 1, 1,
- time.Second, 2*time.Second, rpcclient.JSONrpc, nil, false, nil)
- if err != nil {
- log.Fatal("Could not connect to rater: ", err.Error())
- }
- cdrs := make([]*engine.CDR, 0)
- for i := 0; i < 10000; i++ {
- cdr := &engine.CDR{OriginID: fmt.Sprintf("httpjsonrpc_%d", i),
- ToR: utils.MetaVoice, OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.MetaPseudoPrepaid,
- Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
- SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
- Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}
- cdrs = append(cdrs, cdr)
- }
- var reply string
- for _, cdr := range cdrs {
- if err := cdrsMasterRpc.Call(utils.CDRsV1ProcessCDR, cdr, &reply); err != nil {
- log.Fatal("Unexpected error: ", err.Error())
- } else if reply != utils.OK {
- log.Fatal("Unexpected reply received: ", reply)
- }
- }
-}
diff --git a/cmd/cgr-tester/cgr-tester.go b/cmd/cgr-tester/cgr-tester.go
deleted file mode 100644
index f4014b828..000000000
--- a/cmd/cgr-tester/cgr-tester.go
+++ /dev/null
@@ -1,269 +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 main
-
-import (
- "flag"
- "fmt"
- "log"
- "math"
- "net/rpc"
- "net/rpc/jsonrpc"
- "os"
- "runtime"
- "runtime/pprof"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- cgrTesterFlags = flag.NewFlagSet("cgr-tester", flag.ContinueOnError)
- cgrConfig = config.NewDefaultCGRConfig()
- tstCfg = config.CgrConfig()
- cpuprofile = cgrTesterFlags.String("cpuprofile", "", "write cpu profile to file")
- memprofile = cgrTesterFlags.String("memprofile", "", "write memory profile to this file")
- runs = cgrTesterFlags.Int("runs", int(math.Pow10(5)), "stress cycle number")
-
- cfgPath = cgrTesterFlags.String("config_path", "",
- "Configuration directory path.")
-
- parallel = cgrTesterFlags.Int("parallel", 0, "run n requests in parallel")
- datadbType = cgrTesterFlags.String("datadb_type", cgrConfig.DataDbCfg().Type, "The type of the DataDb database ")
- datadbHost = cgrTesterFlags.String("datadb_host", cgrConfig.DataDbCfg().Host, "The DataDb host to connect to.")
- datadbPort = cgrTesterFlags.String("datadb_port", cgrConfig.DataDbCfg().Port, "The DataDb port to bind to.")
- datadbName = cgrTesterFlags.String("datadb_name", cgrConfig.DataDbCfg().Name, "The name/number of the DataDb to connect to.")
- datadbUser = cgrTesterFlags.String("datadb_user", cgrConfig.DataDbCfg().User, "The DataDb user to sign in as.")
- datadbPass = cgrTesterFlags.String("datadb_pass", cgrConfig.DataDbCfg().Password, "The DataDb user's password.")
- dbdataEncoding = cgrTesterFlags.String("dbdata_encoding", cgrConfig.GeneralCfg().DBDataEncoding, "The encoding used to store object data in strings.")
- redisSentinel = cgrTesterFlags.String("redis_sentinel", utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisSentinelNameCfg]), "The name of redis sentinel")
- dbRedisCluster = cgrTesterFlags.Bool("redis_cluster", false,
- "Is the redis datadb a cluster")
- dbRedisClusterSync = cgrTesterFlags.String("redis_cluster_sync", utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisClusterSyncCfg]),
- "The sync interval for the redis cluster")
- dbRedisClusterDownDelay = cgrTesterFlags.String("redis_cluster_ondown_delay", utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisClusterOnDownDelayCfg]),
- "The delay before executing the commands if the redis cluster is in the CLUSTERDOWN state")
- dbQueryTimeout = cgrTesterFlags.String("query_timeout", utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.QueryTimeoutCfg]),
- "The timeout for queries")
- raterAddress = cgrTesterFlags.String("rater_address", "", "Rater address for remote tests. Empty for internal rater.")
- tor = cgrTesterFlags.String("tor", utils.MetaVoice, "The type of record to use in queries.")
- category = cgrTesterFlags.String("category", "call", "The Record category to test.")
- tenant = cgrTesterFlags.String("tenant", "cgrates.org", "The type of record to use in queries.")
- subject = cgrTesterFlags.String("subject", "1001", "The rating subject to use in queries.")
- destination = cgrTesterFlags.String("destination", "1002", "The destination to use in queries.")
- json = cgrTesterFlags.Bool("json", false, "Use JSON RPC")
- version = cgrTesterFlags.Bool("version", false, "Prints the application version.")
- nilDuration = time.Duration(0)
- usage = cgrTesterFlags.String("usage", "1m", "The duration to use in call simulation.")
- fPath = cgrTesterFlags.String("file_path", "", "read requests from file with path")
- reqSep = cgrTesterFlags.String("req_separator", "\n\n", "separator for requests in file")
-
- err error
-)
-
-func durInternalRater(cd *engine.CallDescriptorWithAPIOpts) (time.Duration, error) {
- dbConn, err := engine.NewDataDBConn(tstCfg.DataDbCfg().Type,
- tstCfg.DataDbCfg().Host, tstCfg.DataDbCfg().Port,
- tstCfg.DataDbCfg().Name, tstCfg.DataDbCfg().User,
- tstCfg.DataDbCfg().Password, tstCfg.GeneralCfg().DBDataEncoding,
- tstCfg.DataDbCfg().Opts)
- if err != nil {
- return nilDuration, fmt.Errorf("Could not connect to data database: %s", err.Error())
- }
- dm := engine.NewDataManager(dbConn, cgrConfig.CacheCfg(), nil) // for the momentn we use here "" for sentinelName
- defer dm.DataDB().Close()
- engine.SetDataStorage(dm)
- if err := dm.LoadDataDBCache(engine.GetDefaultEmptyArgCachePrefix()); err != nil {
- return nilDuration, fmt.Errorf("Cache rating error: %s", err.Error())
- }
- log.Printf("Runnning %d cycles...", *runs)
- var result *engine.CallCost
- start := time.Now()
- for i := 0; i < *runs; i++ {
- result, err = cd.GetCost()
- if *memprofile != "" {
- runtime.MemProfileRate = 1
- runtime.GC()
- f, err := os.Create(*memprofile)
- if err != nil {
- log.Fatal(err)
- }
- pprof.WriteHeapProfile(f)
- f.Close()
- break
- }
- }
- log.Printf("Result:%s\n", utils.ToJSON(result))
-
- memstats := new(runtime.MemStats)
- runtime.ReadMemStats(memstats)
- log.Printf("memstats before GC: Kbytes = %d footprint = %d",
- memstats.HeapAlloc/1024, memstats.Sys/1024)
- return time.Since(start), nil
-}
-
-func durRemoteRater(cd *engine.CallDescriptorWithAPIOpts) (time.Duration, error) {
- result := engine.CallCost{}
- var client *rpc.Client
- var err error
- if *json {
- client, err = jsonrpc.Dial(utils.TCP, *raterAddress)
- } else {
- client, err = rpc.Dial(utils.TCP, *raterAddress)
- }
-
- if err != nil {
- return nilDuration, fmt.Errorf("Could not connect to engine: %s", err.Error())
- }
- defer client.Close()
- start := time.Now()
- if *parallel > 0 {
- // var divCall *rpc.Call
- var sem = make(chan int, *parallel)
- var finish = make(chan int)
- for i := 0; i < *runs; i++ {
- go func() {
- sem <- 1
- client.Call(utils.ResponderGetCost, cd, &result)
- <-sem
- finish <- 1
- // divCall = client.Go(utils.ResponderGetCost, cd, &result, nil)
- }()
- }
- for i := 0; i < *runs; i++ {
- <-finish
- }
- // <-divCall.Done
- } else {
- for j := 0; j < *runs; j++ {
- client.Call(utils.ResponderGetCost, cd, &result)
- }
- }
- log.Printf("Result:%s\n", utils.ToJSON(result))
- return time.Since(start), nil
-}
-
-func main() {
- if err := cgrTesterFlags.Parse(os.Args[1:]); err != nil {
- return
- }
- if *version {
- if rcv, err := utils.GetCGRVersion(); err != nil {
- fmt.Println(err)
- } else {
- fmt.Println(rcv)
- }
- return
- }
-
- if *cfgPath != "" {
- if tstCfg, err = config.NewCGRConfigFromPath(*cfgPath); err != nil {
- log.Fatalf("error loading config file %s", err.Error())
- }
- }
-
- if *datadbType != cgrConfig.DataDbCfg().Type {
- tstCfg.DataDbCfg().Type = *datadbType
- }
- if *datadbHost != cgrConfig.DataDbCfg().Host {
- tstCfg.DataDbCfg().Host = *datadbHost
- }
- if *datadbPort != cgrConfig.DataDbCfg().Port {
- tstCfg.DataDbCfg().Port = *datadbPort
- }
- if *datadbName != cgrConfig.DataDbCfg().Name {
- tstCfg.DataDbCfg().Name = *datadbName
- }
- if *datadbUser != cgrConfig.DataDbCfg().User {
- tstCfg.DataDbCfg().User = *datadbUser
- }
- if *datadbPass != cgrConfig.DataDbCfg().Password {
- tstCfg.DataDbCfg().Password = *datadbPass
- }
- if *dbdataEncoding != "" {
- tstCfg.GeneralCfg().DBDataEncoding = *dbdataEncoding
- }
- if *redisSentinel != utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisSentinelNameCfg]) {
- tstCfg.DataDbCfg().Opts[utils.RedisSentinelNameCfg] = *redisSentinel
- }
- rdsCls, _ := utils.IfaceAsBool(cgrConfig.DataDbCfg().Opts[utils.RedisClusterCfg])
- if *dbRedisCluster != rdsCls {
- tstCfg.DataDbCfg().Opts[utils.RedisClusterCfg] = *dbRedisCluster
- }
- if *dbRedisClusterSync != utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisClusterSyncCfg]) {
- tstCfg.DataDbCfg().Opts[utils.RedisClusterSyncCfg] = *dbRedisClusterSync
- }
- if *dbRedisClusterDownDelay != utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.RedisClusterOnDownDelayCfg]) {
- tstCfg.DataDbCfg().Opts[utils.RedisClusterOnDownDelayCfg] = *dbRedisClusterDownDelay
- }
- if *dbQueryTimeout != utils.IfaceAsString(cgrConfig.DataDbCfg().Opts[utils.QueryTimeoutCfg]) {
- tstCfg.DataDbCfg().Opts[utils.QueryTimeoutCfg] = *dbQueryTimeout
- }
-
- if *cpuprofile != "" {
- f, err := os.Create(*cpuprofile)
- if err != nil {
- log.Fatal(err)
- }
- pprof.StartCPUProfile(f)
- defer pprof.StopCPUProfile()
- }
- if *fPath != "" {
- frt, err := NewFileReaderTester(*fPath, *raterAddress,
- *parallel, *runs, []byte(*reqSep))
- if err != nil {
- log.Fatal(err)
- }
- if err := frt.Test(); err != nil {
- log.Fatal(err)
- }
- return
- }
-
- var timeparsed time.Duration
- var err error
- tstart := time.Now()
- timeparsed, err = utils.ParseDurationWithNanosecs(*usage)
- tend := tstart.Add(timeparsed)
- cd := &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: &engine.CallDescriptor{
- TimeStart: tstart,
- TimeEnd: tend,
- DurationIndex: 60 * time.Second,
- ToR: *tor,
- Category: *category,
- Tenant: *tenant,
- Subject: *subject,
- Destination: *destination,
- },
- }
- var duration time.Duration
- if len(*raterAddress) == 0 {
- duration, err = durInternalRater(cd)
- } else {
- duration, err = durRemoteRater(cd)
- }
- if err != nil {
- log.Fatal(err.Error())
- } else {
- log.Printf("Elapsed: %s resulted: %f req/s.", duration, float64(*runs)/duration.Seconds())
- }
-}
diff --git a/cmd/cgr-tester/combined_max_usage/combined_max_usage.go b/cmd/cgr-tester/combined_max_usage/combined_max_usage.go
deleted file mode 100644
index 24758cf1f..000000000
--- a/cmd/cgr-tester/combined_max_usage/combined_max_usage.go
+++ /dev/null
@@ -1,148 +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 main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/rpc"
- "net/rpc/jsonrpc"
- "path"
- "sync"
- "time"
-
- "github.com/cgrates/cgrates/engine"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
- requests = flag.Int("requests", 10000, "Number of requests")
- gorutines = flag.Int("goroutines", 5, "Number of simultaneous goroutines")
-)
-
-// How to run:
-// 1) Start the engine with the following configuration < cgr-engine -config_path=/usr/share/cgrates/conf/samples/accounts_mysql >
-// 2) Load the data with < cgr-loader -config_path=/usr/share/cgrates/conf/samples/accounts_mysql -verbose -path=/usr/share/cgrates/tariffplans/oldaccvsnew >
-// 3) Run the program with < go run combined_max_usage.go -requests=10000 -goroutines=5 >
-// Additional Information
-// In this scenario we compare the old account system vs the new one. The balance contains the RateID in order to access it directly without the needed of matching.
-// For this scenario the account 1002 is used
-
-func main() {
- flag.Parse()
- var err error
- var rpc *rpc.Client
- var cfgPath string
- var cfg *config.CGRConfig
- cfgPath = path.Join(*dataDir, "conf", "samples", "accounts_mysql")
- if cfg, err = config.NewCGRConfigFromPath(cfgPath); err != nil {
- log.Fatal("Got config error: ", err.Error())
- }
- if rpc, err = jsonrpc.Dial(utils.TCP, cfg.ListenCfg().RPCJSONListen); err != nil {
- return
- }
-
- s1 := rand.NewSource(time.Now().UnixNano())
- r1 := rand.New(s1)
-
- var wgAccountS sync.WaitGroup
- var accountSTime time.Duration
- var sumAccountS float64
-
- var wgRALs sync.WaitGroup
- var ralsTime time.Duration
- var sumRALs float64
-
- for i := 0; i < *requests; i++ {
- wgAccountS.Add(1)
- wgRALs.Add(1)
- usage := fmt.Sprintf("%+vm", 1+r1.Intn(59))
- go func() {
- var eEc *utils.ExtEventCharges
- arg := &utils.ArgsAccountsForEvent{CGREvent: &utils.CGREvent{
- Tenant: "cgrates.org",
- ID: utils.UUIDSha1Prefix(),
- Event: map[string]interface{}{
- utils.AccountField: "1002",
- utils.ToR: utils.MetaVoice,
- utils.Usage: usage,
- }}}
- tNow := time.Now()
- if err := rpc.Call(utils.AccountSv1MaxAbstracts,
- arg, &eEc); err != nil {
- return
- }
- accountSTime += time.Now().Sub(tNow)
- sumAccountS += *eEc.Abstracts
- wgAccountS.Done()
- }()
-
- go func() {
- tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
- usageDur, _ := utils.ParseDurationWithNanosecs(usage)
- cd := &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: &engine.CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "1002",
- Account: "1002",
- Destination: "1003",
- TimeStart: tStart,
- TimeEnd: tStart.Add(usageDur),
- },
- }
- var rply time.Duration
- tNow := time.Now()
- if err := rpc.Call(utils.ResponderGetMaxSessionTime, cd, &rply); err != nil {
- return
- }
- ralsTime += time.Now().Sub(tNow)
- sumRALs += rply.Seconds()
- wgRALs.Done()
- }()
-
- if i%*gorutines == 0 {
- wgAccountS.Wait()
- wgRALs.Wait()
- }
-
- }
- wgAccountS.Wait()
- wgRALs.Wait()
-
- fmt.Println("Sum AccountS MaxUsage")
- fmt.Println(sumAccountS)
- fmt.Println("Average AccountS MaxUsage")
- fmt.Println(accountSTime / time.Duration(*requests))
- fmt.Println("Total AccountS MaxUsage Time")
- fmt.Println(accountSTime)
-
- fmt.Println("Sum RALs GetMaxSessionTime")
- fmt.Println(sumRALs)
- fmt.Println("Average RALs GetMaxSessionTime")
- fmt.Println(ralsTime / time.Duration(*requests))
- fmt.Println("Total RALs GetMaxSessionTime Time")
- fmt.Println(ralsTime)
-
-}
diff --git a/cmd/cgr-tester/combined_max_usage2/combined_max_usage2.go b/cmd/cgr-tester/combined_max_usage2/combined_max_usage2.go
deleted file mode 100644
index 8d349fbcf..000000000
--- a/cmd/cgr-tester/combined_max_usage2/combined_max_usage2.go
+++ /dev/null
@@ -1,148 +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 main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/rpc"
- "net/rpc/jsonrpc"
- "path"
- "sync"
- "time"
-
- "github.com/cgrates/cgrates/engine"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
- requests = flag.Int("requests", 10000, "Number of requests")
- gorutines = flag.Int("goroutines", 5, "Number of simultaneous goroutines")
-)
-
-// How to run:
-// 1) Start the engine with the following configuration < cgr-engine -config_path=/usr/share/cgrates/conf/samples/accounts_mysql >
-// 2) Load the data with < cgr-loader -config_path=/usr/share/cgrates/conf/samples/accounts_mysql -verbose -path=/usr/share/cgrates/tariffplans/oldaccvsnew >
-// 3) Run the program with < go run combined_max_usage2.go -requests=10000 -goroutines=5 >
-// Additional Information
-// In this scenario we compare the old account system vs the new one. The balance doesn't contains the RateID and will let RateS to discover the rate profile that match the event.
-// For this scenario the account 1003 is used
-
-func main() {
- flag.Parse()
- var err error
- var rpc *rpc.Client
- var cfgPath string
- var cfg *config.CGRConfig
- cfgPath = path.Join(*dataDir, "conf", "samples", "accounts_mysql")
- if cfg, err = config.NewCGRConfigFromPath(cfgPath); err != nil {
- log.Fatal("Got config error: ", err.Error())
- }
- if rpc, err = jsonrpc.Dial(utils.TCP, cfg.ListenCfg().RPCJSONListen); err != nil {
- return
- }
-
- s1 := rand.NewSource(time.Now().UnixNano())
- r1 := rand.New(s1)
-
- var wgAccountS sync.WaitGroup
- var accountSTime time.Duration
- var sumAccountS float64
-
- var wgRALs sync.WaitGroup
- var ralsTime time.Duration
- var sumRALs float64
-
- for i := 0; i < *requests; i++ {
- wgAccountS.Add(1)
- wgRALs.Add(1)
- usage := fmt.Sprintf("%+vm", 1+r1.Intn(59))
- go func() {
- var eEc *utils.ExtEventCharges
- arg := &utils.ArgsAccountsForEvent{CGREvent: &utils.CGREvent{
- Tenant: "cgrates.org",
- ID: utils.UUIDSha1Prefix(),
- Event: map[string]interface{}{
- utils.AccountField: "1003",
- utils.ToR: utils.MetaVoice,
- utils.Usage: usage,
- }}}
- tNow := time.Now()
- if err := rpc.Call(utils.AccountSv1MaxAbstracts,
- arg, &eEc); err != nil {
- return
- }
- accountSTime += time.Now().Sub(tNow)
- sumAccountS += *eEc.Abstracts
- wgAccountS.Done()
- }()
-
- go func() {
- tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
- usageDur, _ := utils.ParseDurationWithNanosecs(usage)
- cd := &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: &engine.CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "1003",
- Account: "1003",
- Destination: "1004",
- TimeStart: tStart,
- TimeEnd: tStart.Add(usageDur),
- },
- }
- var rply time.Duration
- tNow := time.Now()
- if err := rpc.Call(utils.ResponderGetMaxSessionTime, cd, &rply); err != nil {
- return
- }
- ralsTime += time.Now().Sub(tNow)
- sumRALs += rply.Seconds()
- wgRALs.Done()
- }()
-
- if i%*gorutines == 0 {
- wgAccountS.Wait()
- wgRALs.Wait()
- }
-
- }
- wgAccountS.Wait()
- wgRALs.Wait()
-
- fmt.Println("Sum AccountS MaxUsage")
- fmt.Println(sumAccountS)
- fmt.Println("Average AccountS MaxUsage")
- fmt.Println(accountSTime / time.Duration(*requests))
- fmt.Println("Total AccountS MaxUsage Time")
- fmt.Println(accountSTime)
-
- fmt.Println("Sum RALs GetMaxSessionTime")
- fmt.Println(sumRALs)
- fmt.Println("Average RALs GetMaxSessionTime")
- fmt.Println(ralsTime / time.Duration(*requests))
- fmt.Println("Total RALs GetMaxSessionTime Time")
- fmt.Println(ralsTime)
-
-}
diff --git a/cmd/cgr-tester/filereader.go b/cmd/cgr-tester/filereader.go
deleted file mode 100644
index 36db75718..000000000
--- a/cmd/cgr-tester/filereader.go
+++ /dev/null
@@ -1,105 +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 main
-
-import (
- "bufio"
- "bytes"
- "io"
- "log"
- "math/rand"
- "net"
- "os"
- "sync"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-func NewFileReaderTester(fPath, cgrAddr string, parallel, runs int, reqSep []byte) (frt *FileReaderTester, err error) {
- frt = &FileReaderTester{
- parallel: parallel, runs: runs,
- reqSep: reqSep,
- }
- if frt.rdr, err = os.Open(fPath); err != nil {
- return nil, err
- }
- if frt.conn, err = net.Dial(utils.TCP, cgrAddr); err != nil {
- return nil, err
- }
- return
-}
-
-// TesterReader will read requests from file and post them remotely
-type FileReaderTester struct {
- parallel int
- runs int
- reqSep []byte
-
- rdr io.Reader
- conn net.Conn
- connScnr *bufio.Scanner
-}
-
-func (frt *FileReaderTester) connSendReq(req []byte) (err error) {
- frt.conn.SetReadDeadline(time.Now().Add(time.Millisecond)) // will block most of the times on read
- if _, err = frt.conn.Write(req); err != nil {
- return
- }
- io.ReadAll(frt.conn)
- return
-}
-
-// Test reads from rdr, split the content based on lineSep and sends individual lines to remote
-func (frt *FileReaderTester) Test() (err error) {
- var fContent []byte
- if fContent, err = io.ReadAll(frt.rdr); err != nil {
- return
- }
- reqs := bytes.Split(fContent, frt.reqSep)
-
- // parallel requests
- if frt.parallel > 0 {
- var wg sync.WaitGroup
- reqLimiter := make(chan struct{}, frt.parallel)
- for i := 0; i < frt.runs; i++ {
- wg.Add(1)
- go func(i int) {
- reqLimiter <- struct{}{} // block till buffer will allow
- if err := frt.connSendReq(reqs[rand.Intn(len(reqs))]); err != nil {
- log.Printf("ERROR: %s", err.Error())
- }
- <-reqLimiter // release one request from buffer
- wg.Done()
- }(i)
- }
- wg.Wait()
- return
- }
-
- // serial requests
- for i := 0; i < frt.runs; i++ {
- for _, req := range reqs {
- if err := frt.connSendReq(req); err != nil {
- log.Printf("ERROR: %s", err.Error())
- }
- }
- }
- return
-}
diff --git a/cmd/cgr-tester/simple_max_usage/simple_max_usage.go b/cmd/cgr-tester/simple_max_usage/simple_max_usage.go
deleted file mode 100644
index 3f9ee64d8..000000000
--- a/cmd/cgr-tester/simple_max_usage/simple_max_usage.go
+++ /dev/null
@@ -1,145 +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 main
-
-import (
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net/rpc"
- "net/rpc/jsonrpc"
- "path"
- "sync"
- "time"
-
- "github.com/cgrates/cgrates/engine"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
- requests = flag.Int("requests", 10000, "Number of requests")
- gorutines = flag.Int("goroutines", 5, "Number of simultaneous goroutines")
-)
-
-// How to run:
-// 1) Start the engine with the following configuration < cgr-engine -config_path=/usr/share/cgrates/conf/samples/accounts_mysql >
-// 2) Load the data with < cgr-loader -config_path=/usr/share/cgrates/conf/samples/accounts_mysql -verbose -path=/usr/share/cgrates/tariffplans/oldaccvsnew >
-// 3) Run the program with < go run simple_max_usage.go -requests=10000 -goroutines=5 >
-
-func main() {
- flag.Parse()
- var err error
- var rpc *rpc.Client
- var cfgPath string
- var cfg *config.CGRConfig
- cfgPath = path.Join(*dataDir, "conf", "samples", "accounts_mysql")
- if cfg, err = config.NewCGRConfigFromPath(cfgPath); err != nil {
- log.Fatal("Got config error: ", err.Error())
- }
- if rpc, err = jsonrpc.Dial(utils.TCP, cfg.ListenCfg().RPCJSONListen); err != nil {
- return
- }
-
- s1 := rand.NewSource(time.Now().UnixNano())
- r1 := rand.New(s1)
-
- var wgAccountS sync.WaitGroup
- var accountSTime time.Duration
- var sumAccountS float64
-
- var wgRALs sync.WaitGroup
- var ralsTime time.Duration
- var sumRALs float64
-
- for i := 0; i < *requests; i++ {
- wgAccountS.Add(1)
- wgRALs.Add(1)
- usage := fmt.Sprintf("%+vm", 1+r1.Intn(59))
- go func() {
- var eEc *utils.ExtEventCharges
- arg := &utils.ArgsAccountsForEvent{CGREvent: &utils.CGREvent{
- Tenant: "cgrates.org",
- ID: utils.UUIDSha1Prefix(),
- Event: map[string]interface{}{
- utils.AccountField: "1001",
- utils.ToR: utils.MetaVoice,
- utils.Usage: usage,
- }}}
- tNow := time.Now()
- if err := rpc.Call(utils.AccountSv1MaxAbstracts,
- arg, &eEc); err != nil {
- return
- }
- accountSTime += time.Now().Sub(tNow)
- sumAccountS += *eEc.Abstracts
- wgAccountS.Done()
- }()
-
- go func() {
- tStart := time.Date(2016, 3, 31, 0, 0, 0, 0, time.UTC)
- usageDur, _ := utils.ParseDurationWithNanosecs(usage)
- cd := &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: &engine.CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "1001",
- Account: "1001",
- Destination: "1002",
- TimeStart: tStart,
- TimeEnd: tStart.Add(usageDur),
- },
- }
- var rply time.Duration
- tNow := time.Now()
- if err := rpc.Call(utils.ResponderGetMaxSessionTime, cd, &rply); err != nil {
- return
- }
- ralsTime += time.Now().Sub(tNow)
- sumRALs += rply.Seconds()
- wgRALs.Done()
- }()
-
- if i%*gorutines == 0 {
- wgAccountS.Wait()
- wgRALs.Wait()
- }
-
- }
- wgAccountS.Wait()
- wgRALs.Wait()
-
- fmt.Println("Sum AccountS MaxUsage")
- fmt.Println(sumAccountS)
- fmt.Println("Average AccountS MaxUsage")
- fmt.Println(accountSTime / time.Duration(*requests))
- fmt.Println("Total AccountS MaxUsage Time")
- fmt.Println(accountSTime)
-
- fmt.Println("Sum RALs GetMaxSessionTime")
- fmt.Println(sumRALs)
- fmt.Println("Average RALs GetMaxSessionTime")
- fmt.Println(ralsTime / time.Duration(*requests))
- fmt.Println("Total RALs GetMaxSessionTime Time")
- fmt.Println(ralsTime)
-
-}
diff --git a/config/apiercfg.go b/config/apiercfg.go
index ee4cd91e0..bb4921f2c 100644
--- a/config/apiercfg.go
+++ b/config/apiercfg.go
@@ -48,13 +48,13 @@ func (aCfg *ApierCfg) loadFromJSONCfg(jsnCfg *ApierJsonCfg) (err error) {
}
}
}
- if jsnCfg.Scheduler_conns != nil {
- aCfg.ActionConns = make([]string, len(*jsnCfg.Scheduler_conns))
- for idx, conn := range *jsnCfg.Scheduler_conns {
+ if jsnCfg.Actions_conns != nil {
+ aCfg.ActionConns = make([]string, len(*jsnCfg.Actions_conns))
+ for idx, conn := range *jsnCfg.Actions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
aCfg.ActionConns[idx] = conn
if conn == utils.MetaInternal {
- aCfg.ActionConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
+ aCfg.ActionConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions)
}
}
}
@@ -100,11 +100,11 @@ func (aCfg *ApierCfg) AsMapInterface() (initialMap map[string]interface{}) {
schedulerConns := make([]string, len(aCfg.ActionConns))
for i, item := range aCfg.ActionConns {
schedulerConns[i] = item
- if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions) {
schedulerConns[i] = utils.MetaInternal
}
}
- initialMap[utils.SchedulerConnsCfg] = schedulerConns
+ initialMap[utils.ActionSConnsCfg] = schedulerConns
}
if aCfg.AttributeSConns != nil {
attributeSConns := make([]string, len(aCfg.AttributeSConns))
diff --git a/config/apiercfg_test.go b/config/apiercfg_test.go
index 45c96b24c..a4475a200 100644
--- a/config/apiercfg_test.go
+++ b/config/apiercfg_test.go
@@ -28,7 +28,7 @@ func TestApierCfgloadFromJsonCfg(t *testing.T) {
jsonCfg := &ApierJsonCfg{
Enabled: utils.BoolPointer(false),
Caches_conns: &[]string{utils.MetaInternal, "*conn1"},
- Scheduler_conns: &[]string{utils.MetaInternal, "*conn1"},
+ Actions_conns: &[]string{utils.MetaInternal, "*conn1"},
Attributes_conns: &[]string{utils.MetaInternal, "*conn1"},
Ees_conns: &[]string{utils.MetaInternal, "*conn1"},
}
@@ -57,7 +57,7 @@ func TestApierCfgAsMapInterface1(t *testing.T) {
eMap := map[string]interface{}{
utils.EnabledCfg: false,
utils.CachesConnsCfg: sls,
- utils.SchedulerConnsCfg: sls,
+ utils.ActionSConnsCfg: sls,
utils.AttributeSConnsCfg: sls,
utils.EEsConnsCfg: sls,
}
@@ -81,7 +81,7 @@ func TestApierCfgAsMapInterface2(t *testing.T) {
expectedMap := map[string]interface{}{
utils.EnabledCfg: true,
utils.CachesConnsCfg: []string{utils.MetaInternal, "*conn1"},
- utils.SchedulerConnsCfg: []string{utils.MetaInternal, "*conn1"},
+ utils.ActionSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.AttributeSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.EEsConnsCfg: []string{utils.MetaInternal, "*conn1"},
}
diff --git a/config/cdrscfg.go b/config/cdrscfg.go
index 4cbd0899b..6e08c392d 100644
--- a/config/cdrscfg.go
+++ b/config/cdrscfg.go
@@ -34,7 +34,7 @@ type CdrsCfg struct {
ThresholdSConns []string
StatSConns []string
OnlineCDRExports []string // list of CDRE templates to use for real-time CDR exports
- SchedulerConns []string
+ ActionSConns []string
EEsConns []string
}
@@ -110,13 +110,13 @@ func (cdrscfg *CdrsCfg) loadFromJSONCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
if jsnCdrsCfg.Online_cdr_exports != nil {
cdrscfg.OnlineCDRExports = append(cdrscfg.OnlineCDRExports, *jsnCdrsCfg.Online_cdr_exports...)
}
- if jsnCdrsCfg.Scheduler_conns != nil {
- cdrscfg.SchedulerConns = make([]string, len(*jsnCdrsCfg.Scheduler_conns))
- for idx, connID := range *jsnCdrsCfg.Scheduler_conns {
+ if jsnCdrsCfg.Actions_conns != nil {
+ cdrscfg.ActionSConns = make([]string, len(*jsnCdrsCfg.Actions_conns))
+ for idx, connID := range *jsnCdrsCfg.Actions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
- cdrscfg.SchedulerConns[idx] = connID
+ cdrscfg.ActionSConns[idx] = connID
if connID == utils.MetaInternal {
- cdrscfg.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
+ cdrscfg.ActionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions)
}
}
}
@@ -204,15 +204,15 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
}
initialMP[utils.StatSConnsCfg] = statSConns
}
- if cdrscfg.SchedulerConns != nil {
- schedulerConns := make([]string, len(cdrscfg.SchedulerConns))
- for i, item := range cdrscfg.SchedulerConns {
+ if cdrscfg.ActionSConns != nil {
+ schedulerConns := make([]string, len(cdrscfg.ActionSConns))
+ for i, item := range cdrscfg.ActionSConns {
schedulerConns[i] = item
- if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions) {
schedulerConns[i] = utils.MetaInternal
}
}
- initialMP[utils.SchedulerConnsCfg] = schedulerConns
+ initialMP[utils.ActionSConnsCfg] = schedulerConns
}
if cdrscfg.EEsConns != nil {
eesConns := make([]string, len(cdrscfg.EEsConns))
@@ -271,10 +271,10 @@ func (cdrscfg CdrsCfg) Clone() (cln *CdrsCfg) {
cln.OnlineCDRExports[i] = con
}
}
- if cdrscfg.SchedulerConns != nil {
- cln.SchedulerConns = make([]string, len(cdrscfg.SchedulerConns))
- for i, con := range cdrscfg.SchedulerConns {
- cln.SchedulerConns[i] = con
+ if cdrscfg.ActionSConns != nil {
+ cln.ActionSConns = make([]string, len(cdrscfg.ActionSConns))
+ for i, con := range cdrscfg.ActionSConns {
+ cln.ActionSConns[i] = con
}
}
if cdrscfg.EEsConns != nil {
diff --git a/config/cdrscfg_test.go b/config/cdrscfg_test.go
index 67f5e3c1d..e94484093 100644
--- a/config/cdrscfg_test.go
+++ b/config/cdrscfg_test.go
@@ -35,7 +35,7 @@ func TestCdrsCfgloadFromJsonCfg(t *testing.T) {
Thresholds_conns: &[]string{utils.MetaInternal, "*conn1"},
Stats_conns: &[]string{utils.MetaInternal, "*conn1"},
Online_cdr_exports: &[]string{"randomVal"},
- Scheduler_conns: &[]string{utils.MetaInternal, "*conn1"},
+ Actions_conns: &[]string{utils.MetaInternal, "*conn1"},
Ees_conns: &[]string{utils.MetaInternal, "*conn1"},
}
expected := &CdrsCfg{
@@ -48,7 +48,7 @@ func TestCdrsCfgloadFromJsonCfg(t *testing.T) {
ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"},
OnlineCDRExports: []string{"randomVal"},
- SchedulerConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
+ ActionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
EEsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs), "*conn1"},
ExtraFields: RSRParsers{},
}
@@ -99,7 +99,7 @@ func TestCdrsCfgAsMapInterface(t *testing.T) {
utils.ThresholdSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.StatSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.OnlineCDRExportsCfg: []string{"http_localhost", "amqp_localhost", "http_test_file"},
- utils.SchedulerConnsCfg: []string{utils.MetaInternal, "*conn1"},
+ utils.ActionSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.EEsConnsCfg: []string{utils.MetaInternal, "*conn1"},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -129,7 +129,7 @@ func TestCdrsCfgAsMapInterface2(t *testing.T) {
utils.ThresholdSConnsCfg: []string{},
utils.StatSConnsCfg: []string{},
utils.OnlineCDRExportsCfg: []string{},
- utils.SchedulerConnsCfg: []string{},
+ utils.ActionSConnsCfg: []string{},
utils.EEsConnsCfg: []string{"conn1"},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -149,7 +149,7 @@ func TestCdrsCfgClone(t *testing.T) {
AttributeSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "*conn1"},
ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"},
- SchedulerConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
+ ActionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
EEsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs), "*conn1"},
OnlineCDRExports: []string{"randomVal"},
ExtraFields: RSRParsers{},
@@ -173,7 +173,7 @@ func TestCdrsCfgClone(t *testing.T) {
if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
t.Errorf("Expected clone to not modify the cloned")
}
- if rcv.SchedulerConns[1] = ""; ban.SchedulerConns[1] != "*conn1" {
+ if rcv.ActionSConns[1] = ""; ban.ActionSConns[1] != "*conn1" {
t.Errorf("Expected clone to not modify the cloned")
}
if rcv.EEsConns[1] = ""; ban.EEsConns[1] != "*conn1" {
diff --git a/config/config_it_test.go b/config/config_it_test.go
index 01398526c..955e2a5c5 100644
--- a/config/config_it_test.go
+++ b/config/config_it_test.go
@@ -421,7 +421,7 @@ func testCGRConfigReloadCDRs(t *testing.T) {
StatSConns: []string{},
SMCostRetries: 5,
StoreCdrs: true,
- SchedulerConns: []string{},
+ ActionSConns: []string{},
EEsConns: []string{utils.MetaLocalHost},
}
if !reflect.DeepEqual(expAttr, cfg.CdrsCfg()) {
diff --git a/config/config_json_test.go b/config/config_json_test.go
index f1c835709..f14b43c1f 100644
--- a/config/config_json_test.go
+++ b/config/config_json_test.go
@@ -713,7 +713,7 @@ func TestDfCdrsJsonCfg(t *testing.T) {
Thresholds_conns: &[]string{},
Stats_conns: &[]string{},
Online_cdr_exports: &[]string{},
- Scheduler_conns: &[]string{},
+ Actions_conns: &[]string{},
Ees_conns: &[]string{},
}
dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
@@ -1925,7 +1925,7 @@ func TestDfLoaderCfg(t *testing.T) {
Disable_reverse: utils.BoolPointer(false),
Field_separator: utils.StringPointer(","),
Caches_conns: &[]string{utils.MetaLocalHost},
- Scheduler_conns: &[]string{utils.MetaLocalHost},
+ Actions_conns: &[]string{utils.MetaLocalHost},
Gapi_credentials: &cred,
Gapi_token: &tok,
}
@@ -2024,7 +2024,7 @@ func TestDfApierCfg(t *testing.T) {
eCfg := &ApierJsonCfg{
Enabled: utils.BoolPointer(false),
Caches_conns: &[]string{utils.MetaInternal},
- Scheduler_conns: &[]string{},
+ Actions_conns: &[]string{},
Attributes_conns: &[]string{},
Ees_conns: &[]string{},
}
diff --git a/config/config_test.go b/config/config_test.go
index ed1b38d73..bcbef7ff5 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -447,7 +447,7 @@ func TestCgrCfgJSONDefaultsCDRS(t *testing.T) {
AttributeSConns: []string{},
ThresholdSConns: []string{},
StatSConns: []string{},
- SchedulerConns: []string{},
+ ActionSConns: []string{},
EEsConns: []string{},
ExtraFields: RSRParsers{},
}
@@ -3608,7 +3608,7 @@ func TestCgrLoaderCfgDefault(t *testing.T) {
DisableReverse: false,
FieldSeparator: rune(utils.CSVSep),
CachesConns: []string{utils.MetaLocalHost},
- SchedulerConns: []string{utils.MetaLocalHost},
+ ActionSConns: []string{utils.MetaLocalHost},
GapiCredentials: json.RawMessage(`".gapi/credentials.json"`),
GapiToken: json.RawMessage(`".gapi/token.json"`),
}
@@ -4176,7 +4176,7 @@ func TestV1GetConfigCdrs(t *testing.T) {
utils.ThresholdSConnsCfg: []string{},
utils.StatSConnsCfg: []string{},
utils.OnlineCDRExportsCfg: []string{},
- utils.SchedulerConnsCfg: []string{},
+ utils.ActionSConnsCfg: []string{},
utils.EEsConnsCfg: []string{},
},
}
@@ -4203,7 +4203,7 @@ func TestV1GetConfigSessionS(t *testing.T) {
utils.StatSConnsCfg: []string{},
utils.RouteSConnsCfg: []string{},
utils.AttributeSConnsCfg: []string{},
- utils.SchedulerConnsCfg: []string{},
+ utils.ActionSConnsCfg: []string{},
utils.ReplicationConnsCfg: []string{},
utils.DebitIntervalCfg: "0",
utils.StoreSCostsCfg: false,
@@ -4648,7 +4648,7 @@ func TestV1GetConfigSectionLoader(t *testing.T) {
utils.DisableReverseCfg: false,
utils.FieldSepCfg: ",",
utils.CachesConnsCfg: []string{"*localhost"},
- utils.SchedulerConnsCfg: []string{"*localhost"},
+ utils.ActionSConnsCfg: []string{"*localhost"},
utils.GapiCredentialsCfg: json.RawMessage(`".gapi/credentials.json"`),
utils.GapiTokenCfg: json.RawMessage(`".gapi/token.json"`),
},
@@ -4706,7 +4706,7 @@ func TestV1GetConfigSectionApierS(t *testing.T) {
ApierS: map[string]interface{}{
utils.EnabledCfg: false,
utils.CachesConnsCfg: []string{utils.MetaInternal},
- utils.SchedulerConnsCfg: []string{},
+ utils.ActionSConnsCfg: []string{},
utils.AttributeSConnsCfg: []string{},
utils.EEsConnsCfg: []string{},
},
diff --git a/config/libconfig_json.go b/config/libconfig_json.go
index e751bb52e..c5a5bda0e 100644
--- a/config/libconfig_json.go
+++ b/config/libconfig_json.go
@@ -141,7 +141,7 @@ type CdrsJsonCfg struct {
Thresholds_conns *[]string
Stats_conns *[]string
Online_cdr_exports *[]string
- Scheduler_conns *[]string
+ Actions_conns *[]string
Ees_conns *[]string
}
@@ -547,7 +547,7 @@ type LoaderCfgJson struct {
Disable_reverse *bool
Field_separator *string
Caches_conns *[]string
- Scheduler_conns *[]string
+ Actions_conns *[]string
Gapi_credentials *json.RawMessage
Gapi_token *json.RawMessage
}
@@ -604,7 +604,7 @@ type AnalyzerSJsonCfg struct {
type ApierJsonCfg struct {
Enabled *bool
Caches_conns *[]string
- Scheduler_conns *[]string
+ Actions_conns *[]string
Attributes_conns *[]string
Ees_conns *[]string
}
diff --git a/config/loadercgrcfg.go b/config/loadercgrcfg.go
index 56aa0d4b9..2433f4f20 100644
--- a/config/loadercgrcfg.go
+++ b/config/loadercgrcfg.go
@@ -29,9 +29,9 @@ type LoaderCgrCfg struct {
TpID string
DataPath string
DisableReverse bool
- FieldSeparator rune // The separator to use when reading csvs
- CachesConns []string
- SchedulerConns []string
+ FieldSeparator rune // The separator to use when reading csvs
+ CachesConns []string // ToDoNext: add actions conn
+ ActionSConns []string
GapiCredentials json.RawMessage
GapiToken json.RawMessage
}
@@ -63,13 +63,13 @@ func (ld *LoaderCgrCfg) loadFromJSONCfg(jsnCfg *LoaderCfgJson) (err error) {
}
}
}
- if jsnCfg.Scheduler_conns != nil {
- ld.SchedulerConns = make([]string, len(*jsnCfg.Caches_conns))
- for idx, conn := range *jsnCfg.Caches_conns {
+ if jsnCfg.Actions_conns != nil {
+ ld.ActionSConns = make([]string, len(*jsnCfg.Actions_conns))
+ for idx, conn := range *jsnCfg.Actions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
- ld.SchedulerConns[idx] = conn
+ ld.ActionSConns[idx] = conn
if conn == utils.MetaInternal {
- ld.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
+ ld.ActionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions)
}
}
}
@@ -100,15 +100,15 @@ func (ld *LoaderCgrCfg) AsMapInterface() (initialMP map[string]interface{}) {
}
initialMP[utils.CachesConnsCfg] = cacheSConns
}
- if ld.SchedulerConns != nil {
- schedulerSConns := make([]string, len(ld.SchedulerConns))
- for i, item := range ld.SchedulerConns {
+ if ld.ActionSConns != nil {
+ schedulerSConns := make([]string, len(ld.ActionSConns))
+ for i, item := range ld.ActionSConns {
schedulerSConns[i] = item
- if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions) {
schedulerSConns[i] = utils.MetaInternal
}
}
- initialMP[utils.SchedulerConnsCfg] = schedulerSConns
+ initialMP[utils.ActionSConnsCfg] = schedulerSConns
}
if ld.GapiCredentials != nil {
initialMP[utils.GapiCredentialsCfg] = ld.GapiCredentials
@@ -136,10 +136,10 @@ func (ld LoaderCgrCfg) Clone() (cln *LoaderCgrCfg) {
cln.CachesConns[i] = k
}
}
- if ld.SchedulerConns != nil {
- cln.SchedulerConns = make([]string, len(ld.SchedulerConns))
- for i, k := range ld.SchedulerConns {
- cln.SchedulerConns[i] = k
+ if ld.ActionSConns != nil {
+ cln.ActionSConns = make([]string, len(ld.ActionSConns))
+ for i, k := range ld.ActionSConns {
+ cln.ActionSConns[i] = k
}
}
return
diff --git a/config/loadercgrcfg_test.go b/config/loadercgrcfg_test.go
index 770a43117..6b6521158 100644
--- a/config/loadercgrcfg_test.go
+++ b/config/loadercgrcfg_test.go
@@ -32,7 +32,7 @@ func TestLoaderCgrCfgloadFromJsonCfg(t *testing.T) {
Disable_reverse: utils.BoolPointer(true),
Field_separator: utils.StringPointer(";"),
Caches_conns: &[]string{utils.MetaInternal},
- Scheduler_conns: &[]string{utils.MetaInternal},
+ Actions_conns: &[]string{utils.MetaInternal},
Gapi_credentials: &json.RawMessage{12, 13, 60},
Gapi_token: &json.RawMessage{13, 16},
}
@@ -42,7 +42,7 @@ func TestLoaderCgrCfgloadFromJsonCfg(t *testing.T) {
DisableReverse: true,
FieldSeparator: rune(';'),
CachesConns: []string{"*internal:*caches"},
- SchedulerConns: []string{"*internal:*scheduler"},
+ ActionSConns: []string{"*internal:*scheduler"},
GapiCredentials: json.RawMessage{12, 13, 60},
GapiToken: json.RawMessage{13, 16},
}
@@ -73,7 +73,7 @@ func TestLoaderCgrCfgAsMapInterface(t *testing.T) {
utils.DisableReverseCfg: false,
utils.FieldSepCfg: ",",
utils.CachesConnsCfg: []string{"*internal", "*localhost"},
- utils.SchedulerConnsCfg: []string{"*internal", "*localhost"},
+ utils.ActionSConnsCfg: []string{"*internal", "*localhost"},
utils.GapiCredentialsCfg: json.RawMessage(`".gapi/credentials.json"`),
utils.GapiTokenCfg: json.RawMessage(`".gapi/token.json"`),
}
@@ -91,7 +91,7 @@ func TestLoaderCgrCfgClone(t *testing.T) {
DisableReverse: true,
FieldSeparator: rune(';'),
CachesConns: []string{"*internal:*caches"},
- SchedulerConns: []string{"*internal:*scheduler"},
+ ActionSConns: []string{"*internal:*scheduler"},
GapiCredentials: json.RawMessage{12, 13, 60},
GapiToken: json.RawMessage{13, 16},
}
@@ -102,7 +102,7 @@ func TestLoaderCgrCfgClone(t *testing.T) {
if rcv.CachesConns[0] = ""; ban.CachesConns[0] != "*internal:*caches" {
t.Errorf("Expected clone to not modify the cloned")
}
- if rcv.SchedulerConns[0] = ""; ban.SchedulerConns[0] != "*internal:*scheduler" {
+ if rcv.ActionSConns[0] = ""; ban.ActionSConns[0] != "*internal:*scheduler" {
t.Errorf("Expected clone to not modify the cloned")
}
if rcv.GapiCredentials[0] = 0; ban.GapiCredentials[0] != 12 {
diff --git a/config/sessionscfg.go b/config/sessionscfg.go
index fe53783d2..98a5ebfa7 100644
--- a/config/sessionscfg.go
+++ b/config/sessionscfg.go
@@ -295,7 +295,7 @@ func (scfg *SessionSCfg) loadFromJSONCfg(jsnCfg *SessionSJsonCfg) (err error) {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
scfg.SchedulerConns[idx] = connID
if connID == utils.MetaInternal {
- scfg.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
+ scfg.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions)
}
}
}
@@ -444,11 +444,11 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
schedulerConns := make([]string, len(scfg.SchedulerConns))
for i, item := range scfg.SchedulerConns {
schedulerConns[i] = item
- if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions) {
schedulerConns[i] = utils.MetaInternal
}
}
- initialMP[utils.SchedulerConnsCfg] = schedulerConns
+ initialMP[utils.ActionSConnsCfg] = schedulerConns
}
return
}
diff --git a/config/sessionscfg_test.go b/config/sessionscfg_test.go
index 78cf33366..672904594 100644
--- a/config/sessionscfg_test.go
+++ b/config/sessionscfg_test.go
@@ -373,7 +373,7 @@ func TestSessionSCfgAsMapInterfaceCase1(t *testing.T) {
utils.PublicKeyPathCfg: "",
utils.PrivateKeyPathCfg: "",
},
- utils.SchedulerConnsCfg: []string{},
+ utils.ActionSConnsCfg: []string{},
utils.DefaultUsageCfg: map[string]string{
utils.MetaAny: "3h0m0s",
utils.MetaVoice: "3h0m0s",
@@ -447,7 +447,7 @@ func TestSessionSCfgAsMapInterfaceCase2(t *testing.T) {
utils.PublicKeyPathCfg: "",
utils.PrivateKeyPathCfg: "",
},
- utils.SchedulerConnsCfg: []string{utils.MetaInternal, "*conn1"},
+ utils.ActionSConnsCfg: []string{utils.MetaInternal, "*conn1"},
utils.DefaultUsageCfg: map[string]string{
utils.MetaAny: "3h0m0s",
utils.MetaVoice: "3h0m0s",
diff --git a/console/cost_details.go b/console/cost_details.go
deleted file mode 100644
index a11a60d08..000000000
--- a/console/cost_details.go
+++ /dev/null
@@ -1,74 +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/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func init() {
- c := &CmdGetCostDetails{
- name: "cost_details",
- rpcMethod: utils.APIerSv1GetEventCost,
- }
- commands[c.Name()] = c
- c.CommandExecuter = &CommandExecuter{c}
-}
-
-// Commander implementation
-type CmdGetCostDetails struct {
- name string
- rpcMethod string
- rpcParams *utils.AttrGetCallCost
- rpcResult string
- *CommandExecuter
-}
-
-func (self *CmdGetCostDetails) Name() string {
- return self.name
-}
-
-func (self *CmdGetCostDetails) RpcMethod() string {
- return self.rpcMethod
-}
-
-func (self *CmdGetCostDetails) RpcParams(reset bool) interface{} {
- if reset || self.rpcParams == nil {
- self.rpcParams = &utils.AttrGetCallCost{RunId: utils.MetaDefault}
- }
- return self.rpcParams
-}
-
-func (self *CmdGetCostDetails) PostprocessRpcParams() error {
- return nil
-}
-
-func (self *CmdGetCostDetails) RpcResult() interface{} {
- return &engine.EventCost{}
-}
-
-func (self *CmdGetCostDetails) GetFormatedResult(result interface{}) string {
- return GetFormatedResult(result, utils.StringSet{
- utils.Usage: {},
- utils.GroupIntervalStart: {},
- utils.RateIncrement: {},
- utils.RateUnit: {},
- })
-}
diff --git a/console/cost_details_test.go b/console/cost_details_test.go
deleted file mode 100644
index 732b6be35..000000000
--- a/console/cost_details_test.go
+++ /dev/null
@@ -1,64 +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"
-
- v1 "github.com/cgrates/cgrates/apier/v1"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestCmdCostDetails(t *testing.T) {
- // commands map is initiated in init function
- command := commands["cost_details"]
- // verify if ApierSv1 object has method on it
- m, ok := reflect.TypeOf(new(v1.APIerSv1)).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)
- }
- // for coverage purpose
- formatedResult := command.GetFormatedResult(command.RpcResult())
- expected := GetFormatedResult(command.RpcResult(), utils.StringSet{
- utils.Usage: {},
- utils.GroupIntervalStart: {},
- utils.RateIncrement: {},
- utils.RateUnit: {},
- })
- if !reflect.DeepEqual(formatedResult, expected) {
- t.Errorf("Expected <%+v>, Received <%+v>", expected, formatedResult)
- }
-}
diff --git a/console/debit.go b/console/debit.go
deleted file mode 100644
index 484e2a9fd..000000000
--- a/console/debit.go
+++ /dev/null
@@ -1,73 +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/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func init() {
- c := &CmdDebit{
- name: "debit",
- rpcMethod: utils.ResponderDebit,
- clientArgs: []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField, utils.Destination, utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject, utils.DryRun},
- }
- commands[c.Name()] = c
- c.CommandExecuter = &CommandExecuter{c}
-}
-
-// Commander implementation
-type CmdDebit struct {
- name string
- rpcMethod string
- rpcParams *engine.CallDescriptorWithAPIOpts
- clientArgs []string
- *CommandExecuter
-}
-
-func (self *CmdDebit) Name() string {
- return self.name
-}
-
-func (self *CmdDebit) RpcMethod() string {
- return self.rpcMethod
-}
-
-func (self *CmdDebit) RpcParams(reset bool) interface{} {
- if reset || self.rpcParams == nil {
- self.rpcParams = &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: new(engine.CallDescriptor),
- APIOpts: make(map[string]interface{}),
- }
- }
- return self.rpcParams
-}
-
-func (self *CmdDebit) PostprocessRpcParams() error {
- return nil
-}
-
-func (self *CmdDebit) RpcResult() interface{} {
- return &engine.CallCost{}
-}
-
-func (self *CmdDebit) ClientArgs() []string {
- return self.clientArgs
-}
diff --git a/console/debit_max.go b/console/debit_max.go
deleted file mode 100644
index 7a31bd703..000000000
--- a/console/debit_max.go
+++ /dev/null
@@ -1,73 +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/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func init() {
- c := &CmdMaxDebit{
- name: "debit_max",
- rpcMethod: utils.ResponderMaxDebit,
- clientArgs: []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField, utils.Destination, utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject},
- }
- commands[c.Name()] = c
- c.CommandExecuter = &CommandExecuter{c}
-}
-
-// Commander implementation
-type CmdMaxDebit struct {
- name string
- rpcMethod string
- rpcParams *engine.CallDescriptorWithAPIOpts
- clientArgs []string
- *CommandExecuter
-}
-
-func (self *CmdMaxDebit) Name() string {
- return self.name
-}
-
-func (self *CmdMaxDebit) RpcMethod() string {
- return self.rpcMethod
-}
-
-func (self *CmdMaxDebit) RpcParams(reset bool) interface{} {
- if reset || self.rpcParams == nil {
- self.rpcParams = &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: new(engine.CallDescriptor),
- APIOpts: make(map[string]interface{}),
- }
- }
- return self.rpcParams
-}
-
-func (self *CmdMaxDebit) PostprocessRpcParams() error {
- return nil
-}
-
-func (self *CmdMaxDebit) RpcResult() interface{} {
- return &engine.CallCost{}
-}
-
-func (self *CmdMaxDebit) ClientArgs() []string {
- return self.clientArgs
-}
diff --git a/console/debit_max_test.go b/console/debit_max_test.go
deleted file mode 100644
index 5dcf4a91f..000000000
--- a/console/debit_max_test.go
+++ /dev/null
@@ -1,59 +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"
-
- v1 "github.com/cgrates/cgrates/apier/v1"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestCmdDebitMax(t *testing.T) {
- // commands map is initiated in init function
- command := commands["debit_max"]
- // verify if ApierSv1 object has method on it
- m, ok := reflect.TypeOf(new(v1.DispatcherResponder)).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)
- }
- expected := []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField,
- utils.Destination, utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject}
-
- if !reflect.DeepEqual(command.ClientArgs(), expected) {
- t.Errorf("Expected <%+v>, Received <%+v>", expected, command.ClientArgs())
- }
-}
diff --git a/console/debit_test.go b/console/debit_test.go
deleted file mode 100644
index 396e6cd8f..000000000
--- a/console/debit_test.go
+++ /dev/null
@@ -1,59 +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"
-
- v1 "github.com/cgrates/cgrates/apier/v1"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestCmdDebit(t *testing.T) {
- // commands map is initiated in init function
- command := commands["debit"]
- // verify if ApierSv1 object has method on it
- m, ok := reflect.TypeOf(new(v1.DispatcherResponder)).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)
- }
- expected := []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField,
- utils.Destination, utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject, utils.DryRun}
-
- if !reflect.DeepEqual(command.ClientArgs(), expected) {
- t.Errorf("Expected <%+v>, Received <%+v>", expected, command.ClientArgs())
- }
-}
diff --git a/console/maxduration.go b/console/maxduration.go
deleted file mode 100644
index 3f21bb970..000000000
--- a/console/maxduration.go
+++ /dev/null
@@ -1,86 +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 (
- "encoding/json"
- "fmt"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func init() {
- c := &CmdGetMaxDuration{
- name: "maxduration",
- rpcMethod: utils.ResponderGetMaxSessionTime,
- clientArgs: []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField, utils.Destination, utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject},
- }
- commands[c.Name()] = c
- c.CommandExecuter = &CommandExecuter{c}
-}
-
-// Commander implementation
-type CmdGetMaxDuration struct {
- name string
- rpcMethod string
- rpcParams *engine.CallDescriptorWithAPIOpts
- clientArgs []string
- *CommandExecuter
-}
-
-func (self *CmdGetMaxDuration) Name() string {
- return self.name
-}
-
-func (self *CmdGetMaxDuration) RpcMethod() string {
- return self.rpcMethod
-}
-
-func (self *CmdGetMaxDuration) RpcParams(reset bool) interface{} {
- if reset || self.rpcParams == nil {
- self.rpcParams = &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: new(engine.CallDescriptor),
- APIOpts: make(map[string]interface{}),
- }
- }
- return self.rpcParams
-}
-
-func (self *CmdGetMaxDuration) PostprocessRpcParams() error {
- return nil
-}
-
-func (self *CmdGetMaxDuration) RpcResult() interface{} {
- var d time.Duration
- return &d
-}
-
-func (self *CmdGetMaxDuration) ClientArgs() []string {
- return self.clientArgs
-}
-
-func (self *CmdGetMaxDuration) GetFormatedResult(result interface{}) string {
- if tv, canCast := result.(*time.Duration); canCast {
- return fmt.Sprintf(`"%s"`, tv.String())
- }
- out, _ := json.MarshalIndent(result, utils.EmptyString, " ")
- return string(out)
-}
diff --git a/console/maxduration_test.go b/console/maxduration_test.go
deleted file mode 100644
index 4fcfdaa1e..000000000
--- a/console/maxduration_test.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 console
-
-import (
- "reflect"
- "strings"
- "testing"
-
- v1 "github.com/cgrates/cgrates/apier/v1"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestCmdMaxDuration(t *testing.T) {
- // commands map is initiated in init function
- command := commands["maxduration"]
- // verify if ApierSv1 object has method on it
- m, ok := reflect.TypeOf(new(v1.DispatcherResponder)).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)
- }
- expected := []string{utils.Category, utils.ToR, utils.Tenant, utils.Subject, utils.AccountField, utils.Destination,
- utils.TimeStart, utils.TimeEnd, utils.CallDuration, utils.FallbackSubject}
-
- if !reflect.DeepEqual(command.ClientArgs(), expected) {
- t.Errorf("Expected <%+v>, Received <%+v>", expected, command.ClientArgs())
- }
- result := command.GetFormatedResult(command.RpcResult())
- if !reflect.DeepEqual(result, `"0s"`) {
- t.Errorf("Expected <%+v>, Received <%+v>", `"0s"`, result)
- }
-
-}
-
-func TestCmdMaxDurationGetFormatedResultCase2(t *testing.T) {
- testStruct := &CmdGetMaxDuration{
- name: "",
- rpcMethod: "",
- rpcParams: nil,
- clientArgs: nil,
- CommandExecuter: nil,
- }
-
- result := testStruct.GetFormatedResult(testStruct)
- if !reflect.DeepEqual(result, "{}") {
- t.Errorf("Expected <%+v>, Received <%+v>", "{}", result)
- }
-}
diff --git a/dispatchers/cdrs.go b/dispatchers/cdrs.go
index 861986bc9..b37c834eb 100644
--- a/dispatchers/cdrs.go
+++ b/dispatchers/cdrs.go
@@ -81,23 +81,6 @@ func (dS *DispatcherService) CDRsV1GetCDRsCount(args *utils.RPCCDRsFilterWithAPI
}, utils.MetaCDRs, utils.CDRsV1GetCDRsCount, args, reply)
}
-func (dS *DispatcherService) CDRsV1StoreSessionCost(args *engine.AttrCDRSStoreSMCost, reply *string) (err error) {
- tnt := dS.cfg.GeneralCfg().DefaultTenant
- if args.Tenant != utils.EmptyString {
- tnt = args.Tenant
- }
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.CDRsV1StoreSessionCost, tnt,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
- return
- }
- }
- return dS.Dispatch(&utils.CGREvent{
- Tenant: tnt,
- APIOpts: args.APIOpts,
- }, utils.MetaCDRs, utils.CDRsV1StoreSessionCost, args, reply)
-}
-
func (dS *DispatcherService) CDRsV1RateCDRs(args *engine.ArgRateCDRs, reply *string) (err error) {
tnt := dS.cfg.GeneralCfg().DefaultTenant
if args.Tenant != utils.EmptyString {
@@ -178,20 +161,3 @@ func (dS *DispatcherService) CDRsV2ProcessEvent(args *engine.ArgV1ProcessEvent,
return dS.Dispatch(&args.CGREvent, utils.MetaCDRs,
utils.CDRsV2ProcessEvent, args, reply)
}
-
-func (dS *DispatcherService) CDRsV2StoreSessionCost(args *engine.ArgsV2CDRSStoreSMCost, reply *string) (err error) {
- tnt := args.Tenant
- if tnt == utils.EmptyString {
- tnt = dS.cfg.GeneralCfg().DefaultTenant
- }
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.CDRsV2StoreSessionCost, tnt,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
- return
- }
- }
- return dS.Dispatch(&utils.CGREvent{
- Tenant: tnt,
- APIOpts: args.APIOpts,
- }, utils.MetaCDRs, utils.CDRsV2StoreSessionCost, args, reply)
-}
diff --git a/dispatchers/replicator.go b/dispatchers/replicator.go
index 0662f86ff..31fc04063 100644
--- a/dispatchers/replicator.go
+++ b/dispatchers/replicator.go
@@ -529,23 +529,6 @@ func (dS *DispatcherService) ReplicatorSv1SetResourceProfile(args *engine.Resour
}, utils.MetaReplicator, utils.ReplicatorSv1SetResourceProfile, args, rpl)
}
-func (dS *DispatcherService) ReplicatorSv1SetActions(args *engine.SetActionsArgsWithAPIOpts, rpl *string) (err error) {
- if args == nil {
- args = &engine.SetActionsArgsWithAPIOpts{}
- }
- args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant)
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.ReplicatorSv1SetActions, 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.ReplicatorSv1SetActions, args, rpl)
-}
-
func (dS *DispatcherService) ReplicatorSv1SetRouteProfile(args *engine.RouteProfileWithAPIOpts, rpl *string) (err error) {
if args == nil {
args = &engine.RouteProfileWithAPIOpts{}
diff --git a/dispatchers/servicemanager.go b/dispatchers/servicemanager.go
index 925338253..3b15ba839 100644
--- a/dispatchers/servicemanager.go
+++ b/dispatchers/servicemanager.go
@@ -19,8 +19,6 @@ along with this program. If not, see
package dispatchers
import (
- "time"
-
"github.com/cgrates/cgrates/utils"
)
@@ -39,57 +37,3 @@ func (dS *DispatcherService) ServiceManagerV1Ping(args *utils.CGREvent,
}
return dS.Dispatch(args, utils.MetaServiceManager, utils.ServiceManagerV1Ping, args, reply)
}
-
-func (dS *DispatcherService) ServiceManagerV1StartService(args ArgStartServiceWithAPIOpts,
- reply *string) (err error) {
- tnt := dS.cfg.GeneralCfg().DefaultTenant
- if args.Tenant != utils.EmptyString {
- tnt = args.Tenant
- }
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.ServiceManagerV1StartService, tnt,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
- return
- }
- }
- return dS.Dispatch(&utils.CGREvent{
- Tenant: tnt,
- APIOpts: args.APIOpts,
- }, utils.MetaServiceManager, utils.ServiceManagerV1StartService, args, reply)
-}
-
-func (dS *DispatcherService) ServiceManagerV1StopService(args ArgStartServiceWithAPIOpts,
- reply *string) (err error) {
- tnt := dS.cfg.GeneralCfg().DefaultTenant
- if args.Tenant != utils.EmptyString {
- tnt = args.Tenant
- }
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.ServiceManagerV1StopService, tnt,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
- return
- }
- }
- return dS.Dispatch(&utils.CGREvent{
- Tenant: tnt,
- APIOpts: args.APIOpts,
- }, utils.MetaServiceManager, utils.ServiceManagerV1StopService, args, reply)
-}
-
-func (dS *DispatcherService) ServiceManagerV1ServiceStatus(args ArgStartServiceWithAPIOpts,
- reply *string) (err error) {
- tnt := dS.cfg.GeneralCfg().DefaultTenant
- if args.Tenant != utils.EmptyString {
- tnt = args.Tenant
- }
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.ServiceManagerV1ServiceStatus, tnt,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
- return
- }
- }
- return dS.Dispatch(&utils.CGREvent{
- Tenant: tnt,
- APIOpts: args.APIOpts,
- }, utils.MetaServiceManager, utils.ServiceManagerV1ServiceStatus, args, reply)
-}
diff --git a/dispatchers/sessions.go b/dispatchers/sessions.go
index 7f716666c..4789b8453 100755
--- a/dispatchers/sessions.go
+++ b/dispatchers/sessions.go
@@ -162,18 +162,6 @@ func (dS *DispatcherService) SessionSv1ProcessEvent(args *sessions.V1ProcessEven
return dS.Dispatch(args.CGREvent, utils.MetaSessionS, utils.SessionSv1ProcessEvent, args, reply)
}
-func (dS *DispatcherService) SessionSv1GetCost(args *sessions.V1ProcessEventArgs,
- reply *sessions.V1GetCostReply) (err error) {
- args.CGREvent.Tenant = utils.FirstNonEmpty(args.CGREvent.Tenant, dS.cfg.GeneralCfg().DefaultTenant)
- if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
- if err = dS.authorize(utils.SessionSv1GetCost, args.CGREvent.Tenant,
- utils.IfaceAsString(args.APIOpts[utils.OptsAPIKey]), args.CGREvent.Time); err != nil {
- return
- }
- }
- return dS.Dispatch(args.CGREvent, utils.MetaSessionS, utils.SessionSv1GetCost, args, reply)
-}
-
func (dS *DispatcherService) SessionSv1GetActiveSessions(args *utils.SessionFilter,
reply *[]*sessions.ExternalSession) (err error) {
tnt := dS.cfg.GeneralCfg().DefaultTenant
diff --git a/dispatchers/utils.go b/dispatchers/utils.go
index 896a76087..96c75e15c 100755
--- a/dispatchers/utils.go
+++ b/dispatchers/utils.go
@@ -21,9 +21,6 @@ package dispatchers
import (
"strings"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/servmanager"
-
"github.com/cgrates/cgrates/sessions"
"github.com/cgrates/cgrates/utils"
)
@@ -46,20 +43,9 @@ type AttrRemoteUnlockWithAPIOpts struct {
RefID string
}
-type ArgStartServiceWithAPIOpts struct {
- APIOpts map[string]interface{}
- Tenant string
- servmanager.ArgStartService
-}
-
func ParseStringSet(s string) utils.StringSet {
if s == utils.MetaZero {
return make(utils.StringSet)
}
return utils.NewStringSet(strings.Split(s, utils.ANDSep))
}
-
-type RatingPlanCost struct {
- EventCost *engine.EventCost
- RatingPlanID string
-}
diff --git a/engine/actions_test.go b/engine/actions_test.go
deleted file mode 100644
index 746a8bcef..000000000
--- a/engine/actions_test.go
+++ /dev/null
@@ -1,2811 +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 (
- "fmt"
- "io"
- "net/http"
- "net/http/httptest"
- "reflect"
- "strings"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/config"
-
- "github.com/cgrates/cgrates/utils"
- "github.com/cgrates/rpcclient"
-)
-
-var (
- err error
- //referenceDate = time.Date(2013, 7, 10, 10, 30, 0, 0, time.Local)
- //referenceDate = time.Date(2013, 12, 31, 23, 59, 59, 0, time.Local)
- //referenceDate = time.Date(2011, 1, 1, 0, 0, 0, 1, time.Local)
- referenceDate = time.Now()
- now = referenceDate
-)
-
-func TestActionTimingAlways(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
- st := at.GetNextStartTime(referenceDate)
- y, m, d := referenceDate.Date()
- expected := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanNothing(t *testing.T) {
- at := &ActionTiming{}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionTimingMidnight(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}}
- y, m, d := referenceDate.Date()
- now := time.Date(y, m, d, 0, 0, 1, 0, time.Local)
- st := at.GetNextStartTime(now)
- expected := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanOnlyHour(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
-
- y, m, d := now.Date()
- expected := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- if referenceDate.After(expected) {
- expected = expected.AddDate(0, 0, 1)
- }
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourYear(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(2022, 1, 1, 10, 1, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanOnlyWeekdays(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}}
- st := at.GetNextStartTime(referenceDate)
-
- y, m, d := now.Date()
- h, min, s := now.Clock()
- e := time.Date(y, m, d, h, min, s, 0, time.Local)
- day := e.Day()
- e = time.Date(e.Year(), e.Month(), day, 0, 0, 0, 0, e.Location())
- for i := 0; i < 8; i++ {
- n := e.AddDate(0, 0, i)
- if n.Weekday() == time.Monday && (n.Equal(now) || n.After(now)) {
- e = n
- break
- }
- }
- if !st.Equal(e) {
- t.Errorf("Expected %v was %v", e, st)
- }
-}
-
-func TestActionPlanHourWeekdays(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{
- WeekDays: []time.Weekday{time.Monday}, StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
-
- y, m, d := now.Date()
- e := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- day := e.Day()
- for i := 0; i < 8; i++ {
- e = time.Date(e.Year(), e.Month(), day, e.Hour(),
- e.Minute(), e.Second(), e.Nanosecond(), e.Location())
- n := e.AddDate(0, 0, i)
- if n.Weekday() == time.Monday && (n.Equal(now) || n.After(now)) {
- e = n
- break
- }
- }
- if !st.Equal(e) {
- t.Errorf("Expected %v was %v", e, st)
- }
-}
-
-func TestActionPlanOnlyMonthdays(t *testing.T) {
-
- y, m, d := now.Date()
- tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{MonthDays: utils.MonthDays{1, 25, 2, tomorrow.Day()}}}}
- st := at.GetNextStartTime(referenceDate)
- expected := tomorrow
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourMonthdays(t *testing.T) {
-
- y, m, d := now.Date()
- testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
- if now.After(testTime) {
- y, m, d = tomorrow.Date()
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()}, StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanOnlyMonths(t *testing.T) {
-
- y, m, _ := now.Date()
- nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{Months: utils.Months{time.February, time.May, nextMonth.Month()}}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(nextMonth.Year(), nextMonth.Month(), 1, 0, 0, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Log("NextMonth: ", nextMonth)
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourMonths(t *testing.T) {
-
- y, m, d := now.Date()
- testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
- if now.After(testTime) {
- testTime = testTime.AddDate(0, 0, 1)
- y, m, _ = testTime.Date()
- }
- if now.After(testTime) {
- m = nextMonth.Month()
- y = nextMonth.Year()
-
- }
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{
- Months: utils.Months{now.Month(), nextMonth.Month()},
- StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(y, m, 1, 10, 1, 0, 0, time.Local)
- if referenceDate.After(expected) {
- expected = expected.AddDate(0, 1, 0)
- }
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourMonthdaysMonths(t *testing.T) {
-
- y, m, d := now.Date()
- testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
- tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
-
- if now.After(testTime) {
- y, m, d = tomorrow.Date()
- }
- nextDay := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- month := nextDay.Month()
- if nextDay.Before(now) {
- if now.After(testTime) {
- month = nextMonth.Month()
- }
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Months: utils.Months{now.Month(), nextMonth.Month()},
- MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
- StartTime: "10:01:00",
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(y, month, d, 10, 1, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanFirstOfTheMonth(t *testing.T) {
-
- y, m, _ := now.Date()
- nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- MonthDays: utils.MonthDays{1},
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- expected := nextMonth
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanOnlyYears(t *testing.T) {
- y, _, _ := referenceDate.Date()
- nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{Years: utils.Years{now.Year(), nextYear.Year()}}}}
- st := at.GetNextStartTime(referenceDate)
- expected := nextYear
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanPast(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourYears(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{
- Years: utils.Years{referenceDate.Year(), referenceDate.Year() + 1}, StartTime: "10:01:00"}}}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(referenceDate.Year(), 1, 1, 10, 1, 0, 0, time.Local)
- if referenceDate.After(expected) {
- expected = expected.AddDate(1, 0, 0)
- }
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourMonthdaysYear(t *testing.T) {
-
- y, m, d := now.Date()
- testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- tomorrow := time.Date(y, m, d, 10, 1, 0, 0, time.Local).AddDate(0, 0, 1)
- nextYear := time.Date(y, 1, d, 10, 1, 0, 0, time.Local).AddDate(1, 0, 0)
- expected := testTime
- if referenceDate.After(testTime) {
- if referenceDate.After(tomorrow) {
- expected = nextYear
- } else {
- expected = tomorrow
- }
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{now.Year(), nextYear.Year()},
- MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
- StartTime: "10:01:00",
- },
- }}
- t.Log(at.Timing.Timing.CronString())
- t.Log(time.Now(), referenceDate, referenceDate.After(testTime), referenceDate.After(testTime))
- st := at.GetNextStartTime(referenceDate)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanHourMonthdaysMonthYear(t *testing.T) {
-
- y, m, d := now.Date()
- testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
- nextYear := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
- nextMonth := time.Date(y, m, 1, 0, 0, 0, 0, time.Local).AddDate(0, 1, 0)
- tomorrow := time.Date(y, m, d, 0, 0, 0, 0, time.Local).AddDate(0, 0, 1)
- day := now.Day()
- if now.After(testTime) {
- day = tomorrow.Day()
- }
- nextDay := time.Date(y, m, day, 10, 1, 0, 0, time.Local)
- month := now.Month()
- if nextDay.Before(now) {
- if now.After(testTime) {
- month = nextMonth.Month()
- }
- }
- nextDay = time.Date(y, month, day, 10, 1, 0, 0, time.Local)
- year := now.Year()
- if nextDay.Before(now) {
- if now.After(testTime) {
- year = nextYear.Year()
- }
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{now.Year(), nextYear.Year()},
- Months: utils.Months{now.Month(), nextMonth.Month()},
- MonthDays: utils.MonthDays{now.Day(), tomorrow.Day()},
- StartTime: "10:01:00",
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- expected := time.Date(year, month, day, 10, 1, 0, 0, time.Local)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanFirstOfTheYear(t *testing.T) {
- y, _, _ := now.Date()
- nextYear := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local).AddDate(1, 0, 0)
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{nextYear.Year()},
- Months: utils.Months{time.January},
- MonthDays: utils.MonthDays{1},
- StartTime: "00:00:00",
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- expected := nextYear
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanFirstMonthOfTheYear(t *testing.T) {
- y, _, _ := now.Date()
- expected := time.Date(y, 1, 1, 0, 0, 0, 0, time.Local)
- if referenceDate.After(expected) {
- expected = expected.AddDate(1, 0, 0)
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Months: utils.Months{time.January},
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanFirstMonthOfTheYearSecondDay(t *testing.T) {
- y, _, _ := now.Date()
- expected := time.Date(y, 1, 2, 0, 0, 0, 0, time.Local)
- if referenceDate.After(expected) {
- expected = expected.AddDate(1, 0, 0)
- }
- at := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Months: utils.Months{time.January},
- MonthDays: utils.MonthDays{2},
- },
- }}
- st := at.GetNextStartTime(referenceDate)
- if !st.Equal(expected) {
- t.Errorf("Expected %v was %v", expected, st)
- }
-}
-
-func TestActionPlanCheckForASAP(t *testing.T) {
- at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{StartTime: utils.MetaASAP}}}
- if !at.IsASAP() {
- t.Errorf("%v should be asap!", at)
- }
-}
-
-func TestActionPlanLogFunction(t *testing.T) {
- a := &Action{
- ActionType: "*log",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("test"),
- Value: &utils.ValueFormula{Static: 1.1},
- },
- }
- at := &ActionTiming{
- actions: []*Action{a},
- }
- err := at.Execute(nil, nil)
- if err != nil {
- t.Errorf("Could not execute LOG action: %v", err)
- }
-}
-
-func TestActionPlanFunctionNotAvailable(t *testing.T) {
- a := &Action{
- ActionType: "VALID_FUNCTION_TYPE",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("test"),
- Value: &utils.ValueFormula{Static: 1.1},
- },
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:dy": true},
- Timing: &RateInterval{},
- actions: []*Action{a},
- }
- err := at.Execute(nil, nil)
- if err != utils.ErrPartiallyExecuted { // because we want to return err if we can't execute all actions
- t.Errorf("Faild to detect wrong function type: %v", err)
- }
-}
-
-func TestActionTimingPriorityListSortByWeight(t *testing.T) {
- at1 := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{2040},
- Months: utils.Months{time.January, time.February, time.March,
- time.April, time.May, time.June, time.July, time.August, time.September,
- time.October, time.November, time.December},
- MonthDays: utils.MonthDays{1},
- StartTime: "00:00:00",
- },
- Weight: 20,
- }}
- at2 := &ActionTiming{Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{2040},
- Months: utils.Months{time.January, time.February, time.March,
- time.April, time.May, time.June, time.July, time.August, time.September,
- time.October, time.November, time.December},
- MonthDays: utils.MonthDays{2},
- StartTime: "00:00:00",
- },
- Weight: 10,
- }}
- var atpl ActionTimingPriorityList
- atpl = append(atpl, at2, at1)
- atpl.Sort()
- if atpl[0] != at1 || atpl[1] != at2 {
- t.Errorf("Timing list not sorted correctly: \n %+v, \n %+v \n %+v",
- utils.ToJSON(at1), utils.ToJSON(at2), utils.ToJSON(atpl))
- }
-}
-
-func TestActionTimingPriorityListWeight(t *testing.T) {
- at1 := &ActionTiming{
- Timing: &RateInterval{
- Timing: &RITiming{
- Months: utils.Months{time.January, time.February, time.March,
- time.April, time.May, time.June, time.July, time.August, time.September,
- time.October, time.November, time.December},
- MonthDays: utils.MonthDays{1},
- StartTime: "00:00:00",
- },
- },
- Weight: 20,
- }
- at2 := &ActionTiming{
- Timing: &RateInterval{
- Timing: &RITiming{
- Months: utils.Months{time.January, time.February, time.March,
- time.April, time.May, time.June, time.July, time.August, time.September,
- time.October, time.November, time.December},
- MonthDays: utils.MonthDays{1},
- StartTime: "00:00:00",
- },
- },
- Weight: 10,
- }
- var atpl ActionTimingPriorityList
- atpl = append(atpl, at2, at1)
- atpl.Sort()
- if atpl[0] != at1 || atpl[1] != at2 {
- t.Error("Timing list not sorted correctly: ", atpl)
- }
-}
-
-func TestActionPlansRemoveMember(t *testing.T) {
-
- account1 := &Account{ID: "one"}
- account2 := &Account{ID: "two"}
-
- dm.SetAccount(account1)
- dm.SetAccount(account2)
-
- ap1 := &ActionPlan{
- Id: "TestActionPlansRemoveMember1",
- AccountIDs: utils.StringMap{"one": true},
- ActionTimings: []*ActionTiming{
- {
- Uuid: "uuid1",
- Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{2012},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- StartTime: utils.MetaASAP,
- },
- },
- Weight: 10,
- ActionsID: "MINI",
- },
- },
- }
-
- ap2 := &ActionPlan{
- Id: "test2",
- AccountIDs: utils.StringMap{"two": true},
- ActionTimings: []*ActionTiming{
- {
- Uuid: "uuid2",
- Timing: &RateInterval{
- Timing: &RITiming{
- Years: utils.Years{2012},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- StartTime: utils.MetaASAP,
- },
- },
- Weight: 10,
- ActionsID: "MINI",
- },
- },
- }
-
- if err := dm.SetActionPlan(ap1.Id, ap1, true,
- utils.NonTransactional); err != nil {
- t.Error(err)
- }
- if err = dm.SetActionPlan(ap2.Id, ap2, true,
- utils.NonTransactional); err != nil {
- t.Error(err)
- }
- if err = dm.CacheDataFromDB(utils.ActionPlanPrefix,
- []string{ap1.Id, ap2.Id}, true); err != nil {
- t.Error(err)
- }
- if err = dm.SetAccountActionPlans(account1.ID,
- []string{ap1.Id}, false); err != nil {
- t.Error(err)
- }
- if err = dm.CacheDataFromDB(utils.AccountActionPlansPrefix,
- []string{account1.ID}, true); err != nil {
- t.Error(err)
- }
- dm.GetAccountActionPlans(account1.ID, true, utils.NonTransactional) // FixMe: remove here after finishing testing of map
- if err = dm.SetAccountActionPlans(account2.ID,
- []string{ap2.Id}, false); err != nil {
- t.Error(err)
- }
- if err = dm.CacheDataFromDB(utils.AccountActionPlansPrefix,
- []string{account2.ID}, false); err != nil {
- t.Error(err)
- }
-
- actions := []*Action{
- {
- Id: "REMOVE",
- ActionType: utils.MetaRemoveAccount,
- },
- }
-
- dm.SetActions(actions[0].Id, actions, utils.NonTransactional)
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{account1.ID: true},
- Timing: &RateInterval{},
- actions: actions,
- }
-
- if err = at.Execute(nil, nil); err != nil {
- t.Errorf("Execute Action: %v", err)
- }
-
- apr, err1 := dm.GetActionPlan(ap1.Id, false, utils.NonTransactional)
-
- if err1 != nil {
- t.Errorf("Get action plan test: %v", err1)
- }
-
- if _, exist := apr.AccountIDs[account1.ID]; exist {
- t.Errorf("Account one is not deleted ")
- }
-
-}
-
-func TestActionTriggerMatchNil(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- var a *Action
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchAllBlank(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{}
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchMinuteBucketBlank(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ExtraParameters: `{"BalanceDirections":"*out"}`}
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchMinuteBucketFull(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`,
- utils.TriggerMaxBalance, 2)}
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchAllFull(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`,
- utils.TriggerMaxBalance, 2)}
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchSomeFalse(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%s"}`,
- utils.TriggerMaxBalanceCounter)}
- if at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatcBalanceFalse(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ExtraParameters: fmt.Sprintf(`{"GroupID":"%s", "ThresholdType":"%s"}`, "TEST", utils.TriggerMaxBalance)}
- if at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatcAllFalse(t *testing.T) {
- at := &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ExtraParameters: fmt.Sprintf(`{"UniqueID":"ZIP", "GroupID":"%s", "ThresholdType":"%s"}`, "TEST",
- utils.TriggerMaxBalance)}
- if at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggerMatchAll(t *testing.T) {
- at := &ActionTrigger{
- ID: "TEST",
- UniqueID: "ZIP",
- ThresholdType: "TT",
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- RatingSubject: utils.StringPointer("test1"),
- Value: &utils.ValueFormula{Static: 2},
- Weight: utils.Float64Pointer(1.0),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")),
- SharedGroups: utils.StringMapPointer(utils.NewStringMap("test2")),
- },
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- RatingSubject: utils.StringPointer("test1"),
- Value: &utils.ValueFormula{Static: 2},
- Weight: utils.Float64Pointer(1.0),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")),
- SharedGroups: utils.StringMapPointer(utils.NewStringMap("test2")),
- }, ExtraParameters: `{"UniqueID":"ZIP", "GroupID":"TEST", "ThresholdType":"TT"}`}
- if !at.Match(a) {
- t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
- }
-}
-
-func TestActionTriggers(t *testing.T) {
- at1 := &ActionTrigger{Weight: 30}
- at2 := &ActionTrigger{Weight: 20}
- at3 := &ActionTrigger{Weight: 10}
- var atpl ActionTriggers
- atpl = append(atpl, at2, at1, at3)
- atpl.Sort()
- if atpl[0] != at1 || atpl[2] != at3 || atpl[1] != at2 {
- t.Error("List not sorted: ", atpl)
- }
-}
-
-func TestActionResetTriggres(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 10},
- },
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")},
- },
- },
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {
- Counters: CounterFilters{
- &CounterFilter{Value: 1},
- },
- },
- },
- },
- ActionTriggers: ActionTriggers{
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true,
- },
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true,
- },
- },
- }
- resetTriggersAction(ub, nil, nil, nil)
- if ub.ActionTriggers[0].Executed == true || ub.ActionTriggers[1].Executed == true {
- t.Error("Reset triggers action failed!")
- }
-}
-
-func TestActionResetTriggresExecutesThem(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 10},
- },
- },
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}},
- },
- },
- ActionTriggers: ActionTriggers{
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true,
- },
- },
- }
- resetTriggersAction(ub, nil, nil, nil)
- if ub.ActionTriggers[0].Executed == true || ub.BalanceMap[utils.MetaMonetary][0].GetValue() == 12 {
- t.Error("Reset triggers action failed!")
- }
-}
-
-func TestActionResetTriggresActionFilter(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 10},
- },
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")},
- },
- },
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}},
- },
- },
- ActionTriggers: ActionTriggers{
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true},
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true}},
- }
- resetTriggersAction(ub, &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaSMS)}}, nil, nil)
- if ub.ActionTriggers[0].Executed == false || ub.ActionTriggers[1].Executed == false {
- t.Error("Reset triggers action failed!")
- }
-}
-
-func TestActionResetTriggresActionFilter2(t *testing.T) {
- ub := &Account{
- ID: "TestActionResetTriggresActionFilter2",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 10},
- },
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")},
- },
- },
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}},
- },
- },
- ActionTriggers: ActionTriggers{
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true},
- &ActionTrigger{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true}},
- }
- resetTriggersAction(ub, &Action{}, nil, nil)
- if ub.ActionTriggers[0].Executed != false && ub.ActionTriggers[1].Executed != false {
- t.Error("Reset triggers action failed!")
- }
-}
-
-func TestActionSetPostpaid(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- allowNegativeAction(ub, nil, nil, nil)
- if !ub.AllowNegative {
- t.Error("Set postpaid action failed!")
- }
-}
-
-func TestActionSetPrepaid(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- AllowNegative: true,
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- denyNegativeAction(ub, nil, nil, nil)
- if ub.AllowNegative {
- t.Error("Set prepaid action failed!")
- }
-}
-
-func TestActionResetPrepaid(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- AllowNegative: true,
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{{Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaSMS)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaSMS)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- resetAccountAction(ub, nil, nil, nil)
- if !ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 0 ||
- len(ub.UnitCounters) != 0 ||
- ub.BalanceMap[utils.MetaVoice][0].GetValue() != 0 ||
- ub.ActionTriggers[0].Executed == true || ub.ActionTriggers[1].Executed == true {
- t.Log(ub.BalanceMap)
- t.Error("Reset account action failed!")
- }
-}
-
-func TestActionResetPostpaid(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{{Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaSMS)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaSMS)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- resetAccountAction(ub, nil, nil, nil)
- if ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 0 ||
- len(ub.UnitCounters) != 0 ||
- ub.BalanceMap[utils.MetaVoice][0].GetValue() != 0 ||
- ub.ActionTriggers[0].Executed == true || ub.ActionTriggers[1].Executed == true {
- t.Error("Reset account action failed!")
- }
-}
-
-func TestActionTopupResetCredit(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}}
- topupResetAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 10 ||
- len(ub.UnitCounters) != 0 || // InitCounters finds no counters
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true || ub.ActionTriggers[1].Executed != true {
- t.Errorf("Topup reset action failed: %+s", utils.ToIJSON(ub))
- }
-}
-
-func TestActionTopupValueFactor(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{},
- }
- a := &Action{
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10},
- },
- ExtraParameters: `{"*monetary":2.0}`,
- }
- topupResetAction(ub, a, nil, nil)
- if len(ub.BalanceMap) != 1 ||
- ub.BalanceMap[utils.MetaMonetary][0].Factor[utils.MetaMonetary] != 2.0 {
- t.Errorf("Topup reset action failed to set Factor: %+v",
- ub.BalanceMap[utils.MetaMonetary][0].Factor)
- }
-}
-
-func TestActionTopupResetCreditId(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 100},
- &Balance{ID: "TEST_B", Value: 15},
- },
- },
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- ID: utils.StringPointer("TEST_B"),
- Value: &utils.ValueFormula{Static: 10}}}
- topupResetAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 110 ||
- len(ub.BalanceMap[utils.MetaMonetary]) != 2 {
- t.Errorf("Topup reset action failed: %+v",
- ub.BalanceMap[utils.MetaMonetary][0])
- }
-}
-
-func TestActionTopupResetCreditNoId(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 100},
- &Balance{ID: "TEST_B", Value: 15},
- },
- },
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}}
- topupResetAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 20 ||
- len(ub.BalanceMap[utils.MetaMonetary]) != 2 {
- t.Errorf("Topup reset action failed: %+v", ub.BalanceMap[utils.MetaMonetary][1])
- }
-}
-
-func TestActionTopupResetMinutes(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {&Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaVoice),
- Value: &utils.ValueFormula{Static: 5}, Weight: utils.Float64Pointer(20),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}
- topupResetAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaVoice].GetTotalValue() != 5 ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 0 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true ||
- ub.ActionTriggers[1].Executed != true {
- t.Errorf("Topup reset minutes action failed: %+v",
- ub.BalanceMap[utils.MetaVoice][0])
- }
-}
-
-func TestActionTopupCredit(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10,
- DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}}
- topupAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 110 ||
- len(ub.UnitCounters) != 0 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true ||
- ub.ActionTriggers[1].Executed != true {
- t.Error("Topup action failed!",
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionTopupMinutes(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 100}},
- utils.MetaVoice: {&Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaVoice),
- Value: &utils.ValueFormula{Static: 5}, Weight: utils.Float64Pointer(20),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}
- topupAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaVoice].GetTotalValue() != 15 ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 0 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true || ub.ActionTriggers[1].Executed != true {
- t.Error("Topup minutes action failed!", ub.BalanceMap[utils.MetaVoice])
- }
-}
-
-func TestActionDebitCredit(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}}
- debitAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 90 ||
- len(ub.UnitCounters) != 0 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true ||
- ub.ActionTriggers[1].Executed != true {
- t.Error("Debit action failed!", utils.ToIJSON(ub))
- }
-}
-
-func TestActionDebitMinutes(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{{Counters: CounterFilters{&CounterFilter{Value: 1}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true},
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaVoice),
- Value: &utils.ValueFormula{Static: 5},
- Weight: utils.Float64Pointer(20),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}
- debitAction(ub, a, nil, nil)
- if ub.AllowNegative ||
- ub.BalanceMap[utils.MetaVoice][0].GetValue() != 5 ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 0 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true || ub.ActionTriggers[1].Executed != true {
- t.Error("Debit minutes action failed!", ub.BalanceMap[utils.MetaVoice][0])
- }
-}
-
-func TestActionResetAllCounters(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- AllowNegative: true,
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {
- &Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{ThresholdType: utils.TriggerMaxEventCounter, ThresholdValue: 2,
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")),
- Weight: utils.Float64Pointer(20)},
- ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- ub.InitCounters()
- resetCountersAction(ub, nil, nil, nil)
- if !ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 1 ||
- len(ub.UnitCounters[utils.MetaMonetary][0].Counters) != 1 ||
- len(ub.BalanceMap[utils.MetaMonetary]) != 1 ||
- ub.ActionTriggers[0].Executed != true {
- t.Errorf("Reset counters action failed: %+v %+v %+v", ub.UnitCounters,
- ub.UnitCounters[utils.MetaMonetary][0], ub.UnitCounters[utils.MetaMonetary][0].Counters[0])
- }
- if len(ub.UnitCounters) < 1 {
- t.FailNow()
- }
- c := ub.UnitCounters[utils.MetaMonetary][0].Counters[0]
- if c.Filter.GetWeight() != 20 || c.Value != 0 ||
- c.Filter.GetDestinationIDs()["NAT"] == false {
- t.Errorf("Balance cloned incorrectly: %+v", c)
- }
-}
-
-func TestActionResetCounterOnlyDefault(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- AllowNegative: true,
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {&Balance{Value: 10, Weight: 20,
- DestinationIDs: utils.NewStringMap("NAT")}, &Balance{Weight: 10,
- DestinationIDs: utils.NewStringMap("RET")}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdType: utils.TriggerMaxEventCounter, ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)}}
- ub.InitCounters()
- resetCountersAction(ub, a, nil, nil)
- if !ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 1 ||
- len(ub.UnitCounters[utils.MetaMonetary][0].Counters) != 1 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true {
- for _, b := range ub.UnitCounters[utils.MetaMonetary][0].Counters {
- t.Logf("B: %+v", b)
- }
- t.Errorf("Reset counters action failed: %+v", ub.UnitCounters)
- }
- if len(ub.UnitCounters) < 1 || len(ub.UnitCounters[utils.MetaMonetary][0].Counters) < 1 {
- t.FailNow()
- }
- c := ub.UnitCounters[utils.MetaMonetary][0].Counters[0]
- if c.Filter.GetWeight() != 0 || c.Value != 0 || len(c.Filter.GetDestinationIDs()) != 0 {
- t.Errorf("Balance cloned incorrectly: %+v!", c)
- }
-}
-
-func TestActionResetCounterCredit(t *testing.T) {
- ub := &Account{
- ID: "TEST_UB",
- AllowNegative: true,
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 100}},
- utils.MetaVoice: {&Balance{Value: 10, Weight: 20, DestinationIDs: utils.NewStringMap("NAT")},
- &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {Counters: CounterFilters{
- &CounterFilter{Value: 1, Filter: new(BalanceFilter)}}}},
- utils.MetaSMS: []*UnitCounter{
- {Counters: CounterFilters{
- &CounterFilter{Value: 1, Filter: new(BalanceFilter)}}}}},
- ActionTriggers: ActionTriggers{
- &ActionTrigger{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)},
- ThresholdValue: 2, ActionsID: "TEST_ACTIONS", Executed: true}},
- }
- a := &Action{Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary)}}
- resetCountersAction(ub, a, nil, nil)
- if !ub.AllowNegative ||
- ub.BalanceMap[utils.MetaMonetary].GetTotalValue() != 100 ||
- len(ub.UnitCounters) != 2 ||
- len(ub.BalanceMap[utils.MetaVoice]) != 2 ||
- ub.ActionTriggers[0].Executed != true {
- t.Error("Reset counters action failed!", ub.UnitCounters)
- }
-}
-
-func TestActionMakeNegative(t *testing.T) {
- a := &Action{Balance: &BalanceFilter{Value: &utils.ValueFormula{Static: 10}}}
- genericMakeNegative(a)
- if a.Balance.GetValue() > 0 {
- t.Error("Failed to make negative: ", a)
- }
- genericMakeNegative(a)
- if a.Balance.GetValue() > 0 {
- t.Error("Failed to preserve negative: ", a)
- }
-}
-
-func TestActionRemove(t *testing.T) {
- if _, err := dm.GetAccount("cgrates.org:remo"); err != nil {
- t.Errorf("account to be removed not found: %v", err)
- }
- a := &Action{
- ActionType: utils.MetaRemoveAccount,
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:remo": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
- afterUb, err := dm.GetAccount("cgrates.org:remo")
- if err == nil || afterUb != nil {
- t.Error("error removing account: ", err, afterUb)
- }
-}
-
-func TestActionTopup(t *testing.T) {
- initialUb, _ := dm.GetAccount("vdf:minu")
- a := &Action{
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary), Value: &utils.ValueFormula{Static: 25},
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("RET")),
- Weight: utils.Float64Pointer(20)},
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"vdf:minu": true},
- actions: Actions{a},
- }
-
- at.Execute(nil, nil)
- afterUb, _ := dm.GetAccount("vdf:minu")
- initialValue := initialUb.BalanceMap[utils.MetaMonetary].GetTotalValue()
- afterValue := afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue()
- if afterValue != initialValue+25 {
- t.Error("Bad topup before and after: ", initialValue, afterValue)
- }
-}
-
-func TestActionTopupLoaded(t *testing.T) {
- initialUb, _ := dm.GetAccount("vdf:minitsboy")
- a := &Action{
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 25},
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("RET")),
- Weight: utils.Float64Pointer(20)},
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"vdf:minitsboy": true},
- actions: Actions{a},
- }
-
- at.Execute(nil, nil)
- afterUb, _ := dm.GetAccount("vdf:minitsboy")
- initialValue := initialUb.BalanceMap[utils.MetaMonetary].GetTotalValue()
- afterValue := afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue()
- if afterValue != initialValue+25 {
- t.Logf("Initial: %+v", initialUb)
- t.Logf("After: %+v", afterUb)
- t.Error("Bad topup before and after: ", initialValue, afterValue)
- }
-}
-
-func TestActionTransactionFuncType(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:trans",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{
- Value: 10,
- }},
- },
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:trans": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Value: &utils.ValueFormula{Static: 1.1},
- Type: utils.StringPointer(utils.MetaMonetary)},
- },
- {
- ActionType: "VALID_FUNCTION_TYPE",
- Balance: &BalanceFilter{Value: &utils.ValueFormula{Static: 1.1},
- Type: utils.StringPointer("test")},
- },
- },
- }
- err = at.Execute(nil, nil)
- acc, err := dm.GetAccount("cgrates.org:trans")
- if err != nil || acc == nil {
- t.Error("Error getting account: ", acc, err)
- }
- if acc.BalanceMap[utils.MetaMonetary][0].Value != 10 {
- t.Errorf("Transaction didn't work: %v", acc.BalanceMap[utils.MetaMonetary][0].Value)
- }
-}
-
-func TestActionTransactionBalanceType(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:trans",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{
- Value: 10,
- }},
- },
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:trans": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Value: &utils.ValueFormula{Static: 1.1},
- Type: utils.StringPointer(utils.MetaMonetary)},
- },
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Type: utils.StringPointer("test")},
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:trans")
- if err != nil || acc == nil {
- t.Error("Error getting account: ", acc, err)
- }
- if acc.BalanceMap[utils.MetaMonetary][0].Value != 11.1 {
- t.Errorf("Transaction didn't work: %v", acc.BalanceMap[utils.MetaMonetary][0].Value)
- }
-}
-
-func TestActionTransactionBalanceNotType(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:trans",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{
- Value: 10,
- }},
- },
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:trans": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Value: &utils.ValueFormula{Static: 1.1},
- Type: utils.StringPointer(utils.MetaVoice)},
- },
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{Type: utils.StringPointer("test")},
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:trans")
- if err != nil || acc == nil {
- t.Error("Error getting account: ", acc, err)
- }
- if acc.BalanceMap[utils.MetaMonetary][0].Value != 10.0 {
- t.Errorf("Transaction didn't work: %v", acc.BalanceMap[utils.MetaMonetary][0].Value)
- }
-}
-
-func TestActionWithExpireWithoutExpire(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:exp",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{
- Value: 10,
- }},
- },
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:exp": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaVoice),
- Value: &utils.ValueFormula{Static: 15},
- },
- },
- {
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaVoice),
- Value: &utils.ValueFormula{Static: 30},
- ExpirationDate: utils.TimePointer(time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC)),
- },
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:exp")
- if err != nil || acc == nil {
- t.Errorf("Error getting account: %+v: %v", acc, err)
- }
- if len(acc.BalanceMap) != 2 ||
- len(acc.BalanceMap[utils.MetaVoice]) != 2 {
- t.Errorf("Error debiting expir and unexpire: %+v", acc.BalanceMap[utils.MetaVoice][0])
- }
-}
-
-func TestActionRemoveBalance(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:rembal",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Value: 10,
- },
- &Balance{
- Value: 10,
- DestinationIDs: utils.NewStringMap("NAT", "RET"),
- ExpirationDate: time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC),
- },
- &Balance{
- Value: 10,
- DestinationIDs: utils.NewStringMap("NAT", "RET"),
- },
- },
- },
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:rembal": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaRemoveBalance,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT", "RET")),
- },
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:rembal")
- if err != nil || acc == nil {
- t.Errorf("Error getting account: %+v: %v", acc, err)
- }
- if len(acc.BalanceMap) != 1 ||
- len(acc.BalanceMap[utils.MetaMonetary]) != 1 {
- t.Errorf("Error removing balance: %+v", acc.BalanceMap[utils.MetaMonetary])
- }
-}
-
-func TestActionRemoveExpiredBalance(t *testing.T) {
- err := dm.SetAccount(&Account{
- ID: "cgrates.org:rembal2",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Value: 10,
- },
- &Balance{
- Value: 10,
- DestinationIDs: utils.NewStringMap("NAT", "RET"),
- ExpirationDate: time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC),
- },
- &Balance{
- Value: 10,
- DestinationIDs: utils.NewStringMap("NAT", "RET"),
- ExpirationDate: time.Date(2010, time.November, 11, 22, 39, 0, 0, time.UTC),
- },
- &Balance{
- Value: 10,
- DestinationIDs: utils.NewStringMap("NAT", "RET"),
- ExpirationDate: time.Date(2012, time.November, 11, 22, 39, 0, 0, time.UTC),
- },
- },
- },
- Disabled: true,
- })
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:rembal2": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- ActionType: utils.MetaRemoveExpired,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:rembal2")
- if err != nil || acc == nil {
- t.Errorf("Error getting account: %+v: %v", acc, err)
- }
- if len(acc.BalanceMap) != 1 ||
- len(acc.BalanceMap[utils.MetaMonetary]) != 2 {
- t.Errorf("Error removing balance: %+v", utils.ToJSON(acc.BalanceMap[utils.MetaMonetary]))
- }
-}
-
-func TestActionTransferMonetaryDefault(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:trans",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Uuid: utils.GenUUID(),
- ID: utils.MetaDefault,
- Value: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 3,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 6,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: -2,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaTransferMonetaryDefault,
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:trans": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:trans")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue() != 17 ||
- afterUb.BalanceMap[utils.MetaMonetary][0].Value != 19 ||
- afterUb.BalanceMap[utils.MetaMonetary][1].Value != 0 ||
- afterUb.BalanceMap[utils.MetaMonetary][2].Value != 0 ||
- afterUb.BalanceMap[utils.MetaMonetary][3].Value != -2 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionTransferMonetaryDefaultFilter(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:trans",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Uuid: utils.GenUUID(),
- ID: utils.MetaDefault,
- Value: 10,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 3,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 1,
- Weight: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 6,
- Weight: 20,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaTransferMonetaryDefault,
- Balance: &BalanceFilter{Weight: utils.Float64Pointer(20)},
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:trans": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:trans")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue() != 20 ||
- afterUb.BalanceMap[utils.MetaMonetary][0].Value != 19 ||
- afterUb.BalanceMap[utils.MetaMonetary][1].Value != 0 ||
- afterUb.BalanceMap[utils.MetaMonetary][2].Value != 1 ||
- afterUb.BalanceMap[utils.MetaMonetary][3].Value != 0 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionConditionalTopup(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:cond",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Uuid: utils.GenUUID(),
- ID: utils.MetaDefault,
- Value: 10,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 3,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 1,
- Weight: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 6,
- Weight: 20,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaTopUp,
- Filter: `{"Type":"*monetary","Value":1,"Weight":10}`,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 11},
- Weight: utils.Float64Pointer(30),
- },
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:cond": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:cond")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if len(afterUb.BalanceMap[utils.MetaMonetary]) != 5 ||
- afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue() != 31 ||
- afterUb.BalanceMap[utils.MetaMonetary][4].Value != 11 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionConditionalTopupNoMatch(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:cond",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Uuid: utils.GenUUID(),
- ID: utils.MetaDefault,
- Value: 10,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 3,
- Weight: 20,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 1,
- Weight: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 6,
- Weight: 20,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaTopUp,
- Filter: `{"Type":"*monetary","Value":2,"Weight":10}`,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 11},
- Weight: utils.Float64Pointer(30),
- },
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:cond": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:cond")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if len(afterUb.BalanceMap[utils.MetaMonetary]) != 4 ||
- afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue() != 20 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionConditionalTopupExistingBalance(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:cond",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 1,
- Weight: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 6,
- Weight: 20,
- },
- },
- utils.MetaVoice: {
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 10,
- Weight: 10,
- },
- &Balance{
- Uuid: utils.GenUUID(),
- Value: 100,
- Weight: 20,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaTopUp,
- Filter: `{"Type":"*voice","Value":{"*gte":100}}`,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 11},
- Weight: utils.Float64Pointer(10),
- },
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:cond": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:cond")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if len(afterUb.BalanceMap[utils.MetaMonetary]) != 2 ||
- afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue() != 18 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue())
- }
-}
-
-func TestActionConditionalDisabledIfNegative(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:af",
- BalanceMap: map[string]Balances{
- "*data": {
- &Balance{
- Uuid: "fc927edb-1bd6-425e-a2a3-9fd8bafaa524",
- ID: "for_v3hsillmilld500m_data_500_m",
- Value: 5.242,
- Weight: 10,
- RatingSubject: "for_v3hsillmilld500m_data_forfait",
- Categories: utils.StringMap{
- "data_france": true,
- },
- },
- },
- "*monetary": {
- &Balance{
- Uuid: "9fa1847a-f36a-41a7-8ec0-dfaab370141e",
- ID: utils.MetaDefault,
- Value: -1.95001,
- },
- },
- "*sms": {
- &Balance{
- Uuid: "d348d15d-2988-4ee4-b847-6a552f94e2ec",
- ID: "for_v3hsillmilld500m_mms_ill",
- Value: 20000,
- Weight: 10,
- DestinationIDs: utils.StringMap{
- "FRANCE_NATIONAL": true,
- },
- Categories: utils.StringMap{
- "mms_france": true,
- "tmms_france": true,
- "vmms_france": true,
- },
- },
- &Balance{
- Uuid: "f4643517-31f6-4199-980f-04cf535471ed",
- ID: "for_v3hsillmilld500m_sms_ill",
- Value: 20000,
- Weight: 10,
- DestinationIDs: utils.StringMap{
- "FRANCE_NATIONAL": true,
- },
- Categories: utils.StringMap{
- "ms_france": true,
- },
- },
- },
- "*voice": {
- &Balance{
- Uuid: "079ab190-77f4-44f3-9c6f-3a0dd1a59dfd",
- ID: "for_v3hsillmilld500m_voice_3_h",
- Value: 10800,
- Weight: 10,
- DestinationIDs: utils.StringMap{
- "FRANCE_NATIONAL": true,
- },
- Categories: utils.StringMap{
- "call_france": true,
- },
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a1 := &Action{
- ActionType: utils.MetaSetBalance,
- Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"ID\":{\"*eq\":\"*default\"}}]}",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("*sms"),
- ID: utils.StringPointer("for_v3hsillmilld500m_sms_ill"),
- Disabled: utils.BoolPointer(true),
- },
- Weight: 9,
- }
- a2 := &Action{
- ActionType: utils.MetaSetBalance,
- Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"ID\":{\"*eq\":\"*default\"}}]}",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("*sms"),
- ID: utils.StringPointer("for_v3hsillmilld500m_mms_ill"),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("FRANCE_NATIONAL")),
- Weight: utils.Float64Pointer(10),
- Disabled: utils.BoolPointer(true),
- },
- Weight: 8,
- }
- a3 := &Action{
- ActionType: utils.MetaSetBalance,
- Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"ID\":{\"*eq\":\"*default\"}}]}",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("*sms"),
- ID: utils.StringPointer("for_v3hsillmilld500m_sms_ill"),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("FRANCE_NATIONAL")),
- Weight: utils.Float64Pointer(10),
- Disabled: utils.BoolPointer(true),
- },
- Weight: 8,
- }
- a4 := &Action{
- ActionType: utils.MetaSetBalance,
- Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"ID\":{\"*eq\":\"*default\"}}]}",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("*data"),
- Uuid: utils.StringPointer("fc927edb-1bd6-425e-a2a3-9fd8bafaa524"),
- RatingSubject: utils.StringPointer("for_v3hsillmilld500m_data_forfait"),
- Weight: utils.Float64Pointer(10),
- Disabled: utils.BoolPointer(true),
- },
- Weight: 7,
- }
- a5 := &Action{
- ActionType: utils.MetaSetBalance,
- Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"ID\":{\"*eq\":\"*default\"}}]}",
- Balance: &BalanceFilter{
- Type: utils.StringPointer("*voice"),
- ID: utils.StringPointer("for_v3hsillmilld500m_voice_3_h"),
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("FRANCE_NATIONAL")),
- Weight: utils.Float64Pointer(10),
- Disabled: utils.BoolPointer(true),
- },
- Weight: 6,
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:af": true},
- actions: Actions{a1, a2, a3, a4, a5},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:af")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
-
- for btype, chain := range afterUb.BalanceMap {
- if btype != utils.MetaMonetary {
- for _, b := range chain {
- if b.Disabled != true {
- t.Errorf("Failed to disabled balance (%s): %+v", btype, b)
- }
- }
- }
- }
-}
-
-func TestActionSetBalance(t *testing.T) {
- err := dm.SetAccount(
- &Account{
- ID: "cgrates.org:setb",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- ID: "m1",
- Uuid: utils.GenUUID(),
- Value: 1,
- Weight: 10,
- },
- &Balance{
- ID: "m2",
- Uuid: utils.GenUUID(),
- Value: 6,
- Weight: 20,
- },
- },
- utils.MetaVoice: {
- &Balance{
- ID: "v1",
- Uuid: utils.GenUUID(),
- Value: 10,
- Weight: 10,
- },
- &Balance{
- ID: "v2",
- Uuid: utils.GenUUID(),
- Value: 100,
- Weight: 20,
- },
- },
- },
- })
- if err != nil {
- t.Errorf("error setting account: %v", err)
- }
-
- a := &Action{
- ActionType: utils.MetaSetBalance,
- Balance: &BalanceFilter{
- ID: utils.StringPointer("m2"),
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 11},
- Weight: utils.Float64Pointer(10),
- },
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:setb": true},
- actions: Actions{a},
- }
- at.Execute(nil, nil)
-
- afterUb, err := dm.GetAccount("cgrates.org:setb")
- if err != nil {
- t.Error("account not found: ", err, afterUb)
- }
- if len(afterUb.BalanceMap[utils.MetaMonetary]) != 2 ||
- afterUb.BalanceMap[utils.MetaMonetary][1].Value != 11 ||
- afterUb.BalanceMap[utils.MetaMonetary][1].Weight != 10 {
- for _, b := range afterUb.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Errorf("Balance: %+v", afterUb.BalanceMap[utils.MetaMonetary][1])
- }
-}
-
-func TestActionCSVFilter(t *testing.T) {
- act, err := dm.GetActions("FILTER", false, utils.NonTransactional)
- if err != nil {
- t.Error("error getting actions: ", err)
- }
- if len(act) != 1 || act[0].Filter != `{"*and":[{"Value":{"*lt":0}},{"Id":{"*eq":"*default"}}]}` {
- t.Error("Error loading actions: ", act[0].Filter)
- }
-}
-
-func TestActionExpirationTime(t *testing.T) {
- a, err := dm.GetActions("EXP", false, utils.NonTransactional)
- if err != nil || a == nil {
- t.Error("Error getting actions: ", err)
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:expo": true},
- actions: a,
- }
- for rep := 0; rep < 5; rep++ {
- at.Execute(nil, nil)
- afterUb, err := dm.GetAccount("cgrates.org:expo")
- if err != nil ||
- len(afterUb.BalanceMap[utils.MetaVoice]) != rep+1 {
- t.Error("error topuping expiration balance: ", utils.ToIJSON(afterUb))
- }
- }
-}
-
-func TestActionExpNoExp(t *testing.T) {
- exp, err := dm.GetActions("EXP", false, utils.NonTransactional)
- if err != nil || exp == nil {
- t.Error("Error getting actions: ", err)
- }
- noexp, err := dm.GetActions("NOEXP", false, utils.NonTransactional)
- if err != nil || noexp == nil {
- t.Error("Error getting actions: ", err)
- }
- exp = append(exp, noexp...)
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:expnoexp": true},
- actions: exp,
- }
- at.Execute(nil, nil)
- afterUb, err := dm.GetAccount("cgrates.org:expnoexp")
- if err != nil ||
- len(afterUb.BalanceMap[utils.MetaVoice]) != 2 {
- t.Error("error topuping expiration balance: ", utils.ToIJSON(afterUb))
- }
-}
-
-func TestActionTopUpZeroNegative(t *testing.T) {
- account := &Account{
- ID: "cgrates.org:zeroNegative",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- ID: "Bal1",
- Value: -10,
- },
- &Balance{
- ID: "Bal2",
- Value: 5,
- },
- },
- },
- }
- err := dm.SetAccount(account)
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:zeroNegative": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- Id: "ZeroMonetary",
- ActionType: utils.TopUpZeroNegative,
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:zeroNegative")
- if err != nil || acc == nil {
- t.Error("Error getting account: ", acc, err)
- }
- //Verify value for first balance(Bal1) should be 0 after execute action TopUpZeroNegative
- if acc.BalanceMap[utils.MetaMonetary][0].Value != 0 {
- t.Errorf("Expecting 0, received: %+v", acc.BalanceMap[utils.MetaMonetary][0].Value)
- }
- //Verify value for secound balance(Bal2) should be the same
- if acc.BalanceMap[utils.MetaMonetary][1].Value != 5 {
- t.Errorf("Expecting 5, received: %+v", acc.BalanceMap[utils.MetaMonetary][1].Value)
- }
-}
-
-func TestActionSetExpiry(t *testing.T) {
- timeNowPlus24h := time.Now().Add(24 * time.Hour)
- account := &Account{
- ID: "cgrates.org:zeroNegative",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{
- ID: "Bal1",
- Value: -10,
- },
- &Balance{
- ID: "Bal2",
- Value: 5,
- },
- },
- },
- }
- err := dm.SetAccount(account)
- if err != nil {
- t.Error("Error setting account: ", err)
- }
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:zeroNegative": true},
- Timing: &RateInterval{},
- actions: []*Action{
- {
- Id: "SetExpiry",
- ActionType: utils.SetExpiry,
- Balance: &BalanceFilter{
- ID: utils.StringPointer("Bal1"),
- Type: utils.StringPointer(utils.MetaMonetary),
- ExpirationDate: utils.TimePointer(timeNowPlus24h),
- },
- },
- },
- }
- err = at.Execute(nil, nil)
- if err != nil {
- t.Error(err)
- }
- acc, err := dm.GetAccount("cgrates.org:zeroNegative")
- if err != nil || acc == nil {
- t.Error("Error getting account: ", acc, err)
- }
- //Verify ExpirationDate for first balance(Bal1)
- if !acc.BalanceMap[utils.MetaMonetary][0].ExpirationDate.Equal(timeNowPlus24h) {
- t.Errorf("Expecting: %+v, received: %+v", timeNowPlus24h, acc.BalanceMap[utils.MetaMonetary][0].ExpirationDate)
- }
-}
-
-type TestRPCParameters struct {
- status string
-}
-
-type Attr struct {
- Name string
- Surname string
- Age float64
-}
-
-func (trpcp *TestRPCParameters) Hopa(in Attr, out *float64) error {
- trpcp.status = utils.OK
- return nil
-}
-
-func (trpcp *TestRPCParameters) Call(serviceMethod string, args interface{}, reply interface{}) error {
- parts := strings.Split(serviceMethod, ".")
- if len(parts) != 2 {
- return utils.ErrNotImplemented
- }
- // get method
- method := reflect.ValueOf(trpcp).MethodByName(parts[1])
- if !method.IsValid() {
- return utils.ErrNotImplemented
- }
-
- // construct the params
- params := []reflect.Value{reflect.ValueOf(args).Elem(), reflect.ValueOf(reply)}
-
- ret := method.Call(params)
- if len(ret) != 1 {
- return utils.ErrServerError
- }
- if ret[0].Interface() == nil {
- return nil
- }
- err, ok := ret[0].Interface().(error)
- if !ok {
- return utils.ErrServerError
- }
- return err
-}
-
-func TestCgrRpcAction(t *testing.T) {
- trpcp := &TestRPCParameters{}
- utils.RegisterRpcParams("", trpcp)
- a := &Action{
- ExtraParameters: `{"Address": "*internal",
- "Transport": "*gob",
- "Method": "TestRPCParameters.Hopa",
- "Attempts":1,
- "Async" :false,
- "Params": {"Name":"n", "Surname":"s", "Age":10.2}}`,
- }
- if err := cgrRPCAction(nil, a, nil, nil); err != nil {
- t.Error("error executing cgr action: ", err)
- }
- if trpcp.status != utils.OK {
- t.Error("RPC not called!")
- }
-}
-
-func TestValueFormulaDebit(t *testing.T) {
- if _, err := dm.GetAccount("cgrates.org:vf"); err != nil {
- t.Errorf("account to be removed not found: %v", err)
- }
-
- at := &ActionTiming{
- accountIDs: utils.StringMap{"cgrates.org:vf": true},
- ActionsID: "VF",
- }
- at.Execute(nil, nil)
- afterUb, err := dm.GetAccount("cgrates.org:vf")
- // not an exact value, depends of month
- v := afterUb.BalanceMap[utils.MetaMonetary].GetTotalValue()
- if err != nil || v > -0.30 || v < -0.36 {
- t.Error("error debiting account: ", err, utils.ToIJSON(afterUb), v)
- }
-}
-
-func TestClonedAction(t *testing.T) {
- a := &Action{
- Id: "test1",
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{
- ID: utils.StringPointer(utils.MetaDefault),
- Value: &utils.ValueFormula{Static: 1},
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- Weight: float64(10),
- }
- if clone := a.Clone(); !reflect.DeepEqual(a, clone) {
- t.Error("error cloning action: ", utils.ToIJSON(clone))
- }
-}
-
-func TestClonedActions(t *testing.T) {
- actions := Actions{
- &Action{
- Id: "RECUR_FOR_V3HSILLMILLD1G",
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{
- ID: utils.StringPointer(utils.MetaDefault),
- Value: &utils.ValueFormula{Static: 1},
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- Weight: float64(30),
- },
- &Action{
- Id: "RECUR_FOR_V3HSILLMILLD5G",
- ActionType: utils.MetaDebit,
- Balance: &BalanceFilter{
- ID: utils.StringPointer(utils.MetaDefault),
- Value: &utils.ValueFormula{Static: 2},
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- Weight: float64(20),
- },
- }
- if clone, err := actions.Clone(); err != nil {
- t.Error("error cloning actions: ", err)
- } else if !reflect.DeepEqual(actions, clone) {
- t.Errorf("Expecting %+v, received: %+v", utils.ToIJSON(actions), utils.ToIJSON(clone))
- }
-
-}
-
-func TestCacheGetClonedActions(t *testing.T) {
- actions := Actions{
- &Action{
- Id: "RECUR_FOR_V3HSILLMILLD1G",
- ActionType: utils.MetaTopUp,
- Balance: &BalanceFilter{
- ID: utils.StringPointer(utils.MetaDefault),
- Value: &utils.ValueFormula{Static: 1},
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- Weight: float64(30),
- },
- &Action{
- Id: "REACT_FOR_V3HSILLMILL",
- ActionType: utils.MetaSetBalance,
- Balance: &BalanceFilter{
- ID: utils.StringPointer("for_v3hsillmill_sms_ill"),
- Type: utils.StringPointer(utils.MetaSMS),
- Value: &utils.ValueFormula{Static: 20000},
- DestinationIDs: &utils.StringMap{
- "FRANCE_NATIONAL": true,
- "FRANCE_NATIONAL_FREE": false,
- "ZONE1": false},
- Categories: &utils.StringMap{
- "sms_eurotarif": true,
- "sms_france": true},
- Disabled: utils.BoolPointer(false),
- Blocker: utils.BoolPointer(false),
- },
- Weight: float64(10),
- },
- }
- if err := Cache.Set(utils.CacheActions, "MYTEST", actions, nil, true, ""); err != nil {
- t.Errorf("Expecting: nil, received: %s", err)
- }
- clned, err := Cache.GetCloned(utils.CacheActions, "MYTEST")
- if err != nil {
- t.Error(err)
- }
- aCloned := clned.(Actions)
- if !reflect.DeepEqual(actions, aCloned) {
- t.Errorf("Expecting: %+v, received: %+v", actions[1].Balance, aCloned[1].Balance)
- }
-}
-
-// TestCdrLogAction
-type RPCMock struct {
- args *ArgV1ProcessEvent
-}
-
-func (r *RPCMock) Call(method string, args interface{}, rply interface{}) error {
- if method != utils.CDRsV1ProcessEvent {
- return rpcclient.ErrUnsupporteServiceMethod
- }
- if r.args != nil {
- return fmt.Errorf("There should be only one call to this function")
- }
- r.args = args.(*ArgV1ProcessEvent)
- rp := rply.(*string)
- *rp = utils.OK
- return nil
-}
-
-func TestCdrLogAction(t *testing.T) {
- mock := RPCMock{}
-
- dfltCfg := config.NewDefaultCGRConfig()
- if err != nil {
- t.Fatal(err)
- }
- dfltCfg.SchedulerCfg().CDRsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)}
- config.SetCgrConfig(dfltCfg)
-
- internalChan := make(chan rpcclient.ClientConnector, 1)
- internalChan <- &mock
-
- NewConnManager(dfltCfg, map[string]chan rpcclient.ClientConnector{
- utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs): internalChan,
- })
-
- var extraData interface{}
- acc := &Account{
- ID: "cgrates.org:1001",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 20},
- },
- },
- UnitCounters: UnitCounters{
- utils.MetaMonetary: []*UnitCounter{
- {
- Counters: CounterFilters{
- &CounterFilter{Value: 1},
- },
- },
- },
- },
- }
- a := &Action{
- Id: "CDRLog1",
- ActionType: utils.CDRLog,
- ExtraParameters: "{\"BalanceID\":\"~*acnt.BalanceID\",\"ActionID\":\"~*act.ActionID\",\"BalanceValue\":\"~*acnt.BalanceValue\"}",
- Weight: 50,
- }
- acs := Actions{
- a,
- &Action{
- Id: "CdrDebit",
- ActionType: "*debit",
- Balance: &BalanceFilter{
- ID: utils.StringPointer(utils.MetaDefault),
- Value: &utils.ValueFormula{Static: 9.95},
- Type: utils.StringPointer(utils.MetaMonetary),
- Weight: utils.Float64Pointer(0),
- },
- Weight: float64(90),
- balanceValue: 10,
- },
- }
- if err := cdrLogAction(acc, a, acs, extraData); err != nil {
- t.Fatal(err)
- }
- if mock.args == nil {
- t.Fatalf("Expected a call to %s", utils.CDRsV1ProcessEvent)
- }
- expCgrEv := utils.CGREvent{
- Tenant: "cgrates.org",
- ID: mock.args.CGREvent.ID,
- Event: map[string]interface{}{
- "Account": "1001",
- "ActionID": "CdrDebit",
- "AnswerTime": mock.args.CGREvent.Event["AnswerTime"],
- "BalanceID": "*default",
- "BalanceValue": "10",
- "CGRID": mock.args.CGREvent.Event["CGRID"],
- "Category": "",
- "Cost": 9.95,
- "CostSource": "",
- "Destination": "",
- "ExtraInfo": "",
- "OrderID": mock.args.CGREvent.Event["OrderID"],
- "OriginHost": "127.0.0.1",
- "OriginID": mock.args.CGREvent.Event["OriginID"],
- "Partial": false,
- "PreRated": true,
- "RequestType": "*none",
- "RunID": "*debit",
- "SetupTime": mock.args.CGREvent.Event["SetupTime"],
- "Source": utils.CDRLog,
- "Subject": "1001",
- "Tenant": "cgrates.org",
- "ToR": "*monetary",
- "Usage": mock.args.CGREvent.Event["Usage"],
- },
- APIOpts: map[string]interface{}{},
- }
- if !reflect.DeepEqual(expCgrEv, mock.args.CGREvent) {
- t.Errorf("Expected: %+v \n,received: %+v", expCgrEv, mock.args.CGREvent)
- }
-}
-
-func TestRemoteSetAccountAction(t *testing.T) {
- expError := `Post "127.1.0.11//": unsupported protocol scheme ""`
- if err = remoteSetAccount(nil, &Action{ExtraParameters: "127.1.0.11//"}, nil, nil); err == nil ||
- err.Error() != expError {
- t.Fatalf("Expected error: %s, received: %v", expError, err)
- }
- expError = `json: unsupported type: func()`
- if err = remoteSetAccount(&Account{
- ActionTriggers: ActionTriggers{{
- Balance: &BalanceFilter{
- Value: &utils.ValueFormula{
- Params: map[string]interface{}{utils.MetaVoice: func() {}},
- },
- },
- }},
- }, &Action{ExtraParameters: "127.1.0.11//"}, nil, nil); err == nil ||
- err.Error() != expError {
- t.Fatalf("Expected error: %s, received: %v", expError, err)
- }
-
- ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { rw.Write([]byte("5")) }))
- acc := &Account{ID: "1001"}
- expError = `json: cannot unmarshal number into Go value of type engine.Account`
- if err = remoteSetAccount(acc, &Action{ExtraParameters: ts.URL}, nil, nil); err == nil ||
- err.Error() != expError {
- t.Fatalf("Expected error: %s, received: %v", expError, err)
- }
- exp := &Account{ID: "1001"}
- if !reflect.DeepEqual(exp, acc) {
- t.Errorf("Expected: %s,received: %s", utils.ToJSON(exp), utils.ToJSON(acc))
- }
- ts.Close()
-
- acc = &Account{ID: "1001"}
- exp = &Account{
- ID: "1001",
- BalanceMap: map[string]Balances{
- utils.MetaVoice: {{
- ID: "money",
- Value: 15,
- }},
- },
- }
- ts = httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- accStr := utils.ToJSON(acc) + "\n"
- val, err := io.ReadAll(r.Body)
- r.Body.Close()
- if err != nil {
- t.Error(err)
- return
- }
- if string(val) != accStr {
- t.Errorf("Expected %q,received: %q", accStr, string(val))
- return
- }
- rw.Write([]byte(utils.ToJSON(exp)))
- }))
- if err = remoteSetAccount(acc, &Action{ExtraParameters: ts.URL}, nil, nil); err != nil {
- t.Fatal(err)
- } else if !reflect.DeepEqual(exp, acc) {
- t.Errorf("Expected: %s,received: %s", utils.ToJSON(exp), utils.ToJSON(acc))
- }
- ts.Close()
-}
-
-/**************** Benchmarks ********************************/
-
-func BenchmarkUUID(b *testing.B) {
- m := make(map[string]int, 1000)
- for i := 0; i < b.N; i++ {
- uuid := utils.GenUUID()
- if len(uuid) == 0 {
- b.Fatalf("GenUUID error %s", uuid)
- }
- b.StopTimer()
- c := m[uuid]
- if c > 0 {
- b.Fatalf("duplicate uuid[%s] count %d", uuid, c)
- }
- m[uuid] = c + 1
- b.StartTimer()
- }
-}
diff --git a/engine/balance_filter.go b/engine/balance_filter.go
index de2ccbec7..409d4a642 100644
--- a/engine/balance_filter.go
+++ b/engine/balance_filter.go
@@ -38,7 +38,6 @@ type BalanceFilter struct {
Categories *utils.StringMap
SharedGroups *utils.StringMap
TimingIDs *utils.StringMap
- Timings []*RITiming
Disabled *bool
Factor *ValueFactor
Blocker *bool
@@ -120,7 +119,6 @@ func (bp *BalanceFilter) CreateBalance() *Balance {
RatingSubject: bp.GetRatingSubject(),
Categories: bp.GetCategories(),
SharedGroups: bp.GetSharedGroups(),
- Timings: bp.Timings,
TimingIDs: bp.GetTimingIDs(),
Disabled: bp.GetDisabled(),
Factor: bp.GetFactor(),
@@ -174,12 +172,6 @@ func (bf *BalanceFilter) Clone() *BalanceFilter {
if bf.TimingIDs != nil {
result.TimingIDs = utils.StringMapPointer(bf.TimingIDs.Clone())
}
- if bf.Timings != nil {
- result.Timings = make([]*RITiming, len(bf.Timings))
- for i, rit := range bf.Timings {
- result.Timings[i] = rit.Clone()
- }
- }
if bf.Disabled != nil {
result.Disabled = new(bool)
*result.Disabled = *bf.Disabled
@@ -226,12 +218,6 @@ func (bf *BalanceFilter) LoadFromBalance(b *Balance) *BalanceFilter {
if !b.TimingIDs.IsEmpty() {
bf.TimingIDs = &b.TimingIDs
}
- if len(b.Timings) != 0 {
- bf.Timings = make([]*RITiming, len(b.Timings))
- for i, timing := range b.Timings {
- bf.Timings[i] = timing
- }
- }
if len(b.Factor) != 0 {
bf.Factor = &b.Factor
}
@@ -241,7 +227,6 @@ func (bf *BalanceFilter) LoadFromBalance(b *Balance) *BalanceFilter {
if b.Blocker {
bf.Blocker = &b.Blocker
}
- bf.Timings = b.Timings
return bf
}
@@ -400,12 +385,6 @@ func (bf *BalanceFilter) ModifyBalance(b *Balance) {
if bf.TimingIDs != nil {
b.TimingIDs = *bf.TimingIDs
}
- if bf.Timings != nil && len(bf.Timings) != 0 {
- b.Timings = make([]*RITiming, len(bf.Timings))
- for i, timing := range bf.Timings {
- b.Timings[i] = timing
- }
- }
if bf.Weight != nil {
b.Weight = *bf.Weight
}
diff --git a/engine/balances.go b/engine/balances.go
index dbdf7e1d8..386cd21c7 100644
--- a/engine/balances.go
+++ b/engine/balances.go
@@ -19,13 +19,10 @@ along with this program. If not, see
package engine
import (
- "errors"
"fmt"
"sort"
- "strings"
"time"
- "github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
@@ -40,7 +37,6 @@ type Balance struct {
RatingSubject string
Categories utils.StringMap
SharedGroups utils.StringMap
- Timings []*RITiming
TimingIDs utils.StringMap
Disabled bool
Factor ValueFactor
@@ -124,25 +120,6 @@ func (b *Balance) IsExpiredAt(t time.Time) bool {
return !b.ExpirationDate.IsZero() && b.ExpirationDate.Before(t)
}
-func (b *Balance) IsActive() bool {
- return b.IsActiveAt(time.Now())
-}
-
-func (b *Balance) IsActiveAt(t time.Time) bool {
- if b.Disabled {
- return false
- }
- if len(b.Timings) == 0 {
- return true
- }
- for _, tim := range b.Timings {
- if tim.IsActiveAt(t) {
- return true
- }
- }
- return false
-}
-
func (b *Balance) MatchCategory(category string) bool {
return len(b.Categories) == 0 || b.Categories[category]
}
@@ -169,7 +146,6 @@ func (b *Balance) Clone() *Balance {
Categories: b.Categories,
SharedGroups: b.SharedGroups,
TimingIDs: b.TimingIDs,
- Timings: b.Timings, // should not be a problem with aliasing
Blocker: b.Blocker,
Disabled: b.Disabled,
dirty: b.dirty,
@@ -180,496 +156,14 @@ func (b *Balance) Clone() *Balance {
return n
}
-func (b *Balance) getMatchingPrefixAndDestID(dest string) (prefix, destID string) {
- if len(b.DestinationIDs) != 0 && !b.DestinationIDs[utils.MetaAny] {
- for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) {
- if destIDs, err := dm.GetReverseDestination(p, true, true, utils.NonTransactional); err == nil {
- for _, dID := range destIDs {
- if b.DestinationIDs[dID] {
- return p, dID
- }
- }
- }
- }
- }
- return
-}
-
-// Returns the available number of seconds for a specified credit
-func (b *Balance) GetMinutesForCredit(origCD *CallDescriptor, initialCredit float64) (duration time.Duration, credit float64) {
- cd := origCD.Clone()
- availableDuration := time.Duration(b.GetValue()) * time.Second
- duration = availableDuration
- credit = initialCredit
- cc, err := b.GetCost(cd, false)
- if err != nil {
- utils.Logger.Err(fmt.Sprintf("Error getting new cost for balance subject: %v", err))
- return 0, credit
- }
- if cc.deductConnectFee {
- connectFee := cc.GetConnectFee()
- if connectFee <= credit {
- credit -= connectFee
- // remove connect fee from the total cost
- cc.Cost -= connectFee
- } else {
- return 0, credit
- }
- }
- if cc.Cost > 0 {
- duration = 0
- for _, ts := range cc.Timespans {
- ts.createIncrementsSlice()
- if cd.MaxRate > 0 && cd.MaxRateUnit > 0 {
- rate, _, rateUnit := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
- if rate/float64(rateUnit.Nanoseconds()) > cd.MaxRate/float64(cd.MaxRateUnit.Nanoseconds()) {
- return
- }
- }
- for _, incr := range ts.Increments {
- if incr.Cost <= credit && availableDuration-incr.Duration >= 0 {
- credit -= incr.Cost
- duration += incr.Duration
- availableDuration -= incr.Duration
- } else {
- return
- }
- }
- }
- }
- return
-}
-
-// Gets the cost using balance RatingSubject if present otherwize
-// retuns a callcost obtained using standard rating
-func (b *Balance) GetCost(cd *CallDescriptor, getStandardIfEmpty bool) (*CallCost, error) {
- // testing only
- if cd.testCallcost != nil {
- return cd.testCallcost, nil
- }
- if b.RatingSubject != "" && !strings.HasPrefix(b.RatingSubject, utils.MetaRatingSubjectPrefix) {
- origSubject := cd.Subject
- cd.Subject = b.RatingSubject
- origAccount := cd.Account
- cd.Account = cd.Subject
- cd.RatingInfos = nil
- cc, err := cd.getCost()
- // restor orig values
- cd.Subject = origSubject
- cd.Account = origAccount
- return cc, err
- }
- if getStandardIfEmpty {
- cd.RatingInfos = nil
- return cd.getCost()
- } else {
- cc := cd.CreateCallCost()
- cc.Cost = 0
- return cc, nil
- }
-}
-
func (b *Balance) GetValue() float64 {
return b.Value
}
-func (b *Balance) AddValue(amount float64) {
- b.SetValue(b.GetValue() + amount)
-}
-
-func (b *Balance) SubstractValue(amount float64) {
- b.SetValue(b.GetValue() - amount)
-}
-
-func (b *Balance) SetValue(amount float64) {
- b.Value = amount
- b.Value = utils.Round(b.GetValue(), globalRoundingDecimals, utils.MetaRoundingMiddle)
- b.dirty = true
-}
-
func (b *Balance) SetDirty() {
b.dirty = true
}
-// debitUnits will debit units for call descriptor.
-// returns the amount debited within cc
-func (b *Balance) debitUnits(cd *CallDescriptor, ub *Account, moneyBalances Balances, count bool, dryRun, debitConnectFee bool) (cc *CallCost, err error) {
- if !b.IsActiveAt(cd.TimeStart) || b.GetValue() <= 0 {
- return
- }
- if duration, err := utils.ParseZeroRatingSubject(cd.ToR, b.RatingSubject, config.CgrConfig().RalsCfg().BalanceRatingSubject); err == nil {
- // we have *zero based units
- cc = cd.CreateCallCost()
- cc.Timespans = append(cc.Timespans, &TimeSpan{
- TimeStart: cd.TimeStart,
- TimeEnd: cd.TimeEnd,
- })
- ts := cc.Timespans[0]
- ts.RoundToDuration(duration)
- ts.RateInterval = &RateInterval{
- Rating: &RIRate{
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0,
- RateIncrement: duration,
- RateUnit: duration,
- },
- },
- },
- }
- prefix, destid := b.getMatchingPrefixAndDestID(cd.Destination)
- if prefix == "" {
- prefix = cd.Destination
- }
- if destid == "" {
- destid = utils.MetaAny
- }
- ts.setRatingInfo(&RatingInfo{
- MatchedSubject: b.Uuid,
- MatchedPrefix: prefix,
- MatchedDestId: destid,
- RatingPlanId: utils.MetaNone,
- })
- ts.createIncrementsSlice()
- //log.Printf("CC: %+v", ts)
- for incIndex, inc := range ts.Increments {
- //log.Printf("INCREMENET: %+v", inc)
-
- amount := float64(inc.Duration.Nanoseconds())
- if b.Factor != nil {
- amount = utils.Round(amount/b.Factor.GetValue(cd.ToR),
- globalRoundingDecimals, utils.MetaRoundingUp)
- }
- if b.GetValue() >= amount {
- b.SubstractValue(amount)
- inc.BalanceInfo.Unit = &UnitInfo{
- UUID: b.Uuid,
- ID: b.ID,
- Value: b.Value,
- DestinationID: cc.Destination,
- Consumed: amount,
- ToR: cc.ToR,
- RateInterval: nil,
- }
- inc.BalanceInfo.AccountID = ub.ID
- inc.Cost = 0
- inc.paid = true
- if count {
- ub.countUnits(amount, cc.ToR, cc, b)
- }
- } else {
- inc.paid = false
- // delete the rest of the unpiad increments/timespans
- if incIndex == 0 {
- // cut the entire current timespan
- cc.Timespans = nil
- } else {
- ts.SplitByIncrement(incIndex)
- }
- if len(cc.Timespans) == 0 {
- cc = nil
- }
- return cc, nil
- }
- }
- } else {
- // get the cost from balance
- //log.Printf("::::::: %+v", cd)
- var debitedConnectFeeBalance Balance
- var ok bool
- cc, err = b.GetCost(cd, true)
- if err != nil {
- return nil, err
- }
- if debitConnectFee {
- // this is the first add, debit the connect fee
- if ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, moneyBalances, count, true); !ok {
- // found blocker balance
- return nil, nil
- }
- }
- cc.Timespans.Decompress()
- //log.Printf("CC: %+v", cc)
-
- for tsIndex, ts := range cc.Timespans {
- if ts.Increments == nil {
- ts.createIncrementsSlice()
- }
- if ts.RateInterval == nil {
- utils.Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd))
- return nil, errors.New("timespan with no rate interval assigned")
- }
-
- if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok {
-
- inc := &Increment{
- Duration: 0,
- Cost: ts.RateInterval.Rating.ConnectFee,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{
- UUID: debitedConnectFeeBalance.Uuid,
- ID: debitedConnectFeeBalance.ID,
- Value: debitedConnectFeeBalance.Value,
- },
- AccountID: ub.ID,
- },
- }
-
- incs := []*Increment{inc}
- ts.Increments = append(incs, ts.Increments...)
- }
-
- maxCost, strategy := ts.RateInterval.GetMaxCost()
- for incIndex, inc := range ts.Increments {
- if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok {
- // go to nextincrement
- continue
- }
-
- // debit minutes and money
- amount := float64(inc.Duration.Nanoseconds())
- if b.Factor != nil {
- amount = utils.Round(amount/b.Factor.GetValue(cd.ToR), globalRoundingDecimals, utils.MetaRoundingUp)
- }
- cost := inc.Cost
- inc.paid = false
- if strategy == utils.MetaMaxCostDisconnect && cd.MaxCostSoFar >= maxCost {
- // cut the entire current timespan
- cc.maxCostDisconect = true
- if dryRun {
- if incIndex == 0 {
- // cut the entire current timespan
- cc.Timespans = cc.Timespans[:tsIndex]
- } else {
- ts.SplitByIncrement(incIndex)
- cc.Timespans = cc.Timespans[:tsIndex+1]
- }
- return cc, nil
- }
- }
- if strategy == utils.MetaMaxCostFree && cd.MaxCostSoFar >= maxCost {
- cost, inc.Cost = 0.0, 0.0
- inc.BalanceInfo.Monetary = &MonetaryInfo{
- UUID: b.Uuid,
- ID: b.ID,
- Value: b.Value,
- RateInterval: ts.RateInterval,
- }
- inc.BalanceInfo.AccountID = ub.ID
- inc.paid = true
- if count {
- ub.countUnits(cost, utils.MetaMonetary, cc, b)
- }
- // go to nextincrement
- continue
- }
- var moneyBal *Balance
- for _, mb := range moneyBalances {
- if mb.GetValue() >= cost {
- moneyBal = mb
- break
- }
- }
- if cost != 0 && moneyBal == nil && (!dryRun || ub.AllowNegative) { // Fix for issue #685
- utils.Logger.Warning(fmt.Sprintf(" Going negative on account %s with AllowNegative: false", cd.GetAccountKey()))
- moneyBal = ub.GetDefaultMoneyBalance()
- }
- if b.GetValue() >= amount && (moneyBal != nil || cost == 0) {
- b.SubstractValue(amount)
- inc.BalanceInfo.Unit = &UnitInfo{
- UUID: b.Uuid,
- ID: b.ID,
- Value: b.Value,
- DestinationID: cc.Destination,
- Consumed: amount,
- ToR: cc.ToR,
- RateInterval: ts.RateInterval,
- }
- inc.BalanceInfo.AccountID = ub.ID
- if cost != 0 {
- moneyBal.SubstractValue(cost)
- inc.BalanceInfo.Monetary = &MonetaryInfo{
- UUID: moneyBal.Uuid,
- ID: moneyBal.ID,
- Value: moneyBal.Value,
- }
- cd.MaxCostSoFar += cost
- }
- inc.paid = true
- if count {
- ub.countUnits(amount, cc.ToR, cc, b)
- if cost != 0 {
- ub.countUnits(cost, utils.MetaMonetary, cc, moneyBal)
- }
- }
- } else {
- inc.paid = false
- // delete the rest of the unpaid increments/timespans
- if incIndex == 0 {
- // cut the entire current timespan
- cc.Timespans = cc.Timespans[:tsIndex]
- } else {
- ts.SplitByIncrement(incIndex)
- cc.Timespans = cc.Timespans[:tsIndex+1]
- }
- if len(cc.Timespans) == 0 {
- cc = nil
- }
- return cc, nil
- }
- }
- }
- }
- return
-}
-
-func (b *Balance) debitMoney(cd *CallDescriptor, ub *Account, moneyBalances Balances, count bool, dryRun, debitConnectFee bool) (cc *CallCost, err error) {
- if !b.IsActiveAt(cd.TimeStart) || b.GetValue() <= 0 {
- return
- }
- //log.Print("B: ", utils.ToJSON(b))
- //log.Printf("}}}}}}} %+v", cd.testCallcost)
- cc, err = b.GetCost(cd, true)
- if err != nil {
- return nil, err
- }
-
- var debitedConnectFeeBalance Balance
- var ok bool
- //log.Print("cc: " + utils.ToJSON(cc))
- if debitConnectFee {
-
- // this is the first add, debit the connect fee
- if ok, debitedConnectFeeBalance = ub.DebitConnectionFee(cc, moneyBalances, count, true); !ok {
- // balance is blocker
- return nil, nil
- }
- }
-
- cc.Timespans.Decompress()
- //log.Printf("CallCost In Debit: %+v", cc)
- //for _, ts := range cc.Timespans {
- // log.Printf("CC_TS: %+v", ts.RateInterval.Rating.Rates[0])
- //}
- for tsIndex, ts := range cc.Timespans {
- if ts.Increments == nil {
- ts.createIncrementsSlice()
- }
- //log.Printf("TS: %+v", ts)
- if ts.RateInterval == nil {
- utils.Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd))
- return nil, errors.New("timespan with no rate interval assigned")
- }
-
- if tsIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && debitConnectFee && cc.deductConnectFee && ok {
-
- inc := &Increment{
- Duration: 0,
- Cost: ts.RateInterval.Rating.ConnectFee,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{
- UUID: debitedConnectFeeBalance.Uuid,
- ID: debitedConnectFeeBalance.ID,
- Value: debitedConnectFeeBalance.Value,
- },
- AccountID: ub.ID,
- },
- }
-
- incs := []*Increment{inc}
- ts.Increments = append(incs, ts.Increments...)
- }
-
- maxCost, strategy := ts.RateInterval.GetMaxCost()
- //log.Printf("Timing: %+v", ts.RateInterval.Timing)
- //log.Printf("RGRate: %+v", ts.RateInterval.Rating)
- for incIndex, inc := range ts.Increments {
- // check standard subject tags
- //log.Printf("INC: %+v", inc)
-
- if tsIndex == 0 && incIndex == 0 && ts.RateInterval.Rating.ConnectFee > 0 && cc.deductConnectFee && ok {
- // go to nextincrement
- continue
- }
-
- amount := inc.Cost
- inc.paid = false
- if strategy == utils.MetaMaxCostDisconnect && cd.MaxCostSoFar >= maxCost {
- // cut the entire current timespan
- cc.maxCostDisconect = true
- if dryRun {
- if incIndex == 0 {
- // cut the entire current timespan
- cc.Timespans = cc.Timespans[:tsIndex]
- } else {
- ts.SplitByIncrement(incIndex)
- cc.Timespans = cc.Timespans[:tsIndex+1]
- }
- return cc, nil
- }
- }
- if strategy == utils.MetaMaxCostFree && cd.MaxCostSoFar >= maxCost {
- amount, inc.Cost = 0.0, 0.0
- inc.BalanceInfo.Monetary = &MonetaryInfo{
- UUID: b.Uuid,
- ID: b.ID,
- Value: b.Value,
- }
- inc.BalanceInfo.AccountID = ub.ID
- if b.RatingSubject != "" {
- inc.BalanceInfo.Monetary.RateInterval = ts.RateInterval
- }
- inc.paid = true
- if count {
- ub.countUnits(amount, utils.MetaMonetary, cc, b)
- }
-
- //log.Printf("TS: %+v", cc.Cost)
- // go to nextincrement
- continue
- }
-
- if b.GetValue() >= amount {
- b.SubstractValue(amount)
- cd.MaxCostSoFar += amount
- inc.BalanceInfo.Monetary = &MonetaryInfo{
- UUID: b.Uuid,
- ID: b.ID,
- Value: b.Value,
- }
- inc.BalanceInfo.AccountID = ub.ID
- if b.RatingSubject != "" {
- inc.BalanceInfo.Monetary.RateInterval = ts.RateInterval
- }
- inc.paid = true
- if count {
- ub.countUnits(amount, utils.MetaMonetary, cc, b)
- }
- } else {
- inc.paid = false
- // delete the rest of the unpiad increments/timespans
- if incIndex == 0 {
- // cut the entire current timespan
- cc.Timespans = cc.Timespans[:tsIndex]
- } else {
- ts.SplitByIncrement(incIndex)
- cc.Timespans = cc.Timespans[:tsIndex+1]
- }
- if len(cc.Timespans) == 0 {
- cc = nil
- }
- return cc, nil
- }
- }
- }
- //log.Printf("END: %+v", cd.testCallcost)
- if len(cc.Timespans) == 0 {
- cc = nil
- }
- return cc, nil
-}
-
// AsBalanceSummary converts the balance towards compressed information to be displayed
func (b *Balance) AsBalanceSummary(typ string) *BalanceSummary {
bd := &BalanceSummary{UUID: b.Uuid, ID: b.ID, Type: typ, Value: b.Value, Disabled: b.Disabled}
@@ -702,16 +196,6 @@ func (bc Balances) Sort() {
sort.Sort(bc)
}
-func (bc Balances) GetTotalValue() (total float64) {
- for _, b := range bc {
- if !b.IsExpiredAt(time.Now()) && b.IsActive() {
- total += b.GetValue()
- }
- }
- total = utils.Round(total, globalRoundingDecimals, utils.MetaRoundingMiddle)
- return
-}
-
func (bc Balances) Equal(o Balances) bool {
if len(bc) != len(o) {
return false
@@ -752,53 +236,6 @@ func (bc Balances) HasBalance(balance *Balance) bool {
return false
}
-func (bc Balances) SaveDirtyBalances(acc *Account) {
- savedAccounts := make(map[string]*Account)
- for _, b := range bc {
- if b.account != nil && b.account != acc && b.dirty && savedAccounts[b.account.ID] == nil {
- savedAccounts[b.account.ID] = b.account
- }
- }
- if len(savedAccounts) != 0 {
- for _, acnt := range savedAccounts {
- acntSummary := acnt.AsAccountSummary()
- cgrEv := &utils.CGREvent{
- Tenant: acntSummary.Tenant,
- ID: utils.GenUUID(),
- Time: utils.TimePointer(time.Now()),
- Event: acntSummary.AsMapInterface(),
- APIOpts: map[string]interface{}{
- utils.MetaEventType: utils.AccountUpdate,
- },
- }
- if len(config.CgrConfig().RalsCfg().ThresholdSConns) != 0 {
- var tIDs []string
- if err := connMgr.Call(config.CgrConfig().RalsCfg().ThresholdSConns, nil,
- utils.ThresholdSv1ProcessEvent, &ThresholdsArgsProcessEvent{
- CGREvent: cgrEv,
- }, &tIDs); err != nil &&
- err.Error() != utils.ErrNotFound.Error() {
- utils.Logger.Warning(
- fmt.Sprintf(" error: %s processing account event %+v with ThresholdS.", err.Error(), cgrEv))
- }
- }
- if len(config.CgrConfig().RalsCfg().StatSConns) != 0 {
- var stsIDs []string
- if err := connMgr.Call(config.CgrConfig().RalsCfg().StatSConns, nil,
- utils.StatSv1ProcessEvent, &StatsArgsProcessEvent{
- CGREvent: cgrEv,
- }, &stsIDs); err != nil &&
- err.Error() != utils.ErrNotFound.Error() {
- utils.Logger.Warning(
- fmt.Sprintf(" error: %s processing account event %+v with StatS.", err.Error(), cgrEv))
- }
- }
-
- }
-
- }
-}
-
type ValueFactor map[string]float64
func (f ValueFactor) GetValue(tor string) float64 {
diff --git a/engine/caches.go b/engine/caches.go
index a7e6a7b35..32bd09fe5 100644
--- a/engine/caches.go
+++ b/engine/caches.go
@@ -71,9 +71,6 @@ func init() {
gob.Register(new(ActionProfile))
gob.Register(new(ActionProfileWithAPIOpts))
- // CDRs
- gob.Register(new(EventCost))
-
// StatMetrics
gob.Register(new(StatASR))
gob.Register(new(StatACD))
@@ -107,7 +104,6 @@ func init() {
// NewCacheS initializes the Cache service and executes the precaching
func NewCacheS(cfg *config.CGRConfig, dm *DataManager, cpS *CapsStats) (c *CacheS) {
- cfg.CacheCfg().AddTmpCaches()
tCache := cfg.CacheCfg().AsTransCacheConfig()
if len(cfg.CacheCfg().ReplicationConns) != 0 {
var reply string
diff --git a/engine/callcost.go b/engine/callcost.go
deleted file mode 100644
index 23fd34cfc..000000000
--- a/engine/callcost.go
+++ /dev/null
@@ -1,262 +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 (
- "errors"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-// The output structure that will be returned with the call cost information.
-type CallCost struct {
- Category string
- Tenant string
- Subject string
- Account string
- Destination string
- ToR string
- Cost float64
- Timespans TimeSpans
- RatedUsage float64
- AccountSummary *AccountSummary
- deductConnectFee bool
- negativeConnectFee bool // the connect fee went negative on default balance
- maxCostDisconect bool
-}
-
-// Merges the received timespan if they are similar (same activation period, same interval, same minute info.
-func (cc *CallCost) Merge(other *CallCost) {
- cc.Timespans = append(cc.Timespans, other.Timespans...)
- cc.Cost += other.Cost
-}
-
-func (cc *CallCost) GetStartTime() time.Time {
- if len(cc.Timespans) == 0 {
- return time.Now()
- }
- return cc.Timespans[0].TimeStart
-}
-
-func (cc *CallCost) GetEndTime() time.Time {
- if len(cc.Timespans) == 0 {
- return time.Now()
- }
- return cc.Timespans[len(cc.Timespans)-1].TimeEnd
-}
-
-func (cc *CallCost) GetDuration() (td time.Duration) {
- for _, ts := range cc.Timespans {
- td += ts.GetDuration()
- }
- return
-}
-
-func (cc *CallCost) UpdateRatedUsage() time.Duration {
- if cc == nil {
- return 0
- }
- totalDuration := cc.GetDuration()
- cc.RatedUsage = float64(totalDuration.Nanoseconds())
- return totalDuration
-}
-
-func (cc *CallCost) GetConnectFee() float64 {
- if len(cc.Timespans) == 0 ||
- cc.Timespans[0].RateInterval == nil ||
- cc.Timespans[0].RateInterval.Rating == nil {
- return 0
- }
- return cc.Timespans[0].RateInterval.Rating.ConnectFee
-}
-
-// Creates a CallDescriptor structure copying related data from CallCost
-func (cc *CallCost) CreateCallDescriptor() *CallDescriptor {
- return &CallDescriptor{
- Category: cc.Category,
- Tenant: cc.Tenant,
- Subject: cc.Subject,
- Account: cc.Account,
- Destination: cc.Destination,
- ToR: cc.ToR,
- }
-}
-
-func (cc *CallCost) IsPaid() bool {
- for _, ts := range cc.Timespans {
- if paid, _ := ts.IsPaid(); !paid {
- return false
- }
- }
- return true
-}
-
-func (cc *CallCost) ToDataCost() (*DataCost, error) {
- if cc.ToR == utils.MetaVoice {
- return nil, errors.New("Not a data call!")
- }
- dc := &DataCost{
- Category: cc.Category,
- Tenant: cc.Tenant,
- Subject: cc.Subject,
- Account: cc.Account,
- Destination: cc.Destination,
- ToR: cc.ToR,
- Cost: cc.Cost,
- deductConnectFee: cc.deductConnectFee,
- }
- dc.DataSpans = make([]*DataSpan, len(cc.Timespans))
- for i, ts := range cc.Timespans {
- length := ts.TimeEnd.Sub(ts.TimeStart).Nanoseconds()
- callDuration := ts.DurationIndex.Nanoseconds()
- dc.DataSpans[i] = &DataSpan{
- DataStart: float64(callDuration - length),
- DataEnd: float64(callDuration),
- Cost: ts.Cost,
- ratingInfo: ts.ratingInfo,
- RateInterval: ts.RateInterval,
- DataIndex: float64(callDuration),
- MatchedSubject: ts.MatchedSubject,
- MatchedPrefix: ts.MatchedPrefix,
- MatchedDestId: ts.MatchedDestId,
- RatingPlanId: ts.RatingPlanId,
- }
- dc.DataSpans[i].Increments = make([]*DataIncrement, len(ts.Increments))
- for j, incr := range ts.Increments {
- dc.DataSpans[i].Increments[j] = &DataIncrement{
- Amount: float64(incr.Duration.Nanoseconds()),
- Cost: incr.Cost,
- BalanceInfo: incr.BalanceInfo,
- CompressFactor: incr.CompressFactor,
- paid: incr.paid,
- }
- }
- }
- return dc, nil
-}
-
-func (cc *CallCost) GetLongestRounding() (roundingDecimals int, roundingMethod string) {
- for _, ts := range cc.Timespans {
- if ts.RateInterval != nil && ts.RateInterval.Rating.RoundingDecimals > roundingDecimals { //ToDo: When will ts.RateInterval be empty?
- roundingDecimals = ts.RateInterval.Rating.RoundingDecimals
- roundingMethod = ts.RateInterval.Rating.RoundingMethod
- }
- }
- return
-}
-
-func (cc *CallCost) AsJSON() string {
- return utils.ToJSON(cc)
-}
-
-// public function to update final (merged) callcost
-func (cc *CallCost) UpdateCost() {
- cc.deductConnectFee = true
- cc.updateCost()
-}
-
-func (cc *CallCost) updateCost() {
- cost := 0.0
- //if cc.deductConnectFee { // add back the connectFee
- // cost += cc.GetConnectFee()
- //}
- for _, ts := range cc.Timespans {
- ts.Cost = ts.CalculateCost()
- cost += ts.Cost
- cost = utils.Round(cost, globalRoundingDecimals, utils.MetaRoundingMiddle) // just get rid of the extra decimals
- }
- cc.Cost = cost
-}
-
-// Round creates the RoundIncrements in timespans
-func (cc *CallCost) Round() {
- if len(cc.Timespans) == 0 || cc.Timespans[0] == nil {
- return
- }
- var totalCorrectionCost float64
- for _, ts := range cc.Timespans {
- if len(ts.Increments) == 0 {
- continue // safe check
- }
- inc := ts.Increments[0]
- if inc.BalanceInfo == nil || inc.BalanceInfo.Monetary == nil || inc.Cost == 0 {
- // this is a unit paid timespan, nothing to round
- continue
- }
- cost := ts.CalculateCost()
- roundedCost := utils.Round(cost,
- ts.RateInterval.Rating.RoundingDecimals,
- ts.RateInterval.Rating.RoundingMethod)
- correctionCost := roundedCost - cost
- //log.Print(cost, roundedCost, correctionCost)
- if correctionCost != 0 {
- ts.RoundIncrement = &Increment{
- Cost: correctionCost,
- BalanceInfo: inc.BalanceInfo,
- CompressFactor: 1,
- }
- totalCorrectionCost += correctionCost
- ts.Cost += correctionCost
- }
- }
- cc.Cost += totalCorrectionCost
-}
-
-func (cc *CallCost) GetRoundIncrements() (roundIncrements Increments) {
- for _, ts := range cc.Timespans {
- if ts.RoundIncrement != nil && ts.RoundIncrement.Cost != 0 {
- roundIncrements = append(roundIncrements, ts.RoundIncrement)
- }
- }
- return
-}
-
-func (cc *CallCost) MatchCCFilter(bf *BalanceFilter) bool {
- if bf == nil {
- return true
- }
- if bf.Categories != nil && cc.Category != "" && !(*bf.Categories)[cc.Category] {
- return false
- }
- // match destination ids
- foundMatchingDestID := false
- if bf.DestinationIDs != nil && cc.Destination != "" {
- for _, p := range utils.SplitPrefix(cc.Destination, MIN_PREFIX_MATCH) {
- if destIDs, err := dm.GetReverseDestination(p,
- true, true, utils.NonTransactional); err == nil {
- for _, dID := range destIDs {
- if _, ok := (*bf.DestinationIDs)[dID]; ok {
- foundMatchingDestID = true
- break // only one found?
- }
- }
- }
- if foundMatchingDestID {
- break
- }
- }
- } else {
- foundMatchingDestID = true
- }
- if !foundMatchingDestID {
- return false
- }
- return true
-}
diff --git a/engine/callcost_test.go b/engine/callcost_test.go
deleted file mode 100644
index 78d1acae7..000000000
--- a/engine/callcost_test.go
+++ /dev/null
@@ -1,200 +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 (
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestSingleResultMerge(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 0, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0",
- Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc1, _ := cd.getCost()
- if cc1.Cost != 61 {
- t.Errorf("expected 61 was %v", cc1.Cost)
- }
- t1 = time.Date(2012, time.February, 2, 17, 1, 0, 0, time.UTC)
- t2 = time.Date(2012, time.February, 2, 17, 2, 0, 0, time.UTC)
- cd = &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc2, _ := cd.GetCost()
- if cc2.Cost != 61 {
- t.Errorf("expected 60 was %v", cc2.Cost)
- }
- cc1.Merge(cc2)
- if len(cc1.Timespans) != 2 || cc1.Timespans[0].GetDuration().Seconds() != 60 || cc1.Timespans[1].GetDuration().Seconds() != 60 {
- for _, ts := range cc1.Timespans {
- t.Logf("TS: %+v", ts)
- }
- t.Error("wrong resulted timespan: ", len(cc1.Timespans), cc1.Timespans[0].GetDuration().Seconds())
- }
- if cc1.Cost != 122 {
- t.Errorf("Exdpected 120 was %v", cc1.Cost)
- }
- d := cc1.UpdateRatedUsage()
- if d != 2*time.Minute || cc1.RatedUsage != 120.0*float64(time.Second) {
- t.Errorf("error updating rating usage: %v, %v", d, cc1.RatedUsage)
- }
-}
-
-func TestMultipleResultMerge(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 0, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc1, _ := cd.getCost()
- if cc1.Cost != 61 {
- //ils.LogFull(cc1)
- t.Errorf("expected 61 was %v", cc1.Cost)
- for _, ts := range cc1.Timespans {
- t.Log(ts.RateInterval)
- }
- }
- t1 = time.Date(2012, time.February, 2, 18, 00, 0, 0, time.UTC)
- t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC)
- cd = &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc2, _ := cd.getCost()
- if cc2.Cost != 30 {
- t.Errorf("expected 30 was %v", cc2.Cost)
- for _, ts := range cc1.Timespans {
- t.Log(ts.RateInterval)
- }
- }
- cc1.Merge(cc2)
- if len(cc1.Timespans) != 2 || cc1.Timespans[0].GetDuration().Seconds() != 60 {
- t.Error("wrong resulted timespans: ", len(cc1.Timespans))
- }
- if cc1.Cost != 91 {
- t.Errorf("Exdpected 91 was %v", cc1.Cost)
- }
-}
-
-func TestMultipleInputLeftMerge(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc1, _ := cd.getCost()
- //log.Printf("Timing: %+v", cc1.Timespans[1].RateInterval.Timing)
- //log.Printf("Rating: %+v", cc1.Timespans[1].RateInterval.Rating)
- if cc1.Cost != 91 {
- t.Errorf("expected 91 was %v", cc1.Cost)
- }
- /*t1 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC)
- t2 = time.Date(2012, time.February, 2, 18, 02, 0, 0, time.UTC)
- cd = &CallDescriptor{ToR: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc2, _ := cd.getCost()
- if cc2.Cost != 30 {
- t.Errorf("expected 30 was %v", cc2.Cost)
- }
- cc1.Merge(cc2)
- if len(cc1.Timespans) != 2 || cc1.Timespans[1].GetDuration().Seconds() != 120 {
- t.Error("wrong resulted timespan: ", len(cc1.Timespans))
- }
- if cc1.Cost != 120 {
- t.Errorf("Exdpected 120 was %v", cc1.Cost)
- }*/
-}
-
-func TestMultipleInputRightMerge(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc1, _ := cd.getCost()
- if cc1.Cost != 61 {
- t.Errorf("expected 61 was %v", cc1.Cost)
- }
- t1 = time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
- t2 = time.Date(2012, time.February, 2, 18, 01, 0, 0, time.UTC)
- cd = &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc2, _ := cd.getCost()
- if cc2.Cost != 91 {
- t.Errorf("expected 91 was %v", cc2.Cost)
- }
- cc1.Merge(cc2)
- if len(cc1.Timespans) != 3 || cc1.Timespans[0].GetDuration().Seconds() != 60 {
- t.Error("wrong resulted timespan: ", len(cc1.Timespans), cc1.Timespans[0].GetDuration().Seconds())
- }
- if cc1.Cost != 152 {
- t.Errorf("Exdpected 152 was %v", cc1.Cost)
- }
-}
-
-func TestCallCostMergeEmpty(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 58, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 17, 59, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cc1, _ := cd.getCost()
- cc2 := &CallCost{}
- cc1.Merge(cc2)
- if len(cc1.Timespans) != 1 {
- t.Error("Error mergin empty call cost: ", len(cc1.Timespans))
- }
-}
-
-func TestCallCostGetDurationZero(t *testing.T) {
- cc := &CallCost{}
- if cc.GetDuration().Seconds() != 0 {
- t.Error("Wrong call cost duration for zero timespans: ", cc.GetDuration())
- }
-}
-
-func TestCallCostGetDuration(t *testing.T) {
- cc := &CallCost{
- Timespans: []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 13, 40, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
- },
- {
- TimeStart: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 13, 41, 30, 0, time.UTC),
- },
- },
- }
- if cc.GetDuration().Seconds() != 90 {
- t.Error("Wrong call cost duration: ", cc.GetDuration())
- }
-}
-
-func TestCallCostToDataCostError(t *testing.T) {
- cd := &CallDescriptor{
- Category: "data",
- Tenant: "cgrates.org",
- Subject: "rif",
- Destination: utils.MetaAny,
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC),
- ToR: utils.MetaVoice,
- }
- cc, _ := cd.getCost()
- _, err := cc.ToDataCost()
- if err == nil {
- t.Error("Failed to throw error on call to datacost!")
- }
-}
diff --git a/engine/calldesc.go b/engine/calldesc.go
deleted file mode 100644
index 8d16e16d1..000000000
--- a/engine/calldesc.go
+++ /dev/null
@@ -1,1049 +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 (
- "errors"
- "fmt"
- "net"
- "sync"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/guardian"
- "github.com/cgrates/cgrates/utils"
-)
-
-const (
- // these might be better in the confs under optimizations section
- RECURSION_MAX_DEPTH = 3
- MIN_PREFIX_MATCH = 1
- FALLBACK_SUBJECT = utils.MetaAny
-)
-
-var (
- debitPeriod = 10 * time.Second
- globalRoundingDecimals = 6
- rpSubjectPrefixMatching bool
- rpSubjectPrefixMatchingMutex sync.RWMutex // used to reload rpSubjectPrefixMatching
-)
-
-// SetRoundingDecimals sets the global rounding method and decimal precision for GetCost method
-func SetRoundingDecimals(rd int) {
- globalRoundingDecimals = rd
-}
-
-// SetRpSubjectPrefixMatching sets rpSubjectPrefixMatching (is thread safe)
-func SetRpSubjectPrefixMatching(flag bool) {
- rpSubjectPrefixMatchingMutex.Lock()
- rpSubjectPrefixMatching = flag
- rpSubjectPrefixMatchingMutex.Unlock()
-}
-
-// getRpSubjectPrefixMatching returns rpSubjectPrefixMatching (is thread safe)
-func getRpSubjectPrefixMatching() (flag bool) {
- rpSubjectPrefixMatchingMutex.RLock()
- flag = rpSubjectPrefixMatching
- rpSubjectPrefixMatchingMutex.RUnlock()
- return
-}
-
-// NewCallDescriptorFromCGREvent converts a CGREvent into CallDescriptor
-func NewCallDescriptorFromCGREvent(cgrEv *utils.CGREvent,
- timezone string) (cd *CallDescriptor, err error) {
- cd = &CallDescriptor{Tenant: cgrEv.Tenant}
- if _, has := cgrEv.Event[utils.Category]; has {
- if cd.Category, err = cgrEv.FieldAsString(utils.Category); err != nil {
- return nil, err
- }
- }
- if cd.Account, err = cgrEv.FieldAsString(utils.AccountField); err != nil {
- return
- }
- if cd.Subject, err = cgrEv.FieldAsString(utils.Subject); err != nil {
- if err != utils.ErrNotFound {
- return
- }
- cd.Subject = cd.Account
- }
- if cd.Destination, err = cgrEv.FieldAsString(utils.Destination); err != nil {
- return nil, err
- }
- if cd.TimeStart, err = cgrEv.FieldAsTime(utils.SetupTime,
- timezone); err != nil {
- return nil, err
- }
- if _, has := cgrEv.Event[utils.AnswerTime]; has { // AnswerTime takes precendence for TimeStart
- if aTime, err := cgrEv.FieldAsTime(utils.AnswerTime,
- timezone); err != nil {
- return nil, err
- } else if !aTime.IsZero() {
- cd.TimeStart = aTime
- }
- }
- if usage, err := cgrEv.FieldAsDuration(utils.Usage); err != nil {
- return nil, err
- } else {
- cd.TimeEnd = cd.TimeStart.Add(usage)
- }
- if _, has := cgrEv.Event[utils.ToR]; has {
- if cd.ToR, err = cgrEv.FieldAsString(utils.ToR); err != nil {
- return nil, err
- }
- }
- return
-}
-
-/*
-The input stucture that contains call information.
-*/
-type CallDescriptor struct {
- Category string
- Tenant string
- Subject string
- Account string
- Destination string
- TimeStart time.Time
- TimeEnd time.Time
- LoopIndex float64 // indicates the position of this segment in a cost request loop
- DurationIndex time.Duration // the call duration so far (till TimeEnd)
- FallbackSubject string // the subject to check for destination if not found on primary subject
- RatingInfos RatingInfos
- Increments Increments
- ToR string // used unit balances selector
- ExtraFields map[string]string // Extra fields, mostly used for user profile matching
- // session limits
- MaxRate float64
- MaxRateUnit time.Duration
- MaxCostSoFar float64
- CgrID string
- RunID string
- ForceDuration bool // for Max debit if less than duration return err
- PerformRounding bool // flag for rating info rounding
- DryRun bool
- DenyNegativeAccount bool // prevent account going on negative during debit
- account *Account
- testCallcost *CallCost // testing purpose only!
-}
-
-// AsCGREvent converts the CallDescriptor into CGREvent
-func (cd *CallDescriptor) AsCGREvent(opts map[string]interface{}) *utils.CGREvent {
- cgrEv := &utils.CGREvent{
- Tenant: cd.Tenant,
- ID: utils.UUIDSha1Prefix(), // make it unique
- Event: make(map[string]interface{}),
- APIOpts: opts,
- }
- for k, v := range cd.ExtraFields {
- cgrEv.Event[k] = v
- }
- cgrEv.Event[utils.ToR] = cd.ToR
- cgrEv.Event[utils.Tenant] = cd.Tenant
- cgrEv.Event[utils.Category] = cd.Category
- cgrEv.Event[utils.AccountField] = cd.Account
- cgrEv.Event[utils.Subject] = cd.Subject
- cgrEv.Event[utils.Destination] = cd.Destination
- cgrEv.Event[utils.AnswerTime] = cd.TimeStart
- cgrEv.Event[utils.Usage] = cd.TimeEnd.Sub(cd.TimeStart)
- return cgrEv
-}
-
-// UpdateFromCGREvent will update CallDescriptor with fields from CGREvent
-// cgrEv contains both fields and their values
-// fields represent fields needing update
-func (cd *CallDescriptor) UpdateFromCGREvent(cgrEv *utils.CGREvent, fields []string) (err error) {
- for _, fldName := range fields {
- switch fldName {
- case utils.ToR:
- if cd.ToR, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.Tenant:
- if cd.Tenant, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.Category:
- if cd.Category, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.AccountField:
- if cd.Account, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.Subject:
- if cd.Subject, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.Destination:
- if cd.Destination, err = cgrEv.FieldAsString(fldName); err != nil {
- return
- }
- case utils.AnswerTime:
- if cd.TimeStart, err = cgrEv.FieldAsTime(fldName,
- config.CgrConfig().GeneralCfg().DefaultTimezone); err != nil {
- return
- }
- case utils.Usage:
- usage, err := cgrEv.FieldAsDuration(fldName)
- if err != nil {
- return err
- }
- cd.TimeEnd = cd.TimeStart.Add(usage)
- default:
- fldVal, err := cgrEv.FieldAsString(fldName)
- if err != nil {
- return err
- }
- cd.ExtraFields[fldName] = fldVal
- }
- }
- return
-}
-
-func (cd *CallDescriptor) ValidateCallData() error {
- if cd.TimeStart.After(cd.TimeEnd) || cd.TimeStart.Equal(cd.TimeEnd) {
- return errors.New("TimeStart must be strctly before TimeEnd")
- }
- if cd.TimeEnd.Sub(cd.TimeStart) < cd.DurationIndex {
- return errors.New("DurationIndex must be equal or greater than TimeEnd - TimeStart")
- }
- return nil
-}
-
-// Adds a rating plan that applyes to current call descriptor.
-func (cd *CallDescriptor) AddRatingInfo(ris ...*RatingInfo) {
- cd.RatingInfos = append(cd.RatingInfos, ris...)
-}
-
-// Gets and caches the user balance information.
-func (cd *CallDescriptor) getAccount() (ub *Account, err error) {
- if cd.account == nil {
- cd.account, err = dm.GetAccount(cd.GetAccountKey())
- }
- if cd.account != nil && cd.account.Disabled {
- return nil, utils.ErrAccountDisabled
- }
- if err != nil || cd.account == nil {
- utils.Logger.Warning(fmt.Sprintf("Account: %s, not found (%v)", cd.GetAccountKey(), err))
- return nil, utils.ErrAccountNotFound
- }
- return cd.account, err
-}
-
-/*
-Restores the activation periods for the specified prefix from storage.
-*/
-func (cd *CallDescriptor) LoadRatingPlans() (err error) {
- var rec int
- err, rec = cd.getRatingPlansForPrefix(cd.GetKey(cd.Subject), 1)
- if err == utils.ErrNotFound && rec == 1 {
- //if err != nil || !cd.continousRatingInfos() {
- // use the default subject only if the initial one was not found
- err, _ = cd.getRatingPlansForPrefix(cd.GetKey(FALLBACK_SUBJECT), 1)
- }
- //load the rating plans
- if err != nil {
- utils.Logger.Err(fmt.Sprintf("Rating plan not found for destination %s and account: %s, subject: %s", cd.Destination, cd.GetAccountKey(), cd.GetKey(cd.Subject)))
- return utils.ErrRatingPlanNotFound
-
- }
- if !cd.continousRatingInfos() {
- utils.Logger.Err(fmt.Sprintf("Destination %s not authorized for account: %s, subject: %s", cd.Destination, cd.GetAccountKey(), cd.GetKey(cd.Subject)))
- return utils.ErrUnauthorizedDestination
- }
- return
-}
-
-// FIXME: this method is not exhaustive but will cover 99% of cases just good
-// it will not cover very long calls with very short activation periods for rates
-func (cd *CallDescriptor) getRatingPlansForPrefix(key string, recursionDepth int) (error, int) {
- if recursionDepth > RECURSION_MAX_DEPTH {
- return utils.ErrMaxRecursionDepth, recursionDepth
- }
- rpf, err := RatingProfileSubjectPrefixMatching(key)
- if err != nil || rpf == nil {
- return utils.ErrNotFound, recursionDepth
- }
- if err = rpf.GetRatingPlansForPrefix(cd); err != nil || !cd.continousRatingInfos() {
- // try rating profile fallback
- recursionDepth++
- for index := 0; index < len(cd.RatingInfos); index++ {
- ri := cd.RatingInfos[index]
- if len(ri.RateIntervals) > 0 {
- // go to next rate info
- continue
- }
- if len(ri.FallbackKeys) > 0 {
- tempCD := &CallDescriptor{
- Category: cd.Category,
- Tenant: cd.Tenant,
- Destination: cd.Destination,
- }
- if index == 0 {
- tempCD.TimeStart = cd.TimeStart
- } else {
- tempCD.TimeStart = ri.ActivationTime
- }
- if index == len(cd.RatingInfos)-1 {
- tempCD.TimeEnd = cd.TimeEnd
- } else {
- tempCD.TimeEnd = cd.RatingInfos[index+1].ActivationTime
- }
- for _, fbk := range ri.FallbackKeys {
- if err, _ := tempCD.getRatingPlansForPrefix(fbk, recursionDepth); err != nil {
- continue
- }
- // extract the rate infos and break
- for newIndex, newRI := range tempCD.RatingInfos {
- // check if the new ri is filled
- if len(newRI.RateIntervals) == 0 {
- continue
- }
- if newIndex == 0 {
- cd.RatingInfos[index] = newRI
- } else {
- // insert extra data
- i := index + newIndex
- cd.RatingInfos = append(cd.RatingInfos, nil)
- copy(cd.RatingInfos[i+1:], cd.RatingInfos[i:])
- cd.RatingInfos[i] = newRI
- }
- }
- // if this fallbackey covered the interval than skip
- // the other fallback keys
- if tempCD.continousRatingInfos() {
- break
- }
- }
- }
- }
- }
- return nil, recursionDepth
-}
-
-// checks if there is rating info for the entire call duration
-func (cd *CallDescriptor) continousRatingInfos() bool {
- if len(cd.RatingInfos) == 0 || cd.RatingInfos[0].ActivationTime.After(cd.TimeStart) {
- return false
- }
- for _, ri := range cd.RatingInfos {
- if ri.RateIntervals == nil {
- return false
- }
- }
- return true
-}
-
-// adds a rating infos only if that call period is not already covered
-// returns true if added
-func (cd *CallDescriptor) addRatingInfos(ris RatingInfos) bool {
- if len(cd.RatingInfos) == 0 {
- cd.RatingInfos = append(cd.RatingInfos, ris...)
- return true
- }
- cd.RatingInfos.Sort()
- // check if we dont have the start covered
- if cd.RatingInfos[0].ActivationTime.After(cd.TimeStart) {
- if ris[0].ActivationTime.Before(cd.RatingInfos[0].ActivationTime) {
- cd.RatingInfos = append(cd.RatingInfos, ris[0])
- cd.RatingInfos.Sort()
- }
- }
- for _, ri := range cd.RatingInfos {
- if ri.RateIntervals == nil {
- for i, newRi := range ris {
- _ = i
- _ = newRi
- }
- }
- }
- return true
-}
-
-// GetKey constructs the key for the storage lookup.
-// The prefixLen is limiting the length of the destination prefix.
-func (cd *CallDescriptor) GetKey(subject string) string {
- return utils.ConcatenatedKey(utils.MetaOut, cd.Tenant, cd.Category, subject)
-}
-
-// GetAccountKey returns the key used to retrive the user balance involved in this call
-func (cd *CallDescriptor) GetAccountKey() string {
- subj := cd.Subject
- if cd.Account != "" {
- subj = cd.Account
- }
- return utils.ConcatenatedKey(cd.Tenant, subj)
-}
-
-// Splits the received timespan into sub time spans according to the activation periods intervals.
-func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
- firstSpan := &TimeSpan{TimeStart: cd.TimeStart, TimeEnd: cd.TimeEnd,
- DurationIndex: cd.DurationIndex}
-
- timespans = append(timespans, firstSpan)
- if len(cd.RatingInfos) == 0 {
- return
- }
- firstSpan.setRatingInfo(cd.RatingInfos[0])
- if cd.ToR == utils.MetaVoice {
- // split on rating plans
- afterStart, afterEnd := false, false //optimization for multiple activation periods
- for _, rp := range cd.RatingInfos {
- //log.Print("RP: ", utils.ToJSON(rp))
- if !afterStart && !afterEnd && rp.ActivationTime.Before(cd.TimeStart) {
- firstSpan.setRatingInfo(rp)
- } else {
- afterStart = true
- for i := 0; i < len(timespans); i++ {
- newTs := timespans[i].SplitByRatingPlan(rp)
- if newTs != nil {
- timespans = append(timespans, newTs)
- } else {
- afterEnd = true
- break
- }
- }
- }
- }
- //log.Printf("After SplitByRatingPlan: %+v", utils.ToJSON(timespans))
- // split on days
-
- for i := 0; i < len(timespans); i++ {
- rp := timespans[i].ratingInfo
- newTs := timespans[i].SplitByDay()
- if newTs != nil {
- //log.Print("NEW TS: ", newTs.TimeStart, newTs.TimeEnd)
- newTs.setRatingInfo(rp)
- // insert the new timespan
- index := i + 1
- timespans = append(timespans, nil)
- copy(timespans[index+1:], timespans[index:])
- timespans[index] = newTs
- }
- }
- }
- //log.Printf("After SplitByDay: %+v", utils.ToJSON(timespans))
- // split on rate intervals
-
- for i := 0; i < len(timespans); i++ {
- //log.Printf("==============%v==================", i)
- //log.Printf("TS: %+v", timespans[i])
- rp := timespans[i].ratingInfo
- //timespans[i].RatingPlan = nil
- rateIntervals := rp.SelectRatingIntevalsForTimespan(timespans[i])
- //log.Print("RIs: ", utils.ToJSON(rateIntervals))
- /*for _, interval := range rp.RateIntervals {
- if !timespans[i].hasBetterRateIntervalThan(interval) {
- timespans[i].SetRateInterval(interval)
- }
- }*/
- //log.Print("ORIG TS: ", timespans[i].TimeStart, timespans[i].TimeEnd)
- //log.Print(timespans[i].RateInterval)
- for _, interval := range rateIntervals {
- //log.Printf("\tINTERVAL: %+v", interval.Timing)
- newTs := timespans[i].SplitByRateInterval(interval, cd.ToR != utils.MetaVoice)
- //utils.PrintFull(timespans[i])
- //utils.PrintFull(newTs)
- if newTs != nil {
- //log.Print("NEW TS: ", newTs.TimeStart, newTs.TimeEnd)
- newTs.setRatingInfo(rp)
- // insert the new timespan
- index := i + 1
- timespans = append(timespans, nil)
- copy(timespans[index+1:], timespans[index:])
- timespans[index] = newTs
- if timespans[i].RateInterval != nil {
- break
- }
- }
- }
- //log.Print("TS: ", timespans[i].TimeStart, timespans[i].TimeEnd)
- //log.Print(timespans[i].RateInterval.Timing)
- }
-
- //log.Printf("After SplitByRateInterval: %+v", timespans[0].RateInterval.Timing)
- timespans = cd.roundTimeSpansToIncrement(timespans)
- //log.Printf("After round: %+v", timespans[0].RateInterval.Timing)
- return
-}
-
-// if the rate interval for any timespan has a RatingIncrement larger than the timespan duration
-// the timespan must expand potentially overlaping folowing timespans and may exceed call
-// descriptor's initial duration
-func (cd *CallDescriptor) roundTimeSpansToIncrement(timespans TimeSpans) []*TimeSpan {
- for i := 0; i < len(timespans); i++ {
- ts := timespans[i]
- if ts.RateInterval != nil {
- _, rateIncrement, _ := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
- // if the timespan duration is larger than the rate increment make sure it is a multiple of it
- if rateIncrement < ts.GetDuration() {
- rateIncrement = utils.RoundDuration(rateIncrement, ts.GetDuration())
- }
- if rateIncrement > ts.GetDuration() {
- initialDuration := ts.GetDuration()
- ts.TimeEnd = ts.TimeStart.Add(rateIncrement)
- ts.DurationIndex = ts.DurationIndex + (rateIncrement - initialDuration)
- timespans.RemoveOverlapedFromIndex(i)
- }
- }
- }
-
- return timespans
-}
-
-// Returns call descripor's total duration
-func (cd *CallDescriptor) GetDuration() time.Duration {
- return cd.TimeEnd.Sub(cd.TimeStart)
-}
-
-/*
-Creates a CallCost structure with the cost information calculated for the received CallDescriptor.
-*/
-func (cd *CallDescriptor) GetCost() (*CallCost, error) {
- cd.account = nil // make sure it's not cached
- cc, err := cd.getCost()
- if err != nil || cd.GetDuration() == 0 {
- return cc, err
- }
- cost := 0.0
- for i, ts := range cc.Timespans {
- // only add connect fee if this is the first/only call cost request
- if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil {
- //Add the ConnectFee increment at the beggining
- ts.Increments = append(Increments{&Increment{
- Duration: 0,
- Cost: ts.RateInterval.Rating.ConnectFee,
- CompressFactor: 1,
- BalanceInfo: &DebitInfo{
- Monetary: nil,
- Unit: nil,
- AccountID: "",
- },
- }}, ts.Increments...)
- //Add the cost from ConnectFee to TimeSpan
- ts.Cost = ts.Cost + ts.RateInterval.Rating.ConnectFee
- }
- // handle max cost
- maxCost, strategy := ts.RateInterval.GetMaxCost()
-
- ts.Cost = ts.CalculateCost()
- cost += ts.Cost
- cd.MaxCostSoFar += cost
-
- if strategy != "" && maxCost > 0 {
- //log.Print("HERE: ", strategy, maxCost)
- if strategy == utils.MetaMaxCostFree && cd.MaxCostSoFar >= maxCost {
- cost = maxCost
- cd.MaxCostSoFar = maxCost
- }
- }
- }
- cc.Cost = cost
-
- // global rounding
- roundingDecimals, roundingMethod := cc.GetLongestRounding()
- cc.Cost = utils.Round(cc.Cost, roundingDecimals, roundingMethod)
- return cc, nil
-}
-
-func (cd *CallDescriptor) getCost() (*CallCost, error) {
- // check for 0 duration
- if cd.GetDuration() == 0 {
- cc := cd.CreateCallCost()
- // add RatingInfo
- err := cd.LoadRatingPlans()
- if err == nil && len(cd.RatingInfos) > 0 {
- ts := &TimeSpan{
- TimeStart: cd.TimeStart,
- TimeEnd: cd.TimeEnd,
- }
- ts.setRatingInfo(cd.RatingInfos[0])
- cc.Timespans = append(cc.Timespans, ts)
- }
- return cc, nil
- }
- if cd.DurationIndex < cd.TimeEnd.Sub(cd.TimeStart) {
- cd.DurationIndex = cd.TimeEnd.Sub(cd.TimeStart)
- }
- if cd.ToR == "" {
- cd.ToR = utils.MetaVoice
- }
- err := cd.LoadRatingPlans()
- if err != nil {
- return &CallCost{Cost: -1}, err
- }
- timespans := cd.splitInTimeSpans()
- cost := 0.0
-
- for i, ts := range timespans {
- ts.createIncrementsSlice()
- // only add connect fee if this is the first/only call cost request
- if cd.LoopIndex == 0 && i == 0 && ts.RateInterval != nil {
- cost += ts.RateInterval.Rating.ConnectFee
- }
- cost += ts.CalculateCost()
- }
-
- cc := cd.CreateCallCost()
- cc.Cost = cost
- cc.Timespans = timespans
-
- // global rounding
- roundingDecimals, roundingMethod := cc.GetLongestRounding()
- cc.Cost = utils.Round(cc.Cost, roundingDecimals, roundingMethod)
- cc.Timespans.Compress()
- cc.UpdateRatedUsage()
- return cc, err
-}
-
-/*
-Returns the approximate max allowed session for user balance. It will try the max amount received in the call descriptor
-If the user has no credit then it will return 0.
-If the user has postpayed plan it returns -1.
-*/
-func (origCD *CallDescriptor) getMaxSessionDuration(origAcc *Account) (time.Duration, error) {
- // clone the account for discarding chenges on debit dry run
- account := origAcc.Clone()
- if account.AllowNegative {
- return -1, nil
- }
- // for zero duration index
- if origCD.DurationIndex < origCD.TimeEnd.Sub(origCD.TimeStart) {
- origCD.DurationIndex = origCD.TimeEnd.Sub(origCD.TimeStart)
- }
- if origCD.ToR == "" {
- origCD.ToR = utils.MetaVoice
- }
- cd := origCD.Clone()
- initialDuration := cd.TimeEnd.Sub(cd.TimeStart)
- defaultBalance := account.GetDefaultMoneyBalance()
-
- //use this to check what increment was payed with debt
- initialDefaultBalanceValue := defaultBalance.GetValue()
-
- cc, err := cd.debit(account, true, false)
- if err != nil {
- return 0, err
- }
-
- // not enough credit for connect fee
- if cc.negativeConnectFee {
- return 0, nil
- }
-
- var totalCost float64
- var totalDuration time.Duration
- cc.Timespans.Decompress()
- for _, ts := range cc.Timespans {
- if cd.MaxRate > 0 && cd.MaxRateUnit > 0 {
- rate, _, rateUnit := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
- if rate/float64(rateUnit.Nanoseconds()) > cd.MaxRate/float64(cd.MaxRateUnit.Nanoseconds()) {
- return utils.MinDuration(initialDuration, totalDuration), nil
- }
- }
- if ts.Increments == nil {
- ts.createIncrementsSlice()
- }
- for _, incr := range ts.Increments {
- totalCost += incr.Cost
- if incr.BalanceInfo.Monetary != nil && incr.BalanceInfo.Monetary.UUID == defaultBalance.Uuid {
- initialDefaultBalanceValue -= incr.Cost
- if initialDefaultBalanceValue < 0 {
- // this increment was payed with debt
- // TODO: improve this check
- return utils.MinDuration(initialDuration, totalDuration), nil
-
- }
- }
- totalDuration += incr.Duration
- if totalDuration >= initialDuration {
- // we have enough, return
- return initialDuration, nil
- }
- }
- }
- return utils.MinDuration(initialDuration, totalDuration), nil
-}
-
-func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err error) {
- cd.account = nil // make sure it's not cached
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- account, err := cd.getAccount()
- if err != nil {
- return 0, err
- }
- acntIDs, err := account.GetUniqueSharedGroupMembers(cd)
- if err != nil {
- return nil, err
- }
- var lkIDs []string
- for acntID := range acntIDs {
- if acntID != cd.GetAccountKey() {
- lkIDs = append(lkIDs, utils.AccountPrefix+acntID)
- }
- }
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- duration, err = cd.getMaxSessionDuration(account)
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, lkIDs...)
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, utils.AccountPrefix+cd.GetAccountKey())
- return
-}
-
-// Interface method used to add/substract an amount of cents or bonus seconds (as returned by GetCost method)
-// from user's money balance.
-func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool) (cc *CallCost, err error) {
- if cd.GetDuration() == 0 {
- cc = cd.CreateCallCost()
- // add RatingInfo
- err := cd.LoadRatingPlans()
- if err == nil && len(cd.RatingInfos) > 0 {
- ts := &TimeSpan{
- TimeStart: cd.TimeStart,
- TimeEnd: cd.TimeEnd,
- }
- ts.setRatingInfo(cd.RatingInfos[0])
- cc.Timespans = append(cc.Timespans, ts)
- }
- return cc, nil
- }
- if cd.ToR == "" {
- cd.ToR = utils.MetaVoice
- }
- //log.Printf("Debit CD: %+v", cd)
- cc, err = account.debitCreditBalance(cd, !dryRun, dryRun, goNegative)
- //log.Printf("HERE: %+v %v", cc, err)
- if err != nil {
- utils.Logger.Err(fmt.Sprintf(" Error getting cost for account key <%s>: %s", cd.GetAccountKey(), err.Error()))
- return nil, err
- }
- cc.updateCost()
- cc.UpdateRatedUsage()
- cc.Timespans.Compress()
- if !dryRun {
- dm.SetAccount(account)
- }
- if cd.PerformRounding {
- cc.Round()
- roundIncrements := cc.GetRoundIncrements()
- if len(roundIncrements) != 0 {
- rcd := cc.CreateCallDescriptor()
- rcd.Increments = roundIncrements
- rcd.refundRounding()
- }
- }
- //log.Printf("OUT CC: ", cc)
- return
-}
-
-func (cd *CallDescriptor) Debit() (cc *CallCost, err error) {
- cd.account = nil // make sure it's not cached
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- // lock all group members
- account, err := cd.getAccount()
- if err != nil {
- return nil, err
- }
- initialAcnt := account.AsAccountSummary()
- acntIDs, sgerr := account.GetUniqueSharedGroupMembers(cd)
- if sgerr != nil {
- return nil, sgerr
- }
- var lkIDs []string
- for acntID := range acntIDs {
- if acntID != cd.GetAccountKey() {
- lkIDs = append(lkIDs, utils.AccountPrefix+acntID)
- }
- }
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- cc, err = cd.debit(account, cd.DryRun, !cd.DenyNegativeAccount)
- if err == nil {
- cc.AccountSummary = cd.AccountSummary(initialAcnt)
- }
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, lkIDs...)
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, utils.AccountPrefix+cd.GetAccountKey())
- return
-}
-
-// Interface method used to add/substract an amount of cents or bonus seconds (as returned by GetCost method)
-// from user's money balance.
-// This methods combines the Debit and GetMaxSessionDuration and will debit the max available time as returned
-// by the GetMaxSessionDuration method. The amount filed has to be filled in call descriptor.
-func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) {
- cd.account = nil // make sure it's not cached
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- account, err := cd.getAccount()
- if err != nil {
- return nil, err
- }
- initialAcnt := account.AsAccountSummary()
- acntIDs, err := account.GetUniqueSharedGroupMembers(cd)
- if err != nil {
- return nil, err
- }
- var lkIDs []string
- for acntID := range acntIDs {
- if acntID != cd.GetAccountKey() {
- lkIDs = append(lkIDs, utils.AccountPrefix+acntID)
- }
- }
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- remainingDuration, err := cd.getMaxSessionDuration(account)
- if err != nil && cd.GetDuration() > 0 {
- return nil, err
- }
- // check ForceDuartion
- if cd.ForceDuration && !account.AllowNegative && remainingDuration < cd.GetDuration() {
- return nil, utils.ErrInsufficientCredit
- }
- if err != nil || remainingDuration == 0 {
- cc = cd.CreateCallCost()
- cc.AccountSummary = cd.AccountSummary(initialAcnt)
- if cd.GetDuration() == 0 {
- // add RatingInfo
- err = cd.LoadRatingPlans()
- if err == nil && len(cd.RatingInfos) > 0 {
- ts := &TimeSpan{
- TimeStart: cd.TimeStart,
- TimeEnd: cd.TimeEnd,
- }
- ts.setRatingInfo(cd.RatingInfos[0])
- cc.Timespans = append(cc.Timespans, ts)
- }
- return
- }
- return
- }
- if remainingDuration > 0 { // for postpaying client returns -1
- initialDuration := cd.GetDuration()
- cd.TimeEnd = cd.TimeStart.Add(remainingDuration)
- cd.DurationIndex -= initialDuration - remainingDuration
- }
- cc, err = cd.debit(account, cd.DryRun, !cd.DenyNegativeAccount)
- if err == nil {
- cc.AccountSummary = cd.AccountSummary(initialAcnt)
- }
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, lkIDs...)
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, utils.AccountPrefix+cd.GetAccountKey())
- return cc, err
-}
-
-// refundIncrements has no locks
-// returns the updated account referenced by the CallDescriptor
-func (cd *CallDescriptor) refundIncrements() (acnt *Account, err error) {
- accountsCache := make(map[string]*Account)
- for _, increment := range cd.Increments {
- // work around for the refund from CDRServer:
- // for the calls with Cost 0 but with at least a TimeSpan it will make the information
- // from BalanceInfo nil so here we can ignore all increments with BalanceInfo nil
- if increment.BalanceInfo == nil {
- continue
- }
-
- account, found := accountsCache[increment.BalanceInfo.AccountID]
- if !found {
- if acc, err := dm.GetAccount(increment.BalanceInfo.AccountID); err == nil && acc != nil {
- account = acc
- accountsCache[increment.BalanceInfo.AccountID] = account
- // will save the account only once at the end of the function
- defer dm.SetAccount(account)
- }
- }
- if account == nil {
- utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountID))
- continue
- }
- //utils.Logger.Info(fmt.Sprintf("Refunding increment %+v", increment))
- var balance *Balance
- unitType := cd.ToR
- cc := cd.CreateCallCost()
- if increment.BalanceInfo.Unit != nil && increment.BalanceInfo.Unit.UUID != "" {
- if balance = account.BalanceMap[unitType].GetBalance(increment.BalanceInfo.Unit.UUID); balance == nil {
- return
- }
- balance.AddValue(float64(increment.Duration.Nanoseconds()))
- account.countUnits(-float64(increment.Duration.Nanoseconds()), unitType, cc, balance)
- }
- // check money too
- if increment.BalanceInfo.Monetary != nil && increment.BalanceInfo.Monetary.UUID != "" {
- if balance = account.BalanceMap[utils.MetaMonetary].GetBalance(increment.BalanceInfo.Monetary.UUID); balance == nil {
- return
- }
- balance.AddValue(increment.Cost)
- account.countUnits(-increment.Cost, utils.MetaMonetary, cc, balance)
- }
- }
- acnt = accountsCache[utils.ConcatenatedKey(cd.Tenant, cd.Account)]
- return
-
-}
-
-func (cd *CallDescriptor) RefundIncrements() (acnt *Account, err error) {
- // get account list for locking
- // all must be locked in order to use cache
- cd.Increments.Decompress()
- accMap := make(utils.StringMap)
- for _, increment := range cd.Increments {
- if increment.BalanceInfo == nil {
- continue
- }
- if increment.BalanceInfo.Monetary != nil || increment.BalanceInfo.Unit != nil {
- accMap[utils.AccountPrefix+increment.BalanceInfo.AccountID] = true
- }
- }
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- acnt, err = cd.refundIncrements()
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, accMap.Slice()...)
- return
-}
-
-func (cd *CallDescriptor) refundRounding() (err error) {
- // get account list for locking
- // all must be locked in order to use cache
- accountsCache := make(map[string]*Account)
- for _, increment := range cd.Increments {
- account, found := accountsCache[increment.BalanceInfo.AccountID]
- if !found {
- if acc, err := dm.GetAccount(increment.BalanceInfo.AccountID); err == nil && acc != nil {
- account = acc
- accountsCache[increment.BalanceInfo.AccountID] = account
- // will save the account only once at the end of the function
- defer dm.SetAccount(account)
- }
- }
- if account == nil {
- utils.Logger.Warning(fmt.Sprintf("Could not get the account to be refunded: %s", increment.BalanceInfo.AccountID))
- continue
- }
- cc := cd.CreateCallCost()
- if increment.BalanceInfo.Monetary != nil {
- var balance *Balance
- if balance = account.BalanceMap[utils.MetaMonetary].GetBalance(increment.BalanceInfo.Monetary.UUID); balance == nil {
- return
- }
- balance.AddValue(-increment.Cost)
- account.countUnits(increment.Cost, utils.MetaMonetary, cc, balance)
- }
- }
- return
-}
-
-func (cd *CallDescriptor) RefundRounding() (err error) {
- accMap := make(utils.StringMap)
- for _, inc := range cd.Increments {
- accMap[utils.AccountPrefix+inc.BalanceInfo.AccountID] = true
- }
- _, err = guardian.Guardian.Guard(func() (iface interface{}, err error) {
- err = cd.refundRounding()
- return
- }, config.CgrConfig().GeneralCfg().LockingTimeout, accMap.Slice()...)
- return
-}
-
-// Creates a CallCost structure copying related data from CallDescriptor
-func (cd *CallDescriptor) CreateCallCost() *CallCost {
- return &CallCost{
- Category: cd.Category,
- Tenant: cd.Tenant,
- Subject: cd.Subject,
- Account: cd.Account,
- Destination: cd.Destination,
- ToR: cd.ToR,
- deductConnectFee: cd.LoopIndex == 0,
- }
-}
-
-func (cd *CallDescriptor) Clone() *CallDescriptor {
- return &CallDescriptor{
- Category: cd.Category,
- Tenant: cd.Tenant,
- Subject: cd.Subject,
- Account: cd.Account,
- Destination: cd.Destination,
- TimeStart: cd.TimeStart,
- TimeEnd: cd.TimeEnd,
- LoopIndex: cd.LoopIndex,
- DurationIndex: cd.DurationIndex,
- MaxRate: cd.MaxRate,
- MaxRateUnit: cd.MaxRateUnit,
- MaxCostSoFar: cd.MaxCostSoFar,
- FallbackSubject: cd.FallbackSubject,
- ToR: cd.ToR,
- ForceDuration: cd.ForceDuration,
- PerformRounding: cd.PerformRounding,
- DryRun: cd.DryRun,
- CgrID: cd.CgrID,
- RunID: cd.RunID,
- }
-
-}
-
-// AccountSummary returns the AccountSummary for cached account
-func (cd *CallDescriptor) AccountSummary(initialAcnt *AccountSummary) *AccountSummary {
- if cd.account == nil {
- return nil
- }
- acntSummary := cd.account.AsAccountSummary()
- for _, initialBal := range initialAcnt.BalanceSummaries {
- for _, currentBal := range acntSummary.BalanceSummaries {
- if currentBal.UUID == initialBal.UUID {
- currentBal.Initial = initialBal.Value
- break
- }
- }
- }
- return acntSummary
-}
-
-// FieldAsInterface is part of utils.DataProvider
-func (cd *CallDescriptor) FieldAsInterface(fldPath []string) (fldVal interface{}, err error) {
- if len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- return utils.ReflectFieldInterface(cd, fldPath[0], utils.ExtraFields)
-}
-
-// FieldAsString is part of utils.DataProvider
-func (cd *CallDescriptor) FieldAsString(fldPath []string) (fldVal string, err error) {
- if len(fldPath) == 0 {
- return "", utils.ErrNotFound
- }
- return utils.ReflectFieldAsString(cd, fldPath[0], utils.ExtraFields)
-}
-
-// String is part of utils.DataProvider
-func (cd *CallDescriptor) String() string {
- return utils.ToJSON(cd)
-}
-
-// RemoteHost is part of utils.DataProvider
-func (cd *CallDescriptor) RemoteHost() net.Addr {
- return utils.LocalAddr()
-}
-
-type CallDescriptorWithAPIOpts struct {
- *CallDescriptor
- APIOpts map[string]interface{}
-}
diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go
deleted file mode 100644
index 8a160b50c..000000000
--- a/engine/calldesc_test.go
+++ /dev/null
@@ -1,2017 +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 (
- "log"
- "reflect"
- "sync"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- marsh = NewCodecMsgpackMarshaler()
-)
-
-func init() {
- dm.DataDB().Flush("")
- populateDB()
-}
-
-func populateDB() {
- ats := []*Action{
- {ActionType: "*topup",
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}},
- {ActionType: "*topup",
- Balance: &BalanceFilter{Type: utils.StringPointer(utils.MetaVoice),
- Weight: utils.Float64Pointer(20),
- Value: &utils.ValueFormula{Static: 10 * float64(time.Second)},
- DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}},
- }
-
- ats1 := []*Action{
- {ActionType: "*topup",
- Balance: &BalanceFilter{
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10}}, Weight: 10},
- {ActionType: "*reset_account", Weight: 20},
- }
-
- minu := &Account{
- ID: "vdf:minu",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {&Balance{Value: 50}},
- utils.MetaVoice: {
- &Balance{Value: 200 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("NAT"), Weight: 10},
- &Balance{Value: 100 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("RET"), Weight: 20},
- }},
- }
- broker := &Account{
- ID: "vdf:broker",
- BalanceMap: map[string]Balances{
- utils.MetaVoice: {
- &Balance{Value: 20 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("NAT"),
- Weight: 10, RatingSubject: "rif"},
- &Balance{Value: 100 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("RET"), Weight: 20},
- }},
- }
- luna := &Account{
- ID: "vdf:luna",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 0, Weight: 20},
- }},
- }
- // this is added to test if csv load tests account will not overwrite balances
- minitsboy := &Account{
- ID: "vdf:minitsboy",
- BalanceMap: map[string]Balances{
- utils.MetaVoice: {
- &Balance{Value: 20 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("NAT"),
- Weight: 10, RatingSubject: "rif"},
- &Balance{Value: 100 * float64(time.Second),
- DestinationIDs: utils.NewStringMap("RET"), Weight: 20},
- },
- utils.MetaMonetary: {
- &Balance{Value: 100, Weight: 10},
- },
- },
- }
- max := &Account{
- ID: "cgrates.org:max",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 11, Weight: 20},
- }},
- }
- money := &Account{
- ID: "cgrates.org:money",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: 10000, Weight: 10},
- }},
- }
- if dm.dataDB != nil {
- dm.SetActions("TEST_ACTIONS", ats, utils.NonTransactional)
- dm.SetActions("TEST_ACTIONS_ORDER", ats1, utils.NonTransactional)
- dm.SetAccount(broker)
- dm.SetAccount(minu)
- dm.SetAccount(minitsboy)
- dm.SetAccount(luna)
- dm.SetAccount(max)
- dm.SetAccount(money)
- } else {
- log.Fatal("Could not connect to db!")
- }
-}
-
-func debitTest(t *testing.T, wg *sync.WaitGroup) {
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 30, 59, 0, time.UTC)
- cd := &CallDescriptor{Category: "call",
- Tenant: "cgrates.org",
- Account: "moneyp", Subject: "nt",
- Destination: "49", TimeStart: t1,
- TimeEnd: t2, LoopIndex: 0}
- if _, err := cd.Debit(); err != nil {
- t.Errorf("Error debiting balance: %s", err)
- }
- wg.Done()
-}
-
-func TestSerialDebit(t *testing.T) {
- var wg sync.WaitGroup
- initialBalance := 10000.0
- moneyConcurent := &Account{
- ID: "cgrates.org:moneyp",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: initialBalance, Weight: 10},
- }},
- }
- if err := dm.SetAccount(moneyConcurent); err != nil {
- t.Error(err)
- }
- debitsToDo := 50
- for i := 0; i < debitsToDo; i++ {
- wg.Add(1)
- debitTest(t, &wg)
- }
- wg.Wait()
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 30, 59, 0, time.UTC)
- cd := &CallDescriptor{Category: "call",
- Tenant: "cgrates.org", Account: "moneyp", Subject: "nt",
- Destination: "49", TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
-
- acc, err := cd.getAccount()
- if err != nil {
- t.Errorf("Error debiting balance: %+v", err)
- }
- expBalance := initialBalance - float64(debitsToDo*60)
- if acc.BalanceMap[utils.MetaMonetary][0].GetValue() != expBalance {
- t.Errorf("Balance does not match: %f, expected %f",
- acc.BalanceMap[utils.MetaMonetary][0].GetValue(), expBalance)
- }
-
-}
-
-func TestParallelDebit(t *testing.T) {
- var wg sync.WaitGroup
- initialBalance := 10000.0
- moneyConcurent := &Account{
- ID: "cgrates.org:moneyp",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Value: initialBalance, Weight: 10},
- }},
- }
- if err := dm.SetAccount(moneyConcurent); err != nil {
- t.Error(err)
- }
- debitsToDo := 50
- for i := 0; i < debitsToDo; i++ {
- wg.Add(1)
- go debitTest(t, &wg)
- }
- wg.Wait()
- time.Sleep(10 * time.Millisecond)
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 30, 59, 0, time.UTC)
- cd := &CallDescriptor{
- Category: "call", Tenant: "cgrates.org",
- Account: "moneyp", Subject: "nt", Destination: "49",
- TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
-
- acc, err := cd.getAccount()
- if err != nil {
- t.Errorf("Error debiting balance: %+v", err)
- }
- expBalance := initialBalance - float64(debitsToDo*60)
- if acc.BalanceMap[utils.MetaMonetary][0].GetValue() != expBalance {
- t.Errorf("Balance does not match: %f, expected %f",
- acc.BalanceMap[utils.MetaMonetary][0].GetValue(), expBalance)
- }
-
-}
-
-func TestSplitSpans(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, ToR: utils.MetaVoice}
-
- cd.LoadRatingPlans()
- timespans := cd.splitInTimeSpans()
- if len(timespans) != 2 {
- t.Log(cd.RatingInfos)
- t.Error("Wrong number of timespans: ", len(timespans))
- }
-}
-
-func TestSplitSpansWeekend(t *testing.T) {
- cd := &CallDescriptor{
- Category: "postpaid",
- ToR: utils.MetaVoice,
- Tenant: "foehn",
- Subject: "foehn",
- Account: "foehn",
- Destination: "0034678096720",
- TimeStart: time.Date(2015, 4, 24, 7, 59, 4, 0, time.UTC),
- TimeEnd: time.Date(2015, 4, 24, 8, 2, 0, 0, time.UTC),
- LoopIndex: 0,
- DurationIndex: 176 * time.Second,
- FallbackSubject: "",
- RatingInfos: RatingInfos{
- &RatingInfo{
- MatchedSubject: "*out:foehn:postpaid:foehn",
- MatchedPrefix: "0034678",
- MatchedDestId: "SPN_MOB",
- ActivationTime: time.Date(2015, 4, 23, 0, 0, 0, 0, time.UTC),
- RateIntervals: []*RateInterval{
- {
- Timing: &RITiming{
- WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
- StartTime: "08:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 6,
- Rates: RateGroups{
- &RGRate{Value: 1, RateIncrement: time.Second, RateUnit: time.Second},
- },
- },
- },
- {
- Timing: &RITiming{
- WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 6,
- Rates: RateGroups{
- &RGRate{Value: 1, RateIncrement: time.Second, RateUnit: time.Second},
- },
- },
- },
- {
- Timing: &RITiming{
- WeekDays: []time.Weekday{time.Saturday, time.Sunday},
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 6,
- Rates: RateGroups{
- &RGRate{Value: 1, RateIncrement: time.Second, RateUnit: time.Second},
- },
- },
- },
- },
- },
- },
- }
-
- timespans := cd.splitInTimeSpans()
- if len(timespans) != 2 {
- t.Log(cd.RatingInfos)
- t.Error("Wrong number of timespans: ", len(timespans))
- }
- if timespans[0].RateInterval == nil ||
- timespans[0].RateInterval.Timing.StartTime != "00:00:00" ||
- timespans[1].RateInterval == nil ||
- timespans[1].RateInterval.Timing.StartTime != "08:00:00" {
- t.Errorf("Error setting rateinterval: %+v %+v", timespans[0].RateInterval.Timing.StartTime, timespans[1].RateInterval.Timing.StartTime)
- }
-}
-
-func TestSplitSpansRoundToIncrements(t *testing.T) {
- t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC)
- t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "test", Subject: "trp",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, DurationIndex: 132 * time.Second}
-
- cd.LoadRatingPlans()
- timespans := cd.splitInTimeSpans()
- if len(timespans) != 2 {
- t.Logf("%+v", cd)
- t.Log(cd.RatingInfos)
- t.Error("Wrong number of timespans: ", len(timespans))
- }
- var d time.Duration
- for _, ts := range timespans {
- d += ts.GetDuration()
- }
- if d != 132*time.Second {
- t.Error("Wrong duration for timespans: ", d)
- }
-}
-
-func TestCalldescHolliday(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2015, time.May, 1, 13, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, time.May, 1, 13, 35, 26, 0, time.UTC),
- RatingInfos: RatingInfos{
- &RatingInfo{
- RateIntervals: RateIntervalList{
- &RateInterval{
- Timing: &RITiming{WeekDays: utils.WeekDays{1, 2, 3, 4, 5}, StartTime: "00:00:00"},
- Weight: 10,
- },
- &RateInterval{
- Timing: &RITiming{WeekDays: utils.WeekDays{6, 7}, StartTime: "00:00:00"},
- Weight: 10,
- },
- &RateInterval{
- Timing: &RITiming{Months: utils.Months{time.May}, MonthDays: utils.MonthDays{1}, StartTime: "00:00:00"},
- Weight: 20,
- },
- },
- },
- },
- }
- timespans := cd.splitInTimeSpans()
- if len(timespans) != 1 {
- t.Error("Error assiging holidy rate interval: ", timespans)
- }
- if timespans[0].RateInterval.Timing.MonthDays == nil {
- t.Errorf("Error setting holiday rate interval: %+v", timespans[0].RateInterval.Timing)
- }
-}
-
-func TestGetCost(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestGetCostRounding(t *testing.T) {
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 33, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "call", Tenant: "cgrates.org",
- Subject: "round", Destination: "49",
- TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
- result, _ := cd.GetCost()
- if result.Cost != 0.3001 || result.GetConnectFee() != 0 { // should be 0.3 :(
- t.Error("bad cost", utils.ToIJSON(result))
- }
-}
-
-func TestDebitRounding(t *testing.T) {
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 33, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "call", Tenant: "cgrates.org",
- Subject: "round", Destination: "49",
- TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
- result, _ := cd.Debit()
- if result.Cost != 0.30006 || result.GetConnectFee() != 0 { // should be 0.3 :(
- t.Error("bad cost", utils.ToJSON(result))
- }
-}
-
-func TestDebitPerformRounding(t *testing.T) {
- t1 := time.Date(2017, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2017, time.February, 2, 17, 33, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "call",
- Tenant: "cgrates.org", Subject: "round", Destination: "49",
- TimeStart: t1, TimeEnd: t2, LoopIndex: 0, PerformRounding: true}
- if result, err := cd.Debit(); err != nil {
- t.Error(err)
- } else if result.Cost != 0.3001 || result.GetConnectFee() != 0 { // should be 0.3 :(
- t.Error("bad cost", utils.ToIJSON(result))
- }
-}
-
-func TestGetCostZero(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 0}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 0}
- if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestGetCostTimespans(t *testing.T) {
- t1 := time.Date(2013, time.October, 8, 9, 23, 2, 0, time.UTC)
- t2 := time.Date(2013, time.October, 8, 9, 24, 27, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "test", Subject: "trp",
- Destination: "0256", TimeStart: t1, TimeEnd: t2,
- LoopIndex: 0, DurationIndex: 85 * time.Second}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "test", Subject: "trp", Destination: "0256", Cost: 85}
- if result.Cost != expected.Cost || result.GetConnectFee() != 0 || len(result.Timespans) != 2 {
- t.Errorf("Expected %+v was %+v", expected, result)
- }
-
-}
-
-func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) {
- t1 := time.Date(2012, time.February, 27, 23, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "CUSTOMER_1",
- Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2,
- LoopIndex: 0, DurationIndex: t2.Sub(t1)}
- result, _ := cd.GetCost()
- if len(result.Timespans) != 3 ||
- !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
- !result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) {
- for _, ts := range result.Timespans {
- t.Logf("TS %+v", ts)
- }
- t.Errorf("Expected %+v was %+v", 3, len(result.Timespans))
- }
-}
-
-func TestGetCostRatingPlansAndRatingIntervalsMore(t *testing.T) {
- t1 := time.Date(2012, time.February, 27, 9, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm",
- Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)}
- result, _ := cd.GetCost()
- if len(result.Timespans) != 4 ||
- !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
- !result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
- !result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) {
- for _, ts := range result.Timespans {
- t.Logf("TS %+v", ts)
- }
- t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
- }
-}
-
-func TestGetCostRatingPlansAndRatingIntervalsMoreDays(t *testing.T) {
- t1 := time.Date(2012, time.February, 20, 9, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 23, 18, 10, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm",
- Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)}
- result, _ := cd.GetCost()
- if len(result.Timespans) != 8 ||
- !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
- !result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
- !result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) ||
- !result.Timespans[3].TimeEnd.Equal(result.Timespans[4].TimeStart) ||
- !result.Timespans[4].TimeEnd.Equal(result.Timespans[5].TimeStart) ||
- !result.Timespans[5].TimeEnd.Equal(result.Timespans[6].TimeStart) ||
- !result.Timespans[6].TimeEnd.Equal(result.Timespans[7].TimeStart) {
- for _, ts := range result.Timespans {
- t.Logf("TS %+v", ts)
- }
- t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
- }
-}
-
-func TestGetCostRatingPlansAndRatingIntervalsMoreDaysWeekend(t *testing.T) {
- t1 := time.Date(2012, time.February, 24, 9, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 27, 18, 10, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm",
- Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, DurationIndex: t2.Sub(t1)}
- result, _ := cd.GetCost()
- if len(result.Timespans) != 5 ||
- !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) ||
- !result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) ||
- !result.Timespans[2].TimeEnd.Equal(result.Timespans[3].TimeStart) ||
- !result.Timespans[3].TimeEnd.Equal(result.Timespans[4].TimeStart) {
- for _, ts := range result.Timespans {
- t.Logf("TS %+v", ts)
- }
- t.Errorf("Expected %+v was %+v", 4, len(result.Timespans))
- }
-}
-
-func TestGetCostRateGroups(t *testing.T) {
- t1 := time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC)
- t2 := time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "test", Subject: "trp",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, DurationIndex: 132 * time.Second}
-
- result, err := cd.GetCost()
- if err != nil {
- t.Error("Error getting cost: ", err)
- }
- if result.Cost != 132 {
- t.Error("Error calculating cost: ", result.Timespans)
- }
-}
-
-func TestGetCostNoConnectFee(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2, LoopIndex: 1}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2700}
- // connect fee is not added because LoopIndex is 1
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestGetCostAccount(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Account: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestFullDestNotFound(t *testing.T) {
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256308200", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0256", Cost: 2701}
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- t.Log(cd.RatingInfos)
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestSubjectNotFound(t *testing.T) {
- t1 := time.Date(2013, time.February, 1, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2013, time.February, 1, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "not_exiting",
- Destination: "025740532", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701}
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- //t.Logf("%+v", result.Timespans[0].RateInterval)
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestSubjectNotFoundCostNegativeOne(t *testing.T) {
- t1 := time.Date(2013, time.February, 1, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2013, time.February, 1, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "cgrates.org", Subject: "not_exiting",
- Destination: "025740532", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- if result.Cost != -1 || result.GetConnectFee() != 0 {
- //t.Logf("%+v", result.Timespans[0].RateInterval)
- t.Errorf("Expected -1 was %v", result)
- }
-}
-
-func TestMultipleRatingPlans(t *testing.T) {
- t1 := time.Date(2012, time.February, 8, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 8, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 2701}
- if result.Cost != expected.Cost || result.GetConnectFee() != 1 {
- t.Log(result.Timespans)
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestSpansMultipleRatingPlans(t *testing.T) {
- t1 := time.Date(2012, time.February, 7, 23, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
- cc, _ := cd.GetCost()
- if cc.Cost != 2100 || cc.GetConnectFee() != 0 {
- t.Errorf("Expected %v was %v (%v)", 2100, cc, cc.GetConnectFee())
- }
-}
-
-func TestLessThanAMinute(t *testing.T) {
- t1 := time.Date(2012, time.February, 8, 23, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 8, 23, 50, 30, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0257308200", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 15}
- if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestUniquePrice(t *testing.T) {
- t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 8, 23, 50, 21, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0723045326", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0723", Cost: 1810.5}
- if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMinutesCost(t *testing.T) {
- t1 := time.Date(2012, time.February, 8, 22, 50, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 8, 22, 51, 50, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0723", TimeStart: t1, TimeEnd: t2}
- result, _ := cd.GetCost()
- expected := &CallCost{Tenant: "vdf", Subject: "minutosu", Destination: "0723", Cost: 55}
- if result.Cost != expected.Cost || result.GetConnectFee() != 0 {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMaxSessionTimeNoAccount(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "ttttttt",
- Destination: "0723"}
- result, err := cd.GetMaxSessionDuration()
- if result != 0 || err == nil {
- t.Errorf("Expected %v was %v (%v)", 0, result, err)
- }
-}
-
-func TestMaxSessionTimeWithAccount(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu",
- Destination: "0723",
- }
- result, err := cd.GetMaxSessionDuration()
- expected := time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMaxSessionTimeWithMaxRate(t *testing.T) {
- ap, err := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- if err != nil {
- t.FailNow()
- }
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:12345": true, "cgrates.org:123456": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "12345",
- Account: "12345",
- Destination: "447956",
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC),
- MaxRate: 1.0,
- MaxRateUnit: time.Minute,
- }
- result, err := cd.GetMaxSessionDuration()
- expected := 40 * time.Second
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMaxSessionTimeWithMaxCost(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:max": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err := cd.GetMaxSessionDuration()
- expected := 10 * time.Second
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestGetMaxSessiontWithBlocker(t *testing.T) {
- ap, _ := dm.GetActionPlan("BLOCK_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:block": true}
- at.Execute(nil, nil)
- }
- acc, err := dm.GetAccount("cgrates.org:block")
- if err != nil {
- t.Error("error getting account: ", err)
- }
- if len(acc.BalanceMap[utils.MetaMonetary]) != 2 ||
- acc.BalanceMap[utils.MetaMonetary][0].Blocker != true {
- for _, b := range acc.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("Error executing action plan on account: ", acc.BalanceMap[utils.MetaMonetary])
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "block",
- Account: "block",
- Destination: "0723",
- TimeStart: time.Date(2016, 1, 13, 14, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2016, 1, 13, 14, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err := cd.GetMaxSessionDuration()
- expected := 17 * time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v (%v)", expected, result, err)
- }
- cd = &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "block",
- Account: "block",
- Destination: "444",
- TimeStart: time.Date(2016, 1, 13, 14, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2016, 1, 13, 14, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err = cd.GetMaxSessionDuration()
- expected = 30 * time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v (%v)", expected, result, err)
- }
-}
-
-func TestGetMaxSessiontWithBlockerEmpty(t *testing.T) {
- ap, _ := dm.GetActionPlan("BLOCK_EMPTY_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:block_empty": true}
- at.Execute(nil, nil)
- }
- acc, err := dm.GetAccount("cgrates.org:block_empty")
- if err != nil {
- t.Error("error getting account: ", err)
- }
- if len(acc.BalanceMap[utils.MetaMonetary]) != 2 ||
- acc.BalanceMap[utils.MetaMonetary][0].Blocker != true {
- for _, b := range acc.BalanceMap[utils.MetaMonetary] {
- t.Logf("B: %+v", b)
- }
- t.Error("Error executing action plan on account: ", acc.BalanceMap[utils.MetaMonetary])
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "block",
- Account: "block_empty",
- Destination: "0723",
- TimeStart: time.Date(2016, 1, 13, 14, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2016, 1, 13, 14, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err := cd.GetMaxSessionDuration()
- expected := 0 * time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v (%v)", expected, result, err)
- }
- cd = &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "block",
- Account: "block_empty",
- Destination: "444",
- TimeStart: time.Date(2016, 1, 13, 14, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2016, 1, 13, 14, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err = cd.GetMaxSessionDuration()
- expected = 30 * time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v (%v)", expected, result, err)
- }
-}
-
-func TestGetCostWithMaxCost(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:max": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.GetCost()
- expected := 1800.0
- if cc.Cost != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, cc.Cost)
- }
-}
-
-func TestGetCostRoundingIssue(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 51, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.GetCost()
- expected := 0.17
- if cc.Cost != expected || err != nil {
- t.Log(utils.ToIJSON(cc))
- t.Errorf("Expected %v was %+v", expected, cc)
- }
-}
-
-func TestGetCostRatingInfoOnZeroTime(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.GetCost()
- if err != nil ||
- len(cc.Timespans) != 1 ||
- cc.Timespans[0].MatchedDestId != "RET" ||
- cc.Timespans[0].MatchedSubject != "*out:cgrates.org:call:dy" ||
- cc.Timespans[0].MatchedPrefix != "0723" ||
- cc.Timespans[0].RatingPlanId != "DY_PLAN" {
- t.Error("MatchedInfo not added:", utils.ToIJSON(cc))
- }
-}
-
-func TestDebitRatingInfoOnZeroTime(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.Debit()
- if err != nil ||
- cc == nil ||
- len(cc.Timespans) != 1 ||
- cc.Timespans[0].MatchedDestId != "RET" ||
- cc.Timespans[0].MatchedSubject != "*out:cgrates.org:call:dy" ||
- cc.Timespans[0].MatchedPrefix != "0723" ||
- cc.Timespans[0].RatingPlanId != "DY_PLAN" {
- t.Error("MatchedInfo not added:", utils.ToIJSON(cc))
- }
-}
-
-func TestMaxDebitRatingInfoOnZeroTime(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.MaxDebit()
- if err != nil ||
- len(cc.Timespans) != 1 ||
- cc.Timespans[0].MatchedDestId != "RET" ||
- cc.Timespans[0].MatchedSubject != "*out:cgrates.org:call:dy" ||
- cc.Timespans[0].MatchedPrefix != "0723" ||
- cc.Timespans[0].RatingPlanId != "DY_PLAN" {
- t.Error("MatchedInfo not added:", utils.ToIJSON(cc))
- }
-}
-
-func TestMaxDebitUnknowDest(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "9999999999",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 29, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.MaxDebit()
- if err == nil || err != utils.ErrUnauthorizedDestination {
- t.Errorf("Bad error reported %+v: %v", cc, err)
- }
-}
-
-func TestMaxDebitRoundingIssue(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 10, 26, 13, 29, 27, 0, time.UTC),
- TimeEnd: time.Date(2015, 10, 26, 13, 29, 51, 0, time.UTC),
- MaxCostSoFar: 0,
- PerformRounding: true,
- }
- acc, err := dm.GetAccount("cgrates.org:dy")
- if err != nil || acc.BalanceMap[utils.MetaMonetary][0].Value != 1 {
- t.Errorf("Error getting account: %+v (%v)", utils.ToIJSON(acc), err)
- }
-
- cc, err := cd.MaxDebit()
- expected := 0.17
- if cc.Cost != expected || err != nil {
- t.Log(utils.ToIJSON(cc))
- t.Errorf("Expected %v was %+v (%v)", expected, cc, err)
- }
- acc, err = dm.GetAccount("cgrates.org:dy")
- if err != nil || acc.BalanceMap[utils.MetaMonetary][0].Value != 1-expected {
- t.Errorf("Error getting account: %+v (%v)", utils.ToIJSON(acc), err)
- }
-}
-
-func TestDebitRoundingRefund(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:dy": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dy",
- Account: "dy",
- Destination: "0723123113",
- TimeStart: time.Date(2016, 3, 4, 13, 50, 00, 0, time.UTC),
- TimeEnd: time.Date(2016, 3, 4, 13, 53, 00, 0, time.UTC),
- MaxCostSoFar: 0,
- PerformRounding: true,
- }
- acc, err := dm.GetAccount("cgrates.org:dy")
- if err != nil || acc.BalanceMap[utils.MetaMonetary][0].Value != 1 {
- t.Errorf("Error getting account: %+v (%v)", utils.ToIJSON(acc), err)
- }
-
- cc, err := cd.Debit()
- expected := 0.3
- if cc.Cost != expected || err != nil {
- t.Log(utils.ToIJSON(cc))
- t.Errorf("Expected %v was %+v (%v)", expected, cc, err)
- }
- acc, err = dm.GetAccount("cgrates.org:dy")
- if err != nil || acc.BalanceMap[utils.MetaMonetary][0].Value != 1-expected {
- t.Errorf("Error getting account: %+v (%v)", utils.ToIJSON(acc), err)
- }
-}
-
-func TestMaxSessionTimeWithMaxCostFree(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:max": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 19, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 19, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- result, err := cd.GetMaxSessionDuration()
- expected := 30 * time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMaxDebitWithMaxCostFree(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:max": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 19, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 19, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cc, err := cd.MaxDebit()
- expected := 10.0
- if cc.Cost != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, cc.Cost)
- }
-}
-
-func TestGetCostWithMaxCostFree(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:max": true}
- at.Execute(nil, nil)
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 19, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 19, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
-
- cc, err := cd.GetCost()
- expected := 10.0
- if cc.Cost != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, cc.Cost)
- }
-}
-
-func TestMaxSessionTimeWithAccountShared(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP_SHARED0_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:empty0": true}
- at.Execute(nil, nil)
- }
- ap, _ = dm.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:empty10": true}
- at.Execute(nil, nil)
- }
-
- cd0 := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "rif",
- Account: "empty0",
- Destination: "0723",
- }
-
- cd1 := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "rif",
- Account: "empty10",
- Destination: "0723",
- }
-
- result0, err := cd0.GetMaxSessionDuration()
- result1, err := cd1.GetMaxSessionDuration()
- if result0 != result1/2 || err != nil {
- t.Errorf("Expected %v was %v, %v", result1/2, result0, err)
- }
-}
-
-func TestMaxDebitWithAccountShared(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP_SHARED0_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:empty0": true}
- at.Execute(nil, nil)
- }
- ap, _ = dm.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:empty10": true}
- at.Execute(nil, nil)
- }
-
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu",
- Account: "empty0",
- Destination: "0723",
- }
-
- cc, err := cd.MaxDebit()
- if err != nil || cc.Cost != 2.5 {
- t.Errorf("Wrong callcost in shared debit: %+v, %v", cc, err)
- }
- acc, _ := cd.getAccount()
- balanceMap := acc.BalanceMap[utils.MetaMonetary]
- if len(balanceMap) != 1 || balanceMap[0].GetValue() != 0 {
- t.Errorf("Wrong shared balance debited: %+v", balanceMap[0])
- }
- other, err := dm.GetAccount("vdf:empty10")
- if err != nil || other.BalanceMap[utils.MetaMonetary][0].GetValue() != 7.5 {
- t.Errorf("Error debiting shared balance: %+v", other.BalanceMap[utils.MetaMonetary][0])
- }
-}
-
-func TestMaxSessionTimeWithAccountAccount(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu_from_tm",
- Account: "minu",
- Destination: "0723",
- }
- result, err := cd.GetMaxSessionDuration()
- expected := time.Minute
- if result != expected || err != nil {
- t.Errorf("Expected %v was %v", expected, result)
- }
-}
-
-func TestMaxSessionTimeNoCredit(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "broker",
- Destination: "0723",
- ToR: utils.MetaVoice,
- }
- result, err := cd.GetMaxSessionDuration()
- if result != time.Minute || err != nil {
- t.Errorf("Expected %v was %v", time.Minute, result)
- }
-}
-
-func TestMaxSessionModifiesCallDesc(t *testing.T) {
- t1 := time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC)
- t2 := time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC)
- cd := &CallDescriptor{
- TimeStart: t1,
- TimeEnd: t2,
- Category: "0",
- Tenant: "vdf",
- Subject: "minu_from_tm",
- Account: "minu",
- Destination: "0723",
- DurationIndex: t2.Sub(t1),
- ToR: utils.MetaVoice,
- }
- initial := cd.Clone()
- _, err := cd.GetMaxSessionDuration()
- if err != nil {
- t.Error("Got error from max duration: ", err)
- }
- cd.account = nil // it's OK to cache the account
- if !reflect.DeepEqual(cd, initial) {
- t.Errorf("GetMaxSessionDuration is changing the call descriptor %+v != %+v", cd, initial)
- }
-}
-
-func TestMaxDebitDurationNoGreatherThanInitialDuration(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu_from_tm",
- Account: "minu",
- Destination: "0723",
- }
- initialDuration := cd.TimeEnd.Sub(cd.TimeStart)
- result, err := cd.GetMaxSessionDuration()
- if err != nil {
- t.Error("Got error from max duration: ", err)
- }
- if result > initialDuration {
- t.Error("max session duration greather than initial duration", initialDuration, result)
- }
-}
-
-func TestDebitAndMaxDebit(t *testing.T) {
- cd1 := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 34, 10, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu_from_tm",
- Account: "minu",
- Destination: "0723",
- }
- cd2 := cd1.Clone()
- cc1, err1 := cd1.Debit()
- cc2, err2 := cd2.MaxDebit()
- if err1 != nil || err2 != nil {
- t.Error("Error debiting and/or maxdebiting: ", err1, err2)
- }
- if cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 90*float64(time.Second) ||
- cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value != 80*float64(time.Second) {
- t.Error("Error setting the Unit.Value: ",
- cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value,
- cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value)
- }
- // make Unit.Values have the same value
- cc1.Timespans[0].Increments[0].BalanceInfo.Unit.Value = 0
- cc2.Timespans[0].Increments[0].BalanceInfo.Unit.Value = 0
- cc1.AccountSummary, cc2.AccountSummary = nil, nil // account changes, enforce here emptying the info so reflect can pass
- if !reflect.DeepEqual(cc1.Timespans, cc2.Timespans) {
- t.Log("CC1: ", utils.ToIJSON(cc1))
- t.Log("CC2: ", utils.ToIJSON(cc2))
- t.Error("Debit and MaxDebit differ")
- }
-}
-
-func TestMaxSesionTimeEmptyBalance(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "minu_from_tm",
- Account: "luna",
- Destination: "0723",
- }
- acc, _ := dm.GetAccount("vdf:luna")
- allowedTime, err := cd.getMaxSessionDuration(acc)
- if err != nil || allowedTime != 0 {
- t.Error("Error get max session for 0 acount", err)
- }
-}
-
-func TestMaxSesionTimeEmptyBalanceAndNoCost(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "one",
- Account: "luna",
- Destination: "112",
- }
- acc, _ := dm.GetAccount("vdf:luna")
- allowedTime, err := cd.getMaxSessionDuration(acc)
- if err != nil || allowedTime == 0 {
- t.Error("Error get max session for 0 acount", err)
- }
-}
-
-func TestMaxSesionTimeLong(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2015, 07, 24, 13, 37, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 07, 24, 15, 37, 0, 0, time.UTC),
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "money",
- Destination: "0723",
- }
- acc, _ := dm.GetAccount("cgrates.org:money")
- allowedTime, err := cd.getMaxSessionDuration(acc)
- if err != nil || allowedTime != cd.TimeEnd.Sub(cd.TimeStart) {
- t.Error("Error get max session for acount:", allowedTime, err)
- }
-}
-
-func TestMaxSesionTimeLongerThanMoney(t *testing.T) {
- cd := &CallDescriptor{
- TimeStart: time.Date(2015, 07, 24, 13, 37, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 07, 24, 16, 37, 0, 0, time.UTC),
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "money",
- Destination: "0723",
- }
- acc, _ := dm.GetAccount("cgrates.org:money")
- allowedTime, err := cd.getMaxSessionDuration(acc)
- expected, err := time.ParseDuration("9999s") // 1 is the connect fee
- if err != nil || allowedTime != expected {
- t.Log(utils.ToIJSON(acc))
- t.Errorf("Expected: %v got %v", expected, allowedTime)
- }
-}
-
-func TestDebitFromShareAndNormal(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:empty10": true}
- at.Execute(nil, nil)
- }
-
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "rif",
- Account: "empty10",
- Destination: "0723",
- }
- cc, err := cd.MaxDebit()
- acc, _ := cd.getAccount()
- balanceMap := acc.BalanceMap[utils.MetaMonetary]
- if err != nil || cc.Cost != 2.5 {
- t.Errorf("Debit from share and normal error: %+v, %v", cc, err)
- }
-
- if balanceMap[0].GetValue() != 10 || balanceMap[1].GetValue() != 27.5 {
- t.Errorf("Error debiting from right balance: %v %v", balanceMap[0].GetValue(), balanceMap[1].GetValue())
- }
-}
-
-func TestDebitFromEmptyShare(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP_EMPTY_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:emptyX": true}
- at.Execute(nil, nil)
- }
-
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "rif",
- Account: "emptyX",
- Destination: "0723",
- }
-
- cc, err := cd.MaxDebit()
- if err != nil || cc.Cost != 2.5 {
- t.Errorf("Debit from empty share error: %+v, %v", cc, err)
- }
- acc, _ := cd.getAccount()
- balanceMap := acc.BalanceMap[utils.MetaMonetary]
- if len(balanceMap) != 2 || balanceMap[0].GetValue() != 0 || balanceMap[1].GetValue() != -2.5 {
- t.Errorf("Error debiting from empty share: %+v", balanceMap[1].GetValue())
- }
-}
-
-func TestDebitNegatve(t *testing.T) {
- ap, _ := dm.GetActionPlan("POST_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"vdf:post": true}
- at.Execute(nil, nil)
- }
-
- cd := &CallDescriptor{
- TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 10, 21, 18, 34, 5, 0, time.UTC),
- Category: "0",
- Tenant: "vdf",
- Subject: "rif",
- Account: "post",
- Destination: "0723",
- }
- cc, err := cd.MaxDebit()
- //utils.PrintFull(cc)
- if err != nil || cc.Cost != 2.5 {
- t.Errorf("Debit from empty share error: %+v, %v", cc, err)
- }
- acc, _ := cd.getAccount()
- //utils.PrintFull(acc)
- balanceMap := acc.BalanceMap[utils.MetaMonetary]
- if len(balanceMap) != 1 || balanceMap[0].GetValue() != -2.5 {
- t.Errorf("Error debiting from empty share: %+v", balanceMap[0].GetValue())
- }
- cc, err = cd.MaxDebit()
- acc, _ = cd.getAccount()
- balanceMap = acc.BalanceMap[utils.MetaMonetary]
- //utils.LogFull(balanceMap)
- if err != nil || cc.Cost != 2.5 {
- t.Errorf("Debit from empty share error: %+v, %v", cc, err)
- }
- if len(balanceMap) != 1 || balanceMap[0].GetValue() != -5 {
- t.Errorf("Error debiting from empty share: %+v", balanceMap[0].GetValue())
- }
-}
-
-func TestMaxDebitZeroDefinedRate(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:12345": true}
- at.Execute(nil, nil)
- }
- cd1 := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "12345",
- Account: "12345",
- Destination: "447956",
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 0, 0, time.UTC),
- LoopIndex: 0,
- DurationIndex: 0}
- cc, err := cd1.MaxDebit()
- if err != nil {
- t.Error("Error maxdebiting: ", err)
- }
- if cc.GetDuration() != 49*time.Second {
- t.Error("Error obtaining max debit duration: ", cc.GetDuration())
- }
-
- if cc.Cost != 0.91 {
- t.Error("Error in max debit cost: ", cc.Cost)
- }
-}
-
-func TestMaxDebitForceDuration(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:12345": true}
- at.Execute(nil, nil)
- }
- cd1 := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "12345",
- Account: "12345",
- Destination: "447956",
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 40, 0, time.UTC),
- LoopIndex: 0,
- DurationIndex: 0,
- ForceDuration: true,
- }
- _, err := cd1.MaxDebit()
- if err != utils.ErrInsufficientCredit {
- t.Fatal("Error forcing duration: ", err)
- }
-}
-
-func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:12345": true}
- at.Execute(nil, nil)
- }
- cd1 := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "12345",
- Account: "12345",
- Destination: "447956",
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 0, 40, 0, time.UTC),
- LoopIndex: 0,
- DurationIndex: 0}
- cc, err := cd1.MaxDebit()
- if err != nil {
- t.Fatal("Error maxdebiting: ", err)
- }
- if cc.GetDuration() != 40*time.Second {
- t.Error("Error obtaining max debit duration: ", cc.GetDuration())
- }
- if cc.Cost != 0.01 {
- t.Error("Error in max debit cost: ", cc.Cost)
- }
-}
-
-func TestMaxDebitConsumesMinutes(t *testing.T) {
- ap, _ := dm.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional)
- for _, at := range ap.ActionTimings {
- at.accountIDs = utils.StringMap{"cgrates.org:12345": true}
- at.Execute(nil, nil)
- }
- cd1 := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "12345",
- Account: "12345",
- Destination: "447956",
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 0, 5, 0, time.UTC),
- LoopIndex: 0,
- DurationIndex: 0}
- cd1.MaxDebit()
- if cd1.account.BalanceMap[utils.MetaVoice][0].GetValue() != 20*float64(time.Second) {
- t.Error("Error using minutes: ",
- cd1.account.BalanceMap[utils.MetaVoice][0].GetValue())
- }
-}
-
-func TestCDGetCostANY(t *testing.T) {
- cd1 := &CallDescriptor{
- Category: "data",
- Tenant: "cgrates.org",
- Subject: "rif",
- Destination: utils.MetaAny,
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 0, 1, 0, time.UTC),
- ToR: utils.MetaData,
- }
- cc, err := cd1.GetCost()
- if err != nil || cc.Cost != 60 {
- t.Errorf("Error getting *any dest: %+v %v", cc, err)
- }
-}
-
-func TestCDSplitInDataSlots(t *testing.T) {
- cd := &CallDescriptor{
- Category: "data",
- Tenant: "cgrates.org",
- Subject: "rif",
- Destination: utils.MetaAny,
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC),
- ToR: utils.MetaData,
- DurationIndex: 65 * time.Second,
- }
- cd.LoadRatingPlans()
- timespans := cd.splitInTimeSpans()
- if len(timespans) != 2 {
- t.Log(cd.RatingInfos[0])
- t.Error("Wrong number of timespans: ", len(timespans))
- }
-}
-
-func TestCDDataGetCost(t *testing.T) {
- cd := &CallDescriptor{
- Category: "data",
- Tenant: "cgrates.org",
- Subject: "rif",
- Destination: utils.MetaAny,
- TimeStart: time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2014, 3, 4, 6, 1, 5, 0, time.UTC),
- ToR: utils.MetaData,
- }
- cc, err := cd.GetCost()
- if err != nil || cc.Cost != 65 {
- t.Errorf("Error getting *any dest: %+v %v", cc, err)
- }
-}
-
-func TestCDRefundIncrements(t *testing.T) {
- ub := &Account{
- ID: "test:ref",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Uuid: "moneya", Value: 100},
- },
- utils.MetaVoice: {
- &Balance{Uuid: "minutea",
- Value: 10 * float64(time.Second),
- Weight: 20,
- DestinationIDs: utils.StringMap{"NAT": true}},
- &Balance{Uuid: "minuteb",
- Value: 10 * float64(time.Second),
- DestinationIDs: utils.StringMap{"RET": true}},
- },
- },
- }
- dm.SetAccount(ub)
- increments := Increments{
- &Increment{Cost: 2, BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}},
- &Increment{Cost: 2, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "minutea"},
- Monetary: &MonetaryInfo{UUID: "moneya"}, AccountID: ub.ID}},
- &Increment{Duration: 4 * time.Second, BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "minuteb"}, AccountID: ub.ID}},
- }
- cd := &CallDescriptor{ToR: utils.MetaVoice, Increments: increments}
- cd.RefundIncrements()
- ub, _ = dm.GetAccount(ub.ID)
- if ub.BalanceMap[utils.MetaMonetary][0].GetValue() != 104 ||
- ub.BalanceMap[utils.MetaVoice][0].GetValue() != 13*float64(time.Second) ||
- ub.BalanceMap[utils.MetaVoice][1].GetValue() != 14*float64(time.Second) {
- t.Error("Error refunding money: ", utils.ToIJSON(ub.BalanceMap))
- }
-}
-
-func TestCDRefundIncrementsZeroValue(t *testing.T) {
- ub := &Account{
- ID: "test:ref",
- BalanceMap: map[string]Balances{
- utils.MetaMonetary: {
- &Balance{Uuid: "moneya", Value: 100},
- },
- utils.MetaVoice: {
- &Balance{Uuid: "minutea", Value: 10, Weight: 20, DestinationIDs: utils.StringMap{"NAT": true}},
- &Balance{Uuid: "minuteb", Value: 10, DestinationIDs: utils.StringMap{"RET": true}},
- },
- },
- }
- dm.SetAccount(ub)
- increments := Increments{
- &Increment{Cost: 0, BalanceInfo: &DebitInfo{AccountID: ub.ID}},
- &Increment{Cost: 0, Duration: 3 * time.Second, BalanceInfo: &DebitInfo{AccountID: ub.ID}},
- &Increment{Cost: 0, Duration: 4 * time.Second, BalanceInfo: &DebitInfo{AccountID: ub.ID}},
- }
- cd := &CallDescriptor{ToR: utils.MetaVoice, Increments: increments}
- cd.RefundIncrements()
- ub, _ = dm.GetAccount(ub.ID)
- if ub.BalanceMap[utils.MetaMonetary][0].GetValue() != 100 ||
- ub.BalanceMap[utils.MetaVoice][0].GetValue() != 10 ||
- ub.BalanceMap[utils.MetaVoice][1].GetValue() != 10 {
- t.Error("Error refunding money: ", utils.ToIJSON(ub.BalanceMap))
- }
-}
-
-func TestCDDebitBalanceSubjectWithFallback(t *testing.T) {
- acnt := &Account{
- ID: "TCDDBSWF:account1",
- BalanceMap: map[string]Balances{
- utils.MetaVoice: {
- &Balance{ID: "voice1", Value: 60 * float64(time.Second),
- RatingSubject: "SubjTCDDBSWF"},
- }},
- }
- dm.SetAccount(acnt)
- dst := &Destination{Id: "DST_TCDDBSWF", Prefixes: []string{"1716"}}
- dm.SetDestination(dst, utils.NonTransactional)
- dm.SetReverseDestination(dst.Id, dst.Prefixes, utils.NonTransactional)
- rpSubj := &RatingPlan{
- Id: "RP_TCDDBSWF",
- Timings: map[string]*RITiming{
- "30eab300": {
- Years: utils.Years{},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- StartTime: "00:00:00",
- },
- },
- Ratings: map[string]*RIRate{
- "b457f86d": {
-
- Rates: []*RGRate{
- {
- GroupIntervalStart: 0,
- Value: 0,
- RateIncrement: 60 * time.Second,
- RateUnit: 60 * time.Second,
- },
- },
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 4,
- },
- },
- DestinationRates: map[string]RPRateList{
- dst.Id: []*RPRate{
- {
- Timing: "30eab300",
- Rating: "b457f86d",
- Weight: 10,
- },
- },
- },
- }
- rpDflt := &RatingPlan{
- Id: "RP_DFLT",
- Timings: map[string]*RITiming{
- "30eab301": {
- Years: utils.Years{},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- StartTime: "00:00:00",
- },
- },
- Ratings: map[string]*RIRate{
- "b457f861": {
- Rates: []*RGRate{
- {
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Second,
- RateUnit: time.Second,
- },
- },
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 4,
- },
- },
- DestinationRates: map[string]RPRateList{
- dst.Id: []*RPRate{
- {
- Timing: "30eab301",
- Rating: "b457f861",
- Weight: 10,
- },
- },
- },
- }
- for _, rpl := range []*RatingPlan{rpSubj, rpDflt} {
- dm.SetRatingPlan(rpl, utils.NonTransactional)
- }
- rpfTCDDBSWF := &RatingProfile{Id: "*out:TCDDBSWF:call:SubjTCDDBSWF",
- RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{
- ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
- RatingPlanId: rpSubj.Id,
- }},
- }
- rpfAny := &RatingProfile{Id: "*out:TCDDBSWF:call:*any",
- RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{
- ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
- RatingPlanId: rpDflt.Id,
- }},
- }
- for _, rpf := range []*RatingProfile{rpfTCDDBSWF, rpfAny} {
- dm.SetRatingProfile(rpf, utils.NonTransactional)
- }
- cd1 := &CallDescriptor{ // test the cost for subject within balance setup
- Category: "call",
- Tenant: "TCDDBSWF",
- Subject: "SubjTCDDBSWF",
- Destination: "1716",
- TimeStart: time.Date(2015, 01, 01, 9, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 01, 01, 9, 2, 0, 0, time.UTC),
- ToR: utils.MetaVoice,
- }
- if cc, err := cd1.GetCost(); err != nil || cc.Cost != 0 {
- t.Errorf("Error getting *any dest: %+v %v", cc, err)
- }
- cd2 := &CallDescriptor{ // equivalent of the extra charge out of *monetary balance when *voice is finished
- Category: "call",
- Tenant: "TCDDBSWF",
- Subject: "dan",
- Destination: "1716",
- TimeStart: time.Date(2015, 01, 01, 9, 1, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 01, 01, 9, 2, 0, 0, time.UTC),
- ToR: utils.MetaVoice,
- }
- if cc, err := cd2.GetCost(); err != nil || cc.Cost != 0.6 {
- t.Errorf("Error getting *any dest: %+v %v", cc, err)
- }
- cd := &CallDescriptor{ // test the cost
- Category: "call",
- Tenant: "TCDDBSWF",
- Account: "account1",
- Subject: "account1",
- Destination: "1716",
- TimeStart: time.Date(2015, 01, 01, 9, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 01, 01, 9, 2, 0, 0, time.UTC),
- ToR: utils.MetaVoice,
- }
- if cc, err := cd.Debit(); err != nil {
- t.Error(err)
- } else if cc.Cost != 0.6 {
- t.Errorf("CallCost: %v", cc)
- }
- if resAcnt, err := dm.GetAccount(acnt.ID); err != nil {
- t.Error(err)
- } else if resAcnt.BalanceMap[utils.MetaVoice][0].ID != "voice1" ||
- resAcnt.BalanceMap[utils.MetaVoice][0].Value != 0 {
- t.Errorf("Account: %v", resAcnt)
- } else if len(resAcnt.BalanceMap[utils.MetaMonetary]) == 0 ||
- resAcnt.BalanceMap[utils.MetaMonetary][0].ID != utils.MetaDefault ||
- resAcnt.BalanceMap[utils.MetaMonetary][0].Value != -0.600013 { // rounding issue
- t.Errorf("Account: %s", utils.ToIJSON(resAcnt))
- }
-}
-func TestCallDescriptorUpdateFromCGREvent(t *testing.T) {
- cgrEv := &utils.CGREvent{
- Tenant: "cgrates.org",
- ID: "Generated",
- Event: map[string]interface{}{
- "Account": "acc1",
- "AnswerTime": time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- "Category": "call",
- "Destination": "0723123113",
- "Subject": "acc1",
- "Tenant": "cgrates.org",
- "ToR": "",
- "Usage": 30 * time.Minute,
- },
- }
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- cdExpected := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "acc1",
- Account: "acc1",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- if err := cd.UpdateFromCGREvent(cgrEv, []string{utils.AccountField, utils.Subject}); err != nil {
- t.Error(err)
- } else {
- if !reflect.DeepEqual(cd, cdExpected) {
- t.Errorf("Expecting: %+v, received: %+v", cdExpected, cd)
- }
- }
- cgrEv = &utils.CGREvent{
- Tenant: "cgrates.org",
- ID: "Generated",
- Event: map[string]interface{}{
- "Account": "acc1",
- "AnswerTime": time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- "Category": "call",
- "Destination": "0723123113",
- "Subject": "acc1",
- "Tenant": "cgrates.org",
- "ToR": "",
- "Usage": 40 * time.Minute,
- },
- }
- if err := cd.UpdateFromCGREvent(cgrEv, []string{utils.AccountField, utils.Subject}); err != nil {
- t.Error(err)
- } else {
- if !reflect.DeepEqual(cd, cdExpected) {
- t.Errorf("Expecting: %+v, received: %+v", cdExpected, cd)
- }
- }
-
-}
-
-func TestCallDescriptorAsCGREvent(t *testing.T) {
- cd := &CallDescriptor{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "max",
- Account: "max",
- Destination: "0723123113",
- TimeStart: time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 3, 23, 6, 30, 0, 0, time.UTC),
- MaxCostSoFar: 0,
- }
- eCGREvent := &utils.CGREvent{Tenant: "cgrates.org",
- ID: "Generated",
- Event: map[string]interface{}{
- "Account": "max",
- "AnswerTime": time.Date(2015, 3, 23, 6, 0, 0, 0, time.UTC),
- "Category": "call",
- "Destination": "0723123113",
- "Subject": "max",
- "Tenant": "cgrates.org",
- "ToR": "",
- "Usage": 30 * time.Minute,
- },
- }
- cgrEvent := cd.AsCGREvent(nil)
- if !reflect.DeepEqual(eCGREvent.Tenant, cgrEvent.Tenant) {
- t.Errorf("Expecting: %+v, received: %+v", eCGREvent.Tenant, cgrEvent.Tenant)
- }
- for fldName, fldVal := range eCGREvent.Event {
- if _, has := cgrEvent.Event[fldName]; !has {
- t.Errorf("Expecting: %+v, received: %+v", fldName, nil)
- } else if fldVal != cgrEvent.Event[fldName] {
- t.Errorf("Expecting: %s:%+v, received: %s:%+v", fldName, eCGREvent.Event[fldName], fldName, cgrEvent.Event[fldName])
- }
- }
-}
-
-/*************** BENCHMARKS ********************/
-func BenchmarkStorageGetting(b *testing.B) {
- b.StopTimer()
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2}
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- dm.GetRatingProfile(cd.GetKey(cd.Subject), false, utils.NonTransactional)
- }
-}
-
-func BenchmarkStorageRestoring(b *testing.B) {
- b.StopTimer()
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- cd.LoadRatingPlans()
- }
-}
-
-func BenchmarkStorageGetCost(b *testing.B) {
- b.StopTimer()
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- cd.GetCost()
- }
-}
-
-func BenchmarkSplitting(b *testing.B) {
- b.StopTimer()
- t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC)
- cd := &CallDescriptor{Category: "0", Tenant: "vdf", Subject: "rif",
- Destination: "0256", TimeStart: t1, TimeEnd: t2}
- cd.LoadRatingPlans()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- cd.splitInTimeSpans()
- }
-}
-
-func BenchmarkStorageSingleGetSessionTime(b *testing.B) {
- b.StopTimer()
- cd := &CallDescriptor{Tenant: "vdf", Subject: "minutosu", Destination: "0723"}
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- cd.GetMaxSessionDuration()
- }
-}
-
-func BenchmarkStorageMultipleGetSessionTime(b *testing.B) {
- b.StopTimer()
- cd := &CallDescriptor{Category: "0", Tenant: "vdf",
- Subject: "minutosu", Destination: "0723"}
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- cd.GetMaxSessionDuration()
- }
-}
diff --git a/engine/cdr.go b/engine/cdr.go
index 86003e8d0..8fba2cdc0 100644
--- a/engine/cdr.go
+++ b/engine/cdr.go
@@ -55,13 +55,6 @@ func NewCDRFromExternalCDR(extCdr *ExternalCDR, timezone string) (*CDR, error) {
return nil, err
}
}
- if len(extCdr.CostDetails) != 0 {
- cdr.CostDetails = &EventCost{}
- if err = json.Unmarshal([]byte(extCdr.CostDetails), cdr.CostDetails); err != nil {
- return nil, err
- }
- cdr.CostDetails.initCache()
- }
if extCdr.ExtraFields != nil {
cdr.ExtraFields = make(map[string]string)
}
@@ -94,7 +87,6 @@ type CDR struct {
PreRated bool // Mark the CDR as rated so we do not process it during rating
CostSource string // The source of this cost
Cost float64 //
- CostDetails *EventCost // Attach the cost details to CDR when possible
}
// AddDefaults will add missing information based on other fields
@@ -122,11 +114,6 @@ func (cdr *CDR) AddDefaults(cfg *config.CGRConfig) {
}
}
-func (cdr *CDR) CostDetailsJson() string {
- mrshled, _ := json.Marshal(cdr.CostDetails)
- return string(mrshled)
-}
-
func (cdr *CDR) ComputeCGRID() {
cdr.CGRID = utils.Sha1(cdr.OriginID, cdr.OriginHost)
}
@@ -187,7 +174,6 @@ func (cdr *CDR) Clone() *CDR {
PreRated: cdr.PreRated,
CostSource: cdr.CostSource,
Cost: cdr.Cost,
- CostDetails: cdr.CostDetails.Clone(),
}
if cdr.ExtraFields != nil {
cln.ExtraFields = make(map[string]string, len(cdr.ExtraFields))
@@ -203,9 +189,6 @@ func (cdr *CDR) AsMapStorage() (mp utils.MapStorage) {
mp = utils.MapStorage{
utils.MetaReq: cdr.AsMapStringIface(),
}
- if cdr.CostDetails != nil {
- mp[utils.MetaEC] = cdr.CostDetails
- }
return
}
@@ -235,9 +218,6 @@ func (cdr *CDR) AsMapStringIface() (mp map[string]interface{}) {
mp[utils.PreRated] = cdr.PreRated
mp[utils.CostSource] = cdr.CostSource
mp[utils.Cost] = cdr.Cost
- if cdr.CostDetails != nil {
- mp[utils.CostDetails] = cdr.CostDetails
- }
return
}
@@ -268,7 +248,6 @@ func (cdr *CDR) AsExternalCDR() *ExternalCDR {
ExtraFields: cdr.ExtraFields,
CostSource: cdr.CostSource,
Cost: cdr.Cost,
- CostDetails: cdr.CostDetailsJson(),
ExtraInfo: cdr.ExtraInfo,
PreRated: cdr.PreRated,
}
@@ -437,7 +416,6 @@ func (cdr *CDR) AsCDRsql() (cdrSQL *CDRsql) {
cdrSQL.ExtraFields = utils.ToJSON(cdr.ExtraFields)
cdrSQL.CostSource = cdr.CostSource
cdrSQL.Cost = cdr.Cost
- cdrSQL.CostDetails = utils.ToJSON(cdr.CostDetails)
cdrSQL.ExtraInfo = cdr.ExtraInfo
cdrSQL.CreatedAt = time.Now()
return
@@ -479,11 +457,6 @@ func NewCDRFromSQL(cdrSQL *CDRsql) (cdr *CDR, err error) {
return nil, err
}
}
- if cdrSQL.CostDetails != "" {
- if err = json.Unmarshal([]byte(cdrSQL.CostDetails), &cdr.CostDetails); err != nil {
- return nil, err
- }
- }
return
}
@@ -527,39 +500,6 @@ type UsageRecord struct {
ExtraFields map[string]string
}
-func (uR *UsageRecord) AsCallDescriptor(timezone string, denyNegative bool) (*CallDescriptor, error) {
- var err error
- cd := &CallDescriptor{
- CgrID: uR.GetId(),
- ToR: uR.ToR,
- Tenant: uR.Tenant,
- Category: uR.Category,
- Subject: uR.Subject,
- Account: uR.Account,
- Destination: uR.Destination,
- DenyNegativeAccount: denyNegative,
- }
- timeStr := uR.AnswerTime
- if len(timeStr) == 0 { // In case of auth, answer time will not be defined, so take it out of setup one
- timeStr = uR.SetupTime
- }
- if cd.TimeStart, err = utils.ParseTimeDetectLayout(timeStr, timezone); err != nil {
- return nil, err
- }
- if usage, err := utils.ParseDurationWithNanosecs(uR.Usage); err != nil {
- return nil, err
- } else {
- cd.TimeEnd = cd.TimeStart.Add(usage)
- }
- if uR.ExtraFields != nil {
- cd.ExtraFields = make(map[string]string)
- }
- for k, v := range uR.ExtraFields {
- cd.ExtraFields[k] = v
- }
- return cd, nil
-}
-
func (uR *UsageRecord) GetId() string {
return utils.Sha1(uR.ToR, uR.RequestType, uR.Tenant, uR.Category, uR.Account, uR.Subject, uR.Destination, uR.SetupTime, uR.AnswerTime, uR.Usage)
}
diff --git a/engine/cdrs.go b/engine/cdrs.go
index 4f3ad75e1..5e801e240 100644
--- a/engine/cdrs.go
+++ b/engine/cdrs.go
@@ -20,7 +20,6 @@ import (
"net/http"
"reflect"
"strings"
- "time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/guardian"
@@ -133,220 +132,9 @@ func (cdrS *CDRServer) RegisterHandlersToServer(server utils.Server) {
server.RegisterHttpFunc(cdrS.cgrCfg.HTTPCfg().HTTPFreeswitchCDRsURL, cdrS.fsCdrHandler)
}
-// storeSMCost will store a SMCost
-func (cdrS *CDRServer) storeSMCost(smCost *SMCost, checkDuplicate bool) error {
- smCost.CostDetails.Compute() // make sure the total cost reflect the increment
- lockKey := utils.MetaCDRs + smCost.CGRID + smCost.RunID + smCost.OriginID // Will lock on this ID
- if checkDuplicate {
- _, err := cdrS.guard.Guard(func() (interface{}, error) {
- smCosts, err := cdrS.cdrDb.GetSMCosts(smCost.CGRID, smCost.RunID, "", "")
- if err != nil && err.Error() != utils.NotFoundCaps {
- return nil, err
- }
- if len(smCosts) != 0 {
- return nil, utils.ErrExists
- }
- return nil, cdrS.cdrDb.SetSMCost(smCost)
- }, config.CgrConfig().GeneralCfg().LockingTimeout, lockKey) // FixMe: Possible deadlock with Guard from SMG session close()
- return err
- }
- return cdrS.cdrDb.SetSMCost(smCost)
-}
-
-// rateCDR will populate cost field
-// Returns more than one rated CDR in case of SMCost retrieved based on prefix
-func (cdrS *CDRServer) rateCDR(cdr *CDRWithAPIOpts) ([]*CDR, error) {
- var qryCC *CallCost
- var err error
- if cdr.RequestType == utils.MetaNone {
- return nil, nil
- }
- if cdr.Usage < 0 {
- cdr.Usage = time.Duration(0)
- }
- cdr.ExtraInfo = "" // Clean previous ExtraInfo, useful when re-rating
- var cdrsRated []*CDR
- _, hasLastUsed := cdr.ExtraFields[utils.LastUsed]
- if utils.SliceHasMember([]string{utils.MetaPrepaid, utils.Prepaid}, cdr.RequestType) &&
- (cdr.Usage != 0 || hasLastUsed) && cdr.CostDetails == nil {
- // ToDo: Get rid of Prepaid as soon as we don't want to support it backwards
- // Should be previously calculated and stored in DB
- fib := utils.Fib()
- var smCosts []*SMCost
- cgrID := cdr.CGRID
- if _, hasIT := cdr.ExtraFields[utils.OriginIDPrefix]; hasIT {
- cgrID = "" // for queries involving originIDPrefix we ignore CGRID
- }
- for i := 0; i < cdrS.cgrCfg.CdrsCfg().SMCostRetries; i++ {
- smCosts, err = cdrS.cdrDb.GetSMCosts(cgrID, cdr.RunID, cdr.OriginHost,
- cdr.ExtraFields[utils.OriginIDPrefix])
- if err == nil && len(smCosts) != 0 {
- break
- }
- if i <= cdrS.cgrCfg.CdrsCfg().SMCostRetries-1 {
- time.Sleep(time.Duration(fib()) * time.Second)
- }
- }
- if len(smCosts) != 0 { // Cost retrieved from SMCost table
- for _, smCost := range smCosts {
- cdrClone := cdr.CDR.Clone()
- cdrClone.OriginID = smCost.OriginID
- if cdr.Usage == 0 {
- cdrClone.Usage = smCost.Usage
- } else if smCost.Usage != cdr.Usage {
- if _, err = cdrS.refundEventCost(smCost.CostDetails, // ToDo: need to maybe mark it in the future in the processed flags
- cdrClone.RequestType, cdrClone.ToR); err != nil {
- return nil, err
- }
- cdrClone.CostDetails = nil
- if qryCC, err = cdrS.getCostFromRater(&CDRWithAPIOpts{CDR: cdrClone}); err != nil {
- return nil, err
- }
- smCost = &SMCost{
- CGRID: cdrClone.CGRID,
- RunID: cdrClone.RunID,
- OriginHost: cdrClone.OriginID,
- CostSource: utils.CDRs,
- Usage: cdrClone.Usage,
- CostDetails: NewEventCostFromCallCost(qryCC, cdrClone.CGRID, cdrClone.RunID),
- }
- }
- cdrClone.Cost = smCost.CostDetails.GetCost()
- cdrClone.CostDetails = smCost.CostDetails
- cdrClone.CostSource = smCost.CostSource
- cdrsRated = append(cdrsRated, cdrClone)
- }
- return cdrsRated, nil
- }
- utils.Logger.Warning(
- fmt.Sprintf(" WARNING: Could not find CallCostLog for cgrid: %s, source: %s, runid: %s, originID: %s originHost: %s, will recalculate",
- cdr.CGRID, utils.MetaSessionS, cdr.RunID, cdr.OriginID, cdr.OriginHost))
- }
- if cdr.CostDetails != nil {
- if cdr.Usage == cdr.CostDetails.GetUsage() { // Costs were previously calculated, make sure they cover the full usage
- cdr.Cost = cdr.CostDetails.GetCost()
- cdr.CostDetails.Compute()
- return []*CDR{cdr.CDR}, nil
- }
- // ToDo: need to maybe mark it in the future in the processed flags
- if _, err = cdrS.refundEventCost(cdr.CostDetails,
- cdr.RequestType, cdr.ToR); err != nil {
- return nil, err
- }
- cdr.CostDetails = nil
- }
- qryCC, err = cdrS.getCostFromRater(cdr)
- if err != nil {
- return nil, err
- }
- if qryCC != nil {
- cdr.Cost = qryCC.Cost
- cdr.CostDetails = NewEventCostFromCallCost(qryCC, cdr.CGRID, cdr.RunID)
- }
- cdr.CostDetails.Compute()
- return []*CDR{cdr.CDR}, nil
-}
-
var reqTypes = utils.NewStringSet([]string{utils.MetaPseudoPrepaid, utils.MetaPostpaid, utils.MetaPrepaid,
utils.PseudoPrepaid, utils.Postpaid, utils.Prepaid, utils.MetaDynaprepaid})
-// getCostFromRater will retrieve the cost from RALs
-func (cdrS *CDRServer) getCostFromRater(cdr *CDRWithAPIOpts) (*CallCost, error) {
- if len(cdrS.cgrCfg.CdrsCfg().RaterConns) == 0 {
- return nil, utils.NewErrNotConnected(utils.RALService)
- }
- cc := new(CallCost)
- var err error
- timeStart := cdr.AnswerTime
- if timeStart.IsZero() { // Fix for FreeSWITCH unanswered calls
- timeStart = cdr.SetupTime
- }
- cd := &CallDescriptor{
- ToR: cdr.ToR,
- Tenant: cdr.Tenant,
- Category: cdr.Category,
- Subject: cdr.Subject,
- Account: cdr.Account,
- Destination: cdr.Destination,
- TimeStart: timeStart,
- TimeEnd: timeStart.Add(cdr.Usage),
- DurationIndex: cdr.Usage,
- PerformRounding: true,
- }
- if reqTypes.Has(cdr.RequestType) { // Prepaid - Cost can be recalculated in case of missing records from SM
- err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().RaterConns, nil,
- utils.ResponderDebit,
- &CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: cdr.APIOpts,
- }, cc)
- if err != nil && err.Error() == utils.ErrAccountNotFound.Error() &&
- cdr.RequestType == utils.MetaDynaprepaid {
- var reply string
- // execute the actionPlan configured in RalS
- if err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().SchedulerConns, nil,
- utils.SchedulerSv1ExecuteActionPlans, &utils.AttrsExecuteActionPlans{
- ActionPlanIDs: cdrS.cgrCfg.RalsCfg().DynaprepaidActionPlans,
- AccountID: cdr.Account, Tenant: cdr.Tenant},
- &reply); err != nil {
- return cc, err
- }
- // execute again the Debit operation
- err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().RaterConns, nil,
- utils.ResponderDebit,
- &CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: cdr.APIOpts,
- }, cc)
- }
- } else {
- err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().RaterConns, nil,
- utils.ResponderGetCost,
- &CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: cdr.APIOpts,
- }, cc)
- }
- if err != nil {
- return cc, err
- }
- cdr.CostSource = utils.MetaCDRs
- return cc, nil
-}
-
-// rateCDRWithErr rates a CDR including errors
-func (cdrS *CDRServer) rateCDRWithErr(cdr *CDRWithAPIOpts) (ratedCDRs []*CDR) {
- var err error
- ratedCDRs, err = cdrS.rateCDR(cdr)
- if err != nil {
- cdr.Cost = -1.0 // If there was an error, mark the CDR
- cdr.ExtraInfo = err.Error()
- ratedCDRs = []*CDR{cdr.CDR}
- }
- return
-}
-
-// refundEventCost will refund the EventCost using RefundIncrements
-func (cdrS *CDRServer) refundEventCost(ec *EventCost, reqType, tor string) (rfnd bool, err error) {
- if len(cdrS.cgrCfg.CdrsCfg().RaterConns) == 0 {
- return false, utils.NewErrNotConnected(utils.RALService)
- }
- if ec == nil || !utils.AccountableRequestTypes.Has(reqType) {
- return // non refundable
- }
- cd := ec.AsRefundIncrements(tor)
- if cd == nil || len(cd.Increments) == 0 {
- return
- }
- var acnt Account
- if err = cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().RaterConns, nil,
- utils.ResponderRefundIncrements,
- &CallDescriptorWithAPIOpts{CallDescriptor: cd}, &acnt); err != nil {
- return
- }
- return true, nil
-}
-
// chrgrSProcessEvent forks CGREventWithOpts into multiples based on matching ChargerS profiles
func (cdrS *CDRServer) chrgrSProcessEvent(cgrEv *utils.CGREvent) (cgrEvs []*utils.CGREvent, err error) {
var chrgrs []*ChrgSProcessEventReply
@@ -512,82 +300,7 @@ func (cdrS *CDRServer) processEvent(ev *utils.CGREvent,
for i := range cgrEvs {
procFlgs[i] = utils.NewStringSet(nil)
}
- if refund {
- for i, cdr := range cdrs {
- if rfnd, errRfd := cdrS.refundEventCost(cdr.CostDetails,
- cdr.RequestType, cdr.ToR); errRfd != nil {
- utils.Logger.Warning(
- fmt.Sprintf("<%s> error: <%s> refunding CDR %+v",
- utils.CDRs, errRfd.Error(), utils.ToJSON(cdr)))
- } else if rfnd {
- procFlgs[i].Add(utils.MetaRefund)
- }
- }
- }
- if ralS {
- for i, cdr := range cdrs {
- for j, rtCDR := range cdrS.rateCDRWithErr(
- &CDRWithAPIOpts{
- CDR: cdr,
- APIOpts: ev.APIOpts,
- }) {
- cgrEv := rtCDR.AsCGREvent()
- cgrEv.APIOpts = cgrEvs[i].APIOpts
- if j == 0 { // the first CDR will replace the events we got already as a small optimization
- cdrs[i] = rtCDR
- cgrEvs[i] = cgrEv
- } else {
- cdrs = append(cdrs, cdr)
- cgrEvs = append(cgrEvs, cgrEv)
- }
- }
- }
- }
- if store {
- refundCDRCosts := func() { // will be used to refund all CDRs on errors
- for _, cdr := range cdrs { // refund what we have charged since duplicates are not allowed
- if _, errRfd := cdrS.refundEventCost(cdr.CostDetails,
- cdr.RequestType, cdr.ToR); errRfd != nil {
- utils.Logger.Warning(
- fmt.Sprintf("<%s> error: <%s> refunding CDR %+v",
- utils.CDRs, errRfd.Error(), utils.ToJSON(cdr)))
- }
- }
- }
- for i, cdr := range cdrs {
- if err = cdrS.cdrDb.SetCDR(cdr, false); err != nil {
- if err != utils.ErrExists || !reRate {
- refundCDRCosts()
- return
- }
- // CDR was found in StorDB
- // reRate is allowed, refund the previous CDR
- var prevCDRs []*CDR // only one should be returned
- if prevCDRs, _, err = cdrS.cdrDb.GetCDRs(
- &utils.CDRsFilter{CGRIDs: []string{cdr.CGRID},
- RunIDs: []string{cdr.RunID}}, false); err != nil {
- refundCDRCosts()
- return
- }
- var rfnd bool
- if rfnd, err = cdrS.refundEventCost(prevCDRs[0].CostDetails,
- cdr.RequestType, cdr.ToR); err != nil {
- refundCDRCosts()
- return
- } else if rfnd {
- procFlgs[i].Add(utils.MetaRefund)
- }
- // after refund we can force update
- if err = cdrS.cdrDb.SetCDR(cdr, true); err != nil {
- utils.Logger.Warning(
- fmt.Sprintf("<%s> error: <%s> updating CDR %+v",
- utils.CDRs, err.Error(), utils.ToJSON(cdr)))
- err = utils.ErrPartiallyExecuted
- return
- }
- }
- }
- }
+
var partiallyExecuted bool // from here actions are optional and a general error is returned
if export {
if len(cdrS.cgrCfg.CdrsCfg().EEsConns) != 0 {
@@ -913,101 +626,6 @@ func (cdrS *CDRServer) V2ProcessEvent(arg *ArgV1ProcessEvent, evs *[]*utils.Even
return nil
}
-// V1StoreSessionCost handles storing of the cost into session_costs table
-func (cdrS *CDRServer) V1StoreSessionCost(attr *AttrCDRSStoreSMCost, reply *string) (err error) {
- if attr.Cost.CGRID == "" {
- return utils.NewCGRError(utils.CDRsCtx,
- utils.MandatoryIEMissingCaps, fmt.Sprintf("%s: CGRID", utils.MandatoryInfoMissing),
- "SMCost: %+v with empty CGRID")
- }
- // RPC caching
- if config.CgrConfig().CacheCfg().Partitions[utils.CacheRPCResponses].Limit != 0 {
- cacheKey := utils.ConcatenatedKey(utils.CDRsV1StoreSessionCost, attr.Cost.CGRID, attr.Cost.RunID)
- refID := guardian.Guardian.GuardIDs("",
- config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic
- defer guardian.Guardian.UnguardIDs(refID)
- if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has {
- cachedResp := itm.(*utils.CachedRPCResponse)
- if cachedResp.Error == nil {
- *reply = *cachedResp.Result.(*string)
- }
- return cachedResp.Error
- }
- defer Cache.Set(utils.CacheRPCResponses, cacheKey,
- &utils.CachedRPCResponse{Result: reply, Error: err},
- nil, true, utils.NonTransactional)
- }
- // end of RPC caching
- if err = cdrS.storeSMCost(attr.Cost, attr.CheckDuplicate); err != nil {
- err = utils.NewErrServerError(err)
- return
- }
- *reply = utils.OK
- return nil
-}
-
-// V2StoreSessionCost will store the SessionCost into session_costs table
-func (cdrS *CDRServer) V2StoreSessionCost(args *ArgsV2CDRSStoreSMCost, reply *string) (err error) {
- if args.Cost.CGRID == "" {
- return utils.NewCGRError(utils.CDRsCtx,
- utils.MandatoryIEMissingCaps, fmt.Sprintf("%s: CGRID", utils.MandatoryInfoMissing),
- "SMCost: %+v with empty CGRID")
- }
- // RPC caching
- if config.CgrConfig().CacheCfg().Partitions[utils.CacheRPCResponses].Limit != 0 {
- cacheKey := utils.ConcatenatedKey(utils.CDRsV1StoreSessionCost, args.Cost.CGRID, args.Cost.RunID)
- refID := guardian.Guardian.GuardIDs("",
- config.CgrConfig().GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic
- defer guardian.Guardian.UnguardIDs(refID)
-
- if itm, has := Cache.Get(utils.CacheRPCResponses, cacheKey); has {
- cachedResp := itm.(*utils.CachedRPCResponse)
- if cachedResp.Error == nil {
- *reply = *cachedResp.Result.(*string)
- }
- return cachedResp.Error
- }
- defer Cache.Set(utils.CacheRPCResponses, cacheKey,
- &utils.CachedRPCResponse{Result: reply, Error: err},
- nil, true, utils.NonTransactional)
- }
- // end of RPC caching
- cc := args.Cost.CostDetails.AsCallCost(utils.EmptyString)
- cc.Round()
- roundIncrements := cc.GetRoundIncrements()
- if len(roundIncrements) != 0 {
- cd := cc.CreateCallDescriptor()
- cd.CgrID = args.Cost.CGRID
- cd.RunID = args.Cost.RunID
- cd.Increments = roundIncrements
- var response float64
- if err := cdrS.connMgr.Call(cdrS.cgrCfg.CdrsCfg().RaterConns, nil,
- utils.ResponderRefundRounding,
- &CallDescriptorWithAPIOpts{CallDescriptor: cd},
- &response); err != nil {
- utils.Logger.Warning(
- fmt.Sprintf(" RefundRounding for cc: %+v, got error: %s",
- cc, err.Error()))
- }
- }
- if err = cdrS.storeSMCost(
- &SMCost{
- CGRID: args.Cost.CGRID,
- RunID: args.Cost.RunID,
- OriginHost: args.Cost.OriginHost,
- OriginID: args.Cost.OriginID,
- CostSource: args.Cost.CostSource,
- Usage: args.Cost.Usage,
- CostDetails: NewEventCostFromCallCost(cc, args.Cost.CGRID, args.Cost.RunID)},
- args.CheckDuplicate); err != nil {
- err = utils.NewErrServerError(err)
- return
- }
- *reply = utils.OK
- return
-
-}
-
// ArgRateCDRs a cdr with extra flags
type ArgRateCDRs struct {
Flags []string
diff --git a/engine/datacost.go b/engine/datacost.go
deleted file mode 100644
index a88d92308..000000000
--- a/engine/datacost.go
+++ /dev/null
@@ -1,46 +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
-
-// type used for showing sane data cost
-type DataCost struct {
- Category, Tenant, Subject, Account,
- Destination, ToR string
- Cost float64
- DataSpans []*DataSpan
- deductConnectFee bool
-}
-type DataSpan struct {
- DataStart, DataEnd float64
- Cost float64
- ratingInfo *RatingInfo
- RateInterval *RateInterval
- DataIndex float64 // the data transfer so far till DataEnd
- Increments []*DataIncrement
- MatchedSubject, MatchedPrefix,
- MatchedDestId, RatingPlanId string
-}
-
-type DataIncrement struct {
- Amount float64
- Cost float64
- BalanceInfo *DebitInfo // need more than one for units with cost
- CompressFactor int
- paid bool
-}
diff --git a/engine/datadbmock.go b/engine/datadbmock.go
index d2f1798ee..040ba83e3 100644
--- a/engine/datadbmock.go
+++ b/engine/datadbmock.go
@@ -88,38 +88,6 @@ func (dbM *DataDBMock) GetReverseDestinationDrv(string, string) ([]string, error
return nil, utils.ErrNotImplemented
}
-func (dbM *DataDBMock) GetActionsDrv(string) (Actions, error) {
- return nil, utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) SetActionsDrv(string, Actions) error {
- return utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) RemoveActionsDrv(string) error {
- return utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) PushTask(*Task) error {
- return utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) PopTask() (*Task, error) {
- return nil, utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) GetAccountDrv(string) (*Account, error) {
- return nil, utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) SetAccountDrv(*Account) error {
- return utils.ErrNotImplemented
-}
-
-func (dbM *DataDBMock) RemoveAccountDrv(string) error {
- return utils.ErrNotImplemented
-}
-
func (dbM *DataDBMock) GetResourceProfileDrv(string, string) (*ResourceProfile, error) {
return nil, utils.ErrNotImplemented
}
diff --git a/engine/datamanager.go b/engine/datamanager.go
index d94d67062..3174970f8 100644
--- a/engine/datamanager.go
+++ b/engine/datamanager.go
@@ -23,7 +23,6 @@ import (
"github.com/cgrates/baningo"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
- "github.com/cgrates/ltcache"
)
var (
@@ -45,13 +44,6 @@ var (
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: {},
@@ -171,8 +163,6 @@ func (dm *DataManager) CacheDataFromDB(prfx string, ids []string, mustBeCached b
_, err = dm.GetDestination(dataID, false, true, utils.NonTransactional)
case utils.ReverseDestinationPrefix:
_, err = dm.GetReverseDestination(dataID, false, true, utils.NonTransactional)
- case utils.ActionPrefix:
- _, err = dm.GetActions(dataID, true, utils.NonTransactional)
case utils.ResourceProfilesPrefix:
tntID := utils.NewTenantID(dataID)
_, err = dm.GetResourceProfile(tntID.Tenant, tntID.ID, false, true, utils.NonTransactional)
@@ -1547,105 +1537,6 @@ func (dm *DataManager) RemoveResourceProfile(tenant, id, transactionID string, w
return
}
-func (dm *DataManager) GetActions(key string, skipCache bool, transactionID string) (as Actions, err error) {
- if !skipCache {
- if x, err := Cache.GetCloned(utils.CacheActions, key); err != nil {
- if err != ltcache.ErrNotFound {
- return nil, err
- }
- } else if x == nil {
- return nil, utils.ErrNotFound
- } else {
- return x.(Actions), nil
- }
- }
- if dm == nil {
- err = utils.ErrNoDatabaseConn
- return
- }
- as, err = dm.DataDB().GetActionsDrv(key)
- if err != nil {
- if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActions]; err == utils.ErrNotFound && itm.Remote {
- if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RmtConns, nil,
- utils.ReplicatorSv1GetActions, &utils.StringWithAPIOpts{
- Arg: key,
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID, utils.EmptyString,
- utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID,
- config.CgrConfig().GeneralCfg().NodeID)),
- }, &as); err == nil {
- err = dm.dataDB.SetActionsDrv(key, as)
- }
- }
- if err != nil {
- err = utils.CastRPCErr(err)
- if err == utils.ErrNotFound {
- if errCh := Cache.Set(utils.CacheActions, key, nil, nil,
- cacheCommit(transactionID), transactionID); errCh != nil {
- return nil, errCh
- }
- }
- return nil, err
- }
- }
- if errCh := Cache.Set(utils.CacheActions, key, as, nil,
- cacheCommit(transactionID), transactionID); errCh != nil {
- return nil, errCh
- }
- return
-}
-
-//SetActionsArgsWithOpts is used to send the key and the Actions to replicator
-type SetActionsArgsWithAPIOpts struct {
- Key string
- Acs Actions
- Tenant string
- APIOpts map[string]interface{}
-}
-
-func (dm *DataManager) SetActions(key string, as Actions, transactionID string) (err error) {
- if dm == nil {
- return utils.ErrNoDatabaseConn
- }
- if err = dm.DataDB().SetActionsDrv(key, as); err != nil {
- return
- }
- if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActions]; itm.Replicate {
- err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns,
- config.CgrConfig().DataDbCfg().RplFiltered,
- utils.ActionPrefix, key, // this are used to get the host IDs from cache
- utils.ReplicatorSv1SetActions,
- &SetActionsArgsWithAPIOpts{
- Key: key,
- Acs: as,
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID,
- config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)})
- }
- return
-}
-
-func (dm *DataManager) RemoveActions(key, transactionID string) (err error) {
- if dm == nil {
- return utils.ErrNoDatabaseConn
- }
- if err = dm.DataDB().RemoveActionsDrv(key); err != nil {
- return
- }
- if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActions]; itm.Replicate {
- replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns,
- config.CgrConfig().DataDbCfg().RplFiltered,
- utils.ActionPrefix, key, // this are used to get the host IDs from cache
- utils.ReplicatorSv1RemoveActions,
- &utils.StringWithAPIOpts{
- Arg: key,
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- APIOpts: utils.GenerateDBItemOpts(itm.APIKey, itm.RouteID,
- config.CgrConfig().DataDbCfg().RplCache, utils.EmptyString)})
- }
- return
-}
-
func (dm *DataManager) HasData(category, subject, tenant string) (has bool, err error) {
if dm == nil {
err = utils.ErrNoDatabaseConn
diff --git a/engine/dynamicdp.go b/engine/dynamicdp.go
index bd89509b2..46fa36caf 100644
--- a/engine/dynamicdp.go
+++ b/engine/dynamicdp.go
@@ -90,9 +90,9 @@ func (dDP *dynamicDP) fieldAsInterface(fldPath []string) (val interface{}, err e
// split the field name in 3 parts
// fieldNameType (~*accounts), accountID(1001) and queried part (BalanceMap.*monetary[0].Value)
- var account Account
- if err = connMgr.Call(dDP.apiConns, nil, utils.APIerSv2GetAccount,
- &utils.AttrGetAccount{Tenant: dDP.tenant, Account: fldPath[1]}, &account); err != nil {
+ var account utils.AccountProfile
+ if err = connMgr.Call(dDP.apiConns, nil, utils.APIerSv1GetAccountProfile,
+ &utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: dDP.tenant, ID: fldPath[1]}}, &account); err != nil {
return
}
//construct dataProvider from account and set it further
@@ -131,18 +131,6 @@ func (dDP *dynamicDP) fieldAsInterface(fldPath []string) (val interface{}, err e
}
dDP.cache.Set(fldPath[:2], dp)
return dp.FieldAsInterface(fldPath[2:])
- case utils.MetaAsm:
- // sample of fieldName ~*asm.BalanceSummaries.HolidayBalance.Value
- stringReq, err := dDP.initialDP.FieldAsString([]string{utils.MetaReq})
- if err != nil {
- return nil, err
- }
- acntSummary, err := NewAccountSummaryFromJSON(stringReq)
- if err != nil {
- return nil, err
- }
- dDP.cache.Set(fldPath[:1], acntSummary)
- return acntSummary.FieldAsInterface(fldPath[1:])
default: // in case of constant we give an empty DataProvider ( empty navigable map )
}
return nil, utils.ErrNotFound
diff --git a/engine/eventcost.go b/engine/eventcost.go
deleted file mode 100644
index 71308788d..000000000
--- a/engine/eventcost.go
+++ /dev/null
@@ -1,1201 +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 (
- "errors"
- "fmt"
- "net"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-// NewBareEventCost will intialize the EventCost with minimum information
-func NewBareEventCost() *EventCost {
- return &EventCost{
- Rating: make(Rating),
- Accounting: make(Accounting),
- RatingFilters: make(RatingFilters),
- Rates: make(ChargedRates),
- Timings: make(ChargedTimings),
- Charges: make([]*ChargingInterval, 0),
- cache: utils.MapStorage{},
- }
-}
-
-// NewEventCostFromCallCost will initilaize the EventCost from a CallCost
-func NewEventCostFromCallCost(cc *CallCost, cgrID, runID string) (ec *EventCost) {
- ec = NewBareEventCost()
- ec.CGRID = cgrID
- ec.RunID = runID
- ec.AccountSummary = cc.AccountSummary
- if len(cc.Timespans) != 0 {
- ec.Charges = make([]*ChargingInterval, len(cc.Timespans))
- ec.StartTime = cc.Timespans[0].TimeStart
- }
- for i, ts := range cc.Timespans {
- cIl := &ChargingInterval{CompressFactor: ts.CompressFactor}
- rf := RatingMatchedFilters{
- utils.DestinationID: ts.MatchedDestId,
- utils.DestinationPrefixName: ts.MatchedPrefix,
- utils.RatingPlanID: ts.RatingPlanId,
- utils.Subject: ts.MatchedSubject,
- }
- isPause := ts.RatingPlanId == utils.MetaPause
- cIl.RatingID = ec.ratingIDForRateInterval(ts.RateInterval, rf, isPause)
- if len(ts.Increments) != 0 {
- cIl.Increments = make([]*ChargingIncrement, 0, len(ts.Increments)+1)
- }
- for _, incr := range ts.Increments {
- cIl.Increments = append(cIl.Increments, ec.newChargingIncrement(incr, rf, false, isPause))
- }
- if ts.RoundIncrement != nil {
- rIncr := ec.newChargingIncrement(ts.RoundIncrement, rf, true, false)
- rIncr.Cost = -rIncr.Cost
- cIl.Increments = append(cIl.Increments, rIncr)
- }
- ec.Charges[i] = cIl
- }
- return
-}
-
-// newChargingIncrement creates ChargingIncrement from a Increment
-// special case if is the roundIncrement the rateID is *rounding
-func (ec *EventCost) newChargingIncrement(incr *Increment, rf RatingMatchedFilters, roundedIncrement, isPause bool) (cIt *ChargingIncrement) {
- cIt = &ChargingIncrement{
- Usage: incr.Duration,
- Cost: incr.Cost,
- CompressFactor: incr.CompressFactor,
- }
- if incr.BalanceInfo == nil {
- return
- }
- if roundedIncrement {
- isPause = false
- }
- rateID := utils.MetaRounding
- //AccountingID
- if incr.BalanceInfo.Unit != nil {
- // 2 balances work-around
- ecUUID := utils.MetaNone // populate no matter what due to Unit not nil
- if incr.BalanceInfo.Monetary != nil {
- if !roundedIncrement {
- rateID = ec.ratingIDForRateInterval(incr.BalanceInfo.Monetary.RateInterval, rf, isPause)
- }
- bc := &BalanceCharge{
- AccountID: incr.BalanceInfo.AccountID,
- BalanceUUID: incr.BalanceInfo.Monetary.UUID,
- Units: incr.Cost,
- RatingID: rateID,
- }
- if isPause {
- ecUUID = utils.MetaPause
- ec.Accounting[ecUUID] = bc
- } else {
- ecUUID = ec.Accounting.GetIDWithSet(bc)
- }
- }
- if !roundedIncrement {
- rateID = ec.ratingIDForRateInterval(incr.BalanceInfo.Unit.RateInterval, rf, isPause)
- }
- bc := &BalanceCharge{
- AccountID: incr.BalanceInfo.AccountID,
- BalanceUUID: incr.BalanceInfo.Unit.UUID,
- Units: incr.BalanceInfo.Unit.Consumed,
- RatingID: rateID,
- ExtraChargeID: ecUUID,
- }
- if isPause {
- cIt.AccountingID = utils.MetaPause
- ec.Accounting[utils.MetaPause] = bc
- } else {
- cIt.AccountingID = ec.Accounting.GetIDWithSet(bc)
- }
- } else if incr.BalanceInfo.Monetary != nil { // Only monetary
- if !roundedIncrement {
- rateID = ec.ratingIDForRateInterval(incr.BalanceInfo.Monetary.RateInterval, rf, isPause)
- }
- bc := &BalanceCharge{
- AccountID: incr.BalanceInfo.AccountID,
- BalanceUUID: incr.BalanceInfo.Monetary.UUID,
- Units: incr.Cost,
- RatingID: rateID,
- }
- if isPause {
- cIt.AccountingID = utils.MetaPause
- ec.Accounting[utils.MetaPause] = bc
- } else {
- cIt.AccountingID = ec.Accounting.GetIDWithSet(bc)
- }
- }
- return
-}
-
-// EventCost stores cost for an Event
-type EventCost struct {
- CGRID string
- RunID string
- StartTime time.Time
- Usage *time.Duration
- Cost *float64 // pointer so we can nil it when dirty
- Charges []*ChargingInterval
- AccountSummary *AccountSummary // Account summary at the end of the event calculation
- Rating Rating
- Accounting Accounting
- RatingFilters RatingFilters
- Rates ChargedRates
- Timings ChargedTimings
-
- cache utils.MapStorage
-}
-
-func (ec *EventCost) initCache() {
- if ec != nil {
- ec.cache = utils.MapStorage{}
- }
-}
-
-func (ec *EventCost) ratingIDForRateInterval(ri *RateInterval, rf RatingMatchedFilters, isPause bool) string {
- if ri == nil || ri.Rating == nil {
- return utils.EmptyString
- }
- var rfUUID string
- if rf != nil {
- if isPause {
- rfUUID = utils.MetaPause
- ec.RatingFilters[rfUUID] = rf
- } else {
- rfUUID = ec.RatingFilters.GetIDWithSet(rf)
- }
- }
- var tmID string
- if ri.Timing != nil {
- // timingID can have random UUID to be reused by other Rates from EventCost
- tmID = ec.Timings.GetIDWithSet(&ChargedTiming{
- Years: ri.Timing.Years,
- Months: ri.Timing.Months,
- MonthDays: ri.Timing.MonthDays,
- WeekDays: ri.Timing.WeekDays,
- StartTime: ri.Timing.StartTime,
- })
- }
- var rtUUID string
- if len(ri.Rating.Rates) != 0 {
- if isPause {
- rtUUID = utils.MetaPause
- ec.Rates[rtUUID] = ri.Rating.Rates
- } else {
- rtUUID = ec.Rates.GetIDWithSet(ri.Rating.Rates)
- }
- }
- ru := &RatingUnit{
- ConnectFee: ri.Rating.ConnectFee,
- RoundingMethod: ri.Rating.RoundingMethod,
- RoundingDecimals: ri.Rating.RoundingDecimals,
- MaxCost: ri.Rating.MaxCost,
- MaxCostStrategy: ri.Rating.MaxCostStrategy,
- TimingID: tmID,
- RatesID: rtUUID,
- RatingFiltersID: rfUUID,
- }
- if isPause {
- ec.Rating[utils.MetaPause] = ru
- return utils.MetaPause
- }
- return ec.Rating.GetIDWithSet(ru)
-}
-
-func (ec *EventCost) rateIntervalForRatingID(ratingID string) (ri *RateInterval) {
- if ratingID == "" {
- return
- }
- cIlRU := ec.Rating[ratingID]
- ri = new(RateInterval)
- ri.Rating = &RIRate{ConnectFee: cIlRU.ConnectFee,
- RoundingMethod: cIlRU.RoundingMethod,
- RoundingDecimals: cIlRU.RoundingDecimals,
- MaxCost: cIlRU.MaxCost, MaxCostStrategy: cIlRU.MaxCostStrategy}
- if cIlRU.RatesID != "" {
- ri.Rating.Rates = ec.Rates[cIlRU.RatesID]
- }
- if cIlRU.TimingID != "" {
- cIlTm := ec.Timings[cIlRU.TimingID]
- ri.Timing = &RITiming{ID: cIlRU.TimingID, Years: cIlTm.Years, Months: cIlTm.Months, MonthDays: cIlTm.MonthDays,
- WeekDays: cIlTm.WeekDays, StartTime: cIlTm.StartTime}
- }
- return
-}
-
-// Clone will create a clone of the object
-func (ec *EventCost) Clone() (cln *EventCost) {
- if ec == nil {
- return
- }
- cln = new(EventCost)
- cln.initCache()
- cln.CGRID = ec.CGRID
- cln.RunID = ec.RunID
- cln.StartTime = ec.StartTime
- if ec.Usage != nil {
- cln.Usage = utils.DurationPointer(*ec.Usage)
- }
- if ec.Cost != nil {
- cln.Cost = utils.Float64Pointer(*ec.Cost)
- }
- if ec.Charges != nil {
- cln.Charges = make([]*ChargingInterval, len(ec.Charges))
- for i, cIl := range ec.Charges {
- cln.Charges[i] = cIl.Clone()
- }
- }
- if ec.AccountSummary != nil {
- cln.AccountSummary = ec.AccountSummary.Clone()
- }
- if ec.Rating != nil {
- cln.Rating = ec.Rating.Clone()
- }
- if ec.Accounting != nil {
- cln.Accounting = ec.Accounting.Clone()
- }
- if ec.RatingFilters != nil {
- cln.RatingFilters = ec.RatingFilters.Clone()
- }
- if ec.Rates != nil {
- cln.Rates = ec.Rates.Clone()
- }
- if ec.Timings != nil {
- cln.Timings = ec.Timings.Clone()
- }
- return
-}
-
-// Compute aggregates all the compute methods on EventCost
-func (ec *EventCost) Compute() {
- ec.GetUsage()
- ec.ComputeEventCostUsageIndexes()
- ec.GetCost()
-}
-
-// ResetCounters will reset all the computed cached values
-func (ec *EventCost) ResetCounters() {
- ec.Cost = nil
- ec.Usage = nil
- for _, cIl := range ec.Charges {
- cIl.cost = nil
- cIl.usage = nil
- cIl.ecUsageIdx = nil
- }
-}
-
-// GetCost iterates through Charges, computing EventCost.Cost
-func (ec *EventCost) GetCost() float64 {
- if ec.Cost == nil {
- var cost float64
- for _, ci := range ec.Charges {
- cost += ci.TotalCost()
- }
- cost = utils.Round(cost, globalRoundingDecimals, utils.MetaRoundingMiddle)
- ec.Cost = &cost
- }
- return *ec.Cost
-}
-
-// GetUsage iterates through Charges, computing EventCost.Usage
-func (ec *EventCost) GetUsage() time.Duration {
- if ec.Usage == nil {
- var usage time.Duration
- for _, ci := range ec.Charges {
- usage += time.Duration(ci.Usage().Nanoseconds() * int64(ci.CompressFactor))
- }
- ec.Usage = &usage
- }
- return *ec.Usage
-}
-
-// ComputeEventCostUsageIndexes will iterate through Chargers and populate their ecUsageIdx
-func (ec *EventCost) ComputeEventCostUsageIndexes() {
- var totalUsage time.Duration
- for _, cIl := range ec.Charges {
- if cIl.ecUsageIdx == nil {
- cIl.ecUsageIdx = utils.DurationPointer(totalUsage)
- }
- totalUsage += time.Duration(cIl.Usage().Nanoseconds() * int64(cIl.CompressFactor))
- }
-}
-
-// AsRefundIncrements converts an EventCost into a CallDescriptor
-func (ec *EventCost) AsRefundIncrements(tor string) (cd *CallDescriptor) {
- cd = &CallDescriptor{
- CgrID: ec.CGRID,
- RunID: ec.RunID,
- ToR: tor,
- TimeStart: ec.StartTime,
- TimeEnd: ec.StartTime.Add(ec.GetUsage()),
- DurationIndex: ec.GetUsage(),
- }
- if len(ec.Charges) == 0 {
- return
- }
- var nrIcrms int
- for _, cIl := range ec.Charges {
- nrIcrms += (cIl.CompressFactor * len(cIl.Increments))
- }
- cd.Increments = make(Increments, nrIcrms)
- var iIdx int
- for _, cIl := range ec.Charges {
- for i := 0; i < cIl.CompressFactor; i++ {
- for _, cIcrm := range cIl.Increments {
- cd.Increments[iIdx] = &Increment{
- Cost: cIcrm.Cost,
- Duration: cIcrm.Usage,
- CompressFactor: cIcrm.CompressFactor,
- }
- if cIcrm.AccountingID != utils.EmptyString {
- cd.Increments[iIdx].BalanceInfo = &DebitInfo{
- AccountID: ec.Accounting[cIcrm.AccountingID].AccountID,
- }
- blncSmry := ec.AccountSummary.BalanceSummaries.BalanceSummaryWithUUD(ec.Accounting[cIcrm.AccountingID].BalanceUUID)
- if blncSmry.Type == utils.MetaMonetary {
- cd.Increments[iIdx].BalanceInfo.Monetary = &MonetaryInfo{UUID: blncSmry.UUID}
- } else if utils.NonMonetaryBalances.Has(blncSmry.Type) {
- cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{UUID: blncSmry.UUID}
- }
- if ec.Accounting[cIcrm.AccountingID].ExtraChargeID == utils.MetaNone ||
- ec.Accounting[cIcrm.AccountingID].ExtraChargeID == utils.EmptyString {
- iIdx++
- continue
- }
- // extra charges, ie: non-free *voice
- extraSmry := ec.AccountSummary.BalanceSummaries.BalanceSummaryWithUUD(
- ec.Accounting[ec.Accounting[cIcrm.AccountingID].ExtraChargeID].BalanceUUID)
- if extraSmry.Type == utils.MetaMonetary {
- cd.Increments[iIdx].BalanceInfo.Monetary = &MonetaryInfo{UUID: extraSmry.UUID}
- } else if utils.NonMonetaryBalances.Has(blncSmry.Type) {
- cd.Increments[iIdx].BalanceInfo.Unit = &UnitInfo{UUID: extraSmry.UUID}
- }
- }
- iIdx++
- }
- }
- }
- return
-}
-
-// AsCallCost converts an EventCost into a CallCost
-func (ec *EventCost) AsCallCost(tor string) *CallCost {
- cc := &CallCost{
- ToR: utils.FirstNonEmpty(tor, utils.MetaVoice),
- Cost: ec.GetCost(),
- RatedUsage: float64(ec.GetUsage().Nanoseconds()),
- AccountSummary: ec.AccountSummary,
- }
- cc.Timespans = make(TimeSpans, len(ec.Charges))
- for i, cIl := range ec.Charges {
- ts := &TimeSpan{
- Cost: cIl.Cost(),
- DurationIndex: *cIl.Usage(),
- CompressFactor: cIl.CompressFactor,
- }
- if cIl.ecUsageIdx == nil { // index was not populated yet
- ec.ComputeEventCostUsageIndexes()
- }
- ts.TimeStart = ec.StartTime.Add(*cIl.ecUsageIdx)
- ts.TimeEnd = ts.TimeStart.Add(
- time.Duration(cIl.Usage().Nanoseconds() * int64(cIl.CompressFactor)))
- if cIl.RatingID != "" &&
- ec.Rating[cIl.RatingID].RatingFiltersID != "" {
- rfs := ec.RatingFilters[ec.Rating[cIl.RatingID].RatingFiltersID]
- ts.MatchedSubject = rfs[utils.Subject].(string)
- ts.MatchedPrefix = rfs[utils.DestinationPrefixName].(string)
- ts.MatchedDestId = rfs[utils.DestinationID].(string)
- ts.RatingPlanId = rfs[utils.RatingPlanID].(string)
- }
- ts.RateInterval = ec.rateIntervalForRatingID(cIl.RatingID)
-
- incrs := cIl.Increments
- if l := len(cIl.Increments); l != 0 {
- if cIl.Increments[l-1].Cost != 0 &&
- ec.Accounting[cIl.Increments[l-1].AccountingID].RatingID == utils.MetaRounding {
- // special case: if the last increment has the ratingID equal to *rounding
- // we consider it as the roundIncrement
- l--
- incrs = incrs[:l]
- ts.RoundIncrement = ec.newIntervalFromCharge(cIl.Increments[l-1])
- ts.RoundIncrement.Cost = -ts.RoundIncrement.Cost
- }
- ts.Increments = make(Increments, l)
- }
- for j, cInc := range incrs {
- ts.Increments[j] = ec.newIntervalFromCharge(cInc)
- }
- cc.Timespans[i] = ts
- }
- return cc
-}
-
-// newIntervalFromCharge creates Increment from a ChargingIncrement
-func (ec *EventCost) newIntervalFromCharge(cInc *ChargingIncrement) (incr *Increment) {
- incr = &Increment{
- Duration: cInc.Usage,
- Cost: cInc.Cost,
- CompressFactor: cInc.CompressFactor,
- BalanceInfo: new(DebitInfo),
- }
- if len(cInc.AccountingID) == 0 {
- return
- }
- cBC := ec.Accounting[cInc.AccountingID]
- incr.BalanceInfo.AccountID = cBC.AccountID
- var balanceType string
- if cBC.BalanceUUID != "" {
- if ec.AccountSummary != nil {
- for _, b := range ec.AccountSummary.BalanceSummaries {
- if b.UUID == cBC.BalanceUUID {
- balanceType = b.Type
- break
- }
- }
- }
- }
- if utils.SliceHasMember([]string{utils.MetaData, utils.MetaVoice}, balanceType) && cBC.ExtraChargeID == "" {
- cBC.ExtraChargeID = utils.MetaNone // mark the balance to be exported as Unit type
- }
- if cBC.ExtraChargeID != "" { // have both monetary and data
- // Work around, enforce logic with 2 balances for *voice/*monetary combination
- // so we can stay compatible with CallCost
- incr.BalanceInfo.Unit = &UnitInfo{UUID: cBC.BalanceUUID, Consumed: cBC.Units}
- incr.BalanceInfo.Unit.RateInterval = ec.rateIntervalForRatingID(cBC.RatingID)
- if cBC.ExtraChargeID != utils.MetaNone {
- cBC = ec.Accounting[cBC.ExtraChargeID] // overwrite original balance so we can process it in one place
- }
- }
- if cBC.ExtraChargeID != utils.MetaNone {
- incr.BalanceInfo.Monetary = &MonetaryInfo{UUID: cBC.BalanceUUID}
- incr.BalanceInfo.Monetary.RateInterval = ec.rateIntervalForRatingID(cBC.RatingID)
- }
- return
-}
-
-// ratingGetIDFomEventCost retrieves UUID based on data from another EventCost
-func (ec *EventCost) ratingGetIDFomEventCost(oEC *EventCost, oRatingID string) string {
- if oRatingID == utils.EmptyString {
- return utils.EmptyString
- } else if oRatingID == utils.MetaPause {
- oCIlRating := oEC.Rating[oRatingID].Clone() // clone so we don't influence the original data
- oCIlRating.TimingID = utils.MetaPause
- ec.Timings[utils.MetaPause] = oEC.Timings[oCIlRating.TimingID]
- oCIlRating.RatingFiltersID = utils.MetaPause
- ec.RatingFilters[utils.MetaPause] = oEC.RatingFilters[oCIlRating.RatingFiltersID]
- oCIlRating.RatesID = utils.MetaPause
- ec.Rates[utils.MetaPause] = oEC.Rates[oCIlRating.RatesID]
- ec.Rating[utils.MetaPause] = oCIlRating
- return utils.MetaPause
- }
- oCIlRating := oEC.Rating[oRatingID].Clone() // clone so we don't influence the original data
- oCIlRating.TimingID = ec.Timings.GetIDWithSet(oEC.Timings[oCIlRating.TimingID])
- oCIlRating.RatingFiltersID = ec.RatingFilters.GetIDWithSet(oEC.RatingFilters[oCIlRating.RatingFiltersID])
- oCIlRating.RatesID = ec.Rates.GetIDWithSet(oEC.Rates[oCIlRating.RatesID])
- return ec.Rating.GetIDWithSet(oCIlRating)
-}
-
-// accountingGetIDFromEventCost retrieves UUID based on data from another EventCost
-func (ec *EventCost) accountingGetIDFromEventCost(oEC *EventCost, oAccountingID string) string {
- if oAccountingID == "" || oAccountingID == utils.MetaNone {
- return ""
- } else if oAccountingID == utils.MetaPause { // *pause represent a pause in debited session
- oBC := oEC.Accounting[oAccountingID].Clone()
- oBC.RatingID = ec.ratingGetIDFomEventCost(oEC, oBC.RatingID)
- ec.Accounting[utils.MetaPause] = oBC
- return utils.MetaPause
- }
- oBC := oEC.Accounting[oAccountingID].Clone()
- oBC.RatingID = ec.ratingGetIDFomEventCost(oEC, oBC.RatingID)
- oBC.ExtraChargeID = ec.accountingGetIDFromEventCost(oEC, oBC.ExtraChargeID)
- return ec.Accounting.GetIDWithSet(oBC)
-}
-
-// appendCIl appends a ChargingInterval to existing chargers
-// no compression done at ChargingInterval level, attempted on ChargingIncrement level
-func (ec *EventCost) appendCIlFromEC(oEC *EventCost, cIlIdx int) {
- cIl := oEC.Charges[cIlIdx]
- cIlCln := cIl.Clone() // add/modify data on clone instead of original
- cIlCln.RatingID = ec.ratingGetIDFomEventCost(oEC, cIl.RatingID)
- lastCIl := ec.Charges[len(ec.Charges)-1]
- lastCIt := lastCIl.Increments[len(lastCIl.Increments)-1]
- appendChargingIncrement := lastCIl.CompressFactor == 1 &&
- lastCIl.RatingID == cIlCln.RatingID // attempt compressing of the ChargingIncrements
- var idxFirstCIt *int // keep here the reference towards last not appended charging increment so we can create separate ChargingInterval
- var idxLastCF *int // reference towards last compress not absorbed by ec.Charges
- for cF := cIl.CompressFactor; cF > 0; cF-- {
- for i, cIt := range cIl.Increments {
- cIlCln.Increments[i].AccountingID = ec.accountingGetIDFromEventCost(oEC, cIt.AccountingID)
- if idxFirstCIt != nil {
- continue
- }
- if !appendChargingIncrement ||
- !lastCIt.PartiallyEquals(cIlCln.Increments[i]) {
- idxFirstCIt = utils.IntPointer(i)
- idxLastCF = utils.IntPointer(cF)
- continue
- }
- lastCIt.CompressFactor += cIt.CompressFactor // compress the iterated ChargingIncrement
- }
- }
- if lastCIl.PartiallyEquals(cIlCln) { // the two CIls are equal, compress the original one
- lastCIl.CompressFactor += cIlCln.CompressFactor
- return
- }
- if idxFirstCIt != nil { // CIt was not completely absorbed
- cIl.RatingID = cIlCln.RatingID // reuse cIl so we don't clone again
- cIl.CompressFactor = 1
- cIl.Increments = cIlCln.Increments[*idxFirstCIt:]
- ec.Charges = append(ec.Charges, cIl)
- if *idxLastCF > 1 { // add the remaining part out of original ChargingInterval
- cIlCln.CompressFactor = *idxLastCF - 1
- // append the cloned charge in order to not keep refrences
- // of the increments used for previous charge
- ec.Charges = append(ec.Charges, cIlCln.Clone())
- }
- }
-}
-
-// AppendChargingInterval appends or compresses a &ChargingInterval to existing ec.Chargers
-func (ec *EventCost) appendChargingIntervalFromEventCost(oEC *EventCost, cIlIdx int) {
- lenChargers := len(ec.Charges)
- if lenChargers != 0 && ec.Charges[lenChargers-1].PartiallyEquals(oEC.Charges[cIlIdx]) {
- ec.Charges[lenChargers-1].CompressFactor++
- } else {
- ec.appendCIlFromEC(oEC, cIlIdx)
- }
-}
-
-// SyncKeys will sync the keys present into ec with the ones in refEC
-func (ec *EventCost) SyncKeys(refEC *EventCost) {
- // sync RatingFilters
- sncedRFilterIDs := make(map[string]string)
- for key, rf := range ec.RatingFilters {
- for refKey, refRf := range refEC.RatingFilters {
- if rf.Equals(refRf) {
- delete(ec.RatingFilters, key)
- sncedRFilterIDs[key] = refKey
- ec.RatingFilters[refKey] = rf
- break
- }
- }
- }
- // sync Rates
- sncedRateIDs := make(map[string]string)
- for key, rt := range ec.Rates {
- for refKey, refRt := range refEC.Rates {
- if rt.Equals(refRt) {
- delete(ec.Rates, key)
- sncedRateIDs[key] = refKey
- ec.Rates[refKey] = rt
- break
- }
- }
- }
- // sync Timings
- sncedTimingIDs := make(map[string]string)
- for key, tm := range ec.Timings {
- for refKey, refTm := range refEC.Timings {
- if tm.Equals(refTm) {
- delete(ec.Timings, key)
- sncedTimingIDs[key] = refKey
- ec.Timings[refKey] = tm
- break
- }
- }
- }
- // sync Rating
- sncedRatingIDs := make(map[string]string)
- for key, ru := range ec.Rating {
- if tmRefKey, has := sncedTimingIDs[ru.TimingID]; has {
- ru.TimingID = tmRefKey
- }
- if rtRefID, has := sncedRateIDs[ru.RatesID]; has {
- ru.RatesID = rtRefID
- }
- if rfRefID, has := sncedRFilterIDs[ru.RatingFiltersID]; has {
- ru.RatingFiltersID = rfRefID
- }
- for refKey, refRU := range refEC.Rating {
- if ru.Equals(refRU) {
- delete(ec.Rating, key)
- sncedRatingIDs[key] = refKey
- ec.Rating[refKey] = ru
- break
- }
- }
- }
- // sync Accounting
- sncedAcntIDs := make(map[string]string)
- for key, acnt := range ec.Accounting {
- if rtRefKey, has := sncedRatingIDs[acnt.RatingID]; has {
- acnt.RatingID = rtRefKey
- }
- for refKey, refAcnt := range refEC.Accounting {
- if acnt.Equals(refAcnt) {
- delete(ec.Accounting, key)
- sncedAcntIDs[key] = refKey
- ec.Accounting[refKey] = acnt
- break
- }
- }
- }
- // correct the ExtraCharge
- for _, acnt := range ec.Accounting {
- if acntRefID, has := sncedAcntIDs[acnt.ExtraChargeID]; has {
- acnt.ExtraChargeID = acntRefID
- }
- }
- // need another sync for the corrected ExtraChargeIDs
- for key, acnt := range ec.Accounting {
- for refKey, refAcnt := range refEC.Accounting {
- if acnt.Equals(refAcnt) {
- delete(ec.Accounting, key)
- sncedAcntIDs[key] = refKey
- ec.Accounting[refKey] = acnt
- break
- }
- }
- }
- // sync Charges
- for _, ci := range ec.Charges {
- if refRatingID, has := sncedRatingIDs[ci.RatingID]; has {
- ci.RatingID = refRatingID
- }
- for _, cIcrmt := range ci.Increments {
- if refAcntID, has := sncedAcntIDs[cIcrmt.AccountingID]; has {
- cIcrmt.AccountingID = refAcntID
- }
- }
- }
-}
-
-// Merge will merge a list of EventCosts into this one
-func (ec *EventCost) Merge(ecs ...*EventCost) {
- for _, newEC := range ecs {
- // updated AccountSummary information
- newEC.AccountSummary.UpdateInitialValue(ec.AccountSummary)
- ec.AccountSummary = newEC.AccountSummary
- for cIlIdx := range newEC.Charges {
- ec.appendChargingIntervalFromEventCost(newEC, cIlIdx)
- }
- }
- ec.ResetCounters()
-}
-
-// RemoveStaleReferences iterates through cached data and makes sure it is still referenced from Charging
-func (ec *EventCost) RemoveStaleReferences() {
- // RatingIDs
- for key := range ec.Rating {
- var keyUsed bool
- for _, cIl := range ec.Charges {
- if cIl.RatingID == key {
- keyUsed = true
- break
- }
- }
- if !keyUsed { // look also in accounting for references
- for _, bc := range ec.Accounting {
- if bc.RatingID == key {
- keyUsed = true
- break
- }
- }
- }
- if !keyUsed { // not used, remove it
- delete(ec.Rating, key)
- }
- }
- for key := range ec.Accounting {
- var keyUsed bool
- for _, cIl := range ec.Charges {
- for _, cIt := range cIl.Increments {
- if cIt.AccountingID == key {
- keyUsed = true
- break
- }
- }
- if !keyUsed {
- for _, bCharge := range ec.Accounting {
- if bCharge.ExtraChargeID == key {
- keyUsed = true
- break
- }
- }
- }
- }
- if !keyUsed {
- delete(ec.Accounting, key)
- }
- }
- for key := range ec.RatingFilters {
- var keyUsed bool
- for _, ru := range ec.Rating {
- if ru.RatingFiltersID == key {
- keyUsed = true
- break
- }
- }
- if !keyUsed {
- delete(ec.RatingFilters, key)
- }
- }
- for key := range ec.Rates {
- var keyUsed bool
- for _, ru := range ec.Rating {
- if ru.RatesID == key {
- keyUsed = true
- break
- }
- }
- if !keyUsed {
- delete(ec.Rates, key)
- }
- }
- for key := range ec.Timings {
- var keyUsed bool
- for _, ru := range ec.Rating {
- if ru.TimingID == key {
- keyUsed = true
- break
- }
-
- }
- if !keyUsed {
- delete(ec.Rates, key)
- }
- }
-}
-
-// Trim will cut the EventCost at specific duration
-// returns the srplusEC as separate EventCost
-func (ec *EventCost) Trim(atUsage time.Duration) (srplusEC *EventCost, err error) {
- if ec.Usage == nil {
- ec.GetUsage()
- }
- origECUsage := ec.GetUsage()
- if atUsage >= *ec.Usage {
- return // no trim
- }
- if atUsage == 0 {
- //clone the event because we need to overwrite ec
- srplusEC = ec.Clone()
- // modify the value of ec
- *ec = *NewBareEventCost()
- ec.CGRID = srplusEC.CGRID
- ec.RunID = srplusEC.RunID
- ec.StartTime = srplusEC.StartTime
- ec.AccountSummary = srplusEC.AccountSummary.Clone()
- return // trim all, fresh EC with 0 usage
- }
-
- srplusEC = NewBareEventCost()
- srplusEC.CGRID = ec.CGRID
- srplusEC.RunID = ec.RunID
- srplusEC.StartTime = ec.StartTime
- srplusEC.AccountSummary = ec.AccountSummary.Clone()
-
- var lastActiveCIlIdx *int // mark last index which should stay with ec
- for i, cIl := range ec.Charges {
- if cIl.ecUsageIdx == nil {
- ec.ComputeEventCostUsageIndexes()
- }
- if cIl.usage == nil {
- ec.GetUsage()
- }
- if *cIl.ecUsageIdx+*cIl.TotalUsage() >= atUsage {
- lastActiveCIlIdx = utils.IntPointer(i)
- break
- }
- }
- if lastActiveCIlIdx == nil {
- return nil, errors.New("cannot find last active ChargingInterval")
- }
- lastActiveCIl := ec.Charges[*lastActiveCIlIdx]
- if *lastActiveCIl.ecUsageIdx >= atUsage {
- return nil, errors.New("failed detecting last active ChargingInterval")
- } else if lastActiveCIl.CompressFactor == 0 {
- return nil, errors.New("ChargingInterval with 0 compressFactor")
- }
- srplusEC.Charges = append(srplusEC.Charges, ec.Charges[*lastActiveCIlIdx+1:]...) // direct assignment will wrongly reference later
- ec.Charges = ec.Charges[:*lastActiveCIlIdx+1]
- ec.Usage = nil
- ec.Cost = nil
- if lastActiveCIl.CompressFactor != 1 &&
- *lastActiveCIl.ecUsageIdx+*lastActiveCIl.TotalUsage() > atUsage { // Split based on compress factor if needed
- var laCF int
- for ciCnt := 1; ciCnt <= lastActiveCIl.CompressFactor; ciCnt++ {
- if *lastActiveCIl.ecUsageIdx+
- time.Duration(lastActiveCIl.usage.Nanoseconds()*int64(ciCnt)) >= atUsage {
- laCF = ciCnt
- break
- }
- }
- if laCF == 0 {
- return nil, errors.New("cannot detect last active CompressFactor in ChargingInterval")
- }
- if laCF != lastActiveCIl.CompressFactor {
- srplsCIl := lastActiveCIl.Clone()
- srplsCIl.CompressFactor = lastActiveCIl.CompressFactor - laCF
- srplusEC.Charges = append([]*ChargingInterval{srplsCIl}, srplusEC.Charges...) // prepend surplus CIl
- lastActiveCIl.CompressFactor = laCF // correct compress factor
- ec.Usage = nil
- ec.Cost = nil
- }
- }
- if atUsage != ec.GetUsage() { // lastInterval covering more than needed, need split
- atUsage -= (ec.GetUsage() - *lastActiveCIl.Usage()) // remaining duration to cover in increments of the last charging interval
- // find out last increment covering duration
- var lastActiveCItIdx *int
- var incrementsUsage time.Duration
- for i, cIt := range lastActiveCIl.Increments {
- incrementsUsage += cIt.TotalUsage()
- if incrementsUsage >= atUsage {
- lastActiveCItIdx = utils.IntPointer(i)
- break
- }
- }
- if lastActiveCItIdx == nil { // bug in increments
- return nil, errors.New("no active increment found")
- }
- lastActiveCIts := lastActiveCIl.Increments // so we can modify the reference in case we have surplus
- lastIncrement := lastActiveCIts[*lastActiveCItIdx]
- if lastIncrement.CompressFactor == 0 {
- return nil, errors.New("empty compress factor in increment")
- }
- var srplsIncrements []*ChargingIncrement
- if *lastActiveCItIdx < len(lastActiveCIl.Increments)-1 { // less that complete increments, have surplus
- srplsIncrements = lastActiveCIts[*lastActiveCItIdx+1:]
- lastActiveCIts = lastActiveCIts[:*lastActiveCItIdx+1]
- ec.Usage = nil
- ec.Cost = nil
- }
- var laItCF int
- if lastIncrement.CompressFactor != 1 && atUsage != incrementsUsage {
- // last increment compress factor is higher that we need to cover
- incrementsUsage -= lastIncrement.TotalUsage()
- for cnt := 1; cnt <= lastIncrement.CompressFactor; cnt++ {
- incrementsUsage += lastIncrement.Usage
- if incrementsUsage >= atUsage {
- laItCF = cnt
- break
- }
- }
- if laItCF == 0 {
- return nil, errors.New("cannot detect last active CompressFactor in ChargingIncrement")
- }
- if laItCF != lastIncrement.CompressFactor {
- srplsIncrement := lastIncrement.Clone()
- srplsIncrement.CompressFactor = srplsIncrement.CompressFactor - laItCF
- srplsIncrements = append([]*ChargingIncrement{srplsIncrement}, srplsIncrements...) // prepend the surplus out of compress
- }
- }
- if len(srplsIncrements) != 0 { // partially covering, need trim
- if lastActiveCIl.CompressFactor > 1 { // ChargingInterval not covering in full, need to split it
- lastActiveCIl.CompressFactor--
- ec.Charges = append(ec.Charges, lastActiveCIl.Clone())
- lastActiveCIl = ec.Charges[len(ec.Charges)-1]
- lastActiveCIl.CompressFactor = 1
- ec.Usage = nil
- ec.Cost = nil
- }
- srplsCIl := lastActiveCIl.Clone()
- srplsCIl.Increments = srplsIncrements
- srplusEC.Charges = append([]*ChargingInterval{srplsCIl}, srplusEC.Charges...)
- lastActiveCIl.Increments = make([]*ChargingIncrement, len(lastActiveCIts))
- for i, incr := range lastActiveCIts {
- lastActiveCIl.Increments[i] = incr.Clone() // avoid pointer references to the other interval
- }
- if laItCF != 0 {
- lastActiveCIl.Increments[len(lastActiveCIl.Increments)-1].CompressFactor = laItCF // correct the compressFactor for the last increment
- ec.Usage = nil
- ec.Cost = nil
- }
- }
- }
- ec.ResetCounters()
- if usage := ec.GetUsage(); usage < atUsage {
- return nil, errors.New("usage of EventCost smaller than requested")
- }
- srplusEC.ResetCounters()
- srplusEC.StartTime = ec.StartTime.Add(ec.GetUsage())
- if srplsUsage := srplusEC.GetUsage(); srplsUsage > origECUsage-atUsage {
- return nil, errors.New("surplus EventCost too big")
- }
- // close surplus with missing cache
- for _, cIl := range srplusEC.Charges {
- cIl.RatingID = srplusEC.ratingGetIDFomEventCost(ec, cIl.RatingID)
- for _, incr := range cIl.Increments {
- incr.AccountingID = srplusEC.accountingGetIDFromEventCost(ec, incr.AccountingID)
- }
- }
- ec.RemoveStaleReferences() // data should be transferred by now, can clean the old one
- return
-}
-
-// FieldAsInterface func to implement DataProvider
-func (ec *EventCost) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if ec.cache == nil {
- ec.cache = utils.MapStorage{} // fix gob deserialization
- }
- if val, err = ec.cache.FieldAsInterface(fldPath); err != nil {
- if err != utils.ErrNotFound { // item found in cache
- return
- }
- err = nil // cancel previous err
- } else if val == nil {
- return nil, utils.ErrNotFound
- } else {
- return // data found in cache
- }
- val, err = ec.fieldAsInterface(fldPath)
- if err == nil {
- ec.cache.Set(fldPath, val)
- } else if err == utils.ErrNotFound {
- ec.cache.Set(fldPath, nil)
- }
- return
-}
-
-// fieldAsInterface the implementation of FieldAsInterface
-func (ec *EventCost) fieldAsInterface(fldPath []string) (val interface{}, err error) {
- switch fldPath[0] {
- default: // "Charges[1]"
- opath, indx := utils.GetPathIndex(fldPath[0])
- if opath != utils.Charges {
- return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
- }
- if indx != nil {
- if len(ec.Charges) <= *indx {
- return nil, utils.ErrNotFound
- }
- return ec.getChargesForPath(fldPath[1:], ec.Charges[*indx])
- }
- case utils.Charges:
- if len(fldPath) != 1 { // slice has no members
- return nil, utils.ErrNotFound
- }
- return ec.Charges, nil
- case utils.CGRID:
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return ec.CGRID, nil
- case utils.RunID:
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return ec.RunID, nil
- case utils.StartTime:
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return ec.StartTime, nil
- case utils.Usage:
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- if ec.Usage == nil {
- return nil, nil
- }
- return *ec.Usage, nil
- case utils.Cost:
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- if ec.Cost == nil {
- return nil, nil
- }
- return *ec.Cost, nil
- case utils.AccountSummary:
- if len(fldPath) == 1 {
- return ec.AccountSummary, nil
- }
- return ec.AccountSummary.FieldAsInterface(fldPath[1:])
- case utils.Timings:
- if len(fldPath) == 1 {
- return ec.Timings, nil
- }
- return ec.Timings.FieldAsInterface(fldPath[1:])
- case utils.Rates:
- if len(fldPath) == 1 {
- return ec.Rates, nil
- }
- return ec.Rates.FieldAsInterface(fldPath[1:])
- case utils.RatingFilters:
- if len(fldPath) == 1 {
- return ec.RatingFilters, nil
- }
- return ec.RatingFilters.FieldAsInterface(fldPath[1:])
- case utils.Accounting:
- if len(fldPath) == 1 {
- return ec.Accounting, nil
- }
- return ec.Accounting.FieldAsInterface(fldPath[1:])
- case utils.Rating:
- if len(fldPath) == 1 {
- return ec.Rating, nil
- }
- return ec.Rating.FieldAsInterface(fldPath[1:])
- }
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
-}
-
-func (ec *EventCost) getChargesForPath(fldPath []string, chr *ChargingInterval) (val interface{}, err error) {
- if chr == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 0 {
- return chr, nil
- }
- if fldPath[0] == utils.CompressFactor {
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return chr.CompressFactor, nil
- }
- if fldPath[0] == utils.Rating {
- return ec.getRatingForPath(fldPath[1:], ec.Rating[chr.RatingID])
- }
- opath, indx := utils.GetPathIndex(fldPath[0])
- if opath != utils.Increments {
- return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
- }
- if indx == nil {
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return chr.Increments, nil
- }
- if len(chr.Increments) <= *indx {
- return nil, utils.ErrNotFound
- }
- incr := chr.Increments[*indx]
- if len(fldPath) == 1 {
- return incr, nil
- }
- if fldPath[1] == utils.Accounting {
- return ec.getAcountingForPath(fldPath[2:], ec.Accounting[incr.AccountingID])
- }
- return incr.FieldAsInterface(fldPath)
-}
-
-func (ec *EventCost) getRatingForPath(fldPath []string, rating *RatingUnit) (val interface{}, err error) {
- if rating == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 0 {
- return rating, nil
- }
-
- switch fldPath[0] {
- default:
- opath, indx := utils.GetPathIndex(fldPath[0])
- if opath != utils.Rates {
- return nil, fmt.Errorf("unsupported field prefix: <%s>", opath)
- }
- rts, has := ec.Rates[rating.RatesID]
- if !has || rts == nil {
- return nil, utils.ErrNotFound
- }
- if indx != nil {
- if len(rts) <= *indx {
- return nil, utils.ErrNotFound
- }
- rt := rts[*indx]
- if len(fldPath) == 1 {
- return rt, nil
- }
- return rt.FieldAsInterface(fldPath[1:])
- }
- case utils.Rates:
- rts, has := ec.Rates[rating.RatesID]
- if !has || rts == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound // no field on slice
- }
- return rts, nil
- case utils.Timing:
- tmg, has := ec.Timings[rating.TimingID]
- if !has || tmg == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return tmg, nil
- }
- return tmg.FieldAsInterface(fldPath[1:])
- case utils.RatingFilter:
- rtFltr, has := ec.RatingFilters[rating.RatingFiltersID]
- if !has || rtFltr == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return rtFltr, nil
- }
- return rtFltr.FieldAsInterface(fldPath[1:])
- }
- return rating.FieldAsInterface(fldPath)
-}
-
-func (ec *EventCost) getAcountingForPath(fldPath []string, bc *BalanceCharge) (val interface{}, err error) {
- if bc == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 0 {
- return bc, nil
- }
-
- if fldPath[0] == utils.BalanceField {
- bl := ec.AccountSummary.BalanceSummaries.BalanceSummaryWithUUD(bc.BalanceUUID)
- if bl == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return bl, nil
- }
- return bl.FieldAsInterface(fldPath[1:])
-
- }
- return bc.FieldAsInterface(fldPath)
-}
-
-// String to implement Dataprovider
-func (ec *EventCost) String() string {
- return utils.ToJSON(ec)
-}
-
-// FieldAsString to implement Dataprovider
-func (ec *EventCost) FieldAsString(fldPath []string) (string, error) {
- ival, err := ec.FieldAsInterface(fldPath)
- if err != nil {
- return utils.EmptyString, err
- }
- return utils.IfaceAsString(ival), nil
-}
-
-// RemoteHost to implement Dataprovider
-func (ec *EventCost) RemoteHost() net.Addr {
- return utils.LocalAddr()
-}
diff --git a/engine/eventcost_test.go b/engine/eventcost_test.go
deleted file mode 100644
index 725b7f853..000000000
--- a/engine/eventcost_test.go
+++ /dev/null
@@ -1,3803 +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 (
- "fmt"
- "reflect"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/utils"
-)
-
-// testEC is used as sample through various tests
-var testEC = &EventCost{
- CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: 0,
- Cost: 0.1,
- AccountingID: "9bdad10",
- CompressFactor: 1,
- },
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 60,
- },
- },
- CompressFactor: 4,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 5,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 50,
- },
- {
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 25,
- },
- {
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: utils.MetaVoice,
- Value: 200,
- },
- },
- AllowNegative: false,
- Disabled: false,
- },
- Rating: Rating{
- "3cd6425": &RatingUnit{
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "7f324ab",
- RatesID: "4910ecf",
- RatingFiltersID: "43e77dc",
- },
- "c1a5ab9": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "7f324ab",
- RatesID: "ec1a177",
- RatingFiltersID: "43e77dc",
- },
- },
- Accounting: Accounting{
- "a012888": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- },
- "188bfa6": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "9bdad10": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.1,
- },
- "44d6c02": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- RatingID: "3cd6425",
- Units: 1,
- ExtraChargeID: "188bfa6",
- },
- "3455b83": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Units: 1,
- ExtraChargeID: "*none",
- },
- },
- RatingFilters: RatingFilters{
- "43e77dc": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Rates: ChargedRates{
- "ec1a177": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Minute,
- RateUnit: time.Second},
- },
- "4910ecf": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- },
- },
- Timings: ChargedTimings{
- "7f324ab": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- cache: utils.MapStorage{},
-}
-
-func TestECClone(t *testing.T) {
- ec := testEC.Clone()
- if !reflect.DeepEqual(testEC, ec) {
- t.Errorf("Expecting: %s, received: %s",
- utils.ToJSON(testEC), utils.ToJSON(ec))
- }
- // making sure we don't influence the original values
- ec.Usage = utils.DurationPointer(time.Second)
- if testEC.Usage != nil {
- t.Error("Usage is not nil")
- }
- ec.Cost = utils.Float64Pointer(1.0)
- if testEC.Cost != nil {
- t.Error("Cost is not nil")
- }
- ec.Charges[0].Increments[0].Cost = 1.0
- if testEC.Charges[0].Increments[0].Cost == 1.0 {
- t.Error("Cost is 1.0")
- }
- ec.AccountSummary.Disabled = true
- if testEC.AccountSummary.Disabled {
- t.Error("Account is disabled")
- }
- ec.AccountSummary.BalanceSummaries[0].Value = 5.0
- if testEC.AccountSummary.BalanceSummaries[0].Value == 5.0 {
- t.Error("Wrong balance summary")
- }
- ec.Rates["ec1a177"][0].Value = 5.0
- if testEC.Rates["ec1a177"][0].Value == 5.0 {
- t.Error("Wrong Value")
- }
- delete(ec.Rates, "ec1a177")
- if _, has := testEC.Rates["ec1a177"]; !has {
- t.Error("Key removed from testEC")
- }
- ec.Timings["7f324ab"].StartTime = "10:00:00"
- if testEC.Timings["7f324ab"].StartTime == "10:00:00" {
- t.Error("Wrong StartTime")
- }
- delete(ec.Timings, "7f324ab")
- if _, has := testEC.Timings["7f324ab"]; !has {
- t.Error("Key removed from testEC")
- }
- ec.RatingFilters["43e77dc"]["DestinationID"] = "GERMANY_MOBILE"
- if testEC.RatingFilters["43e77dc"]["DestinationID"] == "GERMANY_MOBILE" {
- t.Error("Wrong DestinationID")
- }
- delete(ec.RatingFilters, "43e77dc")
- if _, has := testEC.RatingFilters["43e77dc"]; !has {
- t.Error("Key removed from testEC")
- }
- ec.Accounting["a012888"].Units = 5.0
- if testEC.Accounting["a012888"].Units == 5.0 {
- t.Error("Wrong Units")
- }
- delete(ec.Accounting, "a012888")
- if _, has := testEC.Accounting["a012888"]; !has {
- t.Error("Key removed from testEC")
- }
-}
-
-func TestECComputeAndReset(t *testing.T) {
- ec := testEC.Clone()
- eEc := testEC.Clone()
- eEc.Usage = utils.DurationPointer(10 * time.Minute)
- eEc.Cost = utils.Float64Pointer(3.52)
- eEc.Charges[0].ecUsageIdx = utils.DurationPointer(0)
- eEc.Charges[0].usage = utils.DurationPointer(time.Minute)
- eEc.Charges[0].cost = utils.Float64Pointer(0.27)
- eEc.Charges[1].ecUsageIdx = utils.DurationPointer(time.Minute)
- eEc.Charges[1].usage = utils.DurationPointer(time.Minute)
- eEc.Charges[1].cost = utils.Float64Pointer(0.6)
- eEc.Charges[2].ecUsageIdx = utils.DurationPointer(5 * time.Minute)
- eEc.Charges[2].usage = utils.DurationPointer(time.Minute)
- eEc.Charges[2].cost = utils.Float64Pointer(0.17)
- ec.Compute()
- if !reflect.DeepEqual(eEc, ec) {
- t.Errorf("Expecting: %s\n, received: %s", utils.ToJSON(eEc), utils.ToJSON(ec))
- }
- ec.ResetCounters()
- if !reflect.DeepEqual(testEC, ec) {
- t.Errorf("Expecting: %+v, received: %+v", testEC, ec)
- }
-}
-
-func TestNewEventCostFromCallCost(t *testing.T) {
- acntSummary := &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- Type: "*monetary",
- Value: 50,
- Disabled: false},
- {
- ID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: "*monetary",
- Value: 25,
- Disabled: false},
- {
- Type: "*voice",
- Value: 200,
- Disabled: false,
- },
- },
- AllowNegative: false,
- Disabled: false,
- }
- cc := &CallCost{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dan",
- Account: "dan",
- Destination: "+4986517174963",
- ToR: utils.MetaVoice,
- Cost: 0.75,
- RatedUsage: 120.0,
- Timespans: TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- Cost: 0.15,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateUnit: time.Second,
- RateIncrement: time.Minute,
- },
- },
- },
- },
- DurationIndex: time.Minute,
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- RoundIncrement: &Increment{
- Cost: 0.1,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.9},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 1,
- },
- Increments: Increments{
- &Increment{ // ConnectFee
- Cost: 0.1,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.9},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 1,
- },
- &Increment{ // First 30 seconds free
- Duration: time.Second,
- Cost: 0,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{
- UUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
- ID: "free_mins",
- Value: 0,
- Consumed: 1.0,
- ToR: utils.MetaVoice,
- },
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- &Increment{ // Minutes with special price
- Duration: time.Second,
- Cost: 0.005,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{ // Minutes with special price
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: "discounted_mins",
- Value: 0,
- Consumed: 1.0,
- ToR: utils.MetaVoice,
- RateInterval: &RateInterval{
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateUnit: time.Second,
- RateIncrement: time.Second,
- },
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateUnit: time.Second,
- RateIncrement: time.Second,
- },
- },
- },
- },
- },
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.75},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- },
- },
-
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 20, 21, 0, time.UTC),
- Cost: 0.6,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateUnit: time.Second,
- RateIncrement: time.Minute,
- },
- },
- },
- },
- DurationIndex: time.Minute,
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{
- Cost: 0.01,
- Duration: time.Second,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.15},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 60,
- },
- },
- },
- },
- AccountSummary: acntSummary,
- }
-
- eEC := &EventCost{
- CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- Cost: utils.Float64Pointer(0.85),
- Usage: utils.DurationPointer(2 * time.Minute),
- Charges: []*ChargingInterval{
- {
- RatingID: "f2518464-68b8-42f4-acec-aef23d714314",
- Increments: []*ChargingIncrement{
- {
- Usage: 0,
- Cost: 0.1,
- AccountingID: "44e97dec-8a7e-43d0-8b0a-736d46b5613e",
- CompressFactor: 1,
- },
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "a555cde8-4bd0-408a-afbc-c3ba64888927",
- CompressFactor: 30,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "906bfd0f-035c-40a3-93a8-46f71627983e",
- CompressFactor: 30,
- },
- {
- Cost: -0.1,
- AccountingID: "44e97dec-8a7e-43d0-8b0a-e34a152",
- CompressFactor: 1,
- },
- },
- CompressFactor: 1,
- usage: utils.DurationPointer(60 * time.Second),
- cost: utils.Float64Pointer(0.15),
- ecUsageIdx: utils.DurationPointer(0),
- },
- {
- RatingID: "f2518464-68b8-42f4-acec-aef23d714314",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "c890a899-df43-497a-9979-38492713f57b",
- CompressFactor: 60,
- },
- },
- CompressFactor: 1,
- usage: utils.DurationPointer(60 * time.Second),
- cost: utils.Float64Pointer(0.6),
- ecUsageIdx: utils.DurationPointer(60 * time.Second),
- },
- },
- Rating: Rating{
- "4607d907-02c3-4f2b-bc08-95a0dcc7222c": &RatingUnit{
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- RatesID: "e5eb0f1c-3612-4e8c-b749-7f8f41dd90d4",
- RatingFiltersID: "7e73a00d-be53-4083-a1ee-8ee0b546c62a",
- },
- "f2518464-68b8-42f4-acec-aef23d714314": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- RatesID: "6504fb84-6b27-47a8-a1c6-c0d843959f89",
- RatingFiltersID: "7e73a00d-be53-4083-a1ee-8ee0b546c62a",
- },
- },
- Accounting: Accounting{
- "c890a899-df43-497a-9979-38492713f57b": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- },
- "a894f8f1-206a-4457-99ce-df21a0c7fedc": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "44e97dec-8a7e-43d0-8b0a-736d46b5613e": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.1,
- },
- "906bfd0f-035c-40a3-93a8-46f71627983e": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- RatingID: "4607d907-02c3-4f2b-bc08-95a0dcc7222c",
- Units: 1,
- ExtraChargeID: "a894f8f1-206a-4457-99ce-df21a0c7fedc",
- },
- "a555cde8-4bd0-408a-afbc-c3ba64888927": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
- Units: 1,
- ExtraChargeID: "*none",
- },
- "44e97dec-8a7e-43d0-8b0a-e34a152": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- RatingID: "*rounding",
- Units: 0.1,
- ExtraChargeID: "",
- },
- },
- RatingFilters: RatingFilters{
- "7e73a00d-be53-4083-a1ee-8ee0b546c62a": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Rates: ChargedRates{
- "6504fb84-6b27-47a8-a1c6-c0d843959f89": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Minute,
- RateUnit: time.Second},
- },
- "e5eb0f1c-3612-4e8c-b749-7f8f41dd90d4": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- },
- },
- Timings: ChargedTimings{
- "27f1e5f8-05bb-4f1c-a596-bf1010ad296c": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- AccountSummary: acntSummary,
- }
- ec := NewEventCostFromCallCost(cc, "164b0422fdc6a5117031b427439482c6a4f90e41", utils.MetaDefault)
- if cost := ec.GetCost(); cost != cc.Cost {
- t.Errorf("Expecting: %f, received: %f", cc.Cost, cost)
- }
- eUsage := time.Duration(int64(cc.RatedUsage * 1000000000))
- if usage := ec.GetUsage(); usage != eUsage {
- t.Errorf("Expecting: %v, received: %v", eUsage, usage)
- }
- if len(ec.Charges) != len(eEC.Charges) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
- ec.ComputeEventCostUsageIndexes()
- for i := range ec.Charges {
- // Make sure main rating is correct
- if cc.Timespans[i].RateInterval.Rating != nil &&
- !reflect.DeepEqual(cc.Timespans[i].RateInterval.Rating.Rates,
- ec.Rates[ec.Rating[ec.Charges[i].RatingID].RatesID]) {
- t.Errorf("Index: %d, expecting: %+v, received: %+v",
- i, utils.ToJSON(cc.Timespans[i].RateInterval.Rating.Rates),
- ec.Rates[ec.Rating[ec.Charges[i].RatingID].RatesID])
- }
- // Make sure it matches also the expected rates
- if !reflect.DeepEqual(eEC.Rates[eEC.Rating[eEC.Charges[i].RatingID].RatesID],
- ec.Rates[ec.Rating[ec.Charges[i].RatingID].RatesID]) {
- t.Errorf("Index: %d, expecting: %s, received: %s", i,
- utils.ToJSON(eEC.Rates[eEC.Rating[eEC.Charges[i].RatingID].RatesID]),
- utils.ToJSON(ec.Rates[ec.Rating[ec.Charges[i].RatingID].RatesID]))
- }
- if len(eEC.Charges[i].Increments) != len(ec.Charges[i].Increments) {
- t.Errorf("Index %d, expecting: %+v, received: %+v",
- i, eEC.Charges[i].Increments, ec.Charges[i].Increments)
- }
- if !reflect.DeepEqual(eEC.Charges[i].Usage(), ec.Charges[i].Usage()) {
- t.Errorf("Expecting: %v, received: %v",
- eEC.Charges[i].Usage(), ec.Charges[i].Usage())
- }
- if !reflect.DeepEqual(eEC.Charges[i].Cost(), ec.Charges[i].Cost()) {
- t.Errorf("Expecting: %f, received: %f",
- eEC.Charges[i].Cost(), ec.Charges[i].Cost())
- }
- if !reflect.DeepEqual(eEC.Charges[i].ecUsageIdx, ec.Charges[i].ecUsageIdx) {
- t.Errorf("Expecting: %v, received: %v",
- eEC.Charges[i].ecUsageIdx, ec.Charges[i].ecUsageIdx)
- }
- cIlStartTime := ec.Charges[i].StartTime(ec.StartTime)
- if !cc.Timespans[i].TimeStart.Equal(cIlStartTime) {
- t.Errorf("Expecting: %v, received: %v",
- cc.Timespans[i].TimeStart, cIlStartTime)
- }
- if !cc.Timespans[i].TimeEnd.Equal(ec.Charges[i].EndTime(cIlStartTime)) {
- t.Errorf("Expecting: %v, received: %v",
- cc.Timespans[i].TimeStart, ec.Charges[i].EndTime(cIlStartTime))
- }
- }
- if len(ec.Rating) != len(eEC.Rating) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
- // Compare to original timestamp
- if !reflect.DeepEqual(cc.Timespans[0].Increments[2].BalanceInfo.Unit.RateInterval.Rating.Rates,
- ec.Rates[ec.Rating[ec.Accounting[ec.Charges[0].Increments[2].AccountingID].RatingID].RatesID]) {
- t.Errorf("Expecting: %s, received: %s",
- utils.ToJSON(cc.Timespans[0].Increments[2].BalanceInfo.Unit.RateInterval.Rating.Rates),
- utils.ToJSON(ec.Rates[ec.Rating[ec.Accounting[ec.Charges[0].Increments[2].AccountingID].RatingID].RatesID]))
- }
- // Compare to expected EC
- if !reflect.DeepEqual(eEC.Rates[eEC.Rating[eEC.Accounting[eEC.Charges[0].Increments[2].AccountingID].RatingID].RatesID],
- ec.Rates[ec.Rating[ec.Accounting[ec.Charges[0].Increments[2].AccountingID].RatingID].RatesID]) {
- t.Errorf("Expecting: %s, received: %s",
- utils.ToJSON(eEC.Rates[eEC.Rating[eEC.Accounting[eEC.Charges[0].Increments[2].AccountingID].RatingID].RatesID]),
- utils.ToJSON(ec.Rates[ec.Rating[ec.Accounting[ec.Charges[0].Increments[2].AccountingID].RatingID].RatesID]))
- }
-
- // Compare to expected EC
- if !reflect.DeepEqual(eEC.Accounting[eEC.Charges[0].Increments[3].AccountingID],
- ec.Accounting[ec.Charges[0].Increments[3].AccountingID]) {
- t.Errorf("Expecting: %s, received: %s",
- utils.ToJSON(eEC.Accounting[eEC.Charges[0].Increments[3].AccountingID]),
- utils.ToJSON(ec.Accounting[ec.Charges[0].Increments[3].AccountingID]))
- }
- ec.Charges[0].Increments[3].AccountingID = eEC.Charges[0].Increments[3].AccountingID
- if !reflect.DeepEqual(eEC.Charges[0].Increments[3],
- ec.Charges[0].Increments[3]) {
- t.Errorf("Expecting: %s, received: %s",
- utils.ToJSON(eEC.Charges[0].Increments[3]),
- utils.ToJSON(ec.Charges[0].Increments[3]))
- }
- if len(ec.Accounting) != len(eEC.Accounting) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
- if len(ec.Rates) != len(eEC.Rates) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
- if len(ec.Timings) != len(eEC.Timings) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
- if !reflect.DeepEqual(eEC.AccountSummary, ec.AccountSummary) {
- t.Errorf("Expecting: %+v, received: %+v", eEC, ec)
- }
-}
-
-func TestECAsRefundIncrements(t *testing.T) {
- eCD := &CallDescriptor{
- CgrID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- ToR: utils.MetaVoice,
- TimeStart: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 28, 21, 0, time.UTC),
- DurationIndex: 10 * time.Minute,
- }
- eCD.Increments = Increments{
- &Increment{
- Duration: 0,
- Cost: 0.1,
- CompressFactor: 1,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.01,
- CompressFactor: 60,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.01,
- CompressFactor: 60,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.01,
- CompressFactor: 60,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.01,
- CompressFactor: 60,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"}},
- },
- &Increment{
- Duration: 10 * time.Second,
- Cost: 0.01,
- CompressFactor: 2,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- &Increment{
- Duration: time.Second,
- Cost: 0.005,
- CompressFactor: 30,
- BalanceInfo: &DebitInfo{
- AccountID: "cgrates.org:dan",
- Unit: &UnitInfo{
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165"},
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"}},
- },
- }
-
- if cd := testEC.Clone().AsRefundIncrements(utils.MetaVoice); !reflect.DeepEqual(eCD, cd) {
- t.Errorf("expecting: %s\n\n, received: %s", utils.ToIJSON(eCD), utils.ToIJSON(cd))
- }
-}
-
-func TestECAsCallCost(t *testing.T) {
- acntSummary := &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- Type: "*monetary",
- Value: 50,
- Disabled: false},
- {
- ID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: "*monetary",
- Value: 25,
- Disabled: false},
- {
- Type: "*voice",
- Value: 200,
- Disabled: false,
- },
- },
- AllowNegative: false,
- Disabled: false,
- }
- ec := &EventCost{
- CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- Cost: utils.Float64Pointer(0.85),
- Usage: utils.DurationPointer(2 * time.Minute),
- Charges: []*ChargingInterval{
- {
- RatingID: "f2518464-68b8-42f4-acec-aef23d714314",
- Increments: []*ChargingIncrement{
- {
- Usage: 0,
- Cost: 0.1,
- AccountingID: "44e97dec-8a7e-43d0-8b0a-736d46b5613e",
- CompressFactor: 1,
- },
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "a555cde8-4bd0-408a-afbc-c3ba64888927",
- CompressFactor: 30,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "906bfd0f-035c-40a3-93a8-46f71627983e",
- CompressFactor: 30,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "f2518464-68b8-42f4-acec-aef23d714314",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "c890a899-df43-497a-9979-38492713f57b",
- CompressFactor: 60,
- },
- },
- CompressFactor: 1,
- },
- },
- AccountSummary: acntSummary,
- Rating: Rating{
- "4607d907-02c3-4f2b-bc08-95a0dcc7222c": &RatingUnit{
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- RatesID: "e5eb0f1c-3612-4e8c-b749-7f8f41dd90d4",
- RatingFiltersID: "7e73a00d-be53-4083-a1ee-8ee0b546c62a",
- },
- "f2518464-68b8-42f4-acec-aef23d714314": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- RatesID: "6504fb84-6b27-47a8-a1c6-c0d843959f89",
- RatingFiltersID: "7e73a00d-be53-4083-a1ee-8ee0b546c62a",
- },
- },
- Accounting: Accounting{
- "c890a899-df43-497a-9979-38492713f57b": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- },
- "a894f8f1-206a-4457-99ce-df21a0c7fedc": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "44e97dec-8a7e-43d0-8b0a-736d46b5613e": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.1,
- },
- "906bfd0f-035c-40a3-93a8-46f71627983e": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- RatingID: "4607d907-02c3-4f2b-bc08-95a0dcc7222c",
- Units: 1,
- ExtraChargeID: "a894f8f1-206a-4457-99ce-df21a0c7fedc",
- },
- "a555cde8-4bd0-408a-afbc-c3ba64888927": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
- Units: 1,
- ExtraChargeID: "*none",
- },
- },
- RatingFilters: RatingFilters{
- "7e73a00d-be53-4083-a1ee-8ee0b546c62a": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Rates: ChargedRates{
- "6504fb84-6b27-47a8-a1c6-c0d843959f89": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Minute,
- RateUnit: time.Second},
- },
- "e5eb0f1c-3612-4e8c-b749-7f8f41dd90d4": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- },
- },
- Timings: ChargedTimings{
- "27f1e5f8-05bb-4f1c-a596-bf1010ad296c": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- }
- eCC := &CallCost{
- ToR: utils.MetaVoice,
- Cost: 0.85,
- RatedUsage: 120000000000,
- AccountSummary: acntSummary,
- Timespans: TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- Cost: 0.25,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- ID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateUnit: time.Second,
- RateIncrement: time.Minute,
- },
- },
- },
- },
- DurationIndex: time.Minute,
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{ // ConnectFee
- Cost: 0.1,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 1,
- },
- &Increment{ // First 30 seconds free
- Duration: time.Second,
- Cost: 0,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{
- UUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
- Consumed: 1.0,
- },
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- &Increment{ // Minutes with special price
- Duration: time.Second,
- Cost: 0.005,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{ // Minutes with special price
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- Consumed: 1.0,
- RateInterval: &RateInterval{
- Timing: &RITiming{
- ID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateUnit: time.Second,
- RateIncrement: time.Second,
- },
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateUnit: time.Second,
- RateIncrement: time.Second,
- },
- },
- },
- },
- },
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- },
- },
-
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 20, 21, 0, time.UTC),
- Cost: 0.6,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- ID: "27f1e5f8-05bb-4f1c-a596-bf1010ad296c",
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateUnit: time.Second,
- RateIncrement: time.Minute,
- },
- },
- },
- },
- DurationIndex: time.Minute,
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{
- Cost: 0.01,
- Duration: time.Second,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010"},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 60,
- },
- },
- },
- },
- }
- cc := ec.AsCallCost(utils.EmptyString)
- if !reflect.DeepEqual(eCC, cc) {
- t.Errorf("Expecting: %+v,\n received: %+v", utils.ToJSON(eCC), utils.ToJSON(cc))
- }
-}
-
-func TestECAsCallCost2(t *testing.T) {
- eCC := &CallCost{
- ToR: utils.MetaVoice,
- Cost: 0,
- RatedUsage: 60000000000,
- Timespans: TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- Cost: 0,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.01,
- RateUnit: time.Duration(1 * time.Second),
- RateIncrement: time.Duration(1 * time.Minute),
- },
- },
- },
- },
- DurationIndex: time.Minute,
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{ // ConnectFee
- Cost: 0,
- Duration: time.Minute,
- BalanceInfo: &DebitInfo{},
- CompressFactor: 1,
- },
- },
- },
- },
- }
- ec := NewEventCostFromCallCost(eCC, "cgrID", utils.MetaDefault)
- for k := range ec.Timings {
- eCC.Timespans[0].RateInterval.Timing.ID = k
- }
- cc := ec.AsCallCost(utils.EmptyString)
- if !reflect.DeepEqual(eCC, cc) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eCC), utils.ToJSON(cc))
- }
-}
-
-func TestECTrimZeroAndFull(t *testing.T) {
- ec := testEC.Clone()
- if srplsEC, err := ec.Trim(10 * time.Minute); err != nil {
- t.Error(err)
- } else if srplsEC != nil {
- t.Errorf("Expecting nil, got: %+v", srplsEC)
- }
- eFullSrpls := testEC.Clone()
- eFullSrpls.Usage = utils.DurationPointer(10 * time.Minute)
- if srplsEC, err := ec.Trim(0); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eFullSrpls, srplsEC) {
- t.Errorf("\tExpecting: %s,\n\treceived: %s",
- utils.ToJSON(eFullSrpls), utils.ToJSON(srplsEC))
- }
- //verify the event cost
- newEc := NewBareEventCost()
- newEc.CGRID = eFullSrpls.CGRID
- newEc.RunID = eFullSrpls.RunID
- newEc.StartTime = eFullSrpls.StartTime
- newEc.AccountSummary = eFullSrpls.AccountSummary.Clone()
- if !reflect.DeepEqual(newEc, ec) {
- t.Errorf("\tExpecting: %s,\n\treceived: %s",
- utils.ToJSON(newEc), utils.ToJSON(ec))
- }
-}
-
-func TestECTrimMiddle1(t *testing.T) {
- // trim in the middle of increments
- ec := testEC.Clone()
- eEC := testEC.Clone()
- eEC.Charges = []*ChargingInterval{
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: 0,
- Cost: 0.1,
- AccountingID: "9bdad10",
- CompressFactor: 1,
- },
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 60,
- },
- },
- CompressFactor: 2,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 10,
- },
- },
- CompressFactor: 1,
- },
- }
- eSrplsEC := testEC.Clone()
- eSrplsEC.StartTime = time.Date(2017, 1, 9, 16, 21, 31, 0, time.UTC)
- eSrplsEC.Charges = []*ChargingInterval{
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 50,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 60,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "c1a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "a012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 5,
- },
- }
-
- reqDuration := 190 * time.Second
- srplsEC, err := ec.Trim(reqDuration)
- if err != nil {
- t.Error(err)
- }
- if reqDuration != *ec.Usage {
- t.Errorf("Expecting request duration: %v, received: %v", reqDuration, *ec.Usage)
- }
- eSrplsDur := 410 * time.Second
- if srplsUsage := srplsEC.GetUsage(); srplsUsage != eSrplsDur {
- t.Errorf("Expecting surplus duration: %v, received: %v", eSrplsDur, srplsUsage)
- }
- ec.ResetCounters()
- srplsEC.ResetCounters()
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("Expecting: %s\n, received: %s", utils.ToIJSON(eEC), utils.ToIJSON(ec))
- }
- // test surplus, which is not easy to estimate due it's different item ids
- if !eSrplsEC.StartTime.Equal(srplsEC.StartTime) ||
- len(eSrplsEC.Charges) != len(srplsEC.Charges) {
- t.Errorf("Expecting: \n%s, received: \n%s", utils.ToIJSON(eSrplsEC), utils.ToIJSON(srplsEC))
- }
-}
-
-// TestECTrimMUsage is targeting simpler testing of the durations trimmed/remainders
-// using subtests so we can cover the tests with less code
-func TestECTrimMUsage(t *testing.T) {
- // each subtest will trim at some usage duration
- testCases := []struct {
- atUsage time.Duration
- ecUsage time.Duration
- ecCost float64
- srplsUsage time.Duration
- srplsCost float64
- }{
- {5 * time.Second, 5 * time.Second, 0.1,
- 595 * time.Second, 3.42},
- {10 * time.Second, 10 * time.Second, 0.1,
- 590 * time.Second, 3.42},
- {15 * time.Second, 20 * time.Second, 0.11,
- 580 * time.Second, 3.41},
- {20 * time.Second, 20 * time.Second, 0.11,
- 580 * time.Second, 3.41},
- {25 * time.Second, 30 * time.Second, 0.12,
- 570 * time.Second, 3.40},
- {38 * time.Second, 38 * time.Second, 0.16,
- 562 * time.Second, 3.36},
- {60 * time.Second, 60 * time.Second, 0.27,
- 540 * time.Second, 3.25},
- {62 * time.Second, 62 * time.Second, 0.29,
- 538 * time.Second, 3.23},
- {120 * time.Second, 120 * time.Second, 0.87,
- 480 * time.Second, 2.65},
- {121 * time.Second, 121 * time.Second, 0.88,
- 479 * time.Second, 2.64},
- {180 * time.Second, 180 * time.Second, 1.47,
- 420 * time.Second, 2.05},
- {250 * time.Second, 250 * time.Second, 2.17,
- 350 * time.Second, 1.35},
- {299 * time.Second, 299 * time.Second, 2.66,
- 301 * time.Second, 0.86},
- {300 * time.Second, 300 * time.Second, 2.67,
- 300 * time.Second, 0.85},
- {302 * time.Second, 302 * time.Second, 2.67,
- 298 * time.Second, 0.85},
- {310 * time.Second, 310 * time.Second, 2.67,
- 290 * time.Second, 0.85},
- {316 * time.Second, 320 * time.Second, 2.68,
- 280 * time.Second, 0.84},
- {320 * time.Second, 320 * time.Second, 2.68,
- 280 * time.Second, 0.84},
- {321 * time.Second, 330 * time.Second, 2.69,
- 270 * time.Second, 0.83},
- {330 * time.Second, 330 * time.Second, 2.69,
- 270 * time.Second, 0.83},
- {331 * time.Second, 331 * time.Second, 2.695,
- 269 * time.Second, 0.825},
- {359 * time.Second, 359 * time.Second, 2.835,
- 241 * time.Second, 0.685},
- {360 * time.Second, 360 * time.Second, 2.84,
- 240 * time.Second, 0.68},
- {376 * time.Second, 380 * time.Second, 2.85,
- 220 * time.Second, 0.67},
- {391 * time.Second, 391 * time.Second, 2.865,
- 209 * time.Second, 0.655},
- {479 * time.Second, 479 * time.Second, 3.175,
- 121 * time.Second, 0.345},
- {599 * time.Second, 599 * time.Second, 3.515,
- time.Second, 0.005},
- }
- for _, tC := range testCases {
- t.Run(fmt.Sprintf("AtUsage:%s", tC.atUsage), func(t *testing.T) {
- var ec, srplsEC *EventCost
- ec = testEC.Clone()
- if srplsEC, err = ec.Trim(tC.atUsage); err != nil {
- t.Fatal(err)
- }
- if ec.GetUsage() != tC.ecUsage {
- t.Errorf("Wrongly trimmed EC: %s", utils.ToIJSON(ec))
- } else if ec.GetCost() != tC.ecCost {
- t.Errorf("Wrong cost for event: %s", utils.ToIJSON(ec))
- }
- if srplsEC.GetUsage() != tC.srplsUsage {
- t.Errorf("Wrong usage: %v for surplusEC: %s", srplsEC.GetUsage(), utils.ToIJSON(srplsEC))
- } else if srplsEC.GetCost() != tC.srplsCost {
- t.Errorf("Wrong cost: %f in surplus: %s", srplsEC.GetCost(), utils.ToIJSON(srplsEC))
- }
- })
- }
-}
-
-func TestECMergeGT(t *testing.T) {
- // InitialEventCost
- ecGT := &EventCost{
- CGRID: "7636f3f1a06dffa038ba7900fb57f52d28830a24",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2018, 7, 27, 0, 59, 21, 0, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 1,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- ID: "addon_data",
- Type: utils.MetaData,
- Value: 10726871040},
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ecGTUpdt := &EventCost{
- CGRID: "7636f3f1a06dffa038ba7900fb57f52d28830a24",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2018, 7, 27, 0, 59, 38, 0105472, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "6a83227",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "9288f93",
- CompressFactor: 84,
- },
- },
- CompressFactor: 1,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- ID: "addon_data",
- Type: utils.MetaData,
- Value: 10718269440},
- },
- },
- Rating: Rating{
- "6a83227": &RatingUnit{
- RatesID: "52f8b0f",
- RatingFiltersID: "17f7216",
- },
- },
- Accounting: Accounting{
- "9288f93": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "17f7216": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "52f8b0f": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ecGT.Merge(ecGTUpdt)
- ecExpct := &EventCost{
- CGRID: "7636f3f1a06dffa038ba7900fb57f52d28830a24",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2018, 7, 27, 0, 59, 21, 0, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 187,
- },
- },
- CompressFactor: 1,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- ID: "addon_data",
- Type: utils.MetaData,
- Value: 10718269440},
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- if len(ecGT.Charges) != len(ecExpct.Charges) ||
- !reflect.DeepEqual(ecGT.Charges[0].TotalUsage(), ecExpct.Charges[0].TotalUsage()) ||
- !reflect.DeepEqual(ecGT.Charges[0].TotalCost(), ecExpct.Charges[0].TotalCost()) {
- t.Errorf("expecting: %s\n\n, received: %s",
- utils.ToJSON(ecExpct), utils.ToJSON(ecGT))
- }
-
-}
-
-func TestECAppendCIlFromEC(t *testing.T) {
- // Standard compressing 1-1
- ec := &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- oEC := &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "6a83227",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "9288f93",
- CompressFactor: 84,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "6a83227": &RatingUnit{
- RatesID: "52f8b0f",
- RatingFiltersID: "17f7216",
- },
- },
- Accounting: Accounting{
- "9288f93": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "17f7216": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "52f8b0f": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ec.appendCIlFromEC(oEC, 0)
- eEC := &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 187,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("expecting: %s, received: %s", utils.ToJSON(eEC), utils.ToJSON(ec))
- }
-
- // Second case, do not compress if first interval's compress factor is different than 1
- ec = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 2,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- oEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "6a83227",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "9288f93",
- CompressFactor: 84,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "6a83227": &RatingUnit{
- RatesID: "52f8b0f",
- RatingFiltersID: "17f7216",
- },
- },
- Accounting: Accounting{
- "9288f93": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "17f7216": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "52f8b0f": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ec.appendCIlFromEC(oEC, 0)
- eEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 2,
- },
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 84,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("expecting: %s, received: %s", utils.ToJSON(eEC), utils.ToJSON(ec))
- }
-
- // Third case, split oEC
- ec = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 100,
- AccountingID: "0d87a64",
- CompressFactor: 1,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 1,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- oEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "6a83227",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "9288f93",
- CompressFactor: 42,
- },
- {
- Usage: 10240,
- AccountingID: "9288f93",
- CompressFactor: 20,
- },
- },
- CompressFactor: 3,
- },
- },
- Rating: Rating{
- "6a83227": &RatingUnit{
- RatesID: "52f8b0f",
- RatingFiltersID: "17f7216",
- },
- },
- Accounting: Accounting{
- "9288f93": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "17f7216": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "52f8b0f": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ec.appendCIlFromEC(oEC, 0)
- eEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 100,
- AccountingID: "0d87a64",
- CompressFactor: 1,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 145,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 10240,
- AccountingID: "0d87a64",
- CompressFactor: 20,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 42,
- },
- {
- Usage: 10240,
- AccountingID: "0d87a64",
- CompressFactor: 20,
- },
- },
- CompressFactor: 2,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("expecting: %s, received: %s", utils.ToJSON(eEC), utils.ToJSON(ec))
- }
-
- // Fourth case, increase ChargingInterval.CompressFactor
- ec = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 2,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- oEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "6a83227",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "9288f93",
- CompressFactor: 103,
- },
- },
- CompressFactor: 3,
- },
- },
- Rating: Rating{
- "6a83227": &RatingUnit{
- RatesID: "52f8b0f",
- RatingFiltersID: "17f7216",
- },
- },
- Accounting: Accounting{
- "9288f93": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "17f7216": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "52f8b0f": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- ec.appendCIlFromEC(oEC, 0)
- eEC = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "cc68da4",
- Increments: []*ChargingIncrement{
- {
- Usage: 102400,
- AccountingID: "0d87a64",
- CompressFactor: 103,
- },
- },
- CompressFactor: 5,
- },
- },
- Rating: Rating{
- "cc68da4": &RatingUnit{
- RatesID: "06dee2e",
- RatingFiltersID: "216b0a5",
- },
- },
- Accounting: Accounting{
- "0d87a64": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- Units: 102400,
- ExtraChargeID: utils.MetaNone,
- },
- },
- RatingFilters: RatingFilters{
- "216b0a5": RatingMatchedFilters{
- "DestinationID": utils.MetaAny,
- "DestinationPrefix": "42502",
- "RatingPlanID": utils.MetaNone,
- "Subject": "9a767726-fe69-4940-b7bd-f43de9f0f8a5",
- },
- },
- Rates: ChargedRates{
- "06dee2e": RateGroups{
- &RGRate{
- RateIncrement: 102400,
- RateUnit: 102400},
- },
- },
- }
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("expecting: %s, received: %s", utils.ToJSON(eEC), utils.ToJSON(ec))
- }
-}
-
-func TestECSyncKeys(t *testing.T) {
- ec := testEC.Clone()
- ec.Accounting["a012888"].RatingID = "c1a5ab9"
-
- refEC := &EventCost{
- Rating: Rating{
- "21a5ab9": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "2f324ab",
- RatesID: "2c1a177",
- RatingFiltersID: "23e77dc",
- },
- },
- Accounting: Accounting{
- "2012888": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- RatingID: "21a5ab9",
- },
- "288bfa6": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "24d6c02": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- RatingID: "3cd6425",
- Units: 1,
- ExtraChargeID: "288bfa6",
- },
- },
- RatingFilters: RatingFilters{
- "23e77dc": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Timings: ChargedTimings{
- "2f324ab": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- Rates: ChargedRates{
- "2c1a177": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Minute,
- RateUnit: time.Second},
- },
- },
- }
-
- eEC := &EventCost{
- CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: 0,
- Cost: 0.1,
- AccountingID: "9bdad10",
- CompressFactor: 1,
- },
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 60,
- },
- },
- CompressFactor: 4,
- },
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Second,
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: 10 * time.Second,
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Second,
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 5,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 50,
- Disabled: false},
- {
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 25,
- Disabled: false},
- {
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: "*voice",
- Value: 200,
- Disabled: false,
- },
- },
- AllowNegative: false,
- Disabled: false,
- },
- Rating: Rating{
- "3cd6425": &RatingUnit{
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "2f324ab",
- RatesID: "4910ecf",
- RatingFiltersID: "23e77dc",
- },
- "21a5ab9": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "2f324ab",
- RatesID: "2c1a177",
- RatingFiltersID: "23e77dc",
- },
- },
- Accounting: Accounting{
- "2012888": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- RatingID: "21a5ab9",
- },
- "288bfa6": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "9bdad10": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.1,
- },
- "44d6c02": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- RatingID: "3cd6425",
- Units: 1,
- ExtraChargeID: "288bfa6",
- },
- "3455b83": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Units: 1,
- ExtraChargeID: "*none",
- },
- },
- RatingFilters: RatingFilters{
- "23e77dc": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Rates: ChargedRates{
- "2c1a177": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.01,
- RateIncrement: time.Minute,
- RateUnit: time.Second},
- },
- "4910ecf": RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- &RGRate{
- GroupIntervalStart: 60 * time.Second,
- Value: 0.005,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- },
- },
- Timings: ChargedTimings{
- "2f324ab": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- cache: utils.MapStorage{},
- }
-
- ec.SyncKeys(refEC)
- if !reflect.DeepEqual(eEC, ec) {
- t.Errorf("expecting: %s \nreceived: %s",
- utils.ToIJSON(eEC), utils.ToIJSON(ec))
- }
-}
-
-func TestECAsDataProvider(t *testing.T) {
- ecDP := config.NewObjectDP(testEC)
- if data, err := ecDP.FieldAsInterface([]string{"RunID"}); err != nil {
- t.Error(err)
- } else if data != utils.MetaDefault {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", utils.MetaDefault, data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "ID"}); err != nil {
- t.Error(err)
- } else if data != "dan" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "data", data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[1]", "UUID"}); err != nil {
- t.Error(err)
- } else if data != "7a54a9e9-d610-4c82-bcb5-a315b9a65010" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "4b8b53d7-c1a1-4159-b845-4623a00a0165", data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[2]", "Type"}); err != nil {
- t.Error(err)
- } else if data != "*voice" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "*voice", data)
- }
-}
-
-func TestInitCache(t *testing.T) {
- eventCost := &EventCost{}
- eventCost.initCache()
- eOut := utils.MapStorage{}
- if !reflect.DeepEqual(eOut, eventCost.cache) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eOut), utils.ToJSON(eventCost.cache))
- }
-}
-
-func TestEventCostFieldAsInterface(t *testing.T) {
- eventCost := &EventCost{}
- eventCost.initCache()
- // item found in cache
- eventCost.cache = utils.MapStorage{"test": nil}
- if rcv, err := eventCost.FieldAsInterface([]string{"test"}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // data found in cache
- eventCost.cache = utils.MapStorage{"test": "test"}
- if rcv, err := eventCost.FieldAsInterface([]string{"test"}); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if rcv != "test" {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
-}
-
-func TestEventCostfieldAsInterface(t *testing.T) {
- eventCost := &EventCost{}
- // default case
- if rcv, err := eventCost.fieldAsInterface([]string{utils.EmptyString}); err == nil || err.Error() != "unsupported field prefix: <>" {
- t.Error(err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // case utils.Charges:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Charges, utils.Charges}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "RatingID1",
- },
- {
- RatingID: "RatingID2",
- },
- },
- }
- expectedCharges := []*ChargingInterval{
- {
- RatingID: "RatingID1",
- },
- {
- RatingID: "RatingID2",
- },
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Charges}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expectedCharges, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", expectedCharges, rcv)
- }
- // case utils.CGRID:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.CGRID, utils.CGRID}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- CGRID: "CGRID",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.CGRID}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual("CGRID", rcv) {
- t.Errorf("Expecting: \"CGRID\", received: %+v", rcv)
- }
- // case utils.RunID:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.RunID, utils.RunID}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- RunID: "RunID",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.RunID}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual("RunID", rcv) {
- t.Errorf("Expecting: \"RunID\", received: %+v", rcv)
- }
- // case utils.StartTime:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.StartTime, utils.StartTime}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- StartTime: time.Date(2020, time.April, 18, 23, 0, 4, 0, time.UTC),
- }
- expectedStartTime := time.Date(2020, time.April, 18, 23, 0, 4, 0, time.UTC)
- if rcv, err := eventCost.fieldAsInterface([]string{utils.StartTime}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expectedStartTime, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", expectedStartTime, rcv)
- }
- // case utils.Usage:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Usage, utils.Usage}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- Usage: utils.DurationPointer(5 * time.Minute),
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Usage}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(5*time.Minute, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", 5*time.Minute, rcv)
- }
- // case utils.Cost:
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Cost, utils.Cost}); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- Cost: utils.Float64Pointer(0.7),
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Cost}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(0.7, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", 0.7, rcv)
- }
- // case utils.AccountSummary:
- eventCost = &EventCost{
- AccountSummary: &AccountSummary{
- ID: "IDtest",
- },
- }
- expectedAccountSummary := &AccountSummary{ID: "IDtest"}
- if rcv, err := eventCost.fieldAsInterface([]string{utils.AccountSummary}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expectedAccountSummary, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", expectedAccountSummary, rcv)
- }
- eventCost = &EventCost{
- AccountSummary: &AccountSummary{
- ID: "IDtest1",
- Tenant: "Tenant",
- },
- CGRID: "test",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.AccountSummary, utils.Tenant}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual("Tenant", rcv) {
- t.Errorf("Expecting: Tenant, received: %+v", utils.ToJSON(rcv))
- }
- // case utils.Timings:
- eventCost = &EventCost{
- Timings: ChargedTimings{
- "test1": &ChargedTiming{
- StartTime: "StartTime",
- },
- },
- }
- eTimings := ChargedTimings{"test1": &ChargedTiming{StartTime: "StartTime"}}
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Timings}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eTimings, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eTimings, rcv)
- }
- eChargedTiming := &ChargedTiming{
- StartTime: "StartTime",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Timings, "test1"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eChargedTiming, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eChargedTiming), utils.ToJSON(rcv))
- }
- // case utils.Rates:
- eventCost = &EventCost{
- Rates: ChargedRates{
- "test1": RateGroups{
- &RGRate{Value: 0.7},
- },
- },
- }
- eChargedRates := ChargedRates{
- "test1": RateGroups{
- &RGRate{Value: 0.7},
- },
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Rates}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eChargedRates, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eChargedRates), utils.ToJSON(rcv))
- }
- eRateGroup := RateGroups{
- &RGRate{Value: 0.7},
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Rates, "test1"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eRateGroup, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRateGroup), utils.ToJSON(rcv))
- }
- // case utils.RatingFilters:
- eventCost = &EventCost{
- RatingFilters: RatingFilters{
- "test1": RatingMatchedFilters{
- AccountActionsCSVContent: "AccountActionsCSVContent",
- },
- },
- }
- eRatingFilters := RatingFilters{
- "test1": RatingMatchedFilters{
- AccountActionsCSVContent: "AccountActionsCSVContent",
- },
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.RatingFilters}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eRatingFilters, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRatingFilters), utils.ToJSON(rcv))
- }
- eRatingMatchedFilters := RatingMatchedFilters{
- AccountActionsCSVContent: "AccountActionsCSVContent",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.RatingFilters, "test1"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eRatingMatchedFilters, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRatingMatchedFilters), utils.ToJSON(rcv))
- }
- // case utils.Accounting:
- eventCost = &EventCost{
- Accounting: Accounting{
- "test1": &BalanceCharge{
- AccountID: "AccountID",
- },
- },
- }
- eAccounting := Accounting{
- "test1": &BalanceCharge{
- AccountID: "AccountID",
- },
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Accounting}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eAccounting, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAccounting), utils.ToJSON(rcv))
- }
- eBalanceCharge := &BalanceCharge{
- AccountID: "AccountID",
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Accounting, "test1"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eBalanceCharge, rcv) {
- t.Errorf("Expecting: %+v, \nreceived: %+v", utils.ToJSON(eBalanceCharge), utils.ToJSON(rcv))
- }
- // case utils.Rating:
- eventCost = &EventCost{
- Rating: Rating{
- "test1": &RatingUnit{
- ConnectFee: 0.7,
- },
- },
- }
- eRating := Rating{
- "test1": &RatingUnit{
- ConnectFee: 0.7,
- },
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Rating}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eRating, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRating), utils.ToJSON(rcv))
- }
- eRateUnit := &RatingUnit{
- ConnectFee: 0.7,
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Rating, "test1"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eRateUnit, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRateUnit), utils.ToJSON(rcv))
- }
- //default case, utils.Charges
- eventCost = &EventCost{
- Charges: []*ChargingInterval{
- {
- RatingID: "RatingID",
- },
- },
- }
- eCharges := []*ChargingInterval{{RatingID: "RatingID"}}
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Charges}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eCharges, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eCharges), utils.ToJSON(rcv))
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Charges + "[0]"}); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(eCharges[0], rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eCharges[0]), utils.ToJSON(rcv))
- }
- if rcv, err := eventCost.fieldAsInterface([]string{utils.Charges + "[1]"}); err == nil || err != utils.ErrNotFound {
- t.Error(err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
-}
-
-func TestEventCostgetChargesForPath(t *testing.T) {
- eventCost := &EventCost{}
- chargingInterval := &ChargingInterval{
- RatingID: "RatingID",
- }
- // chr == nil
- if rcv, err := eventCost.getChargesForPath(nil, nil); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) == 0
- eChargingInterval := &ChargingInterval{
- RatingID: "RatingID",
- }
- if rcv, err := eventCost.getChargesForPath([]string{}, chargingInterval); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eChargingInterval, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eChargingInterval, rcv)
- }
- // fldPath[0] == utils.CompressFactor
- chargingInterval = &ChargingInterval{
- RatingID: "RatingID",
- CompressFactor: 7,
- }
- if rcv, err := eventCost.getChargesForPath([]string{utils.CompressFactor}, chargingInterval); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if rcv != 7 {
- t.Errorf("Expecting: 7, received: %+v", rcv)
- }
- if rcv, err := eventCost.getChargesForPath([]string{utils.CompressFactor, "mustFail"}, chargingInterval); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // fldPath[0] == utils.Rating
- eventCost = &EventCost{
- Rates: ChargedRates{
- "RatingID": RateGroups{&RGRate{Value: 0.8}}},
- }
- if rcv, err := eventCost.getChargesForPath([]string{utils.Rating}, chargingInterval); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- eventCost = &EventCost{
- Rating: Rating{"RatingID": &RatingUnit{}},
- Rates: ChargedRates{
- "RatingID": RateGroups{&RGRate{Value: 0.8}}},
- }
- if rcv, err := eventCost.getChargesForPath([]string{utils.Rating, "unsupportedfield"}, chargingInterval); err == nil || err.Error() != "unsupported field prefix: " {
- t.Errorf("Expecting: unsupported field prefix: , received: %+v", err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
-
- chargingInterval = &ChargingInterval{
- RatingID: "RatingID",
- CompressFactor: 7,
- }
- eventCost = &EventCost{
- Rating: Rating{"RatingID": &RatingUnit{
- RatesID: "RatesID",
- }},
- Rates: ChargedRates{"RatesID": RateGroups{&RGRate{Value: 0.8}}},
- }
- RateGroups := RateGroups{&RGRate{Value: 0.8}}
- if rcv, err := eventCost.getChargesForPath([]string{utils.Rating, utils.Rates}, chargingInterval); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(RateGroups, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(RateGroups), utils.ToJSON(rcv))
- t.Errorf("Expecting: %+v, received: %+v", RateGroups, rcv)
- }
- // opath != utils.Increments
- if rcv, err := eventCost.getChargesForPath([]string{"unsupportedfield"}, chargingInterval); err == nil || err.Error() != "unsupported field prefix: " {
- t.Errorf("Expecting: unsupported field prefix: , received: %+v", err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // utils.Increments
- eventCost = &EventCost{}
- chargingInterval = &ChargingInterval{
- Increments: []*ChargingIncrement{
- {
- AccountingID: "AccountingID",
- },
- },
- }
- eChargingIncrement := &ChargingIncrement{
- AccountingID: "AccountingID",
- }
- if rcv, err := eventCost.getChargesForPath([]string{"Increments[0]"}, chargingInterval); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eChargingIncrement, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eChargingIncrement, rcv)
- }
- eIncrements := []*ChargingIncrement{
- {
- AccountingID: "AccountingID",
- },
- }
- // indx == nil
- if rcv, err := eventCost.getChargesForPath([]string{"Increments"}, chargingInterval); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eIncrements, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eIncrements, utils.ToJSON(rcv))
- }
- // len(fldPath) != 1
- if rcv, err := eventCost.getChargesForPath([]string{"Increments", utils.Accounting}, chargingInterval); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // fldPath[1] == utils.Accounting
- eventCost = &EventCost{
- Accounting: Accounting{
- "AccountingID": &BalanceCharge{
- AccountID: "AccountID",
- },
- },
- }
- eBalanceCharge := &BalanceCharge{AccountID: "AccountID"}
- if rcv, err := eventCost.getChargesForPath([]string{"Increments[0]", utils.Accounting}, chargingInterval); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eBalanceCharge, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eBalanceCharge, rcv)
- }
-
-}
-
-func TestEventCostgetRatingForPath(t *testing.T) {
- eventCost := &EventCost{}
- ratingUnit := &RatingUnit{}
- // rating == nil
- if rcv, err := eventCost.getRatingForPath(nil, nil); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) == 0
- eratingUnit := &RatingUnit{}
- if rcv, err := eventCost.getRatingForPath([]string{}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eratingUnit, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eratingUnit, rcv)
- }
- // case utils.Rates:
- eventCost = &EventCost{
- Rates: ChargedRates{
- "RatesID": RateGroups{
- &RGRate{Value: 0.7},
- },
- },
- }
- eChargedRates := RateGroups{
- &RGRate{Value: 0.7},
- }
-
- // !has || rts == nil
- ratingUnit = &RatingUnit{
- RatesID: "notfound",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.Rates}, ratingUnit); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) != 1
- ratingUnit = &RatingUnit{
- RatesID: "RatesID",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.Rates, utils.Rates}, ratingUnit); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- //normal case
- if rcv, err := eventCost.getRatingForPath([]string{utils.Rates}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eChargedRates, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eChargedRates), utils.ToJSON(rcv))
- }
- // case utils.Timing:
- eventCost = &EventCost{
- Timings: ChargedTimings{
- "test1": &ChargedTiming{
- StartTime: "StartTime",
- },
- },
- }
- eTimings := &ChargedTiming{
- StartTime: "StartTime",
- }
-
- // !has || tmg == nil
- ratingUnit = &RatingUnit{
- TimingID: "notfound",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.Timing}, ratingUnit); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) == 1
- ratingUnit = &RatingUnit{
- TimingID: "test1",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.Timing}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eTimings, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eTimings), utils.ToJSON(rcv))
- }
- //normal case
- eventCost = &EventCost{
- Timings: ChargedTimings{
- "test1": &ChargedTiming{
- Months: utils.Months{time.April},
- StartTime: "StartTime",
- },
- },
- }
- eMonths := utils.Months{time.April}
- if rcv, err := eventCost.getRatingForPath([]string{utils.Timing, utils.MonthsFieldName}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eMonths, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eMonths), utils.ToJSON(rcv))
- }
- // case utils.RatingFilter:
- eventCost = &EventCost{
- RatingFilters: RatingFilters{
- "RatingFilters1": RatingMatchedFilters{
- "test1": "test1",
- },
- },
- }
- eRatingMatchedFilters := RatingMatchedFilters{
- "test1": "test1",
- }
-
- // !has || tmg == nil
- ratingUnit = &RatingUnit{
- TimingID: "notfound",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.RatingFilter}, ratingUnit); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) == 1
- ratingUnit = &RatingUnit{
- RatingFiltersID: "RatingFilters1",
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.RatingFilter}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eRatingMatchedFilters, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eRatingMatchedFilters, rcv)
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRatingMatchedFilters), utils.ToJSON(rcv))
- }
- //normal case
- eventCost = &EventCost{
- RatingFilters: RatingFilters{
- "RatingFilters1": RatingMatchedFilters{
- "test1": "test-1",
- },
- },
- }
- if rcv, err := eventCost.getRatingForPath([]string{utils.RatingFilter, "test1"}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual("test-1", rcv) {
- t.Errorf("Expecting: test-1, received: %+v", utils.ToJSON(rcv))
- }
- //default case
- eventCost = &EventCost{
- Rates: ChargedRates{
- "RatesID": RateGroups{
- &RGRate{Value: 0.7},
- },
- "RatesID2": RateGroups{
- &RGRate{Value: 0.7},
- },
- },
- }
- if rcv, err := eventCost.getRatingForPath([]string{
- "unsupportedprefix"}, ratingUnit); err == nil || err.Error() != "unsupported field prefix: " {
- t.Errorf("Expecting: 'unsupported field prefix: ', received: %+v", err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", utils.ToJSON(rcv))
- }
- ratingUnit = &RatingUnit{
- RatesID: "RatesID",
- }
- eRate := &RGRate{Value: 0.7}
- if rcv, err := eventCost.getRatingForPath([]string{"Rates[0]"}, ratingUnit); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eRate, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eRate), utils.ToJSON(rcv))
- }
- ratingUnit = &RatingUnit{}
- if rcv, err := eventCost.getRatingForPath([]string{"Rates[1]"}, ratingUnit); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
-}
-
-func TestEventCostgetAcountingForPath(t *testing.T) {
- eventCost := &EventCost{}
- balanceCharge := &BalanceCharge{}
- // bc == nil
- if rcv, err := eventCost.getAcountingForPath(nil, nil); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) == 0
- eBalanceCharge := &BalanceCharge{}
- if rcv, err := eventCost.getAcountingForPath([]string{}, balanceCharge); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eBalanceCharge, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eBalanceCharge, rcv)
- }
- // fldPath[0] == utils.Balance
- eventCost = &EventCost{
- AccountSummary: &AccountSummary{
- BalanceSummaries: BalanceSummaries{
- {
- ID: "ID",
- },
- },
- },
- }
- eBalanceSummaries := &BalanceSummary{
- ID: "ID",
- }
- //len(fldPath) == 1
- if rcv, err := eventCost.getAcountingForPath([]string{utils.BalanceField}, balanceCharge); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual(eBalanceSummaries, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eBalanceSummaries, rcv)
- }
- // bl == nil
- eventCost = &EventCost{AccountSummary: &AccountSummary{}}
- if rcv, err := eventCost.getAcountingForPath([]string{utils.BalanceField}, balanceCharge); err == nil || err != utils.ErrNotFound {
- t.Errorf("Expecting: %+v, received: %+v", utils.ErrNotFound, err)
- } else if rcv != nil {
- t.Errorf("Expecting: nil, received: %+v", rcv)
- }
- // len(fldPath) != 1
- eventCost = &EventCost{
- AccountSummary: &AccountSummary{
- BalanceSummaries: BalanceSummaries{
- {
- ID: "ID",
- },
- },
- },
- }
- if rcv, err := eventCost.getAcountingForPath([]string{utils.BalanceField, "ID"}, balanceCharge); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual("ID", rcv) {
- t.Errorf("Expecting: \"ID\", received: %+v", rcv)
- }
- // fldPath[0] != utils.Balance
- balanceCharge = &BalanceCharge{
- AccountID: "AccountID",
- }
- if rcv, err := eventCost.getAcountingForPath([]string{utils.AccountID}, balanceCharge); err != nil {
- t.Errorf("Expecting: nil, received: %+v", err)
- } else if !reflect.DeepEqual("AccountID", rcv) {
- t.Errorf("Expecting: \"AccountID\", received: %+v", rcv)
- }
-}
-
-func TestEventCostString(t *testing.T) {
- eventCost := &EventCost{}
- eOut := `{"CGRID":"","RunID":"","StartTime":"0001-01-01T00:00:00Z","Usage":null,"Cost":null,"Charges":null,"AccountSummary":null,"Rating":null,"Accounting":null,"RatingFilters":null,"Rates":null,"Timings":null}`
- if rcv := eventCost.String(); !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eOut, rcv)
- }
- eventCost = &EventCost{
- AccountSummary: &AccountSummary{
- BalanceSummaries: BalanceSummaries{
- &BalanceSummary{
- ID: "ID",
- },
- },
- },
- }
- eOut = `{"CGRID":"","RunID":"","StartTime":"0001-01-01T00:00:00Z","Usage":null,"Cost":null,"Charges":null,"AccountSummary":{"Tenant":"","ID":"","BalanceSummaries":[{"UUID":"","ID":"ID","Type":"","Initial":0,"Value":0,"Disabled":false}],"AllowNegative":false,"Disabled":false},"Rating":null,"Accounting":null,"RatingFilters":null,"Rates":null,"Timings":null}`
- if rcv := eventCost.String(); !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eOut, rcv)
- }
-}
-
-func TestEventCostFieldAsString(t *testing.T) {
- eventCost := &EventCost{
- CGRID: "CGRID",
- }
- eventCost.initCache()
- if rcv, err := eventCost.FieldAsString([]string{utils.CGRID}); err != nil {
- t.Error(err)
- } else if rcv != "CGRID" {
- t.Errorf("Expecting: CGRID, received: %+v", rcv)
- }
- if rcv, err := eventCost.FieldAsString([]string{"err"}); err == nil || err.Error() != "unsupported field prefix: " {
- t.Error(err)
- } else if !reflect.DeepEqual(rcv, utils.EmptyString) {
- t.Errorf("Expecting: EmptyString, received: %+v", rcv)
- }
-}
-
-func TestEventCostRemoteHost(t *testing.T) {
- eventCost := &EventCost{}
- eOut := utils.LocalAddr()
- if rcv := eventCost.RemoteHost(); !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %+v, received: %+v", eOut, rcv)
- }
-}
-func TestECAsCallCost3(t *testing.T) {
- eCC := &CallCost{
- Category: "call",
- Tenant: "cgrates.org",
- Subject: "dan",
- Account: "dan",
- Destination: "+4986517174963",
- ToR: utils.MetaVoice,
- Cost: 0.85,
- RatedUsage: 120.0,
- Timespans: TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- Cost: 0.25,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.01,
- RateUnit: time.Duration(1 * time.Second),
- RateIncrement: time.Duration(1 * time.Minute),
- },
- },
- },
- },
- DurationIndex: time.Duration(1 * time.Minute),
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{ // ConnectFee
- Cost: 0.1,
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.9},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 1,
- },
- &Increment{ // First 30 seconds free
- Duration: time.Duration(1 * time.Second),
- Cost: 0,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{
- UUID: "9d54a9e9-d610-4c82-bcb5-a315b9a65089",
- ID: "free_mins",
- Value: 0,
- Consumed: 1.0,
- ToR: utils.MetaVoice,
- },
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- &Increment{ // Minutes with special price
- Duration: time.Duration(1 * time.Second),
- Cost: 0.005,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{ // Minutes with special price
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: "discounted_mins",
- Value: 0,
- Consumed: 1.0,
- ToR: utils.MetaVoice,
- RateInterval: &RateInterval{
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.005,
- RateUnit: time.Duration(1 * time.Second),
- RateIncrement: time.Duration(1 * time.Second),
- },
- &RGRate{
- GroupIntervalStart: time.Duration(60 * time.Second),
- Value: 0.005,
- RateUnit: time.Duration(1 * time.Second),
- RateIncrement: time.Duration(1 * time.Second),
- },
- },
- },
- },
- },
- Monetary: &MonetaryInfo{
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.75},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 30,
- },
- },
- },
-
- &TimeSpan{
- TimeStart: time.Date(2017, 1, 9, 16, 19, 21, 0, time.UTC),
- TimeEnd: time.Date(2017, 1, 9, 16, 20, 21, 0, time.UTC),
- Cost: 0.6,
- RateInterval: &RateInterval{ // standard rating
- Timing: &RITiming{
- StartTime: "00:00:00",
- },
- Rating: &RIRate{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.01,
- RateUnit: time.Duration(1 * time.Second),
- RateIncrement: time.Duration(1 * time.Minute),
- },
- },
- },
- },
- DurationIndex: time.Duration(1 * time.Minute),
- MatchedSubject: "*out:cgrates.org:call:*any",
- MatchedPrefix: "+49",
- MatchedDestId: "GERMANY",
- RatingPlanId: "RPL_RETAIL1",
- CompressFactor: 1,
- Increments: Increments{
- &Increment{
- Cost: 0.01,
- Duration: time.Duration(1 * time.Second),
- BalanceInfo: &DebitInfo{
- Monetary: &MonetaryInfo{UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- ID: utils.MetaDefault,
- Value: 9.15},
- AccountID: "cgrates.org:dan",
- },
- CompressFactor: 60,
- },
- },
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- Type: utils.MetaMonetary,
- Value: 50,
- Disabled: false},
- {
- ID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: utils.MetaMonetary,
- Value: 25,
- Disabled: false},
- {
- Type: utils.MetaVoice,
- Value: 200,
- Disabled: false,
- },
- },
- AllowNegative: false,
- Disabled: false,
- },
- }
-
- eEC := &EventCost{
- CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41",
- RunID: utils.MetaDefault,
- StartTime: time.Date(2017, 1, 9, 16, 18, 21, 0, time.UTC),
- Charges: []*ChargingInterval{
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Duration(0),
- Cost: 0.1,
- AccountingID: "9bdad10",
- CompressFactor: 1,
- },
- {
- Usage: time.Duration(1 * time.Second),
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: time.Duration(10 * time.Second),
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Duration(1 * time.Second),
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 1,
- },
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Duration(1 * time.Second),
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 60,
- },
- },
- CompressFactor: 4,
- },
- {
- RatingID: "21a5ab9",
- Increments: []*ChargingIncrement{
- {
- Usage: time.Duration(1 * time.Second),
- Cost: 0,
- AccountingID: "3455b83",
- CompressFactor: 10,
- },
- {
- Usage: time.Duration(10 * time.Second),
- Cost: 0.01,
- AccountingID: "2012888",
- CompressFactor: 2,
- },
- {
- Usage: time.Duration(1 * time.Second),
- Cost: 0.005,
- AccountingID: "44d6c02",
- CompressFactor: 30,
- },
- },
- CompressFactor: 5,
- },
- },
- AccountSummary: &AccountSummary{
- Tenant: "cgrates.org",
- ID: "dan",
- BalanceSummaries: []*BalanceSummary{
- {
- UUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 50,
- Disabled: false},
- {
- UUID: "7a54a9e9-d610-4c82-bcb5-a315b9a65010",
- Type: utils.MetaMonetary,
- Value: 25,
- Disabled: false},
- {
- UUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Type: utils.MetaVoice,
- Value: 200,
- Disabled: false,
- },
- },
- AllowNegative: false,
- Disabled: false,
- },
- Rating: Rating{
- "3cd6425": &RatingUnit{
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "2f324ab",
- RatesID: "4910ecf",
- RatingFiltersID: "23e77dc",
- },
- "21a5ab9": &RatingUnit{
- ConnectFee: 0.1,
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- TimingID: "2f324ab",
- RatesID: "2c1a177",
- RatingFiltersID: "23e77dc",
- },
- },
- Accounting: Accounting{
- "2012888": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.01,
- RatingID: "21a5ab9",
- },
- "288bfa6": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.005,
- },
- "9bdad10": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "8c54a9e9-d610-4c82-bcb5-a315b9a65010",
- Units: 0.1,
- },
- "44d6c02": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- RatingID: "3cd6425",
- Units: 1,
- ExtraChargeID: "288bfa6",
- },
- "3455b83": &BalanceCharge{
- AccountID: "cgrates.org:dan",
- BalanceUUID: "4b8b53d7-c1a1-4159-b845-4623a00a0165",
- Units: 1,
- ExtraChargeID: "*none",
- },
- },
- RatingFilters: RatingFilters{
- "23e77dc": RatingMatchedFilters{
- "DestinationID": "GERMANY",
- "DestinationPrefix": "+49",
- "RatingPlanID": "RPL_RETAIL1",
- "Subject": "*out:cgrates.org:call:*any",
- },
- },
- Rates: ChargedRates{
- "2c1a177": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.01,
- RateIncrement: time.Duration(1 * time.Minute),
- RateUnit: time.Duration(1 * time.Second)},
- },
- "4910ecf": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Duration(0),
- Value: 0.005,
- RateIncrement: time.Duration(1 * time.Second),
- RateUnit: time.Duration(1 * time.Second)},
- &RGRate{
- GroupIntervalStart: time.Duration(60 * time.Second),
- Value: 0.005,
- RateIncrement: time.Duration(1 * time.Second),
- RateUnit: time.Duration(1 * time.Second)},
- },
- },
- Timings: ChargedTimings{
- "2f324ab": &ChargedTiming{
- StartTime: "00:00:00",
- },
- },
- cache: utils.MapStorage{},
- }
- ec := NewEventCostFromCallCost(eCC, "cgrID", utils.MetaDefault)
- eEC.SyncKeys(ec)
- ec.Merge(eEC)
-
- if _, err := ec.Trim(time.Second); err != nil {
- t.Fatal(err)
- }
-
-}
-
-func TestECAsDataProvider2(t *testing.T) {
- ecDP := testEC
- if data, err := ecDP.FieldAsInterface([]string{"RunID"}); err != nil {
- t.Error(err)
- } else if data != utils.MetaDefault {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", utils.MetaDefault, data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "ID"}); err != nil {
- t.Error(err)
- } else if data != "dan" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "data", data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[1]", "UUID"}); err != nil {
- t.Error(err)
- } else if data != "7a54a9e9-d610-4c82-bcb5-a315b9a65010" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "4b8b53d7-c1a1-4159-b845-4623a00a0165", data)
- }
- if data, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[2]", "Type"}); err != nil {
- t.Error(err)
- } else if data != "*voice" {
- t.Errorf("Expecting: <%s> \nreceived: <%s>", "*voice", data)
- }
- ecDP = &EventCost{AccountSummary: &AccountSummary{}}
- ecDP.initCache()
- if _, err := ecDP.FieldAsInterface([]string{"AccountSummary", "BalanceSummaries[0]", "Type"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Unexpected error:%v", err)
- }
- if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Increments"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Unexpected error:%v", err)
- }
- ecDP.Charges = []*ChargingInterval{{}}
- if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Increments[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Unexpected error:%v", err)
- }
- ecDP.Rating = Rating{"": {}}
- ecDP.Rates = ChargedRates{"": {}, "b": {}}
- if _, err := ecDP.FieldAsInterface([]string{"Charges[0]", "Rating", "Rates[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Unexpected error:%v", err)
- }
-
- if _, err := ecDP.FieldAsInterface([]string{"Rates", "b[0]"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Unexpected error:%v", err)
- }
-}
-
-func TestECFieldAsInterfaceNilEventCost(t *testing.T) {
- dft := config.NewDefaultCGRConfig()
- cdr, err := NewMapEvent(map[string]interface{}{}).AsCDR(dft, "cgrates.org", "UTC")
- if err != nil {
- t.Fatal(err)
- }
- nM := cdr.AsMapStorage()
- if _, err := nM.FieldAsInterface([]string{"*ec", "Charges[0]", "Increments[0]", "Accounting", "Balance", "ID"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Fatalf("Expected error:%s, received: %v", utils.ErrNotFound.Error(), err)
- }
-
- if _, err := nM.FieldAsInterface([]string{"*req", "CostDetails", "Charges[0]", "Increments[0]", "Accounting", "Balance", "ID"}); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Fatalf("Expected error:%s, received: %v", utils.ErrNotFound.Error(), err)
- }
-}
diff --git a/engine/libeventcost.go b/engine/libeventcost.go
deleted file mode 100644
index 68dcffe63..000000000
--- a/engine/libeventcost.go
+++ /dev/null
@@ -1,686 +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 (
- "encoding/json"
- "fmt"
- "reflect"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-// ChargingInterval represents one interval out of Usage providing charging info
-// eg: PEAK vs OFFPEAK
-type ChargingInterval struct {
- RatingID string // reference to RatingUnit
- Increments []*ChargingIncrement // specific increments applied to this interval
- CompressFactor int
- usage *time.Duration // cache usage computation for this interval
- ecUsageIdx *time.Duration // computed value of totalUsage at the starting of the interval
- cost *float64 // cache cost calculation on this interval
-}
-
-// PartiallyEquals does not compare CompressFactor, usefull for Merge
-func (cIl *ChargingInterval) PartiallyEquals(oCIl *ChargingInterval) bool {
- if equals := cIl.RatingID == oCIl.RatingID &&
- len(cIl.Increments) == len(oCIl.Increments); !equals {
- return false
- }
- for i := range cIl.Increments {
- if !cIl.Increments[i].Equals(oCIl.Increments[i]) {
- return false
- }
- }
- return true
-}
-
-// Usage computes the total usage of this ChargingInterval, ignoring CompressFactor
-func (cIl *ChargingInterval) Usage() *time.Duration {
- if cIl.usage == nil {
- var usage time.Duration
- for _, incr := range cIl.Increments {
- usage += incr.TotalUsage()
- }
- cIl.usage = &usage
- }
- return cIl.usage
-}
-
-// TotalUsage returns the total usage of this interval, considering compress factor
-func (cIl *ChargingInterval) TotalUsage() (tu *time.Duration) {
- usage := cIl.Usage()
- if usage == nil {
- return
- }
- tu = new(time.Duration)
- *tu = time.Duration(usage.Nanoseconds() * int64(cIl.CompressFactor))
- return
-}
-
-// EventCostUsageIndex publishes the value of ecUsageIdx
-func (cIl *ChargingInterval) EventCostUsageIndex() *time.Duration {
- return cIl.ecUsageIdx
-}
-
-// StartTime computes a StartTime based on EventCost.Start time and ecUsageIdx
-func (cIl *ChargingInterval) StartTime(ecST time.Time) (st time.Time) {
- if cIl.ecUsageIdx != nil {
- st = ecST.Add(*cIl.ecUsageIdx)
- }
- return
-}
-
-// EndTime computes an EndTime based on ChargingInterval StartTime value and usage
-func (cIl *ChargingInterval) EndTime(cIlST time.Time) (et time.Time) {
- return cIlST.Add(time.Duration(cIl.Usage().Nanoseconds() * int64(cIl.CompressFactor)))
-}
-
-// Cost computes the total cost on this ChargingInterval
-func (cIl *ChargingInterval) Cost() float64 {
- if cIl.cost == nil {
- var cost float64
- for _, incr := range cIl.Increments {
- cost += incr.Cost * float64(incr.CompressFactor)
- }
- cost = utils.Round(cost, 6, utils.MetaRoundingMiddle)
- cIl.cost = &cost
- }
- return *cIl.cost
-}
-
-// TotalCost returns the cost of charges
-func (cIl *ChargingInterval) TotalCost() float64 {
- return utils.Round((cIl.Cost() * float64(cIl.CompressFactor)),
- 6, utils.MetaRoundingMiddle)
-}
-
-// Clone returns a new instance of ChargingInterval with independent data
-func (cIl *ChargingInterval) Clone() (cln *ChargingInterval) {
- cln = new(ChargingInterval)
- cln.RatingID = cIl.RatingID
- cln.CompressFactor = cIl.CompressFactor
- cln.Increments = make([]*ChargingIncrement, len(cIl.Increments))
- for i, cIt := range cIl.Increments {
- cln.Increments[i] = cIt.Clone()
- }
- return
-}
-
-// ChargingIncrement represents one unit charged inside an interval
-type ChargingIncrement struct {
- Usage time.Duration
- Cost float64
- AccountingID string
- CompressFactor int
-}
-
-// Equals returns if the structure has the same value
-func (cIt *ChargingIncrement) Equals(oCIt *ChargingIncrement) bool {
- return cIt.Usage == oCIt.Usage &&
- cIt.Cost == oCIt.Cost &&
- cIt.AccountingID == oCIt.AccountingID &&
- cIt.CompressFactor == oCIt.CompressFactor
-}
-
-// PartiallyEquals ignores the CompressFactor when comparing
-func (cIt *ChargingIncrement) PartiallyEquals(oCIt *ChargingIncrement) bool {
- return cIt.Usage == oCIt.Usage &&
- cIt.Cost == oCIt.Cost &&
- cIt.AccountingID == oCIt.AccountingID
-}
-
-// Clone creates a copy of ChargingIncrement
-func (cIt *ChargingIncrement) Clone() (cln *ChargingIncrement) {
- cln = new(ChargingIncrement)
- *cln = *cIt
- return
-}
-
-// TotalUsage returns the total usage of the increment, considering compress factor
-func (cIt *ChargingIncrement) TotalUsage() time.Duration {
- return time.Duration(cIt.Usage.Nanoseconds() * int64(cIt.CompressFactor))
-}
-
-// TotalCost returns the cost of the increment
-func (cIt *ChargingIncrement) TotalCost() float64 {
- return cIt.Cost * float64(cIt.CompressFactor)
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (cIt *ChargingIncrement) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- switch fldPath[0] {
- default:
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
- case utils.Usage:
- return cIt.Usage, nil
- case utils.Cost:
- return cIt.Cost, nil
- case utils.AccountingID:
- return cIt.AccountingID, nil
- case utils.CompressFactor:
- return cIt.CompressFactor, nil
- }
-}
-
-// BalanceCharge represents one unit charged to a balance
-type BalanceCharge struct {
- AccountID string // keep reference for shared balances
- BalanceUUID string // balance charged
- RatingID string // special price applied on this balance
- Units float64 // number of units charged
- ExtraChargeID string // used in cases when paying *voice with *monetary
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (bc *BalanceCharge) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if bc == nil || len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- switch fldPath[0] {
- default:
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
- case utils.AccountID:
- return bc.AccountID, nil
- case utils.BalanceUUID:
- return bc.BalanceUUID, nil
- case utils.RatingID:
- return bc.RatingID, nil
- case utils.Units:
- return bc.Units, nil
- case utils.ExtraChargeID:
- return bc.ExtraChargeID, nil
- }
-}
-
-// Equals returns if the structure have the same fields
-func (bc *BalanceCharge) Equals(oBC *BalanceCharge) bool {
- bcExtraChargeID := bc.ExtraChargeID
- if bcExtraChargeID == "" {
- bcExtraChargeID = utils.MetaNone
- }
- oBCExtraChargerID := oBC.ExtraChargeID
- if oBCExtraChargerID == "" { // so we can compare them properly
- oBCExtraChargerID = utils.MetaNone
- }
- return bc.AccountID == oBC.AccountID &&
- bc.BalanceUUID == oBC.BalanceUUID &&
- bc.RatingID == oBC.RatingID &&
- bc.Units == oBC.Units &&
- bcExtraChargeID == oBCExtraChargerID
-}
-
-// Clone creates a copy of BalanceCharge
-func (bc *BalanceCharge) Clone() *BalanceCharge {
- clnBC := new(BalanceCharge)
- *clnBC = *bc
- return clnBC
-}
-
-// RatingMatchedFilters a rating filter
-type RatingMatchedFilters map[string]interface{}
-
-// Equals returns if the RatingMatchedFilters are equal
-func (rf RatingMatchedFilters) Equals(oRF RatingMatchedFilters) bool {
- for k := range rf {
- if rf[k] != oRF[k] {
- return false
- }
- }
- return true
-}
-
-// Clone creates a copy of RatingMatchedFilters
-func (rf RatingMatchedFilters) Clone() (cln map[string]interface{}) {
- if rf == nil {
- return nil
- }
- cln = make(map[string]interface{})
- for key, value := range rf {
- cln[key] = value
- }
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (rf RatingMatchedFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if rf == nil || len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- ct, has := rf[fldPath[0]]
- if !has || ct == nil {
- return nil, utils.ErrNotFound
- }
- return ct, nil
-}
-
-// ChargedTiming represents one timing attached to a charge
-type ChargedTiming struct {
- Years utils.Years
- Months utils.Months
- MonthDays utils.MonthDays
- WeekDays utils.WeekDays
- StartTime string
-}
-
-// Equals returns if the timings are equal
-func (ct *ChargedTiming) Equals(oCT *ChargedTiming) bool {
- return ct.Years.Equals(oCT.Years) &&
- ct.Months.Equals(oCT.Months) &&
- ct.MonthDays.Equals(oCT.MonthDays) &&
- ct.WeekDays.Equals(oCT.WeekDays) &&
- ct.StartTime == oCT.StartTime
-}
-
-// Clone creates a copy of ChargedTiming
-func (ct *ChargedTiming) Clone() (cln *ChargedTiming) {
- cln = new(ChargedTiming)
- *cln = *ct
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (ct ChargedTiming) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- switch fldPath[0] {
- default:
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
- case utils.YearsFieldName:
- return ct.Years, nil
- case utils.MonthsFieldName:
- return ct.Months, nil
- case utils.MonthDaysFieldName:
- return ct.MonthDays, nil
- case utils.WeekDaysFieldName:
- return ct.WeekDays, nil
- case utils.StartTime:
- return ct.StartTime, nil
- }
-}
-
-// RatingUnit represents one unit out of RatingPlan matching for an event
-type RatingUnit struct {
- ConnectFee float64
- RoundingMethod string
- RoundingDecimals int
- MaxCost float64
- MaxCostStrategy string
- TimingID string // This RatingUnit is bounded to specific timing profile
- RatesID string
- RatingFiltersID string
-}
-
-// Equals returns if RatingUnit is equal to the other
-func (ru *RatingUnit) Equals(oRU *RatingUnit) bool {
- return ru.ConnectFee == oRU.ConnectFee &&
- ru.RoundingMethod == oRU.RoundingMethod &&
- ru.RoundingDecimals == oRU.RoundingDecimals &&
- ru.MaxCost == oRU.MaxCost &&
- ru.MaxCostStrategy == oRU.MaxCostStrategy &&
- ru.TimingID == oRU.TimingID &&
- ru.RatesID == oRU.RatesID &&
- ru.RatingFiltersID == oRU.RatingFiltersID
-}
-
-// Clone creates a copy of RatingUnit
-func (ru *RatingUnit) Clone() (cln *RatingUnit) {
- cln = new(RatingUnit)
- *cln = *ru
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (ru RatingUnit) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- switch fldPath[0] {
- default:
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
- case utils.ConnectFee:
- return ru.ConnectFee, nil
- case utils.RoundingMethod:
- return ru.RoundingMethod, nil
- case utils.RoundingDecimals:
- return ru.RoundingDecimals, nil
- case utils.MaxCost:
- return ru.MaxCost, nil
- case utils.MaxCostStrategy:
- return ru.MaxCostStrategy, nil
- case utils.TimingID:
- return ru.TimingID, nil
- case utils.RatesID:
- return ru.RatesID, nil
- case utils.RatingFiltersID:
- return ru.RatingFiltersID, nil
- }
-}
-
-// RatingFilters the map of rating filters
-type RatingFilters map[string]RatingMatchedFilters // so we can define search methods
-
-// GetIDWithSet attempts to retrieve the UUID of a matching data or create a new one
-func (rfs RatingFilters) GetIDWithSet(rmf RatingMatchedFilters) string {
- if rmf == nil || len(rmf) == 0 {
- return ""
- }
- for k, v := range rfs {
- if v.Equals(rmf) {
- return k
- }
- }
- // not found, set it here
- uuid := utils.UUIDSha1Prefix()
- rfs[uuid] = rmf
- return uuid
-}
-
-// Clone creates a copy of RatingFilters
-func (rfs RatingFilters) Clone() (cln RatingFilters) {
- cln = make(RatingFilters, len(rfs))
- for k, v := range rfs {
- cln[k] = v.Clone()
- }
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (rfs RatingFilters) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if rfs == nil || len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- ct, has := rfs[fldPath[0]]
- if !has || ct == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return ct, nil
- }
- return ct.FieldAsInterface(fldPath[1:])
-}
-
-// Rating the map of rating units
-type Rating map[string]*RatingUnit
-
-// GetIDWithSet attempts to retrieve the UUID of a matching data or create a new one
-func (crus Rating) GetIDWithSet(cru *RatingUnit) string {
- if cru == nil {
- return ""
- }
- for k, v := range crus {
- if v.Equals(cru) {
- return k
- }
- }
- // not found, set it here
- uuid := utils.UUIDSha1Prefix()
- crus[uuid] = cru
- return uuid
-}
-
-// Clone creates a copy of Rating
-func (crus Rating) Clone() (cln Rating) {
- cln = make(Rating, len(crus))
- for k, v := range crus {
- cln[k] = v.Clone()
- }
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (crus Rating) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if crus == nil || len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- rt, has := crus[fldPath[0]]
- if !has || rt == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return rt, nil
- }
- return rt.FieldAsInterface(fldPath[1:])
-}
-
-// ChargedRates the map with rateGroups
-type ChargedRates map[string]RateGroups
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (crs ChargedRates) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if crs == nil || len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- opath, indx := utils.GetPathIndex(fldPath[0])
- cr, has := crs[opath]
- if !has || cr == nil {
- return nil, utils.ErrNotFound
- }
- if indx != nil {
- if len(cr) <= *indx {
- return nil, utils.ErrNotFound
- }
- rg := cr[*indx]
- if len(fldPath) == 1 {
- return rg, nil
- }
- return rg.FieldAsInterface(fldPath[1:])
- }
- if len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- return cr, nil
-}
-
-// GetIDWithSet attempts to retrieve the UUID of a matching data or create a new one
-func (crs ChargedRates) GetIDWithSet(rg RateGroups) string {
- if rg == nil || len(rg) == 0 {
- return ""
- }
- for k, v := range crs {
- if v.Equals(rg) {
- return k
- }
- }
- // not found, set it here
- uuid := utils.UUIDSha1Prefix()
- crs[uuid] = rg
- return uuid
-}
-
-// Clone creates a copy of ChargedRates
-func (crs ChargedRates) Clone() (cln ChargedRates) {
- cln = make(ChargedRates, len(crs))
- for k, v := range crs {
- cln[k] = v.Clone()
- }
- return
-}
-
-// ChargedTimings the map of ChargedTiming
-type ChargedTimings map[string]*ChargedTiming
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (cts ChargedTimings) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if cts == nil || len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- ct, has := cts[fldPath[0]]
- if !has || ct == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return ct, nil
- }
- return ct.FieldAsInterface(fldPath[1:])
-}
-
-// GetIDWithSet attempts to retrieve the UUID of a matching data or create a new one
-func (cts ChargedTimings) GetIDWithSet(ct *ChargedTiming) string {
- if ct == nil {
- return ""
- }
- for k, v := range cts {
- if v.Equals(ct) {
- return k
- }
- }
- // not found, set it here
- uuid := utils.UUIDSha1Prefix()
- cts[uuid] = ct
- return uuid
-}
-
-// Clone creates a copy of ChargedTimings
-func (cts ChargedTimings) Clone() (cln ChargedTimings) {
- cln = make(ChargedTimings, len(cts))
- for k, v := range cts {
- cln[k] = v.Clone()
- }
- return
-}
-
-// Accounting the map of debited balances
-type Accounting map[string]*BalanceCharge
-
-// GetIDWithSet attempts to retrieve the UUID of a matching data or create a new one
-func (cbs Accounting) GetIDWithSet(cb *BalanceCharge) string {
- if cb == nil {
- return ""
- }
- for k, v := range cbs {
- if v.Equals(cb) {
- return k
- }
- }
- // not found, set it here
- uuid := utils.UUIDSha1Prefix()
- cbs[uuid] = cb
- return uuid
-}
-
-// Clone creates a copy of Accounting
-func (cbs Accounting) Clone() (cln Accounting) {
- cln = make(Accounting, len(cbs))
- for k, v := range cbs {
- cln[k] = v.Clone()
- }
- return
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (cbs Accounting) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if cbs == nil || len(fldPath) == 0 {
- return nil, utils.ErrNotFound
- }
- ac, has := cbs[fldPath[0]]
- if !has || ac == nil {
- return nil, utils.ErrNotFound
- }
- if len(fldPath) == 1 {
- return ac, nil
- }
- return ac.FieldAsInterface(fldPath[1:])
-}
-
-// IfaceAsEventCost converts an interface to EventCost
-func IfaceAsEventCost(itm interface{}) (ec *EventCost, err error) {
- switch otm := itm.(type) {
- case nil:
- case *EventCost:
- ec = otm
- case string:
- var rawEC EventCost
- if errUnmarshal := json.Unmarshal([]byte(otm), &rawEC); errUnmarshal != nil {
- return nil, fmt.Errorf("JSON cannot unmarshal to *EventCost, err: %s", errUnmarshal.Error())
- }
- ec = &rawEC
- case map[string]interface{}:
- ec, err = IfaceAsEventCost(utils.ToJSON(otm))
- default:
- err = utils.ErrNotConvertibleTF(reflect.TypeOf(otm).String(), "*EventCost")
- }
- return
-}
-
-// NewFreeEventCost returns an EventCost of given duration that it's free
-func NewFreeEventCost(cgrID, runID, account string, tStart time.Time, usage time.Duration) *EventCost {
- return &EventCost{
- CGRID: cgrID,
- RunID: runID,
- StartTime: tStart,
- Cost: utils.Float64Pointer(0),
- Charges: []*ChargingInterval{{
- RatingID: utils.MetaPause,
- Increments: []*ChargingIncrement{
- {
- Usage: usage,
- AccountingID: utils.MetaPause,
- CompressFactor: 1,
- },
- },
- CompressFactor: 1,
- }},
-
- Rating: Rating{
- utils.MetaPause: {
- RoundingMethod: "*up",
- RoundingDecimals: 5,
- RatesID: utils.MetaPause,
- RatingFiltersID: utils.MetaPause,
- TimingID: utils.MetaPause,
- },
- },
- Accounting: Accounting{
- utils.MetaPause: {
- AccountID: account,
- // BalanceUUID: "",
- RatingID: utils.MetaPause,
- },
- },
- RatingFilters: RatingFilters{
- utils.MetaPause: {
- utils.Subject: "",
- utils.DestinationPrefixName: "",
- utils.DestinationID: "",
- utils.RatingPlanID: utils.MetaPause,
- },
- },
- Rates: ChargedRates{
- utils.MetaPause: {
- {
- RateIncrement: 1,
- RateUnit: 1,
- },
- },
- },
- Timings: ChargedTimings{
- utils.MetaPause: {
-
- StartTime: "00:00:00",
- },
- },
- cache: utils.MapStorage{},
- }
-}
diff --git a/engine/libeventcost_test.go b/engine/libeventcost_test.go
deleted file mode 100755
index 4f25e2b42..000000000
--- a/engine/libeventcost_test.go
+++ /dev/null
@@ -1,1018 +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"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-//Start tests for ChargingInterval
-func TestChargingIntervalPartiallyEquals(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- },
- CompressFactor: 3,
- }
- ci2 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- },
- CompressFactor: 3,
- }
- if eq := ci1.PartiallyEquals(ci2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- ci2.RatingID = "Rating2"
- if eq := ci1.PartiallyEquals(ci2); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
- ci2.RatingID = "Rating1"
- ci2.Increments[0].AccountingID = "Acc2"
- if eq := ci1.PartiallyEquals(ci2); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestChargingIntervalUsage(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- tCi1 := ci1.Usage()
- eTCi1 := 14*time.Second + 12*time.Millisecond
- if *tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
- }
-}
-
-func TestChargingIntervalTotalUsage(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- tCi1 := ci1.TotalUsage()
- eTCi1 := 3 * (14*time.Second + 12*time.Millisecond)
- if *tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
- }
-}
-
-func TestChargingIntervalEventCostUsageIndex(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- ci1.ecUsageIdx = ci1.TotalUsage()
- tCi1 := ci1.EventCostUsageIndex()
- eTCi1 := 3 * (14*time.Second + 12*time.Millisecond)
- if *tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
- }
-}
-
-func TestChargingIntervalStartTime(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- ci1.ecUsageIdx = ci1.TotalUsage()
- tCi1 := ci1.StartTime(time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC))
- eTCi1 := time.Date(2013, 11, 7, 8, 43, 8, 36000000, time.UTC)
- if tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
- }
-}
-
-func TestChargingIntervalEndTime(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- ci1.ecUsageIdx = ci1.TotalUsage()
- tCi1 := ci1.EndTime(time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC))
- eTCi1 := time.Date(2013, 11, 7, 8, 43, 8, 36000000, time.UTC)
- if tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
- }
-}
-
-func TestChargingIntervalCost(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- tCi1 := ci1.Cost()
- eTCi1 := 10.84
- if tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
- }
-}
-
-func TestChargingIntervalTotalCost(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- tCi1 := ci1.TotalCost()
- eTCi1 := 32.52
- if tCi1 != eTCi1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
- }
-}
-
-func TestChargingIntervalClone(t *testing.T) {
- ci1 := &ChargingInterval{
- RatingID: "Rating1",
- Increments: []*ChargingIncrement{
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 1.23,
- Usage: 5 * time.Second,
- },
- {
- AccountingID: "Acc1",
- CompressFactor: 3,
- Cost: 1.23,
- Usage: 4 * time.Millisecond,
- },
- },
- CompressFactor: 3,
- }
- ci2 := ci1.Clone()
- if !reflect.DeepEqual(ci1, ci2) {
- t.Errorf("Expecting: %+v, received: %+v", ci1, ci2)
- }
- ci1.RatingID = "Rating2"
- if ci2.RatingID != "Rating1" {
- t.Errorf("Expecting: Acc1, received: %+v", ci2)
- }
-
-}
-
-//Start tests for ChargingIncrement
-func TestChargingIncrementEquals(t *testing.T) {
- ch1 := &ChargingIncrement{
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- ch2 := &ChargingIncrement{
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- ch3 := &ChargingIncrement{
- AccountingID: "Acc2",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- if eq := ch1.Equals(ch2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- if eq := ch1.Equals(ch3); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestChargingIncrementClone(t *testing.T) {
- ch1 := &ChargingIncrement{
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- ch2 := ch1.Clone()
- if !reflect.DeepEqual(ch1, ch2) {
- t.Errorf("Expecting: %+v, received: %+v", ch2, ch1)
- }
- ch1.AccountingID = "Acc2"
- if ch2.AccountingID != "Acc1" {
- t.Errorf("Expecting: Acc1, received: %+v", ch1)
- }
-}
-
-func TestChargingIncrementTotalUsage(t *testing.T) {
- ch1 := &ChargingIncrement{
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- tCh1 := ch1.TotalUsage()
- eTCh1 := 4 * time.Second
- if tCh1 != eTCh1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCh1, tCh1)
- }
-}
-
-func TestChargingIncrementTotalCost(t *testing.T) {
- ch1 := &ChargingIncrement{
- AccountingID: "Acc1",
- CompressFactor: 2,
- Cost: 2.345,
- Usage: 2 * time.Second,
- }
- tCh1 := ch1.TotalCost()
- eTCh1 := 4.69
- if tCh1 != eTCh1 {
- t.Errorf("Expecting: %+v, received: %+v", eTCh1, tCh1)
- }
-}
-
-//Start tests for BalanceCharge
-func TestBalanceChargeEquals(t *testing.T) {
- bc1 := &BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }
- bc2 := &BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }
- bc3 := &BalanceCharge{
- AccountID: "1002",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }
- if eq := bc1.Equals(bc2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- if eq := bc1.Equals(bc3); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestBalanceChargeClone(t *testing.T) {
- bc1 := &BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }
- bc2 := bc1.Clone()
- if !reflect.DeepEqual(bc1, bc2) {
- t.Errorf("Expecting: %+v, received: %+v", bc1, bc2)
- }
- bc1.AccountID = "1002"
- if bc2.AccountID != "1001" {
- t.Errorf("Expecting: 1001, received: %+v", bc2)
- }
-}
-
-//Start tests for RatingMatchedFilters
-func TestRatingMatchedFiltersEquals(t *testing.T) {
- rmf1 := RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- }
- rmf2 := RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- }
- rmf3 := RatingMatchedFilters{
- "AccountID": "1002",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- }
- if eq := rmf1.Equals(rmf2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- if eq := rmf1.Equals(rmf3); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestRatingMatchedFiltersClone(t *testing.T) {
- rmf1 := RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- }
- rmf2 := rmf1.Clone()
- if eq := rmf1.Equals(rmf2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- rmf1["AccountID"] = "1002"
- if rmf2["AccountID"] != "1001" {
- t.Errorf("Expecting: 1001, received: %+v", rmf2)
- }
-}
-
-//Start tests for ChargedTiming
-func TestChargedTimingEquals(t *testing.T) {
- ct1 := &ChargedTiming{
- Years: utils.Years{1, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- }
- ct2 := &ChargedTiming{
- Years: utils.Years{1, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- }
- ct3 := &ChargedTiming{
- Years: utils.Years{2, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time2",
- }
- if eq := ct1.Equals(ct2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- if eq := ct1.Equals(ct3); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestChargedTimingClone(t *testing.T) {
- ct1 := &ChargedTiming{
- Years: utils.Years{1, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- }
- ct2 := ct1.Clone()
- if eq := ct1.Equals(ct2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- ct1.StartTime = "Time2"
- if ct2.StartTime != "Time" {
- t.Errorf("Expecting: Time, received: %+v", ct2)
- }
-}
-
-//Start tests for RatingUnit
-func TestRatingUnitEquals(t *testing.T) {
- ru1 := &RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }
- ru2 := &RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }
- ru3 := &RatingUnit{
- ConnectFee: 1.24,
- RoundingMethod: "Meth2",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }
- if eq := ru1.Equals(ru2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- if eq := ru1.Equals(ru3); eq {
- t.Errorf("Expecting: false, received: %+v", eq)
- }
-}
-
-func TestRatingUnitClone(t *testing.T) {
- ru1 := &RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }
- ru2 := ru1.Clone()
- if eq := ru1.Equals(ru2); !eq {
- t.Errorf("Expecting: true, received: %+v", eq)
- }
- ru1.ConnectFee = 2.34
- if ru2.ConnectFee != 1.23 {
- t.Errorf("Expecting: 1.23, received: %+v", ru2)
- }
-}
-
-//Start tests for RatingFilters
-func TestRatingFiltersGetIDWithSet(t *testing.T) {
- rf1 := RatingFilters{
- "Key1": RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- },
- "Key2": RatingMatchedFilters{
- "AccountID": "1002",
- "Units": 1.23,
- "ExtraChargeID": "Extra2",
- },
- }
-
- if id1 := rf1.GetIDWithSet(RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- }); id1 != "Key1" {
- t.Errorf("Expecting: Key1, received: %+v", id1)
- }
-
- if id2 := rf1.GetIDWithSet(RatingMatchedFilters{
- "AccountID": "1004",
- "Units": 2.34,
- "ExtraChargeID": "Extra3",
- }); id2 == "" {
- t.Errorf("Expecting id , received: %+v", id2)
- }
-
- if id3 := rf1.GetIDWithSet(nil); id3 != "" {
- t.Errorf("Expecting , received: %+v", id3)
- }
-}
-
-func TestRatingFiltersClone(t *testing.T) {
- rf1 := RatingFilters{
- "Key1": RatingMatchedFilters{
- "AccountID": "1001",
- "Units": 2.34,
- "ExtraChargeID": "Extra1",
- },
- "Key2": RatingMatchedFilters{
- "AccountID": "1002",
- "Units": 1.23,
- "ExtraChargeID": "Extra2",
- },
- }
- rf2 := rf1.Clone()
- if !reflect.DeepEqual(rf1, rf2) {
- t.Errorf("Expecting: %+v, received: %+v", rf1, rf2)
- }
- rf1["Key1"]["AccountID"] = "1003"
- if rf2["Key1"]["AccountID"] != "1001" {
- t.Errorf("Expecting 1001 , received: %+v", rf2)
- }
-}
-
-//Start tests for Rating
-func TestRatingGetIDWithSet(t *testing.T) {
- r1 := Rating{
- "Key1": &RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- },
- "Key2": &RatingUnit{
- ConnectFee: 0.2,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 2.12,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- },
- }
-
- if id1 := r1.GetIDWithSet(&RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }); id1 != "Key1" {
- t.Errorf("Expecting: Key1, received: %+v", id1)
- }
-
- if id2 := r1.GetIDWithSet(&RatingUnit{
- ConnectFee: 0.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- }); id2 == "" {
- t.Errorf("Expecting id , received: %+v", id2)
- }
-
- if id3 := r1.GetIDWithSet(nil); id3 != "" {
- t.Errorf("Expecting , received: %+v", id3)
- }
-}
-
-func TestRatingClone(t *testing.T) {
- rf1 := Rating{
- "Key1": &RatingUnit{
- ConnectFee: 1.23,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 3.45,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- },
- "Key2": &RatingUnit{
- ConnectFee: 0.2,
- RoundingMethod: "Meth1",
- RoundingDecimals: 4,
- MaxCost: 2.12,
- MaxCostStrategy: "MaxMeth",
- TimingID: "TimingID1",
- RatesID: "RatesID1",
- RatingFiltersID: "RatingFltrID1",
- },
- }
- rf2 := rf1.Clone()
- if !reflect.DeepEqual(rf1, rf2) {
- t.Errorf("Expecting: %+v, received: %+v", rf1, rf2)
- }
- rf1["Key1"].RatesID = "RatesID2"
- if rf2["Key1"].RatesID != "RatesID1" {
- t.Errorf("Expecting RatesID1 , received: %+v", rf2)
- }
-}
-
-//Start tests for ChargedRates
-func TestChargedRatesGetIDWithSet(t *testing.T) {
- cr1 := ChargedRates{
- "Key1": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 0.17,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 0.17,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- },
- "Key2": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 1.12,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: 0,
- Value: 2,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- },
- }
- if id1 := cr1.GetIDWithSet(RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 0.17,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 0.17,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- }); id1 != "Key1" {
- t.Errorf("Expecting: Key1, received: %+v", id1)
- }
-
- id2 := cr1.GetIDWithSet(RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 1,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: 0,
- Value: 2,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- })
- if id2 == "" {
- t.Errorf("Expecting id , received: %+v", id2)
- }
-
- if id3 := cr1.GetIDWithSet(nil); id3 != "" {
- t.Errorf("Expecting , received: %+v", id3)
- }
-}
-
-func TestChargedRatesClone(t *testing.T) {
- cr1 := ChargedRates{
- "Key1": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 0.17,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: 0,
- Value: 0.7,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- },
- "Key2": RateGroups{
- &RGRate{
- GroupIntervalStart: time.Hour,
- Value: 1.12,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- &RGRate{
- GroupIntervalStart: 0,
- Value: 2,
- RateIncrement: time.Second,
- RateUnit: time.Minute,
- },
- },
- }
- cr2 := cr1.Clone()
- if !reflect.DeepEqual(cr1, cr2) {
- t.Errorf("Expecting: %+v, received: %+v", cr1, cr2)
- }
- cr1["Key1"][0].Value = 12.2
- if cr2["Key1"][0].Value != 0.17 {
- t.Errorf("Expecting 0.17 , received: %+v", cr2)
- }
-}
-
-//Start tests for ChargedTimings
-func TestChargedTimingsGetIDWithSet(t *testing.T) {
- ct1 := ChargedTimings{
- "Key1": &ChargedTiming{
- Years: utils.Years{2, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{1, 2, 3, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- },
- "Key2": &ChargedTiming{
- Years: utils.Years{1, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- },
- }
-
- if id1 := ct1.GetIDWithSet(&ChargedTiming{
- Years: utils.Years{2, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{1, 2, 3, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- }); id1 != "Key1" {
- t.Errorf("Expecting: Key1, received: %+v", id1)
- }
-
- if id2 := ct1.GetIDWithSet(&ChargedTiming{
- Years: utils.Years{1, 2, 3},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{1, 2, 3, 5},
- WeekDays: utils.WeekDays{2, 4, 3},
- StartTime: "Time",
- }); id2 == "" {
- t.Errorf("Expecting id , received: %+v", id2)
- }
-
- if id3 := ct1.GetIDWithSet(nil); id3 != "" {
- t.Errorf("Expecting , received: %+v", id3)
- }
-}
-
-func TestChargedTimingsClone(t *testing.T) {
- ct1 := ChargedTimings{
- "Key1": &ChargedTiming{
- Years: utils.Years{2, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{1, 2, 3, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- },
- "Key2": &ChargedTiming{
- Years: utils.Years{1, 2},
- Months: utils.Months{2, 3},
- MonthDays: utils.MonthDays{4, 5},
- WeekDays: utils.WeekDays{2, 3},
- StartTime: "Time",
- },
- }
- ct2 := ct1.Clone()
- if !reflect.DeepEqual(ct1, ct2) {
- t.Errorf("Expecting: %+v, received: %+v", ct1, ct2)
- }
- ct1["Key1"].StartTime = "Time2"
- if ct2["Key1"].StartTime != "Time" {
- t.Errorf("Expecting Time , received: %+v", ct2)
- }
-}
-
-//Start tests for Accounting
-func TestAccountingGetIDWithSet(t *testing.T) {
- a1 := Accounting{
- "Key1": &BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- },
- "Key2": &BalanceCharge{
- AccountID: "1002",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 1.23,
- ExtraChargeID: "Extra1",
- },
- }
-
- if id1 := a1.GetIDWithSet(&BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }); id1 != "Key1" {
- t.Errorf("Expecting: Key1, received: %+v", id1)
- }
-
- if id2 := a1.GetIDWithSet(&BalanceCharge{
- AccountID: "1002",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- }); id2 == "" {
- t.Errorf("Expecting id , received: %+v", id2)
- }
-
- if id3 := a1.GetIDWithSet(nil); id3 != "" {
- t.Errorf("Expecting , received: %+v", id3)
- }
-}
-
-func TestAccountingClone(t *testing.T) {
- a1 := Accounting{
- "Key1": &BalanceCharge{
- AccountID: "1001",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 2.34,
- ExtraChargeID: "Extra1",
- },
- "Key2": &BalanceCharge{
- AccountID: "1002",
- BalanceUUID: "ASD_FGH",
- RatingID: "Rating1001",
- Units: 1.23,
- ExtraChargeID: "Extra1",
- },
- }
- a2 := a1.Clone()
- if !reflect.DeepEqual(a1, a2) {
- t.Errorf("Expecting: %+v, received: %+v", a1, a2)
- }
- a1["Key1"].AccountID = "1004"
- if a2["Key1"].AccountID != "1001" {
- t.Errorf("Expecting 1001 , received: %+v", a2)
- }
-}
diff --git a/engine/libtest.go b/engine/libtest.go
index 2f14848b0..f9efe68ea 100644
--- a/engine/libtest.go
+++ b/engine/libtest.go
@@ -371,10 +371,6 @@ func CallScript(scriptPath string, subcommand string, waitMs int) error {
func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats {
return map[string]*ltcache.CacheStats{
utils.MetaDefault: {},
- utils.CacheAccountActionPlans: {},
- utils.CacheActionPlans: {},
- utils.CacheActionTriggers: {},
- utils.CacheActions: {},
utils.CacheAttributeFilterIndexes: {},
utils.CacheAttributeProfiles: {},
utils.CacheChargerFilterIndexes: {},
@@ -388,14 +384,11 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats {
utils.CacheDestinations: {},
utils.CacheEventResources: {},
utils.CacheFilters: {},
- utils.CacheRatingPlans: {},
- utils.CacheRatingProfiles: {},
utils.CacheResourceFilterIndexes: {},
utils.CacheResourceProfiles: {},
utils.CacheResources: {},
utils.CacheReverseDestinations: {},
utils.CacheRPCResponses: {},
- utils.CacheSharedGroups: {},
utils.CacheStatFilterIndexes: {},
utils.CacheStatQueueProfiles: {},
utils.CacheStatQueues: {},
@@ -414,7 +407,6 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats {
utils.CacheLoadIDs: {},
utils.CacheRPCConnections: {},
utils.CacheCDRIDs: {},
- utils.CacheRatingProfilesTmp: {},
utils.CacheUCH: {},
utils.CacheEventCharges: {},
utils.CacheReverseFilterIndexes: {},
@@ -426,33 +418,23 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats {
utils.CacheAccountProfilesFilterIndexes: {},
utils.CacheReplicationHosts: {},
- 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.CacheTBLTPRateProfiles: {},
- utils.CacheTBLTPActionProfiles: {},
- utils.CacheTBLTPAccountProfiles: {},
+ utils.CacheVersions: {},
+ utils.CacheTBLTPTimings: {},
+ utils.CacheTBLTPDestinations: {},
+ utils.CacheTBLTPResources: {},
+ utils.CacheTBLTPStats: {},
+ utils.CacheTBLTPThresholds: {},
+ utils.CacheTBLTPFilters: {},
+ utils.CacheSessionCostsTBL: {},
+ utils.CacheCDRsTBL: {},
+ utils.CacheTBLTPRoutes: {},
+ utils.CacheTBLTPAttributes: {},
+ utils.CacheTBLTPChargers: {},
+ utils.CacheTBLTPDispatchers: {},
+ utils.CacheTBLTPDispatcherHosts: {},
+ utils.CacheTBLTPRateProfiles: {},
+ utils.CacheTBLTPActionProfiles: {},
+ utils.CacheTBLTPAccountProfiles: {},
}
}
@@ -460,13 +442,6 @@ 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,
diff --git a/engine/mapevent.go b/engine/mapevent.go
index 2cb09dc6c..1a420b2d5 100644
--- a/engine/mapevent.go
+++ b/engine/mapevent.go
@@ -262,11 +262,6 @@ func (me MapEvent) AsCDR(cfg *config.CGRConfig, tnt, tmz string) (cdr *CDR, err
if cdr.Cost, err = utils.IfaceAsFloat64(v); err != nil {
return nil, err
}
- case utils.CostDetails:
- if cdr.CostDetails, err = IfaceAsEventCost(v); err != nil {
- return nil, err
- }
- cdr.CostDetails.initCache()
case utils.ExtraInfo:
cdr.ExtraInfo = utils.IfaceAsString(v)
case utils.OrderID:
diff --git a/engine/model_helpers.go b/engine/model_helpers.go
index 5efe246b5..2dd0ca59a 100644
--- a/engine/model_helpers.go
+++ b/engine/model_helpers.go
@@ -261,105 +261,6 @@ func APItoModelTimings(ts []*utils.ApierTPTiming) (result TimingMdls) {
return result
}
-type ActionMdls []ActionMdl
-
-func (tps ActionMdls) AsMapTPActions() (result map[string]*utils.TPActions) {
- result = make(map[string]*utils.TPActions)
- for _, tp := range tps {
- as := &utils.TPActions{
- TPid: tp.Tpid,
- ID: tp.Tag,
- }
- a := &utils.TPAction{
- Identifier: tp.Action,
- BalanceId: tp.BalanceTag,
- BalanceType: tp.BalanceType,
- Units: tp.Units,
- ExpiryTime: tp.ExpiryTime,
- Filter: tp.Filter,
- TimingTags: tp.TimingTags,
- DestinationIds: tp.DestinationTags,
- RatingSubject: tp.RatingSubject,
- Categories: tp.Categories,
- SharedGroups: tp.SharedGroups,
- BalanceWeight: tp.BalanceWeight,
- BalanceBlocker: tp.BalanceBlocker,
- BalanceDisabled: tp.BalanceDisabled,
- ExtraParameters: tp.ExtraParameters,
- Weight: tp.Weight,
- }
- if existing, exists := result[as.ID]; !exists {
- as.Actions = []*utils.TPAction{a}
- result[as.ID] = as
- } else {
- existing.Actions = append(existing.Actions, a)
- }
- }
- return
-}
-
-func (tps ActionMdls) AsTPActions() (result []*utils.TPActions) {
- for _, tp := range tps.AsMapTPActions() {
- result = append(result, tp)
- }
- return result
-}
-
-func MapTPActions(s []*utils.TPActions) map[string][]*utils.TPAction {
- result := make(map[string][]*utils.TPAction)
- for _, e := range s {
- for _, a := range e.Actions {
- if _, found := result[e.ID]; !found {
- result[e.ID] = []*utils.TPAction{a}
- } else {
- result[e.ID] = append(result[e.ID], a)
- }
- }
- }
- return result
-}
-
-func APItoModelAction(as *utils.TPActions) (result ActionMdls) {
- if as != nil {
- for _, a := range as.Actions {
- result = append(result, ActionMdl{
- Tpid: as.TPid,
- Tag: as.ID,
- Action: a.Identifier,
- BalanceTag: a.BalanceId,
- BalanceType: a.BalanceType,
- Units: a.Units,
- ExpiryTime: a.ExpiryTime,
- Filter: a.Filter,
- TimingTags: a.TimingTags,
- DestinationTags: a.DestinationIds,
- RatingSubject: a.RatingSubject,
- Categories: a.Categories,
- SharedGroups: a.SharedGroups,
- BalanceWeight: a.BalanceWeight,
- BalanceBlocker: a.BalanceBlocker,
- BalanceDisabled: a.BalanceDisabled,
- ExtraParameters: a.ExtraParameters,
- Weight: a.Weight,
- })
- }
- if len(as.Actions) == 0 {
- result = append(result, ActionMdl{
- Tpid: as.TPid,
- Tag: as.ID,
- })
- }
- }
- return
-}
-
-func APItoModelActions(as []*utils.TPActions) (result ActionMdls) {
- for _, a := range as {
- result = append(result, APItoModelAction(a)...)
- }
- return result
-}
-
type ResourceMdls []*ResourceMdl
// CSVHeader return the header for csv fields as a slice of string
@@ -815,7 +716,7 @@ type ThresholdMdls []*ThresholdMdl
func (tps ThresholdMdls) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, utils.ActivationIntervalString,
utils.MaxHits, utils.MinHits, utils.MinSleep,
- utils.Blocker, utils.Weight, utils.ActionIDs, utils.Async}
+ utils.Blocker, utils.Weight, utils.ActionProfileIDs, utils.Async}
}
func (tps ThresholdMdls) AsTPThreshold() (result []*utils.TPThresholdProfile) {
diff --git a/engine/models.go b/engine/models.go
index 5946914af..4f54dc731 100644
--- a/engine/models.go
+++ b/engine/models.go
@@ -19,8 +19,6 @@ along with this program. If not, see
package engine
import (
- "fmt"
- "strings"
"time"
"github.com/cgrates/cgrates/utils"
@@ -57,188 +55,6 @@ func (DestinationMdl) TableName() string {
return utils.TBLTPDestinations
}
-type RateMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*"`
- ConnectFee float64 `index:"1" re:"\d+\.*\d*s*"`
- Rate float64 `index:"2" re:"\d+\.*\d*s*"`
- RateUnit string `index:"3" re:"\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*"`
- RateIncrement string `index:"4" re:"\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*"`
- GroupIntervalStart string `index:"5" re:"\d+\.*\d*(ns|us|µs|ms|s|m|h)*\s*"`
- CreatedAt time.Time
-}
-
-func (RateMdl) TableName() string {
- return utils.TBLTPRates
-}
-
-type DestinationRateMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*"`
- DestinationsTag string `index:"1" re:"\w+\s*|\*any"`
- RatesTag string `index:"2" re:"\w+\s*"`
- RoundingMethod string `index:"3" re:"\*up|\*down|\*middle"`
- RoundingDecimals int `index:"4" re:"\d+"`
- MaxCost float64 `index:"5" re:"\d+\.*\d*s*"`
- MaxCostStrategy string `index:"6" re:"\*free|\*disconnect"`
- CreatedAt time.Time
-}
-
-func (DestinationRateMdl) TableName() string {
- return utils.TBLTPDestinationRates
-}
-
-type RatingPlanMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*,\s*"`
- DestratesTag string `index:"1" re:"\w+\s*,\s*|\*any"`
- TimingTag string `index:"2" re:"\w+\s*,\s*|\*any"`
- Weight float64 `index:"3" re:"\d+.?\d*"`
- CreatedAt time.Time
-}
-
-func (RatingPlanMdl) TableName() string {
- return utils.TBLTPRatingPlans
-}
-
-type RatingProfileMdl struct {
- Id int64
- Tpid string
- Loadid string
- Tenant string `index:"0" re:"[0-9A-Za-z_\.]+\s*"`
- Category string `index:"1" re:"\w+\s*"`
- Subject string `index:"2" re:"\*any\s*|(\w+;?)+\s*"`
- ActivationTime string `index:"3" re:"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z"`
- RatingPlanTag string `index:"4" re:"\w+\s*"`
- FallbackSubjects string `index:"5" re:"\w+\s*"`
- CreatedAt time.Time
-}
-
-func (RatingProfileMdl) TableName() string {
- return utils.TBLTPRatingProfiles
-}
-
-type ActionMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*"`
- Action string `index:"1" re:"\*\w+\s*"`
- ExtraParameters string `index:"2" re:"\S+\s*"`
- Filter string `index:"3" re:"\S+\s*"`
- BalanceTag string `index:"4" re:"\w+\s*"`
- BalanceType string `index:"5" re:"\*\w+\s*"`
- Categories string `index:"6" re:""`
- DestinationTags string `index:"7" re:"\*any|\w+\s*"`
- RatingSubject string `index:"8" re:"\w+\s*"`
- SharedGroups string `index:"9" re:"[0-9A-Za-z_;]*"`
- ExpiryTime string `index:"10" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
- TimingTags string `index:"11" re:"[0-9A-Za-z_;]*|\*any"`
- Units string `index:"12" re:"\d+\s*"`
- BalanceWeight string `index:"13" re:"\d+\.?\d*\s*"`
- BalanceBlocker string `index:"14" re:""`
- BalanceDisabled string `index:"15" re:""`
- Weight float64 `index:"16" re:"\d+\.?\d*\s*"`
- CreatedAt time.Time
-}
-
-func (ActionMdl) TableName() string {
- return utils.TBLTPActions
-}
-
-type ActionPlanMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*,\s*"`
- ActionsTag string `index:"1" re:"\w+\s*,\s*"`
- TimingTag string `index:"2" re:"\w+\s*,\s*"|\*any`
- Weight float64 `index:"3" re:"\d+\.?\d*"`
- CreatedAt time.Time
-}
-
-func (ActionPlanMdl) TableName() string {
- return utils.TBLTPActionPlans
-}
-
-type ActionTriggerMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+"`
- UniqueId string `index:"1" re:"\w+"`
- ThresholdType string `index:"2" re:"\*\w+"`
- ThresholdValue float64 `index:"3" re:"\d+\.?\d*"`
- Recurrent bool `index:"4" re:"true|false|"`
- MinSleep string `index:"5" re:"\d+[smh]?"`
- ExpiryTime string `index:"6" re:""`
- ActivationTime string `index:"7" re:""`
- BalanceTag string `index:"8" re:"\w+\s*"`
- BalanceType string `index:"9" re:"\*\w+"`
- BalanceCategories string `index:"10" re:""`
- BalanceDestinationTags string `index:"11" re:"\w+|\*any"`
- BalanceRatingSubject string `index:"12" re:"\w+|\*any"`
- BalanceSharedGroups string `index:"13" re:"\w+|\*any"`
- BalanceExpiryTime string `index:"14" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
- BalanceTimingTags string `index:"15" re:"[0-9A-Za-z_;]*|\*any"`
- BalanceWeight string `index:"16" re:"\d+\.?\d*"`
- BalanceBlocker string `index:"17" re:""`
- BalanceDisabled string `index:"18" re:""`
- ActionsTag string `index:"19" re:"\w+"`
- Weight float64 `index:"20" re:"\d+\.?\d*"`
- CreatedAt time.Time
-}
-
-func (ActionTriggerMdl) TableName() string {
- return utils.TBLTPActionTriggers
-}
-
-type AccountActionMdl struct {
- Id int64
- Tpid string
- Loadid string
- Tenant string `index:"0" re:"\w+\s*"`
- Account string `index:"1" re:"(\w+;?)+\s*"`
- ActionPlanTag string `index:"2" re:"\w+\s*"`
- ActionTriggersTag string `index:"3" re:"\w+\s*"`
- AllowNegative bool `index:"4" re:""`
- Disabled bool `index:"5" re:""`
- CreatedAt time.Time
-}
-
-func (AccountActionMdl) TableName() string {
- return utils.TBLTPAccountActions
-}
-
-func (aa *AccountActionMdl) SetAccountActionId(id string) error {
- ids := strings.Split(id, utils.ConcatenatedKeySep)
- if len(ids) != 3 {
- return fmt.Errorf("Wrong TP Account Action Id: %s", id)
- }
- aa.Loadid = ids[0]
- aa.Tenant = ids[1]
- aa.Account = ids[2]
- return nil
-}
-
-func (aa *AccountActionMdl) GetAccountActionId() string {
- return utils.ConcatenatedKey(aa.Tenant, aa.Account)
-}
-
-type SharedGroupMdl struct {
- Id int64
- Tpid string
- Tag string `index:"0" re:"\w+\s*"`
- Account string `index:"1" re:"\*?\w+\s*"`
- Strategy string `index:"2" re:"\*\w+\s*"`
- RatingSubject string `index:"3" re:"\*?\w]+\s*"`
- CreatedAt time.Time
-}
-
-func (SharedGroupMdl) TableName() string {
- return utils.TBLTPSharedGroups
-}
-
type ResourceMdl struct {
PK uint `gorm:"primary_key"`
Tpid string
diff --git a/engine/rateinterval.go b/engine/rateinterval.go
deleted file mode 100644
index cf1e4866b..000000000
--- a/engine/rateinterval.go
+++ /dev/null
@@ -1,294 +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 (
- "fmt"
- "sort"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-type RGRate struct {
- GroupIntervalStart time.Duration
- Value float64
- RateIncrement time.Duration
- RateUnit time.Duration
-}
-
-// FieldAsInterface func to help EventCost FieldAsInterface
-func (r *RGRate) FieldAsInterface(fldPath []string) (val interface{}, err error) {
- if r == nil || len(fldPath) != 1 {
- return nil, utils.ErrNotFound
- }
- switch fldPath[0] {
- default:
- return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0])
- case utils.GroupIntervalStart:
- return r.GroupIntervalStart, nil
- case utils.Value:
- return r.Value, nil
- case utils.RateIncrement:
- return r.RateIncrement, nil
- case utils.RateUnit:
- return r.RateUnit, nil
- }
-}
-
-func (r *RGRate) Stringify() string {
- return utils.Sha1(fmt.Sprintf("%v", r))[:8]
-}
-
-func (p *RGRate) Equal(o *RGRate) bool {
- return p.GroupIntervalStart == o.GroupIntervalStart &&
- p.Value == o.Value &&
- p.RateIncrement == o.RateIncrement &&
- p.RateUnit == o.RateUnit
-}
-
-type RateGroups []*RGRate
-
-func (pg RateGroups) Len() int {
- return len(pg)
-}
-
-func (pg RateGroups) Swap(i, j int) {
- pg[i], pg[j] = pg[j], pg[i]
-}
-
-func (pg RateGroups) Less(i, j int) bool {
- return pg[i].GroupIntervalStart < pg[j].GroupIntervalStart
-}
-
-func (pg RateGroups) Sort() {
- sort.Sort(pg)
-}
-
-func (pg RateGroups) Equal(og RateGroups) bool {
- if len(pg) != len(og) {
- return false
- }
- for i := 0; i < len(pg); i++ {
- if !pg[i].Equal(og[i]) {
- return false
- }
- }
- return true
-}
-
-func (pg *RateGroups) AddRate(ps ...*RGRate) {
- for _, p := range ps {
- found := false
- for _, op := range *pg {
- if op.Equal(p) {
- found = true
- break
- }
- }
- if !found {
- *pg = append(*pg, p)
- }
- }
-}
-
-func (pg RateGroups) Equals(oRG RateGroups) bool {
- if len(pg) != len(oRG) {
- return false
- }
- for i := range pg {
- if !pg[i].Equal(oRG[i]) {
- return false
- }
- }
- return true
-}
-
-func (pg RateGroups) Clone() (cln RateGroups) {
- cln = make(RateGroups, len(pg))
- for i, rt := range pg {
- cln[i] = new(RGRate)
- *cln[i] = *rt
- }
- return
-}
-
-func (i *RateInterval) GetCost(duration, startSecond time.Duration) float64 {
- price, _, rateUnit := i.GetRateParameters(startSecond)
- price /= float64(rateUnit.Nanoseconds())
- d := float64(duration.Nanoseconds())
- return utils.Round(d*price, globalRoundingDecimals, utils.MetaRoundingMiddle)
-}
-
-// Gets the price for a the provided start second
-func (i *RateInterval) GetRateParameters(startSecond time.Duration) (rate float64, rateIncrement, rateUnit time.Duration) {
- if i.Rating == nil {
- return -1, -1, -1
- }
- i.Rating.Rates.Sort()
- for index, price := range i.Rating.Rates {
- if price.GroupIntervalStart <= startSecond && (index == len(i.Rating.Rates)-1 ||
- i.Rating.Rates[index+1].GroupIntervalStart > startSecond) {
- if price.RateIncrement == 0 {
- price.RateIncrement = 1 * time.Second
- }
- if price.RateUnit == 0 {
- price.RateUnit = 1 * time.Second
- }
- return price.Value, price.RateIncrement, price.RateUnit
- }
- }
- return -1, -1, -1
-}
-
-func (ri *RateInterval) GetMaxCost() (float64, string) {
- if ri.Rating == nil {
- return 0.0, ""
- }
- return ri.Rating.MaxCost, ri.Rating.MaxCostStrategy
-}
-
-// Structure to store intervals according to weight
-type RateIntervalList []*RateInterval
-
-func (rl RateIntervalList) GetWeight() float64 {
- // all reates should have the same weight
- // just in case get the max
- var maxWeight float64
- for _, r := range rl {
- if r.Weight > maxWeight {
- maxWeight = r.Weight
- }
- }
- return maxWeight
-}
-
-// Structure to store intervals according to weight
-type RateIntervalTimeSorter struct {
- referenceTime time.Time
- ris []*RateInterval
-}
-
-func (il *RateIntervalTimeSorter) Len() int {
- return len(il.ris)
-}
-
-func (il *RateIntervalTimeSorter) Swap(i, j int) {
- il.ris[i], il.ris[j] = il.ris[j], il.ris[i]
-}
-
-// we need higher weights earlyer in the list
-func (il *RateIntervalTimeSorter) Less(j, i int) bool {
- if il.ris[i].Weight < il.ris[j].Weight {
- return il.ris[i].Weight < il.ris[j].Weight
- }
- t1 := il.ris[i].Timing.getLeftMargin(il.referenceTime)
- t2 := il.ris[j].Timing.getLeftMargin(il.referenceTime)
- return t1.After(t2)
-}
-
-func (il *RateIntervalTimeSorter) Sort() []*RateInterval {
- sort.Sort(il)
- return il.ris
-}
-
-// Clone clones RateInterval
-func (i *RateInterval) Clone() (cln *RateInterval) {
- if i == nil {
- return
- }
- cln = &RateInterval{
- Timing: i.Timing.Clone(),
- Rating: i.Rating.Clone(),
- Weight: i.Weight,
- }
- return
-}
-
-// Clone clones RITiming
-func (rit *RITiming) Clone() (cln *RITiming) {
- if rit == nil {
- return
- }
- cln = &RITiming{
- ID: rit.ID,
- StartTime: rit.StartTime,
- EndTime: rit.EndTime,
- }
- if len(rit.Years) != 0 {
- cln.Years = make(utils.Years, len(rit.Years))
- for i, year := range rit.Years {
- cln.Years[i] = year
- }
- }
- if len(rit.Months) != 0 {
- cln.Months = make(utils.Months, len(rit.Months))
- for i, month := range rit.Months {
- cln.Months[i] = month
- }
- }
- if len(rit.MonthDays) != 0 {
- cln.MonthDays = make(utils.MonthDays, len(rit.MonthDays))
- for i, monthDay := range rit.MonthDays {
- cln.MonthDays[i] = monthDay
- }
- }
- if len(rit.WeekDays) != 0 {
- cln.WeekDays = make(utils.WeekDays, len(rit.WeekDays))
- for i, weekDay := range rit.WeekDays {
- cln.WeekDays[i] = weekDay
- }
- }
- return
-}
-
-// Clone clones RIRate
-func (rit *RIRate) Clone() (cln *RIRate) {
- if rit == nil {
- return
- }
- cln = &RIRate{
- ConnectFee: rit.ConnectFee,
- RoundingMethod: rit.RoundingMethod,
- RoundingDecimals: rit.RoundingDecimals,
- MaxCost: rit.MaxCost,
- MaxCostStrategy: rit.MaxCostStrategy,
- }
- if rit.Rates != nil {
- cln.Rates = make([]*RGRate, len(rit.Rates))
- for i, rate := range rit.Rates {
- cln.Rates[i] = rate.Clone()
- }
- }
- return cln
-}
-
-// Clone clones Rates
-func (r *RGRate) Clone() (cln *RGRate) {
- if r == nil {
- return
- }
- cln = &RGRate{
- GroupIntervalStart: r.GroupIntervalStart,
- Value: r.Value,
- RateIncrement: r.RateIncrement,
- RateUnit: r.RateUnit,
- }
- return
-}
diff --git a/engine/ratingprofile.go b/engine/ratingprofile.go
deleted file mode 100644
index 2649759c0..000000000
--- a/engine/ratingprofile.go
+++ /dev/null
@@ -1,98 +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 (
- "encoding/json"
- "sort"
- "time"
-)
-
-type RatingInfo struct {
- MatchedSubject string
- RatingPlanId string
- MatchedPrefix string
- MatchedDestId string
- ActivationTime time.Time
- RateIntervals RateIntervalList
- FallbackKeys []string
-}
-
-// SelectRatingIntevalsForTimespan orders rate intervals in time preserving only those which aply to the specified timestamp
-func (ri RatingInfo) SelectRatingIntevalsForTimespan(ts *TimeSpan) (result RateIntervalList) {
- sorter := &RateIntervalTimeSorter{referenceTime: ts.TimeStart, ris: ri.RateIntervals}
- rateIntervals := sorter.Sort()
- // get the rating interval closest to begining of timespan
- var delta time.Duration = -1
- var bestRateIntervalIndex int
- var bestIntervalWeight float64
- for index, rateInterval := range rateIntervals {
- if !rateInterval.Contains(ts.TimeStart, false) {
- continue
- }
- if rateInterval.Weight < bestIntervalWeight {
- break // don't consider lower weights'
- }
- startTime := rateInterval.Timing.getLeftMargin(ts.TimeStart)
- tmpDelta := ts.TimeStart.Sub(startTime)
- if (startTime.Before(ts.TimeStart) ||
- startTime.Equal(ts.TimeStart)) &&
- (delta == -1 || tmpDelta < delta) {
- bestRateIntervalIndex = index
- bestIntervalWeight = rateInterval.Weight
- delta = tmpDelta
- }
- }
- result = append(result, rateIntervals[bestRateIntervalIndex])
- // check if later rating intervals influence this timespan
- //log.Print("RIS: ", utils.ToIJSON(rateIntervals))
- for i := bestRateIntervalIndex + 1; i < len(rateIntervals); i++ {
- if rateIntervals[i].Weight < bestIntervalWeight {
- break // don't consider lower weights'
- }
- startTime := rateIntervals[i].Timing.getLeftMargin(ts.TimeStart)
- if startTime.Before(ts.TimeEnd) {
- result = append(result, rateIntervals[i])
- }
- }
- return
-}
-
-type RatingInfos []*RatingInfo
-
-func (ris RatingInfos) Len() int {
- return len(ris)
-}
-
-func (ris RatingInfos) Swap(i, j int) {
- ris[i], ris[j] = ris[j], ris[i]
-}
-
-func (ris RatingInfos) Less(i, j int) bool {
- return ris[i].ActivationTime.Before(ris[j].ActivationTime)
-}
-
-func (ris RatingInfos) Sort() {
- sort.Sort(ris)
-}
-
-func (ris RatingInfos) String() string {
- b, _ := json.MarshalIndent(ris, "", " ")
- return string(b)
-}
diff --git a/engine/routes.go b/engine/routes.go
index 4f00a3576..2704f29c2 100644
--- a/engine/routes.go
+++ b/engine/routes.go
@@ -193,19 +193,19 @@ func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
utils.Destination, utils.SetupTime}); err != nil {
return
}
- var acnt, subj, dst string
- if acnt, err = ev.FieldAsString(utils.AccountField); err != nil {
- return
- }
- if subj, err = ev.FieldAsString(utils.Subject); err != nil {
- if err != utils.ErrNotFound {
- return
- }
- subj = acnt
- }
- if dst, err = ev.FieldAsString(utils.Destination); err != nil {
- return
- }
+ // var acnt , subj, dst string
+ // if acnt, err = ev.FieldAsString(utils.AccountField); err != nil {
+ // return
+ // }
+ // if subj, err = ev.FieldAsString(utils.Subject); err != nil {
+ // if err != utils.ErrNotFound {
+ // return
+ // }
+ // subj = acnt
+ // }
+ // if dst, err = ev.FieldAsString(utils.Destination); err != nil {
+ // return
+ // }
var sTime time.Time
if sTime, err = ev.FieldAsTime(utils.SetupTime, rpS.cgrcfg.GeneralCfg().DefaultTimezone); err != nil {
return
@@ -223,17 +223,17 @@ func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
var acntCost map[string]interface{}
var initialUsage time.Duration
if len(acntIDs) != 0 {
- if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetMaxSessionTimeOnAccounts,
- &utils.GetMaxSessionTimeOnAccountsArgs{
- Tenant: ev.Tenant,
- Subject: subj,
- Destination: dst,
- SetupTime: sTime,
- Usage: usage,
- AccountIDs: acntIDs,
- }, &acntCost); err != nil {
- return nil, err
- }
+ // if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetMaxSessionTimeOnAccounts,
+ // &utils.GetMaxSessionTimeOnAccountsArgs{
+ // Tenant: ev.Tenant,
+ // Subject: subj,
+ // Destination: dst,
+ // SetupTime: sTime,
+ // Usage: usage,
+ // AccountIDs: acntIDs,
+ // }, &acntCost); err != nil {
+ // return nil, err
+ // }
if ifaceMaxUsage, has := acntCost[utils.CapMaxUsage]; has {
if accountMaxUsage, err = utils.IfaceAsDuration(ifaceMaxUsage); err != nil {
return nil, err
@@ -256,18 +256,18 @@ func (rpS *RouteService) costForEvent(ev *utils.CGREvent,
if accountMaxUsage == 0 || accountMaxUsage < initialUsage {
var rpCost map[string]interface{}
- if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetCostOnRatingPlans,
- &utils.GetCostOnRatingPlansArgs{
- Tenant: ev.Tenant,
- Account: acnt,
- Subject: subj,
- Destination: dst,
- SetupTime: sTime,
- Usage: usage,
- RatingPlanIDs: rpIDs,
- }, &rpCost); err != nil {
- return nil, err
- }
+ // if err := rpS.connMgr.Call(rpS.cgrcfg.RouteSCfg().RALsConns, nil, utils.ResponderGetCostOnRatingPlans,
+ // &utils.GetCostOnRatingPlansArgs{
+ // Tenant: ev.Tenant,
+ // Account: acnt,
+ // Subject: subj,
+ // Destination: dst,
+ // SetupTime: sTime,
+ // Usage: usage,
+ // RatingPlanIDs: rpIDs,
+ // }, &rpCost); err != nil {
+ // return nil, err
+ // }
for k, v := range rpCost { // do not overwrite the return map
costData[k] = v
}
@@ -526,17 +526,17 @@ func (attr *ArgsGetRoutes) asOptsGetRoutes() (opts *optsGetRoutes, err error) {
utils.Destination, utils.SetupTime, utils.Usage}); err != nil {
return
}
- // rates.V1CostForEvent
- cd, err := NewCallDescriptorFromCGREvent(attr.CGREvent,
- config.CgrConfig().GeneralCfg().DefaultTimezone)
- if err != nil {
- return nil, err
- }
- cc, err := cd.GetCost()
- if err != nil {
- return nil, err
- }
- opts.maxCost = cc.Cost
+ // ToDoNext: rates.V1CostForEvent
+ // cd, err := NewCallDescriptorFromCGREvent(attr.CGREvent,
+ // config.CgrConfig().GeneralCfg().DefaultTimezone)
+ // if err != nil {
+ // return nil, err
+ // }
+ // cc, err := cd.GetCost()
+ // if err != nil {
+ // return nil, err
+ // }
+ // opts.maxCost = cc.Cost
} else if attr.MaxCost != "" {
if opts.maxCost, err = strconv.ParseFloat(attr.MaxCost,
64); err != nil {
diff --git a/engine/storage_csv.go b/engine/storage_csv.go
index a3c198f31..c7020d92d 100644
--- a/engine/storage_csv.go
+++ b/engine/storage_csv.go
@@ -46,7 +46,6 @@ type CSVStorage struct {
// file names
destinationsFn []string
timingsFn []string
- actionsFn []string
resProfilesFn []string
statsFn []string
thresholdsFn []string
@@ -63,7 +62,7 @@ type CSVStorage struct {
// NewCSVStorage creates a CSV storege that takes the data from the paths specified
func NewCSVStorage(sep rune,
- destinationsFn, timingsFn, actionsFn,
+ destinationsFn, timingsFn,
resProfilesFn, statsFn, thresholdsFn, filterFn, routeProfilesFn,
attributeProfilesFn, chargerProfilesFn, dispatcherProfilesFn, dispatcherHostsFn,
rateProfilesFn, actionProfilesFn, accountProfilesFn []string) *CSVStorage {
@@ -72,7 +71,6 @@ func NewCSVStorage(sep rune,
generator: NewCsvFile,
destinationsFn: destinationsFn,
timingsFn: timingsFn,
- actionsFn: actionsFn,
resProfilesFn: resProfilesFn,
statsFn: statsFn,
thresholdsFn: thresholdsFn,
@@ -96,7 +94,6 @@ func NewFileCSVStorage(sep rune, dataPath string) *CSVStorage {
}
destinationsPaths := appendName(allFoldersPath, utils.DestinationsCsv)
timingsPaths := appendName(allFoldersPath, utils.TimingsCsv)
- actionsPaths := appendName(allFoldersPath, utils.ActionsCsv)
resourcesPaths := appendName(allFoldersPath, utils.ResourcesCsv)
statsPaths := appendName(allFoldersPath, utils.StatsCsv)
thresholdsPaths := appendName(allFoldersPath, utils.ThresholdsCsv)
@@ -112,7 +109,6 @@ func NewFileCSVStorage(sep rune, dataPath string) *CSVStorage {
return NewCSVStorage(sep,
destinationsPaths,
timingsPaths,
- actionsPaths,
resourcesPaths,
statsPaths,
thresholdsPaths,
@@ -130,11 +126,11 @@ func NewFileCSVStorage(sep rune, dataPath string) *CSVStorage {
// NewStringCSVStorage creates a csv storage from strings
func NewStringCSVStorage(sep rune,
- destinationsFn, timingsFn, actionsFn,
+ destinationsFn, timingsFn,
resProfilesFn, statsFn, thresholdsFn, filterFn, routeProfilesFn,
attributeProfilesFn, chargerProfilesFn, dispatcherProfilesFn, dispatcherHostsFn,
rateProfilesFn, actionProfilesFn, accountProfilesFn string) *CSVStorage {
- c := NewCSVStorage(sep, []string{destinationsFn}, []string{timingsFn}, []string{actionsFn},
+ c := NewCSVStorage(sep, []string{destinationsFn}, []string{timingsFn},
[]string{resProfilesFn}, []string{statsFn}, []string{thresholdsFn}, []string{filterFn},
[]string{routeProfilesFn}, []string{attributeProfilesFn}, []string{chargerProfilesFn},
[]string{dispatcherProfilesFn}, []string{dispatcherHostsFn}, []string{rateProfilesFn},
@@ -162,7 +158,6 @@ func NewGoogleCSVStorage(sep rune, spreadsheetID string) (*CSVStorage, error) {
c := NewCSVStorage(sep,
getIfExist(utils.Destinations),
getIfExist(utils.Timings),
- getIfExist(utils.Actions),
getIfExist(utils.Resources),
getIfExist(utils.Stats),
getIfExist(utils.Thresholds),
@@ -189,14 +184,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage {
var destinationsPaths []string
var timingsPaths []string
var ratesPaths []string
- var destinationRatesPaths []string
- var ratingPlansPaths []string
- var ratingProfilesPaths []string
- var sharedGroupsPaths []string
- var actionsPaths []string
- var actionPlansPaths []string
- var actionTriggersPaths []string
- var accountActionsPaths []string
var resourcesPaths []string
var statsPaths []string
var thresholdsPaths []string
@@ -215,14 +202,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage {
destinationsPaths = append(destinationsPaths, joinURL(baseURL, utils.DestinationsCsv))
timingsPaths = append(timingsPaths, joinURL(baseURL, utils.TimingsCsv))
ratesPaths = append(ratesPaths, joinURL(baseURL, utils.RatesCsv))
- destinationRatesPaths = append(destinationRatesPaths, joinURL(baseURL, utils.DestinationRatesCsv))
- ratingPlansPaths = append(ratingPlansPaths, joinURL(baseURL, utils.RatingPlansCsv))
- ratingProfilesPaths = append(ratingProfilesPaths, joinURL(baseURL, utils.RatingProfilesCsv))
- sharedGroupsPaths = append(sharedGroupsPaths, joinURL(baseURL, utils.SharedGroupsCsv))
- actionsPaths = append(actionsPaths, joinURL(baseURL, utils.ActionsCsv))
- actionPlansPaths = append(actionPlansPaths, joinURL(baseURL, utils.ActionPlansCsv))
- actionTriggersPaths = append(actionTriggersPaths, joinURL(baseURL, utils.ActionTriggersCsv))
- accountActionsPaths = append(accountActionsPaths, joinURL(baseURL, utils.AccountActionsCsv))
resourcesPaths = append(resourcesPaths, joinURL(baseURL, utils.ResourcesCsv))
statsPaths = append(statsPaths, joinURL(baseURL, utils.StatsCsv))
thresholdsPaths = append(thresholdsPaths, joinURL(baseURL, utils.ThresholdsCsv))
@@ -244,22 +223,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage {
timingsPaths = append(timingsPaths, baseURL)
case strings.HasSuffix(baseURL, utils.RatesCsv):
ratesPaths = append(ratesPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.DestinationRatesCsv):
- destinationRatesPaths = append(destinationRatesPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.RatingPlansCsv):
- ratingPlansPaths = append(ratingPlansPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.RatingProfilesCsv):
- ratingProfilesPaths = append(ratingProfilesPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.SharedGroupsCsv):
- sharedGroupsPaths = append(sharedGroupsPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.ActionsCsv):
- actionsPaths = append(actionsPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.ActionPlansCsv):
- actionPlansPaths = append(actionPlansPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.ActionTriggersCsv):
- actionTriggersPaths = append(actionTriggersPaths, baseURL)
- case strings.HasSuffix(baseURL, utils.AccountActionsCsv):
- accountActionsPaths = append(accountActionsPaths, baseURL)
case strings.HasSuffix(baseURL, utils.ResourcesCsv):
resourcesPaths = append(resourcesPaths, baseURL)
case strings.HasSuffix(baseURL, utils.StatsCsv):
@@ -291,7 +254,6 @@ func NewURLCSVStorage(sep rune, dataPath string) *CSVStorage {
c := NewCSVStorage(sep,
destinationsPaths,
timingsPaths,
- actionsPaths,
resourcesPaths,
statsPaths,
thresholdsPaths,
@@ -396,18 +358,6 @@ func (csvs *CSVStorage) GetTPDestinations(tpid, id string) ([]*utils.TPDestinati
return tpDests.AsTPDestinations(), nil
}
-func (csvs *CSVStorage) GetTPActions(tpid, id string) ([]*utils.TPActions, error) {
- var tpActions ActionMdls
- if err := csvs.proccesData(ActionMdl{}, csvs.actionsFn, func(tp interface{}) {
- a := tp.(ActionMdl)
- a.Tpid = tpid
- tpActions = append(tpActions, a)
- }); err != nil {
- return nil, err
- }
- return tpActions.AsTPActions(), nil
-}
-
func (csvs *CSVStorage) GetTPResources(tpid, tenant, id string) ([]*utils.TPResourceProfile, error) {
var tpResLimits ResourceMdls
if err := csvs.proccesData(ResourceMdl{}, csvs.resProfilesFn, func(tp interface{}) {
diff --git a/engine/storage_interface.go b/engine/storage_interface.go
index 8468ccfb2..4b678fcc4 100644
--- a/engine/storage_interface.go
+++ b/engine/storage_interface.go
@@ -53,11 +53,6 @@ type DataDB interface {
RemoveReverseDestinationDrv(string, string, string) error
SetReverseDestinationDrv(string, []string, string) error
GetReverseDestinationDrv(string, string) ([]string, error)
- GetActionsDrv(string) (Actions, error)
- SetActionsDrv(string, Actions) error
- RemoveActionsDrv(string) error
- PushTask(*Task) error
- PopTask() (*Task, error)
GetResourceProfileDrv(string, string) (*ResourceProfile, error)
SetResourceProfileDrv(*ResourceProfile) error
RemoveResourceProfileDrv(string, string) error
@@ -126,10 +121,6 @@ type StorDB interface {
type CdrStorage interface {
Storage
SetCDR(*CDR, bool) error
- SetSMCost(smc *SMCost) error
- GetSMCosts(cgrid, runid, originHost, originIDPrfx string) ([]*SMCost, error)
- RemoveSMCost(*SMCost) error
- RemoveSMCosts(qryFltr *utils.SMCostFilter) error
GetCDRs(*utils.CDRsFilter, bool) ([]*CDR, int64, error)
}
@@ -146,7 +137,6 @@ type LoadReader interface {
map[string]string, *utils.PaginatorWithSearch) ([]string, error)
GetTPTimings(string, string) ([]*utils.ApierTPTiming, error)
GetTPDestinations(string, string) ([]*utils.TPDestination, error)
- GetTPActions(string, string) ([]*utils.TPActions, error)
GetTPResources(string, string, string) ([]*utils.TPResourceProfile, error)
GetTPStats(string, string, string) ([]*utils.TPStatProfile, error)
GetTPThresholds(string, string, string) ([]*utils.TPThresholdProfile, error)
@@ -165,7 +155,6 @@ type LoadWriter interface {
RemTpData(string, string, map[string]string) error
SetTPTimings([]*utils.ApierTPTiming) error
SetTPDestinations([]*utils.TPDestination) error
- SetTPActions([]*utils.TPActions) error
SetTPResources([]*utils.TPResourceProfile) error
SetTPStats([]*utils.TPStatProfile) error
SetTPThresholds([]*utils.TPThresholdProfile) error
diff --git a/engine/storage_internal_datadb.go b/engine/storage_internal_datadb.go
index 0442ada98..fafa3521d 100644
--- a/engine/storage_internal_datadb.go
+++ b/engine/storage_internal_datadb.go
@@ -32,7 +32,6 @@ import (
// InternalDB is used as a DataDB and a StorDB
type InternalDB struct {
- tasks []*Task
mu sync.RWMutex
stringIndexedFields []string
prefixIndexedFields []string
@@ -183,8 +182,7 @@ func (iDB *InternalDB) IsDBEmpty() (isEmpty bool, err error) {
func (iDB *InternalDB) HasDataDrv(category, subject, tenant string) (bool, error) {
switch category {
- case utils.DestinationPrefix, utils.RatingPlanPrefix, utils.RatingProfilePrefix,
- utils.ActionPrefix, utils.ActionPlanPrefix, utils.AccountPrefix:
+ case utils.DestinationPrefix:
return Cache.HasItem(utils.CachePrefixToInstance[category], subject), nil
case utils.ResourcesPrefix, utils.ResourceProfilesPrefix, utils.StatQueuePrefix,
utils.StatQueueProfilePrefix, utils.ThresholdPrefix, utils.ThresholdProfilePrefix,
@@ -261,77 +259,6 @@ func (iDB *InternalDB) GetReverseDestinationDrv(prefix, transactionID string) (i
return nil, utils.ErrNotFound
}
-func (iDB *InternalDB) GetActionsDrv(id string) (acts Actions, err error) {
- if x, ok := Cache.Get(utils.CacheActions, id); ok && x != nil {
- return x.(Actions), err
- }
- return nil, utils.ErrNotFound
-}
-
-func (iDB *InternalDB) SetActionsDrv(id string, acts Actions) (err error) {
- Cache.SetWithoutReplicate(utils.CacheActions, id, acts, nil,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return
-}
-
-func (iDB *InternalDB) RemoveActionsDrv(id string) (err error) {
- Cache.RemoveWithoutReplicate(utils.CacheActions, id,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return
-}
-
-func (iDB *InternalDB) PushTask(t *Task) (err error) {
- iDB.mu.Lock()
- iDB.tasks = append(iDB.tasks, t)
- iDB.mu.Unlock()
- return
-}
-
-func (iDB *InternalDB) PopTask() (t *Task, err error) {
- iDB.mu.Lock()
- if len(iDB.tasks) > 0 {
- t = iDB.tasks[0]
- iDB.tasks[0] = nil
- iDB.tasks = iDB.tasks[1:]
- } else {
- err = utils.ErrNotFound
- }
- iDB.mu.Unlock()
- return
-}
-
-func (iDB *InternalDB) GetAccountDrv(id string) (acc *Account, err error) {
- if x, ok := Cache.Get(utils.CacheAccounts, id); ok && x != nil {
- return x.(*Account).Clone(), nil
- }
- return nil, utils.ErrNotFound
-}
-
-func (iDB *InternalDB) SetAccountDrv(acc *Account) (err error) {
- // never override existing account with an empty one
- // UPDATE: if all balances expired and were cleaned it makes
- // sense to write empty balance map
- if len(acc.BalanceMap) == 0 {
- if ac, err := iDB.GetAccountDrv(acc.ID); err == nil && !ac.allBalancesExpired() {
- ac.ActionTriggers = acc.ActionTriggers
- ac.UnitCounters = acc.UnitCounters
- ac.AllowNegative = acc.AllowNegative
- ac.Disabled = acc.Disabled
- acc = ac
- }
- }
- acc.UpdateTime = time.Now()
- Cache.SetWithoutReplicate(utils.CacheAccounts, acc.ID, acc, nil,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return
-}
-
-func (iDB *InternalDB) RemoveAccountDrv(id string) (err error) {
- Cache.RemoveWithoutReplicate(utils.CacheAccounts, id,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return
-}
-
func (iDB *InternalDB) GetResourceProfileDrv(tenant, id string) (rp *ResourceProfile, err error) {
if x, ok := Cache.Get(utils.CacheResourceProfiles, utils.ConcatenatedKey(tenant, id)); ok && x != nil {
return x.(*ResourceProfile), nil
diff --git a/engine/storage_internal_stordb.go b/engine/storage_internal_stordb.go
index 4701eb5f7..8f9a07efe 100644
--- a/engine/storage_internal_stordb.go
+++ b/engine/storage_internal_stordb.go
@@ -49,18 +49,6 @@ func (iDB *InternalDB) GetTpTableIds(tpid, table string, distinct utils.TPDistin
fullIDs := Cache.GetItemIDs(utils.CacheStorDBPartitions[table], tpid)
idSet := make(utils.StringSet)
for _, fullID := range fullIDs {
- switch table {
- // in case of account action and rating profile
- // the retutned value may be only the loadID
- case utils.TBLTPAccountActions, utils.TBLTPRatingProfiles:
- if len(distinct) == 1 { // special case when to return only the loadID
- sliceID := strings.Split(fullID[len(tpid)+1:], utils.ConcatenatedKeySep)
- idSet.Add(sliceID[0])
- continue
- }
- // in the rest of the cases we return all ID every time
- default:
- }
idSet.Add(fullID[len(tpid)+1:])
}
ids = idSet.AsSlice()
@@ -107,26 +95,6 @@ func (iDB *InternalDB) GetTPDestinations(tpid, id string) (dsts []*utils.TPDesti
return
}
-func (iDB *InternalDB) GetTPActions(tpid, id string) (actions []*utils.TPActions, err error) {
- key := tpid
- if id != utils.EmptyString {
- key += utils.ConcatenatedKeySep + id
- }
- ids := Cache.GetItemIDs(utils.CacheTBLTPActions, key)
- for _, id := range ids {
- x, ok := Cache.Get(utils.CacheTBLTPActions, id)
- if !ok || x == nil {
- return nil, utils.ErrNotFound
- }
- actions = append(actions, x.(*utils.TPActions))
-
- }
- if len(actions) == 0 {
- return nil, utils.ErrNotFound
- }
- return
-}
-
func (iDB *InternalDB) GetTPResources(tpid, tenant, id string) (resources []*utils.TPResourceProfile, err error) {
key := tpid
if tenant != utils.EmptyString {
@@ -407,16 +375,7 @@ func (iDB *InternalDB) RemTpData(table, tpid string, args map[string]string) (er
}
key := tpid
if args != nil {
- if table == utils.TBLTPAccountActions {
- key += utils.ConcatenatedKeySep + args["loadid"] +
- utils.ConcatenatedKeySep + args["tenant"] +
- utils.ConcatenatedKeySep + args["account"]
- } else if table == utils.TBLTPRatingProfiles {
- key += utils.ConcatenatedKeySep + args["loadid"] +
- utils.ConcatenatedKeySep + args["tenant"] +
- utils.ConcatenatedKeySep + args["category"] +
- utils.ConcatenatedKeySep + args["subject"]
- } else if tag, has := args["tag"]; has {
+ if tag, has := args["tag"]; has {
key += utils.ConcatenatedKeySep + tag
} else if id, has := args["id"]; has {
key += utils.ConcatenatedKeySep + args["tenant"] +
@@ -452,17 +411,6 @@ func (iDB *InternalDB) SetTPDestinations(dests []*utils.TPDestination) (err erro
return
}
-func (iDB *InternalDB) SetTPActions(acts []*utils.TPActions) (err error) {
- if len(acts) == 0 {
- return nil
- }
- for _, action := range acts {
- Cache.SetWithoutReplicate(utils.CacheTBLTPActions, utils.ConcatenatedKey(action.TPid, action.ID), action, nil,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- }
- return
-}
-
func (iDB *InternalDB) SetTPResources(resources []*utils.TPResourceProfile) (err error) {
if len(resources) == 0 {
return nil
@@ -644,94 +592,6 @@ func (iDB *InternalDB) SetCDR(cdr *CDR, allowUpdate bool) (err error) {
return
}
-func (iDB *InternalDB) RemoveSMCost(smc *SMCost) (err error) {
- Cache.RemoveWithoutReplicate(utils.CacheSessionCostsTBL, utils.ConcatenatedKey(smc.CGRID, smc.RunID, smc.OriginHost, smc.OriginID),
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return
-}
-
-func (iDB *InternalDB) RemoveSMCosts(qryFltr *utils.SMCostFilter) error {
- var smMpIDs utils.StringMap
- // Apply string filter
- for _, fltrSlc := range []struct {
- key string
- ids []string
- }{
- {utils.CGRID, qryFltr.CGRIDs},
- {utils.RunID, qryFltr.RunIDs},
- {utils.OriginID, qryFltr.OriginIDs},
- {utils.OriginHost, qryFltr.OriginHosts},
- {utils.CostSource, qryFltr.CostSources},
- } {
- if len(fltrSlc.ids) == 0 {
- continue
- }
- grpMpIDs := make(utils.StringMap)
- for _, id := range fltrSlc.ids {
- grpIDs := Cache.tCache.GetGroupItemIDs(utils.CacheSessionCostsTBL, utils.ConcatenatedKey(fltrSlc.key, id))
- for _, id := range grpIDs {
- grpMpIDs[id] = true
- }
- }
- if len(grpMpIDs) == 0 {
- return utils.ErrNotFound
- }
- if smMpIDs == nil {
- smMpIDs = grpMpIDs
- } else {
- for id := range smMpIDs {
- if !grpMpIDs.HasKey(id) {
- delete(smMpIDs, id)
- if len(smMpIDs) == 0 {
- return utils.ErrNotFound
- }
- }
- }
- }
- }
-
- if smMpIDs == nil {
- smMpIDs = utils.StringMapFromSlice(Cache.GetItemIDs(utils.CacheSessionCostsTBL, utils.EmptyString))
- }
-
- // check for Not filters
- for _, fltrSlc := range []struct {
- key string
- ids []string
- }{
- {utils.CGRID, qryFltr.NotCGRIDs},
- {utils.RunID, qryFltr.NotRunIDs},
- {utils.OriginID, qryFltr.NotOriginIDs},
- {utils.OriginHost, qryFltr.NotOriginHosts},
- {utils.CostSource, qryFltr.NotCostSources},
- } {
- if len(fltrSlc.ids) == 0 {
- continue
- }
- for _, id := range fltrSlc.ids {
- grpIDs := Cache.tCache.GetGroupItemIDs(utils.CacheCDRsTBL, utils.ConcatenatedKey(fltrSlc.key, id))
- for _, id := range grpIDs {
- if smMpIDs.HasKey(id) {
- delete(smMpIDs, id)
- if len(smMpIDs) == 0 {
- return utils.ErrNotFound
- }
- }
- }
- }
- }
-
- if len(smMpIDs) == 0 {
- return utils.ErrNotFound
- }
-
- for key := range smMpIDs {
- Cache.RemoveWithoutReplicate(utils.CacheSessionCostsTBL, key,
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- }
- return nil
-}
-
// GetCDRs returns the CDRs from DB based on given filters
func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*CDR, count int64, err error) {
// filterPair used only for GetCDRs for internalDB
@@ -1177,74 +1037,3 @@ func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*C
}
return
}
-
-func (iDB *InternalDB) GetSMCosts(cgrid, runid, originHost, originIDPrfx string) (smCosts []*SMCost, err error) {
- var smMpIDs utils.StringMap
- for _, fltrSlc := range []struct {
- key string
- id string
- }{
- {utils.CGRID, cgrid},
- {utils.RunID, runid},
- {utils.OriginHost, originHost},
- } {
- if fltrSlc.id == utils.EmptyString {
- continue
- }
- grpMpIDs := make(utils.StringMap)
-
- grpIDs := Cache.tCache.GetGroupItemIDs(utils.CacheSessionCostsTBL, utils.ConcatenatedKey(fltrSlc.key, fltrSlc.id))
- for _, id := range grpIDs {
- grpMpIDs[id] = true
- }
-
- if len(grpMpIDs) == 0 {
- return nil, utils.ErrNotFound
- }
- if smMpIDs == nil {
- smMpIDs = grpMpIDs
- } else {
- for id := range smMpIDs {
- if !grpMpIDs.HasKey(id) {
- delete(smMpIDs, id)
- if len(smMpIDs) == 0 {
- return nil, utils.ErrNotFound
- }
- }
- }
- }
- }
- if smMpIDs == nil {
- smMpIDs = utils.StringMapFromSlice(Cache.GetItemIDs(utils.CacheSessionCostsTBL, utils.EmptyString))
- }
- if len(smMpIDs) == 0 {
- return nil, utils.ErrNotFound
- }
- for key := range smMpIDs {
- x, ok := Cache.Get(utils.CacheSessionCostsTBL, key)
- if !ok || x == nil {
- return nil, utils.ErrNotFound
- }
- smCost := x.(*SMCost)
- if originIDPrfx != utils.EmptyString && !strings.HasPrefix(smCost.OriginID, originIDPrfx) {
- continue
- }
- smCosts = append(smCosts, smCost)
- }
- return
-}
-
-func (iDB *InternalDB) SetSMCost(smCost *SMCost) (err error) {
- if smCost.CostDetails == nil {
- return nil
- }
- idxs := make(utils.StringSet)
- idxs.Add(utils.ConcatenatedKey(utils.CGRID, smCost.CGRID))
- idxs.Add(utils.ConcatenatedKey(utils.RunID, smCost.RunID))
- idxs.Add(utils.ConcatenatedKey(utils.OriginHost, smCost.OriginHost))
- idxs.Add(utils.ConcatenatedKey(utils.OriginID, smCost.OriginID))
- idxs.Add(utils.ConcatenatedKey(utils.CostSource, smCost.CostSource))
- Cache.SetWithoutReplicate(utils.CacheSessionCostsTBL, utils.ConcatenatedKey(smCost.CGRID, smCost.RunID, smCost.OriginHost, smCost.OriginID), smCost, idxs.AsSlice(),
- cacheCommit(utils.NonTransactional), utils.NonTransactional)
- return err
-}
diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go
index 8927bd780..f99f1d96a 100644
--- a/engine/storage_mongo_datadb.go
+++ b/engine/storage_mongo_datadb.go
@@ -39,7 +39,6 @@ import (
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/x/bsonx"
@@ -325,20 +324,12 @@ func (ms *MongoStorage) ensureIndexesForCol(col string) (err error) { // exporte
}
//StorDB
case utils.TBLTPTimings, utils.TBLTPDestinations,
- utils.TBLTPDestinationRates, utils.TBLTPRatingPlans,
- utils.TBLTPSharedGroups, utils.TBLTPActions,
- utils.TBLTPActionPlans, utils.TBLTPActionTriggers,
utils.TBLTPStats, utils.TBLTPResources, utils.TBLTPDispatchers,
utils.TBLTPDispatcherHosts, utils.TBLTPChargers,
utils.TBLTPRoutes, utils.TBLTPThresholds:
if err = ms.enusureIndex(col, true, "tpid", "id"); err != nil {
return
}
- case utils.TBLTPRatingProfiles:
- if err = ms.enusureIndex(col, true, "tpid", "tenant",
- "category", "subject", "loadid"); err != nil {
- return
- }
case utils.CDRsTBL:
if err = ms.enusureIndex(col, true, CGRIDLow, RunIDLow,
OriginIDLow); err != nil {
@@ -388,11 +379,8 @@ func (ms *MongoStorage) EnsureIndexes(cols ...string) (err error) {
}
if ms.storageType == utils.StorDB {
for _, col := range []string{utils.TBLTPTimings, utils.TBLTPDestinations,
- utils.TBLTPDestinationRates, utils.TBLTPRatingPlans,
- utils.TBLTPSharedGroups, utils.TBLTPActions,
- utils.TBLTPActionPlans, utils.TBLTPActionTriggers,
utils.TBLTPStats, utils.TBLTPResources,
- utils.TBLTPRatingProfiles, utils.CDRsTBL, utils.SessionCostsTBL} {
+ utils.CDRsTBL, utils.SessionCostsTBL} {
if err = ms.ensureIndexesForCol(col); err != nil {
return
}
@@ -436,24 +424,6 @@ func (ms *MongoStorage) RemoveKeysForPrefix(prefix string) (err error) {
colName = ColDst
case utils.ReverseDestinationPrefix:
colName = ColRds
- case utils.ActionPrefix:
- colName = ColAct
- case utils.ActionPlanPrefix:
- colName = ColApl
- case utils.AccountActionPlansPrefix:
- colName = ColAAp
- case utils.TasksKey:
- colName = ColTsk
- case utils.ActionTriggerPrefix:
- colName = ColAtr
- case utils.RatingPlanPrefix:
- colName = ColRpl
- case utils.RatingProfilePrefix:
- colName = ColRpf
- case utils.AccountPrefix:
- colName = ColAcc
- case utils.SharedGroupPrefix:
- colName = ColShg
case utils.LoadInstKey:
colName = ColLht
case utils.VersionPrefix:
@@ -594,23 +564,6 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er
result, err = ms.getField(sctx, ColDst, utils.DestinationPrefix, subject, "key")
case utils.ReverseDestinationPrefix:
result, err = ms.getField(sctx, ColRds, utils.ReverseDestinationPrefix, subject, "key")
- case utils.RatingPlanPrefix:
- result, err = ms.getField(sctx, ColRpl, utils.RatingPlanPrefix, subject, "key")
- case utils.RatingProfilePrefix:
- if strings.HasPrefix(prefix[keyLen:], utils.MetaOut) {
- subject = fmt.Sprintf("^\\%s", prefix[keyLen:]) // rewrite the id cause it start with * from `*out`
- }
- result, err = ms.getField(sctx, ColRpf, utils.RatingProfilePrefix, subject, "id")
- case utils.ActionPrefix:
- result, err = ms.getField(sctx, ColAct, utils.ActionPrefix, subject, "key")
- case utils.ActionPlanPrefix:
- result, err = ms.getField(sctx, ColApl, utils.ActionPlanPrefix, subject, "key")
- case utils.ActionTriggerPrefix:
- result, err = ms.getField(sctx, ColAtr, utils.ActionTriggerPrefix, subject, "key")
- case utils.SharedGroupPrefix:
- result, err = ms.getField(sctx, ColShg, utils.SharedGroupPrefix, subject, "id")
- case utils.AccountPrefix:
- result, err = ms.getField(sctx, ColAcc, utils.AccountPrefix, subject, "id")
case utils.ResourceProfilesPrefix:
result, err = ms.getField2(sctx, ColRsP, utils.ResourceProfilesPrefix, subject, tntID)
case utils.ResourcesPrefix:
@@ -619,8 +572,6 @@ func (ms *MongoStorage) GetKeysForPrefix(prefix string) (result []string, err er
result, err = ms.getField2(sctx, ColSqs, utils.StatQueuePrefix, subject, tntID)
case utils.StatQueueProfilePrefix:
result, err = ms.getField2(sctx, ColSqp, utils.StatQueueProfilePrefix, subject, tntID)
- case utils.AccountActionPlansPrefix:
- result, err = ms.getField(sctx, ColAAp, utils.AccountActionPlansPrefix, subject, "key")
case utils.TimingsPrefix:
result, err = ms.getField(sctx, ColTmg, utils.TimingsPrefix, subject, "id")
case utils.FilterPrefix:
@@ -685,16 +636,6 @@ func (ms *MongoStorage) HasDataDrv(category, subject, tenant string) (has bool,
switch category {
case utils.DestinationPrefix:
count, err = ms.getCol(ColDst).CountDocuments(sctx, bson.M{"key": subject})
- case utils.RatingPlanPrefix:
- count, err = ms.getCol(ColRpl).CountDocuments(sctx, bson.M{"key": subject})
- case utils.RatingProfilePrefix:
- count, err = ms.getCol(ColRpf).CountDocuments(sctx, bson.M{"key": subject})
- case utils.ActionPrefix:
- count, err = ms.getCol(ColAct).CountDocuments(sctx, bson.M{"key": subject})
- case utils.ActionPlanPrefix:
- count, err = ms.getCol(ColApl).CountDocuments(sctx, bson.M{"key": subject})
- case utils.AccountPrefix:
- count, err = ms.getCol(ColAcc).CountDocuments(sctx, bson.M{"id": subject})
case utils.ResourcesPrefix:
count, err = ms.getCol(ColRes).CountDocuments(sctx, bson.M{"tenant": tenant, "id": subject})
case utils.ResourceProfilesPrefix:
@@ -841,50 +782,6 @@ func (ms *MongoStorage) SetReverseDestinationDrv(destID string, prefixes []strin
return nil
}
-func (ms *MongoStorage) GetActionsDrv(key string) (as Actions, err error) {
- var result struct {
- Key string
- Value Actions
- }
- if err = ms.query(func(sctx mongo.SessionContext) (err error) {
- cur := ms.getCol(ColAct).FindOne(sctx, bson.M{"key": key})
- if err := cur.Decode(&result); err != nil {
- if err == mongo.ErrNoDocuments {
- return utils.ErrNotFound
- }
- return err
- }
- return nil
- }); err != nil {
- return nil, err
- }
- as = result.Value
- return
-}
-
-func (ms *MongoStorage) SetActionsDrv(key string, as Actions) error {
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- _, err = ms.getCol(ColAct).UpdateOne(sctx, bson.M{"key": key},
- bson.M{"$set": struct {
- Key string
- Value Actions
- }{Key: key, Value: as}},
- options.Update().SetUpsert(true),
- )
- return err
- })
-}
-
-func (ms *MongoStorage) RemoveActionsDrv(key string) error {
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- dr, err := ms.getCol(ColAct).DeleteOne(sctx, bson.M{"key": key})
- if dr.DeletedCount == 0 {
- return utils.ErrNotFound
- }
- return err
- })
-}
-
// Limit will only retrieve the last n items out of history, newest first
func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool,
transactionID string) (loadInsts []*utils.LoadInstance, err error) {
@@ -990,33 +887,6 @@ func (ms *MongoStorage) AddLoadHistory(ldInst *utils.LoadInstance,
return err
}
-func (ms *MongoStorage) PushTask(t *Task) error {
- return ms.query(func(sctx mongo.SessionContext) error {
- _, err := ms.getCol(ColTsk).InsertOne(sctx, bson.M{"_id": primitive.NewObjectID(), "task": t})
- return err
- })
-}
-
-func (ms *MongoStorage) PopTask() (t *Task, err error) {
- v := struct {
- ID primitive.ObjectID `bson:"_id"`
- Task *Task
- }{}
- if err = ms.query(func(sctx mongo.SessionContext) (err error) {
- cur := ms.getCol(ColTsk).FindOneAndDelete(sctx, bson.D{})
- if err := cur.Decode(&v); err != nil {
- if err == mongo.ErrNoDocuments {
- return utils.ErrNotFound
- }
- return err
- }
- return nil
- }); err != nil {
- return nil, err
- }
- return v.Task, nil
-}
-
func (ms *MongoStorage) GetResourceProfileDrv(tenant, id string) (rp *ResourceProfile, err error) {
rp = new(ResourceProfile)
err = ms.query(func(sctx mongo.SessionContext) (err error) {
diff --git a/engine/storage_mongo_stordb.go b/engine/storage_mongo_stordb.go
index fb716e3cc..a90c30c08 100644
--- a/engine/storage_mongo_stordb.go
+++ b/engine/storage_mongo_stordb.go
@@ -269,33 +269,6 @@ func (ms *MongoStorage) GetTPStats(tpid, tenant, id string) ([]*utils.TPStatProf
return results, err
}
-func (ms *MongoStorage) GetTPActions(tpid, id string) ([]*utils.TPActions, error) {
- filter := bson.M{"tpid": tpid}
- if id != "" {
- filter["id"] = id
- }
- var results []*utils.TPActions
- err := ms.query(func(sctx mongo.SessionContext) (err error) {
- cur, err := ms.getCol(utils.TBLTPActions).Find(sctx, filter)
- if err != nil {
- return err
- }
- for cur.Next(sctx) {
- var el utils.TPActions
- err := cur.Decode(&el)
- if err != nil {
- return err
- }
- results = append(results, &el)
- }
- if len(results) == 0 {
- return utils.ErrNotFound
- }
- return cur.Close(sctx)
- })
- return results, err
-}
-
func (ms *MongoStorage) RemTpData(table, tpid string, args map[string]string) error {
if len(table) == 0 { // Remove tpid out of all tables
return ms.query(func(sctx mongo.SessionContext) error {
@@ -375,27 +348,6 @@ func (ms *MongoStorage) SetTPDestinations(tpDsts []*utils.TPDestination) (err er
})
}
-func (ms *MongoStorage) SetTPActions(tps []*utils.TPActions) error {
- if len(tps) == 0 {
- return nil
- }
- m := make(map[string]bool)
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- for _, tp := range tps {
- if !m[tp.ID] {
- m[tp.ID] = true
- if _, err := ms.getCol(utils.TBLTPActions).DeleteMany(sctx, bson.M{"tpid": tp.TPid, "id": tp.ID}); err != nil {
- return err
- }
- }
- if _, err := ms.getCol(utils.TBLTPActions).InsertOne(sctx, tp); err != nil {
- return err
- }
- }
- return nil
- })
-}
-
func (ms *MongoStorage) SetTPResources(tpRLs []*utils.TPResourceProfile) (err error) {
if len(tpRLs) == 0 {
return
@@ -428,81 +380,6 @@ func (ms *MongoStorage) SetTPRStats(tps []*utils.TPStatProfile) (err error) {
})
}
-func (ms *MongoStorage) SetSMCost(smc *SMCost) error {
- if smc.CostDetails == nil {
- return nil
- }
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- _, err = ms.getCol(utils.SessionCostsTBL).InsertOne(sctx, smc)
- return err
- })
-}
-
-func (ms *MongoStorage) RemoveSMCost(smc *SMCost) error {
- remParams := bson.M{}
- if smc != nil {
- remParams = bson.M{"cgrid": smc.CGRID, "runid": smc.RunID}
- }
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- _, err = ms.getCol(utils.SessionCostsTBL).DeleteMany(sctx, remParams)
- return err
- })
-}
-
-func (ms *MongoStorage) GetSMCosts(cgrid, runid, originHost, originIDPrefix string) (smcs []*SMCost, err error) {
- filter := bson.M{}
- if cgrid != "" {
- filter[CGRIDLow] = cgrid
- }
- if runid != "" {
- filter[RunIDLow] = runid
- }
- if originHost != "" {
- filter[OriginHostLow] = originHost
- }
- if originIDPrefix != "" {
- filter[OriginIDLow] = bsonx.Regex(fmt.Sprintf("^%s", originIDPrefix), "")
- }
- err = ms.query(func(sctx mongo.SessionContext) (err error) {
- cur, err := ms.getCol(utils.SessionCostsTBL).Find(sctx, filter)
- if err != nil {
- return err
- }
- for cur.Next(sctx) {
- var smCost SMCost
- err := cur.Decode(&smCost)
- if err != nil {
- return err
- }
- clone := smCost
- clone.CostDetails.initCache()
- smcs = append(smcs, &clone)
- }
- if len(smcs) == 0 {
- return utils.ErrNotFound
- }
- return cur.Close(sctx)
- })
- return smcs, err
-}
-
-func (ms *MongoStorage) RemoveSMCosts(qryFltr *utils.SMCostFilter) error {
- filters := bson.M{
- CGRIDLow: bson.M{"$in": qryFltr.CGRIDs, "$nin": qryFltr.NotCGRIDs},
- RunIDLow: bson.M{"$in": qryFltr.RunIDs, "$nin": qryFltr.NotRunIDs},
- OriginHostLow: bson.M{"$in": qryFltr.OriginHosts, "$nin": qryFltr.NotOriginHosts},
- OriginIDLow: bson.M{"$in": qryFltr.OriginIDs, "$nin": qryFltr.NotOriginIDs},
- CostSourceLow: bson.M{"$in": qryFltr.CostSources, "$nin": qryFltr.NotCostSources},
- UsageLow: bson.M{"$gte": qryFltr.Usage.Min, "$lt": qryFltr.Usage.Max},
- CreatedAtLow: bson.M{"$gte": qryFltr.CreatedAt.Begin, "$lt": qryFltr.CreatedAt.End},
- }
- ms.cleanEmptyFilters(filters)
- return ms.query(func(sctx mongo.SessionContext) (err error) {
- _, err = ms.getCol(utils.SessionCostsTBL).DeleteMany(sctx, filters)
- return err
- })
-}
-
func (ms *MongoStorage) SetCDR(cdr *CDR, allowUpdate bool) error {
if cdr.OrderID == 0 {
cdr.OrderID = ms.cnter.Next()
@@ -735,7 +612,6 @@ func (ms *MongoStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR,
return err
}
clone := cdr
- clone.CostDetails.initCache()
cdrs = append(cdrs, &clone)
}
if len(cdrs) == 0 {
diff --git a/engine/storage_redis.go b/engine/storage_redis.go
index f9f226f45..a4468c1c7 100644
--- a/engine/storage_redis.go
+++ b/engine/storage_redis.go
@@ -32,7 +32,6 @@ import (
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/guardian"
"github.com/cgrates/cgrates/utils"
- "github.com/cgrates/ltcache"
"github.com/mediocregopher/radix/v3"
)
@@ -227,25 +226,8 @@ func (rs *RedisStorage) getKeysForFilterIndexesKeys(fkeys []string) (keys []stri
return
}
-func (rs *RedisStorage) RebbuildActionPlanKeys() (err error) {
- var keys []string
- if err = rs.Cmd(&keys, redis_KEYS, utils.ActionPlanPrefix+"*"); err != nil {
- return
- }
- for _, key := range keys {
- if err = rs.Cmd(nil, redis_SADD, utils.ActionPlanIndexes, key); err != nil {
- return
- }
- }
- return
-}
-
func (rs *RedisStorage) GetKeysForPrefix(prefix string) (keys []string, err error) {
- if prefix == utils.ActionPlanPrefix { // so we can avoid the full scan on scheduler reloads
- err = rs.Cmd(&keys, redis_SMEMBERS, utils.ActionPlanIndexes)
- } else {
- err = rs.Cmd(&keys, redis_KEYS, prefix+"*")
- }
+ err = rs.Cmd(&keys, redis_KEYS, prefix+"*")
if err != nil {
return
}
@@ -262,8 +244,7 @@ func (rs *RedisStorage) GetKeysForPrefix(prefix string) (keys []string, err erro
func (rs *RedisStorage) HasDataDrv(category, subject, tenant string) (exists bool, err error) {
var i int
switch category {
- case utils.DestinationPrefix, utils.RatingPlanPrefix, utils.RatingProfilePrefix,
- utils.ActionPrefix, utils.ActionPlanPrefix, utils.AccountPrefix:
+ case utils.DestinationPrefix:
err = rs.Cmd(&i, redis_EXISTS, category+subject)
return i == 1, err
case utils.ResourcesPrefix, utils.ResourceProfilesPrefix, utils.StatQueuePrefix,
@@ -277,91 +258,6 @@ func (rs *RedisStorage) HasDataDrv(category, subject, tenant string) (exists boo
return false, errors.New("unsupported HasData category")
}
-func (rs *RedisStorage) GetRatingPlanDrv(key string) (rp *RatingPlan, err error) {
- key = utils.RatingPlanPrefix + key
- var values []byte
- if err = rs.Cmd(&values, redis_GET, key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- b := bytes.NewBuffer(values)
- var r io.ReadCloser
- if r, err = zlib.NewReader(b); err != nil {
- return
- }
- var out []byte
- if out, err = io.ReadAll(r); err != nil {
- return
- }
- r.Close()
- err = rs.ms.Unmarshal(out, &rp)
- return
-}
-
-func (rs *RedisStorage) SetRatingPlanDrv(rp *RatingPlan) (err error) {
- var result []byte
- if result, err = rs.ms.Marshal(rp); err != nil {
- return
- }
- var b bytes.Buffer
- w := zlib.NewWriter(&b)
- w.Write(result)
- w.Close()
- err = rs.Cmd(nil, redis_SET, utils.RatingPlanPrefix+rp.Id, b.String())
- return
-}
-
-func (rs *RedisStorage) RemoveRatingPlanDrv(key string) (err error) {
- var keys []string
- if err = rs.Cmd(&keys, redis_KEYS, utils.RatingPlanPrefix+key+"*"); err != nil {
- return
- }
- for _, key := range keys {
- if err = rs.Cmd(nil, redis_DEL, key); err != nil {
- return
- }
- }
- return
-}
-
-func (rs *RedisStorage) GetRatingProfileDrv(key string) (rpf *RatingProfile, err error) {
- key = utils.RatingProfilePrefix + key
- var values []byte
- if err = rs.Cmd(&values, redis_GET, key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- err = rs.ms.Unmarshal(values, &rpf)
- return
-}
-
-func (rs *RedisStorage) SetRatingProfileDrv(rpf *RatingProfile) (err error) {
- var result []byte
- if result, err = rs.ms.Marshal(rpf); err != nil {
- return
- }
- key := utils.RatingProfilePrefix + rpf.Id
- err = rs.Cmd(nil, redis_SET, key, string(result))
- return
-}
-
-func (rs *RedisStorage) RemoveRatingProfileDrv(key string) (err error) {
- var keys []string
- if err = rs.Cmd(&keys, redis_KEYS, utils.RatingProfilePrefix+key+"*"); err != nil {
- return
- }
- for _, key := range keys {
- if err = rs.Cmd(nil, redis_DEL, key); err != nil {
- return
- }
- }
- return
-}
-
// GetDestination retrieves a destination with id from tp_db
func (rs *RedisStorage) GetDestinationDrv(key, transactionID string) (dest *Destination, err error) {
var values []byte
@@ -425,95 +321,6 @@ func (rs *RedisStorage) RemoveReverseDestinationDrv(dstID, prfx, transactionID s
return rs.Cmd(nil, redis_SREM, utils.ReverseDestinationPrefix+prfx, dstID)
}
-func (rs *RedisStorage) GetActionsDrv(key string) (as Actions, err error) {
- var values []byte
- if err = rs.Cmd(&values, redis_GET, utils.ActionPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- err = rs.ms.Unmarshal(values, &as)
- return
-}
-
-func (rs *RedisStorage) SetActionsDrv(key string, as Actions) (err error) {
- var result []byte
- if result, err = rs.ms.Marshal(&as); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, utils.ActionPrefix+key, string(result))
-}
-
-func (rs *RedisStorage) RemoveActionsDrv(key string) (err error) {
- return rs.Cmd(nil, redis_DEL, utils.ActionPrefix+key)
-}
-
-func (rs *RedisStorage) GetSharedGroupDrv(key string) (sg *SharedGroup, err error) {
- var values []byte
- if err = rs.Cmd(&values, redis_GET, utils.SharedGroupPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- err = rs.ms.Unmarshal(values, &sg)
- return
-}
-
-func (rs *RedisStorage) SetSharedGroupDrv(sg *SharedGroup) (err error) {
- var result []byte
- if result, err = rs.ms.Marshal(sg); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, utils.SharedGroupPrefix+sg.Id, string(result))
-}
-
-func (rs *RedisStorage) RemoveSharedGroupDrv(id string) (err error) {
- return rs.Cmd(nil, redis_DEL, utils.SharedGroupPrefix+id)
-}
-
-func (rs *RedisStorage) GetAccountDrv(key string) (ub *Account, err error) {
- var values []byte
- if err = rs.Cmd(&values, redis_GET, utils.AccountPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- ub = &Account{ID: key}
- if err = rs.ms.Unmarshal(values, ub); err != nil {
- return nil, err
- }
- return ub, nil
-}
-
-func (rs *RedisStorage) SetAccountDrv(acc *Account) (err error) {
- // never override existing account with an empty one
- // UPDATE: if all balances expired and were cleaned it makes
- // sense to write empty balance map
- if len(acc.BalanceMap) == 0 {
- var ac *Account
- if ac, err = rs.GetAccountDrv(acc.ID); err == nil && !ac.allBalancesExpired() {
- ac.ActionTriggers = acc.ActionTriggers
- ac.UnitCounters = acc.UnitCounters
- ac.AllowNegative = acc.AllowNegative
- ac.Disabled = acc.Disabled
- acc = ac
- }
- }
- acc.UpdateTime = time.Now()
- var result []byte
- if result, err = rs.ms.Marshal(acc); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, utils.AccountPrefix+acc.ID, string(result))
-}
-
-func (rs *RedisStorage) RemoveAccountDrv(key string) (err error) {
- return rs.Cmd(nil, redis_DEL, utils.AccountPrefix+key)
-}
-
// Limit will only retrieve the last n items out of history, newest first
func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool,
transactionID string) (loadInsts []*utils.LoadInstance, err error) {
@@ -594,244 +401,6 @@ func (rs *RedisStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize
return
}
-func (rs *RedisStorage) GetActionTriggersDrv(key string) (atrs ActionTriggers, err error) {
- var values []byte
- if err = rs.Cmd(&values, redis_GET, utils.ActionTriggerPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- err = rs.ms.Unmarshal(values, &atrs)
- return
-}
-
-func (rs *RedisStorage) SetActionTriggersDrv(key string, atrs ActionTriggers) (err error) {
- if len(atrs) == 0 {
- // delete the key
- return rs.Cmd(nil, redis_DEL, utils.ActionTriggerPrefix+key)
- }
- var result []byte
- if result, err = rs.ms.Marshal(atrs); err != nil {
- return
- }
- if err = rs.Cmd(nil, redis_SET, utils.ActionTriggerPrefix+key, string(result)); err != nil {
- return
- }
- return
-}
-
-func (rs *RedisStorage) RemoveActionTriggersDrv(key string) (err error) {
- return rs.Cmd(nil, redis_DEL, utils.ActionTriggerPrefix+key)
-}
-
-func (rs *RedisStorage) GetActionPlanDrv(key string, skipCache bool,
- transactionID string) (ats *ActionPlan, err error) {
- if !skipCache {
- if x, err := Cache.GetCloned(utils.CacheActionPlans, key); err != nil {
- if err != ltcache.ErrNotFound { // Only consider cache if item was found
- return nil, err
- }
- } else if x == nil { // item was placed nil in cache
- return nil, utils.ErrNotFound
- } else {
- return x.(*ActionPlan), nil
- }
- }
- var values []byte
- if err = rs.Cmd(&values, redis_GET, utils.ActionPlanPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- if errCh := Cache.Set(utils.CacheActionPlans, key, nil, nil,
- cacheCommit(transactionID), transactionID); errCh != nil {
- return nil, errCh
- }
- err = utils.ErrNotFound
- return
- }
- b := bytes.NewBuffer(values)
- var r io.ReadCloser
- if r, err = zlib.NewReader(b); err != nil {
- return
- }
- var out []byte
- if out, err = io.ReadAll(r); err != nil {
- return
- }
- r.Close()
- if err = rs.ms.Unmarshal(out, &ats); err != nil {
- return
- }
- err = Cache.Set(utils.CacheActionPlans, key, ats, nil,
- cacheCommit(transactionID), transactionID)
- return
-}
-func (rs *RedisStorage) RemoveActionPlanDrv(key string,
- transactionID string) (err error) {
- cCommit := cacheCommit(transactionID)
- if err = rs.Cmd(nil, redis_SREM, utils.ActionPlanIndexes, utils.ActionPlanPrefix+key); err != nil {
- return
- }
- err = rs.Cmd(nil, redis_DEL, utils.ActionPlanPrefix+key)
- if errCh := Cache.Remove(utils.CacheActionPlans, key,
- cCommit, transactionID); errCh != nil {
- return errCh
- }
- return
-}
-
-func (rs *RedisStorage) SetActionPlanDrv(key string, ats *ActionPlan,
- overwrite bool, transactionID string) (err error) {
- cCommit := cacheCommit(transactionID)
- if len(ats.ActionTimings) == 0 {
- // delete the key
- if err = rs.Cmd(nil, redis_SREM, utils.ActionPlanIndexes, utils.ActionPlanPrefix+key); err != nil {
- return
- }
- err = rs.Cmd(nil, redis_DEL, utils.ActionPlanPrefix+key)
- if errCh := Cache.Remove(utils.CacheActionPlans, key,
- cCommit, transactionID); errCh != nil {
- return errCh
- }
- return
- }
- if !overwrite {
- // get existing action plan to merge the account ids
- if existingAts, _ := rs.GetActionPlanDrv(key, true, transactionID); existingAts != nil {
- if ats.AccountIDs == nil && len(existingAts.AccountIDs) > 0 {
- ats.AccountIDs = make(utils.StringMap)
- }
- for accID := range existingAts.AccountIDs {
- ats.AccountIDs[accID] = true
- }
- }
- }
- var result []byte
- if result, err = rs.ms.Marshal(ats); err != nil {
- return
- }
- var b bytes.Buffer
- w := zlib.NewWriter(&b)
- w.Write(result)
- w.Close()
- if err = rs.Cmd(nil, redis_SADD, utils.ActionPlanIndexes, utils.ActionPlanPrefix+key); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, utils.ActionPlanPrefix+key, b.String())
-}
-
-func (rs *RedisStorage) GetAllActionPlansDrv() (ats map[string]*ActionPlan, err error) {
- var keys []string
- if keys, err = rs.GetKeysForPrefix(utils.ActionPlanPrefix); err != nil {
- return
- }
- if len(keys) == 0 {
- err = utils.ErrNotFound
- return
- }
- ats = make(map[string]*ActionPlan, len(keys))
- for _, key := range keys {
- if ats[key[len(utils.ActionPlanPrefix):]], err = rs.GetActionPlanDrv(key[len(utils.ActionPlanPrefix):],
- false, utils.NonTransactional); err != nil {
- return nil, err
- }
- }
- return
-}
-
-func (rs *RedisStorage) GetAccountActionPlansDrv(acntID string, skipCache bool,
- transactionID string) (aPlIDs []string, err error) {
- if !skipCache {
- if x, ok := Cache.Get(utils.CacheAccountActionPlans, acntID); ok {
- if x == nil {
- return nil, utils.ErrNotFound
- }
- return x.([]string), nil
- }
- }
- var values []byte
- if err = rs.Cmd(&values, redis_GET,
- utils.AccountActionPlansPrefix+acntID); err != nil {
- return
- } else if len(values) == 0 {
- if errCh := Cache.Set(utils.CacheAccountActionPlans, acntID, nil, nil,
- cacheCommit(transactionID), transactionID); errCh != nil {
- return nil, errCh
- }
- err = utils.ErrNotFound
- return
- }
- if err = rs.ms.Unmarshal(values, &aPlIDs); err != nil {
- return
- }
- err = Cache.Set(utils.CacheAccountActionPlans, acntID, aPlIDs, nil,
- cacheCommit(transactionID), transactionID)
- return
-}
-
-func (rs *RedisStorage) SetAccountActionPlansDrv(acntID string, aPlIDs []string, overwrite bool) (err error) {
- if !overwrite {
- var oldaPlIDs []string
- if oldaPlIDs, err = rs.GetAccountActionPlansDrv(acntID, true, utils.NonTransactional); err != nil && err != utils.ErrNotFound {
- return
- }
- for _, oldAPid := range oldaPlIDs {
- if !utils.IsSliceMember(aPlIDs, oldAPid) {
- aPlIDs = append(aPlIDs, oldAPid)
- }
- }
- }
- var result []byte
- if result, err = rs.ms.Marshal(aPlIDs); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, utils.AccountActionPlansPrefix+acntID, string(result))
-}
-
-func (rs *RedisStorage) RemAccountActionPlansDrv(acntID string, aPlIDs []string) (err error) {
- key := utils.AccountActionPlansPrefix + acntID
- if len(aPlIDs) == 0 {
- return rs.Cmd(nil, redis_DEL, key)
- }
- var oldaPlIDs []string
- if oldaPlIDs, err = rs.GetAccountActionPlansDrv(acntID, true, utils.NonTransactional); err != nil {
- return
- }
- for i := 0; i < len(oldaPlIDs); {
- if utils.IsSliceMember(aPlIDs, oldaPlIDs[i]) {
- oldaPlIDs = append(oldaPlIDs[:i], oldaPlIDs[i+1:]...)
- continue // if we have stripped, don't increase index so we can check next element by next run
- }
- i++
- }
- if len(oldaPlIDs) == 0 { // no more elements, remove the reference
- return rs.Cmd(nil, redis_DEL, key)
- }
- var result []byte
- if result, err = rs.ms.Marshal(oldaPlIDs); err != nil {
- return
- }
- return rs.Cmd(nil, redis_SET, key, string(result))
-}
-
-func (rs *RedisStorage) PushTask(t *Task) (err error) {
- var result []byte
- if result, err = rs.ms.Marshal(t); err != nil {
- return
- }
- return rs.Cmd(nil, redis_RPUSH, utils.TasksKey, string(result))
-}
-
-func (rs *RedisStorage) PopTask() (t *Task, err error) {
- var values []byte
- if err = rs.Cmd(&values, redis_LPOP, utils.TasksKey); err != nil {
- return
- }
- t = &Task{}
- err = rs.ms.Unmarshal(values, t)
- return
-}
-
func (rs *RedisStorage) GetResourceProfileDrv(tenant, id string) (rsp *ResourceProfile, err error) {
var values []byte
if err = rs.Cmd(&values, redis_GET, utils.ResourceProfilesPrefix+utils.ConcatenatedKey(tenant, id)); err != nil {
diff --git a/engine/storage_sql.go b/engine/storage_sql.go
index b37e0f754..b42a63af2 100644
--- a/engine/storage_sql.go
+++ b/engine/storage_sql.go
@@ -21,7 +21,6 @@ package engine
import (
"bytes"
"database/sql"
- "encoding/json"
"fmt"
"os"
"path"
@@ -99,11 +98,9 @@ func (sqls *SQLStorage) CreateTablesFromScript(scriptPath string) error {
func (sqls *SQLStorage) IsDBEmpty() (resp bool, err error) {
tbls := []string{
- utils.TBLTPTimings, utils.TBLTPDestinations, utils.TBLTPRates,
- utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, utils.TBLTPRatingProfiles,
- utils.TBLTPSharedGroups, utils.TBLTPActions, utils.TBLTPActionTriggers,
- utils.TBLTPAccountActions, utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPThresholds,
- utils.TBLTPFilters, utils.SessionCostsTBL, utils.CDRsTBL, utils.TBLTPActionPlans,
+ utils.TBLTPTimings, utils.TBLTPDestinations,
+ utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPThresholds,
+ utils.TBLTPFilters, utils.SessionCostsTBL, utils.CDRsTBL,
utils.TBLVersions, utils.TBLTPRoutes, utils.TBLTPAttributes, utils.TBLTPChargers,
utils.TBLTPDispatchers, utils.TBLTPDispatcherHosts,
}
@@ -123,29 +120,23 @@ func (sqls *SQLStorage) GetTpIds(colName string) ([]string, error) {
var err error
qryStr := fmt.Sprintf(" (SELECT tpid FROM %s)", colName)
if colName == "" {
- qryStr = fmt.Sprintf(
- "(SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s) UNION (SELECT tpid FROM %s)",
+
+ for _, clNm := range []string{
utils.TBLTPTimings,
utils.TBLTPDestinations,
- utils.TBLTPRates,
- utils.TBLTPDestinationRates,
- utils.TBLTPRatingPlans,
- utils.TBLTPRatingProfiles,
- utils.TBLTPSharedGroups,
- utils.TBLTPActions,
- utils.TBLTPActionTriggers,
- utils.TBLTPAccountActions,
utils.TBLTPResources,
utils.TBLTPStats,
utils.TBLTPThresholds,
utils.TBLTPFilters,
- utils.TBLTPActionPlans,
utils.TBLTPRoutes,
utils.TBLTPAttributes,
utils.TBLTPChargers,
utils.TBLTPDispatchers,
utils.TBLTPDispatcherHosts,
- )
+ } {
+ qryStr += fmt.Sprintf("UNION (SELECT tpid FROM %s)", clNm)
+ }
+ qryStr = strings.TrimPrefix(qryStr, "UNION ")
}
rows, err = sqls.Db.Query(qryStr)
if err != nil {
@@ -236,11 +227,9 @@ func (sqls *SQLStorage) RemTpData(table, tpid string, args map[string]string) er
tx := sqls.db.Begin()
if len(table) == 0 { // Remove tpid out of all tables
- for _, tblName := range []string{utils.TBLTPTimings, utils.TBLTPDestinations, utils.TBLTPRates,
- utils.TBLTPDestinationRates, utils.TBLTPRatingPlans, utils.TBLTPRatingProfiles,
- utils.TBLTPSharedGroups, utils.TBLTPActions, utils.TBLTPActionTriggers,
- utils.TBLTPAccountActions, utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPThresholds,
- utils.TBLTPFilters, utils.TBLTPActionPlans, utils.TBLTPRoutes, utils.TBLTPAttributes,
+ for _, tblName := range []string{utils.TBLTPTimings, utils.TBLTPDestinations,
+ utils.TBLTPResources, utils.TBLTPStats, utils.TBLTPThresholds,
+ utils.TBLTPFilters, utils.TBLTPRoutes, utils.TBLTPAttributes,
utils.TBLTPChargers, utils.TBLTPDispatchers, utils.TBLTPDispatcherHosts, utils.TBLTPAccountProfiles,
utils.TBLTPActionProfiles, utils.TBLTPRateProfiles} {
if err := tx.Table(tblName).Where("tpid = ?", tpid).Delete(nil).Error; err != nil {
@@ -308,31 +297,6 @@ func (sqls *SQLStorage) SetTPDestinations(dests []*utils.TPDestination) error {
return nil
}
-func (sqls *SQLStorage) SetTPActions(acts []*utils.TPActions) error {
- if len(acts) == 0 {
- return nil //Nothing to set
- }
- m := make(map[string]bool)
- tx := sqls.db.Begin()
- for _, a := range acts {
- if !m[a.ID] {
- m[a.ID] = true
- if err := tx.Where(&ActionMdl{Tpid: a.TPid, Tag: a.ID}).Delete(ActionMdl{}).Error; err != nil {
- tx.Rollback()
- return err
- }
- }
- for _, sa := range APItoModelAction(a) {
- if err := tx.Create(&sa).Error; err != nil {
- tx.Rollback()
- return err
- }
- }
- }
- tx.Commit()
- return nil
-}
-
func (sqls *SQLStorage) SetTPResources(rls []*utils.TPResourceProfile) error {
if len(rls) == 0 {
return nil
@@ -595,150 +559,6 @@ func (sqls *SQLStorage) SetTPAccountProfiles(tpAps []*utils.TPAccountProfile) er
return nil
}
-func (sqls *SQLStorage) SetSMCost(smc *SMCost) error {
- if smc.CostDetails == nil {
- return nil
- }
- tx := sqls.db.Begin()
- cd := &SessionCostsSQL{
- Cgrid: smc.CGRID,
- RunID: smc.RunID,
- OriginHost: smc.OriginHost,
- OriginID: smc.OriginID,
- CostSource: smc.CostSource,
- CostDetails: utils.ToJSON(smc.CostDetails),
- Usage: smc.Usage.Nanoseconds(),
- CreatedAt: time.Now(),
- }
- if tx.Save(cd).Error != nil { // Check further since error does not properly reflect duplicates here (sql: no rows in result set)
- tx.Rollback()
- return tx.Error
- }
- tx.Commit()
- return nil
-}
-
-func (sqls *SQLStorage) RemoveSMCost(smc *SMCost) error {
- tx := sqls.db.Begin()
- var rmParam *SessionCostsSQL
- if smc != nil {
- rmParam = &SessionCostsSQL{Cgrid: smc.CGRID,
- RunID: smc.RunID}
- }
- if err := tx.Where(rmParam).Delete(SessionCostsSQL{}).Error; err != nil {
- tx.Rollback()
- return err
- }
- tx.Commit()
- return nil
-}
-
-func (sqls *SQLStorage) RemoveSMCosts(qryFltr *utils.SMCostFilter) error {
- q := sqls.db.Table(utils.SessionCostsTBL).Select("*")
- // Add filters, use in to replace the high number of ORs
- if len(qryFltr.CGRIDs) != 0 {
- q = q.Where("cgrid in (?)", qryFltr.CGRIDs)
- }
- if len(qryFltr.NotCGRIDs) != 0 {
- q = q.Where("cgrid not in (?)", qryFltr.NotCGRIDs)
- }
- if len(qryFltr.RunIDs) != 0 {
- q = q.Where("run_id in (?)", qryFltr.RunIDs)
- }
- if len(qryFltr.NotRunIDs) != 0 {
- q = q.Where("run_id not in (?)", qryFltr.NotRunIDs)
- }
- if len(qryFltr.OriginIDs) != 0 {
- q = q.Where("origin_id in (?)", qryFltr.OriginIDs)
- }
- if len(qryFltr.NotOriginIDs) != 0 {
- q = q.Where("origin_id not in (?)", qryFltr.NotOriginIDs)
- }
- if len(qryFltr.OriginHosts) != 0 {
- q = q.Where("origin_host in (?)", qryFltr.OriginHosts)
- }
- if len(qryFltr.NotOriginHosts) != 0 {
- q = q.Where("origin_host not in (?)", qryFltr.NotOriginHosts)
- }
- if len(qryFltr.CostSources) != 0 {
- q = q.Where("costsource in (?)", qryFltr.CostSources)
- }
- if len(qryFltr.NotCostSources) != 0 {
- q = q.Where("costsource not in (?)", qryFltr.NotCostSources)
- }
- if qryFltr.CreatedAt.Begin != nil {
- q = q.Where("created_at >= ?", qryFltr.CreatedAt.Begin)
- }
- if qryFltr.CreatedAt.End != nil {
- q = q.Where("created_at < ?", qryFltr.CreatedAt.End)
- }
- if qryFltr.Usage.Min != nil {
- if sqls.db.Dialector.Name() == utils.MySQL { // MySQL needs escaping for usage
- q = q.Where("`usage` >= ?", qryFltr.Usage.Min.Nanoseconds())
- } else {
- q = q.Where("usage >= ?", qryFltr.Usage.Min.Nanoseconds())
- }
- }
- if qryFltr.Usage.Max != nil {
- if sqls.db.Dialector.Name() == utils.MySQL { // MySQL needs escaping for usage
- q = q.Where("`usage` < ?", qryFltr.Usage.Max.Nanoseconds())
- } else {
- q = q.Where("usage < ?", qryFltr.Usage.Max.Nanoseconds())
- }
- }
- if err := q.Delete(nil).Error; err != nil {
- q.Rollback()
- return err
- }
- return nil
-}
-
-// GetSMCosts is used to retrieve one or multiple SMCosts based on filter
-func (sqls *SQLStorage) GetSMCosts(cgrid, runid, originHost, originIDPrefix string) ([]*SMCost, error) {
- var smCosts []*SMCost
- filter := &SessionCostsSQL{}
- if cgrid != "" {
- filter.Cgrid = cgrid
- }
- if runid != "" {
- filter.RunID = runid
- }
- if originHost != "" {
- filter.OriginHost = originHost
- }
- q := sqls.db.Where(filter)
- if originIDPrefix != "" {
- q = sqls.db.Where(filter).Where(fmt.Sprintf("origin_id LIKE '%s%%'", originIDPrefix))
- }
- results := make([]*SessionCostsSQL, 0)
- if err := q.Find(&results).Error; err != nil {
- return nil, err
- }
- for _, result := range results {
- if len(result.CostDetails) == 0 {
- continue
- }
- smc := &SMCost{
- CGRID: result.Cgrid,
- RunID: result.RunID,
- OriginHost: result.OriginHost,
- OriginID: result.OriginID,
- CostSource: result.CostSource,
- Usage: time.Duration(result.Usage),
- CostDetails: new(EventCost),
- }
- if err := json.Unmarshal([]byte(result.CostDetails), smc.CostDetails); err != nil {
- return nil, err
- }
- smc.CostDetails.initCache()
- smCosts = append(smCosts, smc)
- }
- if len(smCosts) == 0 {
- return smCosts, utils.ErrNotFound
- }
- return smCosts, nil
-}
-
func (sqls *SQLStorage) SetCDR(cdr *CDR, allowUpdate bool) error {
tx := sqls.db.Begin()
cdrSQL := cdr.AsCDRsql()
@@ -1026,7 +846,6 @@ func (sqls *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter, remove bool) ([]*CDR,
if cdr, err := NewCDRFromSQL(result); err != nil {
return nil, 0, err
} else {
- cdr.CostDetails.initCache()
cdrs = append(cdrs, cdr)
}
}
@@ -1067,22 +886,6 @@ func (sqls *SQLStorage) GetTPTimings(tpid, id string) ([]*utils.ApierTPTiming, e
return ts, nil
}
-func (sqls *SQLStorage) GetTPActions(tpid, id string) ([]*utils.TPActions, error) {
- var tpActions ActionMdls
- q := sqls.db.Where("tpid = ?", tpid)
- if len(id) != 0 {
- q = q.Where("tag = ?", id)
- }
- if err := q.Find(&tpActions).Error; err != nil {
- return nil, err
- }
- as := tpActions.AsTPActions()
- if len(as) == 0 {
- return as, utils.ErrNotFound
- }
- return as, nil
-}
-
func (sqls *SQLStorage) GetTPResources(tpid, tenant, id string) ([]*utils.TPResourceProfile, error) {
var rls ResourceMdls
q := sqls.db.Where("tpid = ?", tpid)
diff --git a/engine/storage_utils.go b/engine/storage_utils.go
index 17fbfda67..c0f105a14 100644
--- a/engine/storage_utils.go
+++ b/engine/storage_utils.go
@@ -123,38 +123,3 @@ func NewStorDBConn(dbType, host, port, name, user, pass, marshaler string,
}
return
}
-
-// SMCost stores one Cost coming from SM
-type SMCost struct {
- CGRID string
- RunID string
- OriginHost string
- OriginID string
- CostSource string
- Usage time.Duration
- CostDetails *EventCost
-}
-
-type AttrCDRSStoreSMCost struct {
- Cost *SMCost
- CheckDuplicate bool
- APIOpts map[string]interface{}
- Tenant string
-}
-
-type ArgsV2CDRSStoreSMCost struct {
- Cost *V2SMCost
- CheckDuplicate bool
- APIOpts map[string]interface{}
- Tenant string
-}
-
-type V2SMCost struct {
- CGRID string
- RunID string
- OriginHost string
- OriginID string
- CostSource string
- Usage time.Duration
- CostDetails *EventCost
-}
diff --git a/engine/task.go b/engine/task.go
deleted file mode 100644
index c79725139..000000000
--- a/engine/task.go
+++ /dev/null
@@ -1,81 +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 (
- "net"
- "strings"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-// Task is a one time action executed by the scheduler
-type Task struct {
- Uuid string
- AccountID string
- ActionsID string
-}
-
-func (t *Task) Execute() error {
- at := &ActionTiming{
- Uuid: t.Uuid,
- ActionsID: t.ActionsID,
- }
- if len(t.AccountID) != 0 {
- at.accountIDs = utils.StringMap{t.AccountID: true}
- }
- return at.Execute(nil, nil)
-}
-
-// String implements utils.DataProvider
-func (t *Task) String() string {
- return utils.ToJSON(t)
-}
-
-// FieldAsInterface implements utils.DataProvider
-// ToDo: support Action fields
-func (t *Task) FieldAsInterface(fldPath []string) (iface interface{}, err error) {
- return t.FieldAsString(fldPath)
-}
-
-// FieldAsString implements utils.DataProvider
-// ToDo: support Action fields
-func (t *Task) FieldAsString(fldPath []string) (s string, err error) {
- if len(fldPath) == 0 {
- return
- }
- if fldPath[0] != utils.MetaAct || len(fldPath) < 2 {
- return "", utils.ErrPrefixNotFound(strings.Join(fldPath, utils.NestingSep))
- }
- switch fldPath[1] {
- case utils.UUID:
- return t.Uuid, nil
- case utils.AccountID:
- return t.AccountID, nil
- case utils.ActionsID:
- return t.ActionsID, nil
- default:
- return "", utils.ErrPrefixNotFound(strings.Join(fldPath, utils.NestingSep))
- }
-}
-
-// RemoteHost implements utils.DataProvider
-func (t *Task) RemoteHost() (rh net.Addr) {
- return
-}
diff --git a/engine/task_test.go b/engine/task_test.go
deleted file mode 100644
index 1d515adad..000000000
--- a/engine/task_test.go
+++ /dev/null
@@ -1,137 +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 (
- "net"
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestTaskString(t *testing.T) {
- task := &Task{
- Uuid: "test",
- AccountID: "test2",
- ActionsID: "test3",
- }
- eOut := "{\"Uuid\":\"test\",\"AccountID\":\"test2\",\"ActionsID\":\"test3\"}"
- rcv := task.String()
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
-}
-
-func TestTaskFieldAsinterface(t *testing.T) {
- //empty check
- task := new(Task)
- fldPath := []string{utils.MetaAct, utils.UUID, utils.ActionsID}
- rcv, err := task.FieldAsInterface(fldPath)
- eOut := ""
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
- //Uuid check
- task = &Task{
- Uuid: "test",
- AccountID: "test2",
- ActionsID: "test3",
- }
- rcv, err = task.FieldAsInterface(fldPath)
- eOut = "test"
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
-
-}
-
-func TestTaskFieldAsString(t *testing.T) {
- //empty check
- task := new(Task)
- eOut := ""
- var fldPath []string // := {"string1","string2"}
- rcv, err := task.FieldAsString(fldPath)
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
- //Uuid check
- task = &Task{
- Uuid: "test",
- AccountID: "test2",
- ActionsID: "test3",
- }
- fldPath = []string{utils.MetaAct, utils.UUID, "string2"}
- eOut = "test"
- rcv, err = task.FieldAsString(fldPath)
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
- //AccountID check
- fldPath = []string{utils.MetaAct, utils.AccountID, "string2"}
- eOut = "test2"
- rcv, err = task.FieldAsString(fldPath)
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
- //ActionsID check
- fldPath = []string{utils.MetaAct, utils.ActionsID, "string2"}
- eOut = "test3"
- rcv, err = task.FieldAsString(fldPath)
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
- //default check
- fldPath = []string{utils.MetaAct, "default", "case"}
- eOut = ""
- rcv, err = task.FieldAsString(fldPath)
- if err == nil {
- t.Error("Expecting NOT_FOUND error, received nil")
- }
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
-}
-
-func TestTaskRemoteHost(t *testing.T) {
- task := new(Task)
- var eOut net.Addr
- rcv := task.RemoteHost()
- if !reflect.DeepEqual(eOut, rcv) {
- t.Errorf("Expecting: %q, received: %q", eOut, rcv)
- }
-}
diff --git a/engine/thresholds.go b/engine/thresholds.go
index 8781210b0..b8594d9e2 100644
--- a/engine/thresholds.go
+++ b/engine/thresholds.go
@@ -86,37 +86,37 @@ func (t *Threshold) ProcessEvent(args *ThresholdsArgsProcessEvent, dm *DataManag
t.Hits > t.tPrfl.MaxHits) {
return
}
- var tntAcnt string
- var acnt string
- if utils.IfaceAsString(args.APIOpts[utils.MetaEventType]) == utils.AccountUpdate {
- acnt, _ = args.FieldAsString(utils.ID)
- } else {
- acnt, _ = args.FieldAsString(utils.AccountField)
- }
- if acnt != utils.EmptyString {
- tntAcnt = utils.ConcatenatedKey(args.Tenant, acnt)
- }
+ // var tntAcnt string
+ // var acnt string
+ // if utils.IfaceAsString(args.APIOpts[utils.MetaEventType]) == utils.AccountUpdate {
+ // acnt, _ = args.FieldAsString(utils.ID)
+ // } else {
+ // acnt, _ = args.FieldAsString(utils.AccountField)
+ // }
+ // if acnt != utils.EmptyString {
+ // tntAcnt = utils.ConcatenatedKey(args.Tenant, acnt)
+ // }
- for _, actionSetID := range t.tPrfl.ActionIDs {
- at := &ActionTiming{
- Uuid: utils.GenUUID(),
- ActionsID: actionSetID,
- ExtraData: args.CGREvent,
- }
- if tntAcnt != utils.EmptyString {
- at.accountIDs = utils.NewStringMap(tntAcnt)
- }
- if t.tPrfl.Async {
- go func() {
- if errExec := at.Execute(nil, nil); errExec != nil {
- utils.Logger.Warning(fmt.Sprintf(" failed executing actions: %s, error: %s", actionSetID, errExec.Error()))
- }
- }()
- } else if errExec := at.Execute(nil, nil); errExec != nil {
- utils.Logger.Warning(fmt.Sprintf(" failed executing actions: %s, error: %s", actionSetID, errExec.Error()))
- err = utils.ErrPartiallyExecuted
- }
- }
+ // for _, actionSetID := range t.tPrfl.ActionIDs {
+ // at := &ActionTiming{
+ // Uuid: utils.GenUUID(),
+ // ActionsID: actionSetID,
+ // ExtraData: args.CGREvent,
+ // }
+ // if tntAcnt != utils.EmptyString {
+ // at.accountIDs = utils.NewStringMap(tntAcnt)
+ // }
+ // if t.tPrfl.Async {
+ // go func() {
+ // if errExec := at.Execute(nil, nil); errExec != nil {
+ // utils.Logger.Warning(fmt.Sprintf(" failed executing actions: %s, error: %s", actionSetID, errExec.Error()))
+ // }
+ // }()
+ // } else if errExec := at.Execute(nil, nil); errExec != nil {
+ // utils.Logger.Warning(fmt.Sprintf(" failed executing actions: %s, error: %s", actionSetID, errExec.Error()))
+ // err = utils.ErrPartiallyExecuted
+ // }
+ // }
return
}
diff --git a/engine/timespans.go b/engine/timespans.go
deleted file mode 100644
index f7881df63..000000000
--- a/engine/timespans.go
+++ /dev/null
@@ -1,826 +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 (
- "fmt"
- "reflect"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/utils"
-)
-
-/*
-A unit in which a call will be split that has a specific price related interval attached to it.
-*/
-type TimeSpan struct {
- TimeStart time.Time
- TimeEnd time.Time
- Cost float64
- RateInterval *RateInterval
- DurationIndex time.Duration // the call duration so far till TimeEnd
- Increments Increments
- RoundIncrement *Increment
- MatchedSubject string
- MatchedPrefix string
- MatchedDestId string
- RatingPlanId string
- CompressFactor int
- ratingInfo *RatingInfo
-}
-
-type Increment struct {
- Duration time.Duration
- Cost float64
- BalanceInfo *DebitInfo // need more than one for units with cost
- CompressFactor int
- paid bool
-}
-
-// Holds information about the balance that made a specific payment
-type DebitInfo struct {
- Unit *UnitInfo
- Monetary *MonetaryInfo
- AccountID string // used when debited from shared balance
-}
-
-func (di *DebitInfo) Equal(other *DebitInfo) bool {
- return di.Unit.Equal(other.Unit) &&
- di.Monetary.Equal(other.Monetary) &&
- di.AccountID == other.AccountID
-}
-
-func (di *DebitInfo) Clone() *DebitInfo {
- nDi := &DebitInfo{
- AccountID: di.AccountID,
- }
- if di.Unit != nil {
- nDi.Unit = di.Unit.Clone()
- }
- if di.Monetary != nil {
- nDi.Monetary = di.Monetary.Clone()
- }
- return nDi
-}
-
-type MonetaryInfo struct {
- UUID string
- ID string
- Value float64
- RateInterval *RateInterval
-}
-
-func (mi *MonetaryInfo) Clone() *MonetaryInfo {
- newMi := *mi
- return &newMi
-}
-
-func (mi *MonetaryInfo) Equal(other *MonetaryInfo) bool {
- if mi == nil && other == nil {
- return true
- }
- if mi == nil || other == nil {
- return false
- }
- return mi.UUID == other.UUID &&
- reflect.DeepEqual(mi.RateInterval, other.RateInterval)
-}
-
-type UnitInfo struct {
- UUID string
- ID string
- Value float64
- DestinationID string
- Consumed float64
- ToR string
- RateInterval *RateInterval
-}
-
-func (ui *UnitInfo) Clone() *UnitInfo {
- newUi := *ui
- return &newUi
-}
-
-func (ui *UnitInfo) Equal(other *UnitInfo) bool {
- if ui == nil && other == nil {
- return true
- }
- if ui == nil || other == nil {
- return false
- }
- return ui.UUID == other.UUID &&
- ui.DestinationID == other.DestinationID &&
- ui.Consumed == other.Consumed &&
- ui.ToR == other.ToR &&
- reflect.DeepEqual(ui.RateInterval, other.RateInterval)
-}
-
-type TimeSpans []*TimeSpan
-
-// Will delete all timespans that are `under` the timespan at index
-func (timespans *TimeSpans) RemoveOverlapedFromIndex(index int) {
- tsList := *timespans
- ts := tsList[index]
- endOverlapIndex := index
- for i := index + 1; i < len(tsList); i++ {
- if tsList[i].TimeEnd.Before(ts.TimeEnd) || tsList[i].TimeEnd.Equal(ts.TimeEnd) {
- endOverlapIndex = i
- } else if tsList[i].TimeStart.Before(ts.TimeEnd) {
- tsList[i].TimeStart = ts.TimeEnd
- break
- }
- }
- if endOverlapIndex > index {
- newSliceEnd := len(tsList) - (endOverlapIndex - index)
- // delete overlapped
- copy(tsList[index+1:], tsList[endOverlapIndex+1:])
- for i := newSliceEnd; i < len(tsList); i++ {
- tsList[i] = nil
- }
- *timespans = tsList[:newSliceEnd]
- return
- }
- *timespans = tsList
-}
-
-// The paidTs will replace the timespans that are exactly `under` them
-// from the reciver list
-func (timespans *TimeSpans) OverlapWithTimeSpans(paidTs TimeSpans, newTs *TimeSpan, index int) bool {
- tsList := *timespans
- // calculate overlaped timespans
- var paidDuration time.Duration
- for _, pts := range paidTs {
- paidDuration += pts.GetDuration()
- }
- if paidDuration > 0 {
- // we must add the rest of the current ts to the remaingTs
- var remainingTs []*TimeSpan
- overlapStartIndex := index
- if newTs != nil {
- remainingTs = append(remainingTs, newTs)
- overlapStartIndex += 1
- }
- for tsi := overlapStartIndex; tsi < len(tsList); tsi++ {
- remainingTs = append(remainingTs, tsList[tsi])
- }
- overlapEndIndex := 0
- for i, rts := range remainingTs {
- if paidDuration >= rts.GetDuration() {
- paidDuration -= rts.GetDuration()
- } else {
- if paidDuration > 0 {
- // this ts was not fully paid
- fragment := rts.SplitByDuration(paidDuration)
- paidTs = append(paidTs, fragment)
- }
- // find the end position in tsList
- overlapEndIndex = overlapStartIndex + i
- break
- }
- // find the end position in tsList
- overlapEndIndex = overlapStartIndex + i
- }
- // delete from index to current
- if overlapEndIndex == len(tsList)-1 {
- tsList = tsList[:overlapStartIndex]
- } else {
- if overlapEndIndex+1 < len(tsList) {
- tsList = append(tsList[:overlapStartIndex], tsList[overlapEndIndex+1:]...)
- }
- }
- // append the timespans to outer tsList
- for i, pts := range paidTs {
- tsList = append(tsList, nil)
- copy(tsList[overlapStartIndex+i+1:], tsList[overlapStartIndex+i:])
- tsList[overlapStartIndex+i] = pts
- }
- *timespans = tsList
- return true
- }
- *timespans = tsList
- return false
-}
-
-func (tss *TimeSpans) Compress() { // must be pointer receiver
- for _, ts := range *tss {
- ts.Increments.Compress()
- }
- var cTss TimeSpans
- for _, ts := range *tss {
- if len(cTss) == 0 || !cTss[len(cTss)-1].Equal(ts) {
- ts.GetCompressFactor() // sideefect
- cTss = append(cTss, ts)
- } else {
- cTs := cTss[len(cTss)-1]
- cTs.CompressFactor++
- cTs.Cost += ts.Cost
- cTs.TimeEnd = ts.TimeEnd
- cTs.DurationIndex = ts.DurationIndex
- }
- }
- *tss = cTss
-}
-
-func (tss *TimeSpans) Decompress() { // must be pointer receiver
- for _, ts := range *tss {
- ts.Increments.Decompress()
- }
- var cTss TimeSpans
- for _, cTs := range *tss {
- var duration time.Duration
- if cTs.GetCompressFactor() > 1 {
- duration = cTs.GetUnitDuration()
- }
- for i := cTs.GetCompressFactor(); i > 1; i-- {
- uTs := &TimeSpan{}
- *uTs = *cTs // cloned by copy
- uTs.TimeEnd = cTs.TimeStart.Add(duration)
- uTs.DurationIndex = cTs.DurationIndex - time.Duration((i-1)*int(duration))
- uTs.CompressFactor = 1
- uTs.Cost = cTs.Cost / float64(cTs.GetCompressFactor())
- cTs.TimeStart = uTs.TimeEnd
- cTss = append(cTss, uTs)
- }
- cTs.Cost = cTs.GetUnitCost()
- cTs.CompressFactor = 1
- cTss = append(cTss, cTs)
- }
- *tss = cTss
-}
-
-func (tss *TimeSpans) Merge() { // Merge whenever possible
- tssVal := *tss
- if len(tssVal) > 2 { // Optimization for faster merge
- middle := len(tssVal) / 2
- tssVal1 := tssVal[:middle]
- tssVal2 := tssVal[middle:]
- tssVal1.Merge()
- tssVal2.Merge()
- tssVal = append(tssVal1, tssVal2...)
- }
- for i := 1; i < len(tssVal); i++ {
- if tssVal[i-1].Merge(tssVal[i]) {
- tssVal = append(tssVal[:i], tssVal[i+1:]...)
- i-- // Reschedule checking of last index since slice will decrease
- }
- }
- *tss = tssVal
-}
-
-func (incr *Increment) Clone() *Increment {
- nInc := &Increment{
- Duration: incr.Duration,
- Cost: incr.Cost,
- CompressFactor: incr.CompressFactor,
- }
- if incr.BalanceInfo != nil {
- nInc.BalanceInfo = incr.BalanceInfo.Clone()
- }
- return nInc
-}
-
-func (incr *Increment) Equal(other *Increment) bool {
- return incr.Duration == other.Duration &&
- incr.Cost == other.Cost &&
- ((incr.BalanceInfo == nil && other.BalanceInfo == nil) || incr.BalanceInfo.Equal(other.BalanceInfo))
-}
-
-func (incr *Increment) GetCompressFactor() int {
- if incr.CompressFactor == 0 {
- incr.CompressFactor = 1
- }
- return incr.CompressFactor
-}
-
-func (incr *Increment) GetCost() float64 {
- return float64(incr.GetCompressFactor()) * incr.Cost
-}
-
-type Increments []*Increment
-
-func (incs Increments) Clone() (cln Increments) {
- if incs == nil {
- return nil
- }
- cln = make(Increments, len(incs))
- for index, increment := range incs {
- cln[index] = increment.Clone()
- }
- return cln
-}
-
-func (incs Increments) Equal(other Increments) bool {
- if len(other) < len(incs) { // Protect index in case of not being the same size
- return false
- }
- for index, i := range incs {
- if !i.Equal(other[index]) || i.GetCompressFactor() != other[index].GetCompressFactor() {
- return false
- }
- }
- return true
-}
-
-func (incs *Increments) Compress() { // must be pointer receiver
- var cIncrs Increments
- for _, incr := range *incs {
- if len(cIncrs) == 0 || !cIncrs[len(cIncrs)-1].Equal(incr) {
- incr.GetCompressFactor() // sideefect
- cIncrs = append(cIncrs, incr)
- } else {
- cIncrs[len(cIncrs)-1].CompressFactor++
- if cIncrs[len(cIncrs)-1].BalanceInfo != nil && incr.BalanceInfo != nil {
- if cIncrs[len(cIncrs)-1].BalanceInfo.Monetary != nil && incr.BalanceInfo.Monetary != nil {
- cIncrs[len(cIncrs)-1].BalanceInfo.Monetary.Value = incr.BalanceInfo.Monetary.Value
- }
- if cIncrs[len(cIncrs)-1].BalanceInfo.Unit != nil && incr.BalanceInfo.Unit != nil {
- cIncrs[len(cIncrs)-1].BalanceInfo.Unit.Value = incr.BalanceInfo.Unit.Value
- }
- }
- }
- }
- *incs = cIncrs
-}
-
-func (incs *Increments) Decompress() { // must be pointer receiver
- var cIncrs Increments
- for _, cIncr := range *incs {
- cf := cIncr.GetCompressFactor()
- for i := 0; i < cf; i++ {
- incr := cIncr.Clone()
- incr.CompressFactor = 1
- // set right Values
- if incr.BalanceInfo != nil {
- if incr.BalanceInfo.Monetary != nil {
- incr.BalanceInfo.Monetary.Value += (float64(cf-(i+1)) * incr.Cost)
- }
- if incr.BalanceInfo.Unit != nil {
- incr.BalanceInfo.Unit.Value += (float64(cf-(i+1)) * incr.BalanceInfo.Unit.Consumed)
- }
- }
- cIncrs = append(cIncrs, incr)
- }
- }
- *incs = cIncrs
-}
-
-// Estimate whether the increments are the same ignoring the CompressFactor
-func (incs Increments) SharingSignature(other Increments) bool {
- otherCloned := other.Clone()
- thisCloned := incs.Clone()
- otherCloned.Compress()
- thisCloned.Compress()
- if len(otherCloned) < len(thisCloned) { // Protect index in case of not being the same size
- return false
- }
- for index, i := range thisCloned {
- if !i.Equal(otherCloned[index]) {
- return false
- }
- }
- return true
-}
-
-func (incs Increments) GetTotalCost() float64 {
- cost := 0.0
- for _, increment := range incs {
- cost += increment.GetCost()
- }
- return utils.Round(cost, globalRoundingDecimals, utils.MetaRoundingMiddle)
-}
-
-func (incs Increments) Length() (length int) {
- for _, incr := range incs {
- length += incr.GetCompressFactor()
- }
- return
-}
-
-// Returns the duration of the timespan
-func (ts *TimeSpan) GetDuration() time.Duration {
- return ts.TimeEnd.Sub(ts.TimeStart)
-}
-
-//Returns the duration of a unitary timespan in a compressed set
-func (ts *TimeSpan) GetUnitDuration() time.Duration {
- return time.Duration(int(ts.TimeEnd.Sub(ts.TimeStart)) / ts.GetCompressFactor())
-}
-
-func (ts *TimeSpan) GetUnitCost() float64 {
- return ts.Cost / float64(ts.GetCompressFactor())
-}
-
-// Returns true if the given time is inside timespan range.
-func (ts *TimeSpan) Contains(t time.Time) bool {
- return t.After(ts.TimeStart) && t.Before(ts.TimeEnd)
-}
-
-func (ts *TimeSpan) SetRateInterval(interval *RateInterval) {
- if interval == nil {
- return
- }
- if !ts.hasBetterRateIntervalThan(interval) {
- ts.RateInterval = interval
- }
-}
-
-// Returns the cost of the timespan according to the relevant cost interval.
-// It also sets the Cost field of this timespan (used for refund on session
-// manager debit loop where the cost cannot be recalculated)
-func (ts *TimeSpan) CalculateCost() float64 {
- if ts.Increments.Length() == 0 {
- if ts.RateInterval == nil {
- return 0
- }
- return ts.RateInterval.GetCost(ts.GetDuration(), ts.GetGroupStart())
- }
- return ts.Increments.GetTotalCost() * float64(ts.GetCompressFactor())
-}
-
-func (ts *TimeSpan) setRatingInfo(rp *RatingInfo) {
- ts.ratingInfo = rp
- ts.MatchedSubject = rp.MatchedSubject
- ts.MatchedPrefix = rp.MatchedPrefix
- ts.MatchedDestId = rp.MatchedDestId
- ts.RatingPlanId = rp.RatingPlanId
-}
-
-func (ts *TimeSpan) createIncrementsSlice() {
- if ts.RateInterval == nil {
- return
- }
- ts.Increments = make([]*Increment, 0)
- // create rated units series
- _, rateIncrement, _ := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
- // we will use the calculated cost and devide by nb of increments
- // because ts cost is rounded
- //incrementCost := rate / rateUnit.Seconds() * rateIncrement.Seconds()
- nbIncrements := int(ts.GetDuration() / rateIncrement)
- if nbIncrements > config.CgrConfig().RalsCfg().MaxIncrements {
- utils.Logger.Warning(fmt.Sprintf("error: <%s with %+v>, when creating increments slice, TimeSpan: %s", utils.ErrMaxIncrementsExceeded, nbIncrements, utils.ToJSON(ts)))
- return
- }
- incrementCost := ts.CalculateCost() / float64(nbIncrements)
- incrementCost = utils.Round(incrementCost, globalRoundingDecimals, utils.MetaRoundingMiddle)
- for s := 0; s < nbIncrements; s++ {
- inc := &Increment{
- Duration: rateIncrement,
- Cost: incrementCost,
- BalanceInfo: &DebitInfo{},
- }
- ts.Increments = append(ts.Increments, inc)
- }
- // put the rounded cost back in timespan
- ts.Cost = incrementCost * float64(nbIncrements)
-}
-
-// returns whether the timespan has all increments marked as paid and if not
-// it also returns the first unpaied increment
-func (ts *TimeSpan) IsPaid() (bool, int) {
- if ts.Increments.Length() == 0 {
- return false, 0
- }
- for incrementIndex, increment := range ts.Increments {
- if !increment.paid {
- return false, incrementIndex
- }
- }
- return true, len(ts.Increments)
-}
-
-/*
-Splits the given timespan according to how it relates to the interval.
-It will modify the endtime of the received timespan and it will return
-a new timespan starting from the end of the received one.
-The interval will attach itself to the timespan that overlaps the interval.
-*/
-func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSpan) {
- // if the span is not in interval return nil
- //log.Printf("Checking: %+v (%v,%v)", i.Timing, ts.TimeStart, ts.TimeEnd)
- if !(i.Contains(ts.TimeStart, false) || i.Contains(ts.TimeEnd, true)) {
- //log.Print("Not in interval")
- return
- }
- // split by GroupStart
- if i.Rating != nil {
- i.Rating.Rates.Sort()
- for _, rate := range i.Rating.Rates {
- if ts.GetGroupStart() < rate.GroupIntervalStart && ts.GetGroupEnd() > rate.GroupIntervalStart {
- //log.Print("Splitting")
- ts.SetRateInterval(i)
- splitTime := ts.TimeStart.Add(rate.GroupIntervalStart - ts.GetGroupStart())
- nts = &TimeSpan{
- TimeStart: splitTime,
- TimeEnd: ts.TimeEnd,
- }
- nts.copyRatingInfo(ts)
- ts.TimeEnd = splitTime
- nts.SetRateInterval(i)
- nts.DurationIndex = ts.DurationIndex
- ts.SetNewDurationIndex(nts)
- return
- }
- }
- }
- if data {
- if i.Contains(ts.TimeStart, false) {
- ts.SetRateInterval(i)
- }
- return
- }
- // if the span is enclosed in the interval try to set as new interval and return nil
- //log.Printf("Timing: %+v", i.Timing)
- if i.Contains(ts.TimeStart, false) && i.Contains(ts.TimeEnd, true) {
- //log.Print("All in interval")
- ts.SetRateInterval(i)
- return
- }
- // if only the start time is in the interval split the interval to the right
- if i.Contains(ts.TimeStart, false) {
- //log.Print("Start in interval")
- splitTime := i.Timing.getRightMargin(ts.TimeStart)
- ts.SetRateInterval(i)
- if splitTime == ts.TimeStart || splitTime.Equal(ts.TimeEnd) {
- return
- }
- nts = &TimeSpan{
- TimeStart: splitTime,
- TimeEnd: ts.TimeEnd,
- }
- nts.copyRatingInfo(ts)
- ts.TimeEnd = splitTime
- nts.DurationIndex = ts.DurationIndex
- ts.SetNewDurationIndex(nts)
- return
- }
- // if only the end time is in the interval split the interval to the left
- if i.Contains(ts.TimeEnd, true) {
- splitTime := i.Timing.getLeftMargin(ts.TimeEnd)
- splitTime = utils.CopyHour(splitTime, ts.TimeStart)
- if splitTime.Equal(ts.TimeEnd) {
- return
- }
- nts = &TimeSpan{
- TimeStart: splitTime,
- TimeEnd: ts.TimeEnd,
- }
- nts.copyRatingInfo(ts)
- ts.TimeEnd = splitTime
- nts.SetRateInterval(i)
- nts.DurationIndex = ts.DurationIndex
- ts.SetNewDurationIndex(nts)
- return
- }
- return
-}
-
-// Split the timespan at the given increment start
-func (ts *TimeSpan) SplitByIncrement(index int) *TimeSpan {
- if index <= 0 || index >= len(ts.Increments) {
- return nil
- }
- timeStart := ts.GetTimeStartForIncrement(index)
- newTs := &TimeSpan{
- RateInterval: ts.RateInterval,
- TimeStart: timeStart,
- TimeEnd: ts.TimeEnd,
- }
- newTs.copyRatingInfo(ts)
- newTs.DurationIndex = ts.DurationIndex
- ts.TimeEnd = timeStart
- newTs.Increments = ts.Increments[index:]
- ts.Increments = ts.Increments[:index]
- ts.SetNewDurationIndex(newTs)
- return newTs
-}
-
-// Split the timespan at the given second
-func (ts *TimeSpan) SplitByDuration(duration time.Duration) *TimeSpan {
- if duration <= 0 || duration >= ts.GetDuration() {
- return nil
- }
- timeStart := ts.TimeStart.Add(duration)
- newTs := &TimeSpan{
- RateInterval: ts.RateInterval,
- TimeStart: timeStart,
- TimeEnd: ts.TimeEnd,
- }
- newTs.copyRatingInfo(ts)
- newTs.DurationIndex = ts.DurationIndex
- ts.TimeEnd = timeStart
- // split the increment
- for incrIndex, incr := range ts.Increments {
- if duration-incr.Duration >= 0 {
- duration -= incr.Duration
- } else {
-
- splitIncrement := ts.Increments[incrIndex].Clone()
- splitIncrement.Duration -= duration
- ts.Increments[incrIndex].Duration = duration
- newTs.Increments = Increments{splitIncrement}
- if incrIndex < len(ts.Increments)-1 {
- newTs.Increments = append(newTs.Increments, ts.Increments[incrIndex+1:]...)
- }
- ts.Increments = ts.Increments[:incrIndex+1]
- break
- }
- }
- ts.SetNewDurationIndex(newTs)
- return newTs
-}
-
-// Splits the given timespan on activation period's activation time.
-func (ts *TimeSpan) SplitByRatingPlan(rp *RatingInfo) (newTs *TimeSpan) {
- activationTime := rp.ActivationTime.In(ts.TimeStart.Location())
- if !ts.Contains(activationTime) {
- return nil
- }
- newTs = &TimeSpan{
- TimeStart: activationTime,
- TimeEnd: ts.TimeEnd,
- }
- newTs.copyRatingInfo(ts)
- newTs.DurationIndex = ts.DurationIndex
- ts.TimeEnd = activationTime
- ts.SetNewDurationIndex(newTs)
- return
-}
-
-// Splits the given timespan on activation period's activation time.
-func (ts *TimeSpan) SplitByDay() (newTs *TimeSpan) {
- if ts.TimeStart.Day() == ts.TimeEnd.Day() || utils.TimeIs0h(ts.TimeEnd) {
- return
- }
-
- splitDate := ts.TimeStart.AddDate(0, 0, 1)
- splitDate = time.Date(splitDate.Year(), splitDate.Month(), splitDate.Day(), 0, 0, 0, 0, splitDate.Location())
- newTs = &TimeSpan{
- TimeStart: splitDate,
- TimeEnd: ts.TimeEnd,
- }
- newTs.copyRatingInfo(ts)
- newTs.DurationIndex = ts.DurationIndex
- ts.TimeEnd = splitDate
- ts.SetNewDurationIndex(newTs)
- return
-}
-
-// Returns the starting time of this timespan
-func (ts *TimeSpan) GetGroupStart() time.Duration {
- s := ts.DurationIndex - ts.GetDuration()
- if s < 0 {
- s = 0
- }
- return s
-}
-
-func (ts *TimeSpan) GetGroupEnd() time.Duration {
- return ts.DurationIndex
-}
-
-// sets the DurationIndex attribute to reflect new timespan
-func (ts *TimeSpan) SetNewDurationIndex(nts *TimeSpan) {
- d := ts.DurationIndex - nts.GetDuration()
- if d < 0 {
- d = 0
- }
- ts.DurationIndex = d
-}
-
-func (nts *TimeSpan) copyRatingInfo(ts *TimeSpan) {
- if ts.ratingInfo == nil {
- return
- }
- nts.setRatingInfo(ts.ratingInfo)
-}
-
-// returns a time for the specified second in the time span
-func (ts *TimeSpan) GetTimeStartForIncrement(index int) time.Time {
-
- start := ts.TimeStart
- for incIndex, inc := range ts.Increments {
- if incIndex < index {
- start = start.Add(time.Duration(inc.Duration.Nanoseconds()))
- }
- }
- return start
- //return ts.TimeStart.Add(time.Duration(int64(index) * ts.Increments[0].Duration.Nanoseconds()))
-}
-
-func (ts *TimeSpan) RoundToDuration(duration time.Duration) {
- if duration < ts.GetDuration() {
- duration = utils.RoundDuration(duration, ts.GetDuration())
- }
- if duration > ts.GetDuration() {
- initialDuration := ts.GetDuration()
- ts.TimeEnd = ts.TimeStart.Add(duration)
- ts.DurationIndex = ts.DurationIndex + (duration - initialDuration)
- }
-}
-
-func (ts *TimeSpan) AddIncrement(inc *Increment) {
- ts.Increments = append(ts.Increments, inc)
- ts.TimeEnd.Add(inc.Duration)
-}
-
-func (ts *TimeSpan) hasBetterRateIntervalThan(interval *RateInterval) bool {
- if interval.Timing == nil {
- return false
- }
- otherLeftMargin := interval.Timing.getLeftMargin(ts.TimeStart)
- otherDistance := ts.TimeStart.Sub(otherLeftMargin)
- //log.Print("OTHER LEFT: ", otherLeftMargin)
- //log.Print("OTHER DISTANCE: ", otherDistance)
- // if the distance is negative it's not usable
- if otherDistance < 0 {
- return true
- }
- //log.Print("RI: ", ts.RateInterval)
- if ts.RateInterval == nil {
- return false
- }
-
- // the higher the weight the better
- if ts.RateInterval != nil &&
- ts.RateInterval.Weight < interval.Weight {
- return false
- }
- // check interval is closer than the new one
- ownLeftMargin := ts.RateInterval.Timing.getLeftMargin(ts.TimeStart)
- ownDistance := ts.TimeStart.Sub(ownLeftMargin)
-
- // if own interval is closer than its better
- if ownDistance > otherDistance {
- return false
- }
- ownPrice, _, _ := ts.RateInterval.GetRateParameters(ts.GetGroupStart())
- otherPrice, _, _ := interval.GetRateParameters(ts.GetGroupStart())
- // if own price is smaller than it's better
- if ownPrice < otherPrice {
- return true
- }
- return true
-}
-
-func (ts *TimeSpan) Equal(other *TimeSpan) bool {
- return ts.Increments.Equal(other.Increments) &&
- ts.RateInterval.Equal(other.RateInterval) &&
- ts.GetUnitCost() == other.GetUnitCost() &&
- ts.GetUnitDuration() == other.GetUnitDuration() &&
- ts.MatchedSubject == other.MatchedSubject &&
- ts.MatchedPrefix == other.MatchedPrefix &&
- ts.MatchedDestId == other.MatchedDestId &&
- ts.RatingPlanId == other.RatingPlanId
-}
-
-// Estimate if they share charging signature
-func (ts *TimeSpan) SharingSignature(other *TimeSpan) bool {
- if ts.GetCompressFactor() != other.GetCompressFactor() ||
- !ts.Increments.SharingSignature(other.Increments) ||
- !ts.RateInterval.Equal(other.RateInterval) ||
- ts.MatchedSubject != other.MatchedSubject ||
- ts.MatchedPrefix != other.MatchedPrefix ||
- ts.MatchedDestId != other.MatchedDestId ||
- ts.RatingPlanId != other.RatingPlanId {
- return false
- }
- return true
-}
-
-func (ts *TimeSpan) GetCompressFactor() int {
- if ts.CompressFactor == 0 {
- ts.CompressFactor = 1
- }
- return ts.CompressFactor
-}
-
-// Merges timespans if they share the same charging signature, useful to run in SM before compressing
-func (ts *TimeSpan) Merge(other *TimeSpan) bool {
- if !ts.SharingSignature(other) {
- return false
- } else if !ts.TimeEnd.Equal(other.TimeStart) { // other needs to continue ts for merge to be possible
- return false
- }
- ts.TimeEnd = other.TimeEnd
- ts.Cost += other.Cost
- ts.DurationIndex = other.DurationIndex
- ts.Increments = append(ts.Increments, other.Increments...)
- return true
-}
diff --git a/engine/timespans_test.go b/engine/timespans_test.go
deleted file mode 100644
index b14e27ae3..000000000
--- a/engine/timespans_test.go
+++ /dev/null
@@ -1,1995 +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"
- "time"
-
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestRightMargin(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
- t1 := time.Date(2012, time.February, 3, 23, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 4, 0, 10, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 24, 0, 0, 0, time.UTC) {
- t.Error("Incorrect first half", ts)
- }
- if nts.TimeStart != time.Date(2012, time.February, 4, 0, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration() != 15*time.Minute || nts.GetDuration() != 10*time.Minute {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), ts.GetDuration())
- }
-
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestSplitMiddle(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
- StartTime: "18:00:00",
- EndTime: "",
- }}
- ts := &TimeSpan{
- TimeStart: time.Date(2012, 2, 27, 0, 0, 0, 0, time.UTC),
- TimeEnd: time.Date(2012, 2, 28, 0, 0, 0, 0, time.UTC),
- ratingInfo: &RatingInfo{},
- }
-
- if !i.Contains(ts.TimeEnd, true) {
- t.Errorf("%+v should contain %+v", i, ts.TimeEnd)
- }
-
- newTs := ts.SplitByRateInterval(i, false)
- if newTs == nil {
- t.Errorf("Error spliting interval %+v", newTs)
- }
-}
-
-func TestRightHourMargin(t *testing.T) {
- i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, EndTime: "17:59:00"}}
- t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 0, 0, time.UTC) {
- t.Error("Incorrect first half", ts)
- }
- if nts.TimeStart != time.Date(2012, time.February, 3, 17, 59, 0, 0, time.UTC) || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration() != 29*time.Minute || nts.GetDuration() != time.Minute {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), nts.GetDuration())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestLeftMargin(t *testing.T) {
- i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
- t1 := time.Date(2012, time.February, 5, 23, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 6, 0, 10, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) {
- t.Error("Incorrect first half", ts)
- }
- if nts.TimeStart != time.Date(2012, time.February, 6, 0, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if nts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
- if ts.GetDuration().Seconds() != 15*60 || nts.GetDuration().Seconds() != 10*60 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestLeftHourMargin(t *testing.T) {
- i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.December}, MonthDays: utils.MonthDays{1}, StartTime: "09:00:00"}}
- t1 := time.Date(2012, time.December, 1, 8, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.December, 1, 9, 20, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) {
- t.Error("Incorrect first half", ts)
- }
- if nts.TimeStart != time.Date(2012, time.December, 1, 9, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if nts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
- if ts.GetDuration().Seconds() != 15*60 || nts.GetDuration().Seconds() != 20*60 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestEnclosingMargin(t *testing.T) {
- i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Sunday}}}
- t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
- nts := ts.SplitByRateInterval(i, false)
- if ts.TimeStart != t1 || ts.TimeEnd != t2 || nts != nil {
- t.Error("Incorrect enclosing", ts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-}
-
-func TestOutsideMargin(t *testing.T) {
- i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}
- t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2}
- result := ts.SplitByRateInterval(i, false)
- if result != nil {
- t.Error("RateInterval not split correctly")
- }
-}
-
-func TestContains(t *testing.T) {
- t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
- t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
- ts := TimeSpan{TimeStart: t1, TimeEnd: t2}
- if ts.Contains(t1) {
- t.Error("It should NOT contain ", t1)
- }
- if ts.Contains(t2) {
- t.Error("It should NOT contain ", t1)
- }
- if !ts.Contains(t3) {
- t.Error("It should contain ", t3)
- }
-}
-
-func TestSplitByRatingPlan(t *testing.T) {
- t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
- t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
- ts := TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- ap1 := &RatingInfo{ActivationTime: t1}
- ap2 := &RatingInfo{ActivationTime: t2}
- ap3 := &RatingInfo{ActivationTime: t3}
-
- if ts.SplitByRatingPlan(ap1) != nil {
- t.Error("Error spliting on left margin")
- }
- if ts.SplitByRatingPlan(ap2) != nil {
- t.Error("Error spliting on right margin")
- }
- result := ts.SplitByRatingPlan(ap3)
- if result.TimeStart != t3 || result.TimeEnd != t2 {
- t.Error("Error spliting on interior")
- }
-}
-
-func TestTimespanGetCost(t *testing.T) {
- t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
- ts1 := TimeSpan{TimeStart: t1, TimeEnd: t2}
- if ts1.CalculateCost() != 0 {
- t.Error("No interval and still kicking")
- }
- ts1.SetRateInterval(
- &RateInterval{
- Timing: &RITiming{},
- Rating: &RIRate{Rates: RateGroups{&RGRate{0, 1.0, time.Second, time.Second}}},
- },
- )
- if ts1.CalculateCost() != 600 {
- t.Error("Expected 10 got ", ts1.Cost)
- }
- ts1.RateInterval = nil
- ts1.SetRateInterval(&RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{0, 1.0, time.Second, 60 * time.Second}}}})
- if ts1.CalculateCost() != 10 {
- t.Error("Expected 6000 got ", ts1.Cost)
- }
-}
-
-func TestTimespanGetCostIntervals(t *testing.T) {
- ts := &TimeSpan{}
- ts.Increments = make(Increments, 11)
- for i := 0; i < 11; i++ {
- ts.Increments[i] = &Increment{Cost: 0.02}
- }
- if ts.CalculateCost() != 0.22 {
- t.Error("Error caclulating timespan cost: ", ts.CalculateCost())
- }
-}
-
-func TestSetRateInterval(t *testing.T) {
- i1 := &RateInterval{
- Timing: &RITiming{},
- Rating: &RIRate{Rates: RateGroups{&RGRate{0, 1.0, time.Second, time.Second}}},
- }
- ts1 := TimeSpan{RateInterval: i1}
- i2 := &RateInterval{
- Timing: &RITiming{},
- Rating: &RIRate{Rates: RateGroups{&RGRate{0, 2.0, time.Second, time.Second}}},
- }
- if !ts1.hasBetterRateIntervalThan(i2) {
- ts1.SetRateInterval(i2)
- }
- if ts1.RateInterval != i1 {
- t.Error("Smaller price interval should win")
- }
- i2.Weight = 1
- ts1.SetRateInterval(i2)
- if ts1.RateInterval != i2 {
- t.Error("Bigger ponder interval should win")
- }
-}
-
-func TestTimespanSplitGroupedRates(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- EndTime: "17:59:00",
- },
- Rating: &RIRate{
- Rates: RateGroups{&RGRate{0, 2, time.Second, time.Second}, &RGRate{900 * time.Second, 1, time.Second, time.Second}},
- },
- }
- t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 1800 * time.Second, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- splitTime := time.Date(2012, time.February, 3, 17, 45, 00, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", ts.TimeStart, ts.TimeEnd)
- }
- if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
- c1 := ts.RateInterval.GetCost(ts.GetDuration(), ts.GetGroupStart())
- c2 := nts.RateInterval.GetCost(nts.GetDuration(), nts.GetGroupStart())
- if c1 != 1800 || c2 != 900 {
- t.Error("Wrong costs: ", c1, c2)
- }
-
- if ts.GetDuration().Seconds() != 15*60 || nts.GetDuration().Seconds() != 15*60 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- EndTime: "17:59:00",
- },
- Rating: &RIRate{
- Rates: RateGroups{
- &RGRate{
- GroupIntervalStart: 0,
- Value: 2,
- RateIncrement: time.Second,
- RateUnit: time.Second},
- &RGRate{
- GroupIntervalStart: 30 * time.Second,
- Value: 1,
- RateIncrement: time.Minute,
- RateUnit: time.Second,
- }}},
- }
- t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 17, 31, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 60 * time.Second, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- cd := &CallDescriptor{}
- timespans := cd.roundTimeSpansToIncrement([]*TimeSpan{ts, nts})
- if len(timespans) != 2 {
- t.Error("Error rounding timespans: ", timespans)
- }
- ts = timespans[0]
- nts = timespans[1]
- splitTime := time.Date(2012, time.February, 3, 17, 30, 30, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", ts)
- }
- t3 := time.Date(2012, time.February, 3, 17, 31, 30, 0, time.UTC)
- if nts.TimeStart != splitTime || nts.TimeEnd != t3 {
- t.Error("Incorrect second half", nts.TimeStart, nts.TimeEnd)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
- c1 := ts.RateInterval.GetCost(ts.GetDuration(), ts.GetGroupStart())
- c2 := nts.RateInterval.GetCost(nts.GetDuration(), nts.GetGroupStart())
- if c1 != 60 || c2 != 60 {
- t.Error("Wrong costs: ", c1, c2)
- }
-
- if ts.GetDuration().Seconds() != 0.5*60 || nts.GetDuration().Seconds() != 60 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration()+nts.GetDuration() != oldDuration+30*time.Second {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
-}
-
-func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- EndTime: "17:00:30",
- },
- Rating: &RIRate{
- Rates: RateGroups{&RGRate{0, 2, time.Second, time.Second}, &RGRate{60 * time.Second, 1, 60 * time.Second, time.Second}},
- },
- }
- t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 17, 01, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- splitTime := time.Date(2012, time.February, 3, 17, 00, 30, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", ts)
- }
- if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration().Seconds() != 30 || nts.GetDuration().Seconds() != 30 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
- nnts := nts.SplitByRateInterval(i, false)
- if nnts != nil {
- t.Error("Bad new split", nnts)
- }
-}
-
-func TestTimespanSplitGroupSecondSplit(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- EndTime: "17:03:30",
- },
- Rating: &RIRate{
- Rates: RateGroups{&RGRate{0, 2, time.Second, time.Second}, &RGRate{60 * time.Second, 1, time.Second, time.Second}}},
- }
- t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 240 * time.Second, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", nts)
- }
- if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration().Seconds() != 60 || nts.GetDuration().Seconds() != 180 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
- nnts := nts.SplitByRateInterval(i, false)
- nsplitTime := time.Date(2012, time.February, 3, 17, 03, 30, 0, time.UTC)
- if nts.TimeStart != splitTime || nts.TimeEnd != nsplitTime {
- t.Error("Incorrect first half", nts)
- }
- if nnts.TimeStart != nsplitTime || nnts.TimeEnd != t2 {
- t.Error("Incorrect second half", nnts)
- }
- if nts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if nts.GetDuration().Seconds() != 150 || nnts.GetDuration().Seconds() != 30 {
- t.Error("Wrong durations.for RateIntervals", nts.GetDuration().Seconds(), nnts.GetDuration().Seconds())
- }
-}
-
-func TestTimespanSplitLong(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- StartTime: "18:00:00",
- },
- }
- t1 := time.Date(2013, time.October, 9, 9, 0, 0, 0, time.UTC)
- t2 := time.Date(2013, time.October, 10, 20, 0, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: t2.Sub(t1), ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- splitTime := time.Date(2013, time.October, 9, 18, 0, 0, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", nts)
- }
- if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if nts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration() != 9*time.Hour || nts.GetDuration() != 26*time.Hour {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), nts.GetDuration())
- }
- if ts.GetDuration()+nts.GetDuration() != oldDuration {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration(), nts.GetDuration(), oldDuration)
- }
-}
-
-func TestTimespanSplitMultipleGroup(t *testing.T) {
- i := &RateInterval{
- Timing: &RITiming{
- EndTime: "17:05:00",
- },
- Rating: &RIRate{
- Rates: RateGroups{&RGRate{0, 2, time.Second, time.Second}, &RGRate{60 * time.Second, 1, time.Second, time.Second}, &RGRate{180 * time.Second, 1, time.Second, time.Second}}},
- }
- t1 := time.Date(2012, time.February, 3, 17, 00, 0, 0, time.UTC)
- t2 := time.Date(2012, time.February, 3, 17, 04, 0, 0, time.UTC)
- ts := &TimeSpan{TimeStart: t1, TimeEnd: t2, DurationIndex: 240 * time.Second, ratingInfo: &RatingInfo{}}
- oldDuration := ts.GetDuration()
- nts := ts.SplitByRateInterval(i, false)
- splitTime := time.Date(2012, time.February, 3, 17, 01, 00, 0, time.UTC)
- if ts.TimeStart != t1 || ts.TimeEnd != splitTime {
- t.Error("Incorrect first half", nts)
- }
- if nts.TimeStart != splitTime || nts.TimeEnd != t2 {
- t.Error("Incorrect second half", nts)
- }
- if ts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if ts.GetDuration().Seconds() != 60 || nts.GetDuration().Seconds() != 180 {
- t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds())
- }
- if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() {
- t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds())
- }
- nnts := nts.SplitByRateInterval(i, false)
- nsplitTime := time.Date(2012, time.February, 3, 17, 03, 00, 0, time.UTC)
- if nts.TimeStart != splitTime || nts.TimeEnd != nsplitTime {
- t.Error("Incorrect first half", nts)
- }
- if nnts.TimeStart != nsplitTime || nnts.TimeEnd != t2 {
- t.Error("Incorrect second half", nnts)
- }
- if nts.RateInterval != i {
- t.Error("RateInterval not attached correctly")
- }
-
- if nts.GetDuration().Seconds() != 120 || nnts.GetDuration().Seconds() != 60 {
- t.Error("Wrong durations.for RateIntervals", nts.GetDuration().Seconds(), nnts.GetDuration().Seconds())
- }
-}
-
-func TestTimespanExpandingPastEnd(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 60 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 1 {
- t.Error("Error removing overlaped intervals: ", timespans)
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 31, 0, 0, time.UTC)) {
- t.Errorf("Error expanding timespan: %+v", timespans[0])
- }
-}
-
-func TestTimespanExpandingDurationIndex(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 60 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
-
- if len(timespans) != 1 || timespans[0].GetDuration() != time.Minute {
- t.Error("Error setting call duration: ", timespans[0])
- }
-}
-
-func TestTimespanExpandingRoundingPastEnd(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 20, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 15 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 20, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 40, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 2 {
- t.Error("Error removing overlaped intervals: ", timespans[0])
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC)) {
- t.Error("Error expanding timespan: ", timespans[0])
- }
-}
-
-func TestTimespanExpandingPastEndMultiple(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 60 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 40, 0, time.UTC),
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 40, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 50, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 1 {
- t.Error("Error removing overlaped intervals: ", timespans)
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 31, 0, 0, time.UTC)) {
- t.Error("Error expanding timespan: ", timespans[0])
- }
-}
-
-func TestTimespanExpandingPastEndMultipleEqual(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 60 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 40, 0, time.UTC),
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 40, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 31, 00, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 1 {
- t.Error("Error removing overlaped intervals: ", timespans)
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 31, 0, 0, time.UTC)) {
- t.Error("Error expanding timespan: ", timespans[0])
- }
-}
-
-func TestTimespanExpandingBeforeEnd(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 45 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 31, 0, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 2 {
- t.Error("Error removing overlaped intervals: ", timespans)
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC)) ||
- !timespans[1].TimeStart.Equal(time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC)) ||
- !timespans[1].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 31, 0, 0, time.UTC)) {
- t.Error("Error expanding timespan: ", timespans[0])
- }
-}
-
-func TestTimespanExpandingBeforeEndMultiple(t *testing.T) {
- timespans := []*TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{RateIncrement: 45 * time.Second},
- }}},
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 50, 0, time.UTC),
- },
- {
- TimeStart: time.Date(2013, 9, 10, 14, 30, 50, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 31, 00, 0, time.UTC),
- },
- }
- cd := &CallDescriptor{}
- timespans = cd.roundTimeSpansToIncrement(timespans)
- if len(timespans) != 3 {
- t.Error("Error removing overlaped intervals: ", timespans)
- }
- if !timespans[0].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC)) ||
- !timespans[1].TimeStart.Equal(time.Date(2013, 9, 10, 14, 30, 45, 0, time.UTC)) ||
- !timespans[1].TimeEnd.Equal(time.Date(2013, 9, 10, 14, 30, 50, 0, time.UTC)) {
- t.Error("Error expanding timespan: ", timespans[0])
- }
-}
-
-func TestTimespanCreateSecondsSlice(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
- RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{
- &RGRate{Value: 2.0},
- }}},
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 30 {
- t.Error("Error creating second slice: ", ts.Increments)
- }
- if ts.Increments[0].Cost != 2.0 {
- t.Error("Wrong second slice: ", ts.Increments[0])
- }
-}
-
-func TestTimespanCreateIncrements(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 100000000, time.UTC),
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 3 {
- t.Error("Error creating increment slice: ", len(ts.Increments))
- }
- if len(ts.Increments) < 3 || ts.Increments[2].Cost != 20.066667 {
- t.Error("Wrong second slice: ", ts.Increments[2].Cost)
- }
-}
-
-func TestTimespanSplitByIncrement(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
- DurationIndex: 60 * time.Second,
- ratingInfo: &RatingInfo{},
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 6 {
- t.Error("Error creating increment slice: ", len(ts.Increments))
- }
- newTs := ts.SplitByIncrement(5)
- if ts.GetDuration() != 50*time.Second || newTs.GetDuration() != 10*time.Second {
- t.Error("Error spliting by increment: ", ts.GetDuration(), newTs.GetDuration())
- }
- if ts.DurationIndex != 50*time.Second || newTs.DurationIndex != 60*time.Second {
- t.Error("Error spliting by increment at setting call duration: ", ts.DurationIndex, newTs.DurationIndex)
- }
- if len(ts.Increments) != 5 || len(newTs.Increments) != 1 {
- t.Error("Error spliting increments: ", ts.Increments, newTs.Increments)
- }
-}
-
-func TestTimespanSplitByIncrementStart(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
- DurationIndex: 60 * time.Second,
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 6 {
- t.Error("Error creating increment slice: ", len(ts.Increments))
- }
- newTs := ts.SplitByIncrement(0)
- if ts.GetDuration() != 60*time.Second || newTs != nil {
- t.Error("Error spliting by increment: ", ts.GetDuration())
- }
- if ts.DurationIndex != 60*time.Second {
- t.Error("Error spliting by incrementat setting call duration: ", ts.DurationIndex)
- }
- if len(ts.Increments) != 6 {
- t.Error("Error spliting increments: ", ts.Increments)
- }
-}
-
-func TestTimespanSplitByIncrementEnd(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
- DurationIndex: 60 * time.Second,
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 6 {
- t.Error("Error creating increment slice: ", len(ts.Increments))
- }
- newTs := ts.SplitByIncrement(6)
- if ts.GetDuration() != 60*time.Second || newTs != nil {
- t.Error("Error spliting by increment: ", ts.GetDuration())
- }
- if ts.DurationIndex != 60*time.Second {
- t.Error("Error spliting by increment at setting call duration: ", ts.DurationIndex)
- }
- if len(ts.Increments) != 6 {
- t.Error("Error spliting increments: ", ts.Increments)
- }
-}
-
-func TestTimespanSplitByDuration(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
- DurationIndex: 60 * time.Second,
- ratingInfo: &RatingInfo{},
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- }
- ts.createIncrementsSlice()
- if len(ts.Increments) != 6 {
- t.Error("Error creating increment slice: ", len(ts.Increments))
- }
- newTs := ts.SplitByDuration(46 * time.Second)
- if ts.GetDuration() != 46*time.Second || newTs.GetDuration() != 14*time.Second {
- t.Error("Error spliting by duration: ", ts.GetDuration(), newTs.GetDuration())
- }
- if ts.DurationIndex != 46*time.Second || newTs.DurationIndex != 60*time.Second {
- t.Error("Error spliting by duration at setting call duration: ", ts.DurationIndex, newTs.DurationIndex)
- }
- if len(ts.Increments) != 5 || len(newTs.Increments) != 2 {
- t.Error("Error spliting increments: ", ts.Increments, newTs.Increments)
- }
- if ts.Increments[4].Duration != 6*time.Second || newTs.Increments[0].Duration != 4*time.Second {
- t.Error("Error spliting increment: ", ts.Increments[4], newTs.Increments[0])
- }
-}
-
-func TestRemoveOverlapedFromIndexMiddle(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(1)
- if len(tss) != 3 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(1)
- if len(tss) != 4 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC) ||
- tss[2].TimeStart != time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(1)
- if len(tss) != 3 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC) ||
- tss[2].TimeStart != time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexEnd(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(1)
- if len(tss) != 2 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexEndPast(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 50, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(1)
- if len(tss) != 2 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 50, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexAll(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(0)
- if len(tss) != 1 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexNone(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(0)
- if len(tss) != 4 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexOne(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(0)
- if len(tss) != 1 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestRemoveOverlapedFromIndexTwo(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 50, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- }
- (&tss).RemoveOverlapedFromIndex(0)
- if len(tss) != 1 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 50, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error removing overlaped timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansMiddleLong(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 1)
- if len(tss) != 3 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansMiddleMedium(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 1)
- if len(tss) != 4 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansMiddleShort(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 1)
- if len(tss) != 5 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 46, 30, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[4].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansStart(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 0)
- if len(tss) != 3 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansAlmostEnd(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 3)
- if len(tss) != 5 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 48, 30, 0, time.UTC) ||
- tss[4].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansEnd(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 3)
- if len(tss) != 4 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansPastEnd(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 3)
- if len(tss) != 4 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC) ||
- tss[2].TimeEnd != time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC) ||
- tss[3].TimeEnd != time.Date(2013, 12, 5, 15, 49, 30, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansAll(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 0)
- if len(tss) != 1 ||
- tss[0].TimeStart != time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC) ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansAllPast(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 46, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 47, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- },
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 0)
- if len(tss) != 1 ||
- tss[0].TimeStart != time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC) ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 49, 30, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestOverlapWithTimeSpansOne(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC),
- },
- }
- newTss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC),
- },
- }
- (&tss).OverlapWithTimeSpans(newTss, nil, 0)
- if len(tss) != 2 ||
- tss[0].TimeEnd != time.Date(2013, 12, 5, 15, 47, 30, 0, time.UTC) ||
- tss[1].TimeEnd != time.Date(2013, 12, 5, 15, 49, 0, 0, time.UTC) {
- for _, ts := range tss {
- t.Logf("TS: %v", ts)
- }
- t.Error("Error overlaping with timespans timespans: ", tss)
- }
-}
-
-func TestIncrementsCompressDecompress(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- Increments: Increments{
- &Increment{
- Duration: time.Minute,
- Cost: 2,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", Value: 25, DestinationID: "1", Consumed: 1, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2", Value: 98},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 2,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", Value: 24, DestinationID: "1", Consumed: 1, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2", Value: 96},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 2,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", Value: 23, DestinationID: "1", Consumed: 1, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2", Value: 94},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 2,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", Value: 22, DestinationID: "1", Consumed: 1, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2", Value: 92},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 2,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", Value: 21, DestinationID: "1", Consumed: 1, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2", Value: 90},
- AccountID: "3"},
- },
- },
- },
- }
- tss.Compress()
- if len(tss[0].Increments) != 3 {
- t.Error("Error compressing timespan: ", utils.ToIJSON(tss[0]))
- }
- tss.Decompress()
- if len(tss[0].Increments) != 5 {
- t.Error("Error decompressing timespans: ", utils.ToIJSON(tss[0]))
- }
-}
-
-func TestMultipleIncrementsCompressDecompress(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- Increments: Increments{
- &Increment{
- Duration: time.Minute,
- Cost: 10.4,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 10.4,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 10.4,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 10.4,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 1111 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 10.4,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- },
- },
- }
- tss.Compress()
- if len(tss[0].Increments) != 3 {
- t.Error("Error compressing timespan: ", tss[0].Increments)
- }
- tss.Decompress()
- if len(tss[0].Increments) != 5 {
- t.Error("Error decompressing timespans: ", tss[0].Increments)
- }
-}
-
-func TestBetterIntervalZero(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}}
- if !ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalBefore(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "07:00:00"}}
- if !ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalEqual(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}}
- if !ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalAfter(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "13:00:00"}}
- if !ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalBetter(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "08:00:00"}}
- if ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalBetterHour(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "06:00:00"}}
- if ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestBetterIntervalAgainAfter(t *testing.T) {
- ts := &TimeSpan{
- TimeStart: time.Date(2015, 4, 27, 8, 0, 0, 0, time.UTC),
- RateInterval: &RateInterval{Timing: &RITiming{StartTime: "00:00:00"}},
- }
-
- interval := &RateInterval{Timing: &RITiming{StartTime: "13:00:00"}}
- if !ts.hasBetterRateIntervalThan(interval) {
- t.Error("Wrong better rate interval!")
- }
-}
-
-func TestCompressDecompress(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- Cost: 1.2,
- DurationIndex: time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- Cost: 1.2,
- DurationIndex: 2 * time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
- Cost: 1.2,
- DurationIndex: 3 * time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
- Cost: 1.2,
- DurationIndex: 4 * time.Minute,
- },
- }
- tss.Compress()
- if len(tss) != 1 ||
- !tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
- !tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
- tss[0].DurationIndex != 4*time.Minute ||
- tss[0].Cost != 4.8 ||
- tss[0].CompressFactor != 4 {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error compressing timespans: ", tss)
- }
- tss.Decompress()
- if len(tss) != 4 ||
- !tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
- !tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- tss[0].DurationIndex != time.Minute ||
- tss[0].CompressFactor != 1 ||
- tss[0].Cost != 1.2 ||
- !tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- !tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- tss[1].DurationIndex != 2*time.Minute ||
- tss[1].CompressFactor != 1 ||
- tss[1].Cost != 1.2 ||
- !tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- !tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
- tss[2].DurationIndex != 3*time.Minute ||
- tss[2].CompressFactor != 1 ||
- tss[2].Cost != 1.2 ||
- !tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
- !tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
- tss[3].DurationIndex != 4*time.Minute ||
- tss[3].CompressFactor != 1 ||
- tss[3].Cost != 1.2 {
- for i, ts := range tss {
- t.Logf("TS(%d): %+v", i, ts)
- }
- t.Error("Error decompressing timespans: ", tss)
- }
-}
-
-func TestDifferentCompressDecompress(t *testing.T) {
- tss := TimeSpans{
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- RateInterval: &RateInterval{Weight: 1},
- Cost: 1.2,
- DurationIndex: time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- RateInterval: &RateInterval{Weight: 2},
- Cost: 1.2,
- DurationIndex: 2 * time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
- RateInterval: &RateInterval{Weight: 1},
- Cost: 1.2,
- DurationIndex: 3 * time.Minute,
- },
- &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
- RateInterval: &RateInterval{Weight: 1},
- Cost: 1.2,
- DurationIndex: 4 * time.Minute,
- },
- }
- tss.Compress()
- if len(tss) != 3 ||
- !tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
- !tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- tss[0].DurationIndex != time.Minute ||
- tss[0].Cost != 1.2 ||
- !tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- !tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- tss[1].DurationIndex != 2*time.Minute ||
- tss[1].Cost != 1.2 ||
- !tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- !tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
- tss[2].DurationIndex != 4*time.Minute ||
- tss[2].Cost != 2.4 {
- for _, ts := range tss {
- t.Logf("TS: %+v", ts)
- }
- t.Error("Error compressing timespans: ", tss)
- }
- tss.Decompress()
- if len(tss) != 4 ||
- !tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
- !tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- tss[0].DurationIndex != time.Minute ||
- tss[0].CompressFactor != 1 ||
- tss[0].Cost != 1.2 ||
- !tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
- !tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- tss[1].DurationIndex != 2*time.Minute ||
- tss[1].CompressFactor != 1 ||
- tss[1].Cost != 1.2 ||
- !tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
- !tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
- tss[2].DurationIndex != 3*time.Minute ||
- tss[2].CompressFactor != 1 ||
- tss[2].Cost != 1.2 ||
- !tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
- !tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
- tss[3].DurationIndex != 4*time.Minute ||
- tss[3].CompressFactor != 1 ||
- tss[3].Cost != 1.2 {
- for i, ts := range tss {
- t.Logf("TS(%d): %+v", i, ts)
- }
- t.Error("Error decompressing timespans: ", tss)
- }
-}
-
-func TestMerge(t *testing.T) {
- tss1 := &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- Cost: 3,
- DurationIndex: time.Minute,
- Increments: Increments{
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- CompressFactor: 3,
- },
- },
- }
- tss2 := &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- Cost: 2,
- DurationIndex: 2 * time.Minute,
- Increments: Increments{
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- },
- },
- }
- eMergedTSS := &TimeSpan{
- TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
- TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
- RateInterval: &RateInterval{
- Rating: &RIRate{
- RoundingMethod: utils.MetaRoundingMiddle,
- RoundingDecimals: 2,
- Rates: RateGroups{
- &RGRate{
- Value: 2.0,
- RateIncrement: 10 * time.Second,
- },
- },
- },
- },
- Cost: 5,
- DurationIndex: 2 * time.Minute,
- Increments: Increments{
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- CompressFactor: 3,
- },
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- CompressFactor: 1,
- },
- &Increment{
- Duration: time.Minute,
- Cost: 1,
- BalanceInfo: &DebitInfo{
- Unit: &UnitInfo{UUID: "1", DestinationID: "1", Consumed: 2.3, ToR: utils.MetaVoice, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&RGRate{GroupIntervalStart: 0, Value: 100, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}},
- Monetary: &MonetaryInfo{UUID: "2"},
- AccountID: "3"},
- CompressFactor: 1,
- },
- },
- CompressFactor: 1,
- }
- if merged := tss1.Merge(tss2); !merged {
- t.Error("Not merged")
- } else if !tss1.Equal(eMergedTSS) {
- t.Errorf("Expecting: %+v, received: %+v", eMergedTSS, tss1)
- }
-}
-
-func TestIncrementClone(t *testing.T) {
- incr := &Increment{}
- eOut := &Increment{}
- if clone := incr.Clone(); !reflect.DeepEqual(eOut, clone) {
- t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eOut), utils.ToJSON(clone))
- }
- incr = &Increment{
- Duration: 10,
- Cost: 0.7,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{AccountID: "AccountID_test"},
- }
- eOut = &Increment{
- Duration: 10,
- Cost: 0.7,
- CompressFactor: 10,
- BalanceInfo: &DebitInfo{AccountID: "AccountID_test"},
- }
- if clone := incr.Clone(); !reflect.DeepEqual(eOut, clone) {
- t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(eOut), utils.ToJSON(clone))
- }
-}
diff --git a/engine/tpexporter.go b/engine/tpexporter.go
index a83d73ade..c8f84b6af 100644
--- a/engine/tpexporter.go
+++ b/engine/tpexporter.go
@@ -108,18 +108,6 @@ func (tpExp *TPExporter) Run() error {
}
}
- storDataActions, err := tpExp.storDb.GetTPActions(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.TpActions))
- withError = true
- }
- for _, sd := range storDataActions {
- sdModels := APItoModelAction(sd)
- for _, sdModel := range sdModels {
- toExportMap[utils.ActionsCsv] = append(toExportMap[utils.ActionsCsv], sdModel)
- }
- }
-
storDataResources, err := tpExp.storDb.GetTPResources(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.TpResources))
diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go
index 0ac83a5cd..2d770217e 100644
--- a/engine/tpimporter_csv.go
+++ b/engine/tpimporter_csv.go
@@ -42,7 +42,6 @@ type TPCSVImporter struct {
var fileHandlers = map[string]func(*TPCSVImporter, string) error{
utils.TimingsCsv: (*TPCSVImporter).importTimings,
utils.DestinationsCsv: (*TPCSVImporter).importDestinations,
- utils.ActionsCsv: (*TPCSVImporter).importActions,
utils.ResourcesCsv: (*TPCSVImporter).importResources,
utils.StatsCsv: (*TPCSVImporter).importStats,
utils.ThresholdsCsv: (*TPCSVImporter).importThresholds,
@@ -108,21 +107,6 @@ func (tpImp *TPCSVImporter) importDestinations(fn string) error {
return tpImp.StorDb.SetTPDestinations(tps)
}
-func (tpImp *TPCSVImporter) importActions(fn string) error {
- if tpImp.Verbose {
- log.Printf("Processing file: <%s> ", fn)
- }
- tps, err := tpImp.csvr.GetTPActions(tpImp.TPid, "")
- if err != nil {
- return err
- }
- for i := 0; i < len(tps); i++ {
- tps[i].TPid = tpImp.TPid
- }
-
- return tpImp.StorDb.SetTPActions(tps)
-}
-
func (tpImp *TPCSVImporter) importResources(fn string) error {
if tpImp.Verbose {
log.Printf("Processing file: <%s> ", fn)
diff --git a/engine/tpreader.go b/engine/tpreader.go
index 412262f3c..30fe93ef1 100644
--- a/engine/tpreader.go
+++ b/engine/tpreader.go
@@ -23,11 +23,9 @@ import (
"fmt"
"log"
"strconv"
- "strings"
"time"
"github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/structmatcher"
"github.com/cgrates/cgrates/utils"
)
@@ -36,7 +34,6 @@ type TpReader struct {
timezone string
dm *DataManager
lr LoadReader
- actions map[string][]*Action
destinations map[string]*Destination
timings map[string]*utils.TPTiming
resProfiles map[utils.TenantID]*utils.TPResourceProfile
@@ -80,7 +77,6 @@ func NewTpReader(db DataDB, lr LoadReader, tpid, timezone string,
}
func (tpr *TpReader) Init() {
- tpr.actions = make(map[string][]*Action)
tpr.destinations = make(map[string]*Destination)
tpr.timings = make(map[string]*utils.TPTiming)
tpr.resProfiles = make(map[utils.TenantID]*utils.TPResourceProfile)
@@ -149,114 +145,6 @@ func (tpr *TpReader) LoadTimings() (err error) {
return err
}
-func (tpr *TpReader) LoadActions() (err error) {
- tps, err := tpr.lr.GetTPActions(tpr.tpid, "")
- if err != nil {
- return err
- }
- storActs := MapTPActions(tps)
- // map[string][]*Action
- for tag, tpacts := range storActs {
- acts := make([]*Action, len(tpacts))
- for idx, tpact := range tpacts {
- // check filter field
- if len(tpact.Filter) > 0 {
- if _, err := structmatcher.NewStructMatcher(tpact.Filter); err != nil {
- return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
- }
- }
- acts[idx] = &Action{
- Id: tag,
- ActionType: tpact.Identifier,
- Weight: tpact.Weight,
- ExtraParameters: tpact.ExtraParameters,
- ExpirationString: tpact.ExpiryTime,
- Filter: tpact.Filter,
- Balance: &BalanceFilter{},
- }
- if tpact.BalanceId != "" && tpact.BalanceId != utils.MetaAny {
- acts[idx].Balance.ID = utils.StringPointer(tpact.BalanceId)
- }
- if tpact.BalanceType != "" && tpact.BalanceType != utils.MetaAny {
- acts[idx].Balance.Type = utils.StringPointer(tpact.BalanceType)
- }
-
- if tpact.Units != "" && tpact.Units != utils.MetaAny {
- vf, err := utils.ParseBalanceFilterValue(tpact.BalanceType, tpact.Units)
- if err != nil {
- return err
- }
- acts[idx].Balance.Value = vf
- }
-
- if tpact.BalanceWeight != "" && tpact.BalanceWeight != utils.MetaAny {
- u, err := strconv.ParseFloat(tpact.BalanceWeight, 64)
- if err != nil {
- return err
- }
- acts[idx].Balance.Weight = utils.Float64Pointer(u)
- }
-
- if tpact.RatingSubject != "" && tpact.RatingSubject != utils.MetaAny {
- acts[idx].Balance.RatingSubject = utils.StringPointer(tpact.RatingSubject)
- }
-
- if tpact.Categories != "" && tpact.Categories != utils.MetaAny {
- acts[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(tpact.Categories))
- }
- if tpact.DestinationIds != "" && tpact.DestinationIds != utils.MetaAny {
- acts[idx].Balance.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(tpact.DestinationIds))
- }
- if tpact.SharedGroups != "" && tpact.SharedGroups != utils.MetaAny {
- acts[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(tpact.SharedGroups))
- }
- if tpact.TimingTags != "" && tpact.TimingTags != utils.MetaAny {
- acts[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(tpact.TimingTags))
- }
- if tpact.BalanceBlocker != "" && tpact.BalanceBlocker != utils.MetaAny {
- u, err := strconv.ParseBool(tpact.BalanceBlocker)
- if err != nil {
- return err
- }
- acts[idx].Balance.Blocker = utils.BoolPointer(u)
- }
- if tpact.BalanceDisabled != "" && tpact.BalanceDisabled != utils.MetaAny {
- u, err := strconv.ParseBool(tpact.BalanceDisabled)
- if err != nil {
- return err
- }
- acts[idx].Balance.Disabled = utils.BoolPointer(u)
- }
-
- // load action timings from tags
- if tpact.TimingTags != "" {
- timingIds := strings.Split(tpact.TimingTags, utils.InfieldSep)
- for _, timingID := range timingIds {
- timing, found := tpr.timings[timingID]
- if !found {
- if timing, err = tpr.dm.GetTiming(timingID, false,
- utils.NonTransactional); err != nil {
- return fmt.Errorf("error: <%s> querying timing with id: <%s>",
- err.Error(), timingID)
- }
- }
- acts[idx].Balance.Timings = append(acts[idx].Balance.Timings, &RITiming{
- ID: timingID,
- Years: timing.Years,
- Months: timing.Months,
- MonthDays: timing.MonthDays,
- WeekDays: timing.WeekDays,
- StartTime: timing.StartTime,
- EndTime: timing.EndTime,
- })
- }
- }
- }
- tpr.actions[tag] = acts
- }
- return nil
-}
-
func (tpr *TpReader) LoadResourceProfilesFiltered(tag string) (err error) {
rls, err := tpr.lr.GetTPResources(tpr.tpid, "", tag)
if err != nil {
@@ -510,9 +398,6 @@ func (tpr *TpReader) LoadAll() (err error) {
if err = tpr.LoadTimings(); err != nil && err.Error() != utils.NotFoundCaps {
return
}
- if err = tpr.LoadActions(); err != nil && err.Error() != utils.NotFoundCaps {
- return
- }
if err = tpr.LoadFilters(); err != nil && err.Error() != utils.NotFoundCaps {
return
}
@@ -575,21 +460,6 @@ func (tpr *TpReader) WriteToDatabase(verbose, disableReverse bool) (err error) {
loadIDs[utils.CacheReverseDestinations] = loadID
}
- if verbose {
- log.Print("Actions:")
- }
- for k, as := range tpr.actions {
- if err = tpr.dm.SetActions(k, as, utils.NonTransactional); err != nil {
- return
- }
- if verbose {
- log.Println("\t", k)
- }
- }
- if len(tpr.actions) != 0 {
- loadIDs[utils.CacheActions] = loadID
- }
-
if verbose {
log.Print("Filters:")
}
@@ -922,16 +792,7 @@ func (tpr *TpReader) WriteToDatabase(verbose, disableReverse bool) (err error) {
if len(tpr.timings) != 0 {
loadIDs[utils.CacheTimings] = loadID
}
- if !disableReverse {
- if len(tpr.acntActionPlans) > 0 {
- if verbose {
- log.Print("Rebuilding account action plans")
- }
- if err = tpr.dm.RebuildReverseForPrefix(utils.AccountActionPlansPrefix); err != nil {
- return
- }
- }
- }
+
return tpr.dm.SetLoadIDs(loadIDs)
}
@@ -950,8 +811,6 @@ func (tpr *TpReader) ShowStatistics() {
for k, v := range prefixDist {
log.Printf("%d: %d", k, v)
}
- // actions
- log.Print("Actions: ", len(tpr.actions))
// resource profiles
log.Print("ResourceProfiles: ", len(tpr.resProfiles))
// stats
@@ -995,15 +854,6 @@ func (tpr *TpReader) GetLoadedIds(categ string) ([]string, error) {
}
}
return keys.AsSlice(), nil
- case utils.ActionPrefix:
- keys := make([]string, len(tpr.actions))
- i := 0
- for k := range tpr.actions {
- keys[i] = k
- i++
- }
- return keys, nil
-
case utils.ResourceProfilesPrefix:
keys := make([]string, len(tpr.resProfiles))
i := 0
@@ -1110,17 +960,7 @@ func (tpr *TpReader) RemoveFromDatabase(verbose, disableReverse bool) (err error
log.Print("\t", d.Id, " : ", d.Prefixes)
}
}
- if verbose {
- log.Print("Actions:")
- }
- for k := range tpr.actions {
- if err = tpr.dm.RemoveActions(k, utils.NonTransactional); err != nil {
- return
- }
- if verbose {
- log.Println("\t", k)
- }
- }
+
if verbose {
log.Print("ResourceProfiles:")
}
@@ -1310,14 +1150,6 @@ func (tpr *TpReader) RemoveFromDatabase(verbose, disableReverse bool) (err error
return
}
}
- if len(tpr.acntActionPlans) > 0 {
- if verbose {
- log.Print("Removing account action plans")
- }
- if err = tpr.dm.DataDB().RemoveKeysForPrefix(utils.AccountActionPlansPrefix); err != nil {
- return
- }
- }
}
//We remove the filters at the end because of indexes
if verbose {
@@ -1336,12 +1168,6 @@ func (tpr *TpReader) RemoveFromDatabase(verbose, disableReverse bool) (err error
loadIDs[utils.CacheDestinations] = loadID
loadIDs[utils.CacheReverseDestinations] = loadID
}
- if len(tpr.acntActionPlans) != 0 {
- loadIDs[utils.CacheAccountActionPlans] = loadID
- }
- if len(tpr.actions) != 0 {
- loadIDs[utils.CacheActions] = loadID
- }
if len(tpr.filters) != 0 {
loadIDs[utils.CacheFilters] = loadID
}
@@ -1404,14 +1230,8 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i
// take IDs for each type
dstIds, _ := tpr.GetLoadedIds(utils.DestinationPrefix)
revDstIDs, _ := tpr.GetLoadedIds(utils.ReverseDestinationPrefix)
- rplIds, _ := tpr.GetLoadedIds(utils.RatingPlanPrefix)
- rpfIds, _ := tpr.GetLoadedIds(utils.RatingProfilePrefix)
- actIds, _ := tpr.GetLoadedIds(utils.ActionPrefix)
- aapIDs, _ := tpr.GetLoadedIds(utils.AccountActionPlansPrefix)
- shgIds, _ := tpr.GetLoadedIds(utils.SharedGroupPrefix)
rspIDs, _ := tpr.GetLoadedIds(utils.ResourceProfilesPrefix)
resIDs, _ := tpr.GetLoadedIds(utils.ResourcesPrefix)
- aatIDs, _ := tpr.GetLoadedIds(utils.ActionTriggerPrefix)
stqIDs, _ := tpr.GetLoadedIds(utils.StatQueuePrefix)
stqpIDs, _ := tpr.GetLoadedIds(utils.StatQueueProfilePrefix)
trsIDs, _ := tpr.GetLoadedIds(utils.ThresholdPrefix)
@@ -1424,7 +1244,6 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i
dphIDs, _ := tpr.GetLoadedIds(utils.DispatcherHostPrefix)
ratePrfIDs, _ := tpr.GetLoadedIds(utils.RateProfilePrefix)
actionPrfIDs, _ := tpr.GetLoadedIds(utils.ActionProfilePrefix)
- aps, _ := tpr.GetLoadedIds(utils.ActionPlanPrefix)
accountPrfIDs, _ := tpr.GetLoadedIds(utils.AccountProfilePrefix)
//compose Reload Cache argument
@@ -1433,15 +1252,8 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i
ArgsCache: map[string][]string{
utils.DestinationIDs: dstIds,
utils.ReverseDestinationIDs: revDstIDs,
- utils.RatingPlanIDs: rplIds,
- utils.RatingProfileIDs: rpfIds,
- utils.ActionIDs: actIds,
- utils.ActionPlanIDs: aps,
- utils.AccountActionPlanIDs: aapIDs,
- utils.SharedGroupIDs: shgIds,
utils.ResourceProfileIDs: rspIDs,
utils.ResourceIDs: resIDs,
- utils.ActionTriggerIDs: aatIDs,
utils.StatsQueueIDs: stqIDs,
utils.StatsQueueProfileIDs: stqpIDs,
utils.ThresholdIDs: trsIDs,
@@ -1544,20 +1356,20 @@ func (tpr *TpReader) ReloadCache(caching string, verbose bool, opts map[string]i
return
}
-func (tpr *TpReader) ReloadScheduler(verbose bool) (err error) {
- var reply string
- aps, _ := tpr.GetLoadedIds(utils.ActionPlanPrefix)
- // in case we have action plans reload the scheduler
- if len(aps) == 0 {
- return
- }
- if verbose {
- log.Print("Reloading scheduler")
- }
- if err = connMgr.Call(tpr.schedulerConns, nil, utils.SchedulerSv1Reload,
- new(utils.CGREvent), &reply); err != nil {
- log.Printf("WARNING: Got error on scheduler reload: %s\n", err.Error())
- }
+func (tpr *TpReader) ReloadScheduler(verbose bool) (err error) { // ToDoNext: add reload to new actions
+ // var reply string
+ // aps, _ := tpr.GetLoadedIds(utils.ActionPlanPrefix)
+ // // in case we have action plans reload the scheduler
+ // if len(aps) == 0 {
+ // return
+ // }
+ // if verbose {
+ // log.Print("Reloading scheduler")
+ // }
+ // if err = connMgr.Call(tpr.schedulerConns, nil, utils.SchedulerSv1Reload,
+ // new(utils.CGREvent), &reply); err != nil {
+ // log.Printf("WARNING: Got error on scheduler reload: %s\n", err.Error())
+ // }
return
}
diff --git a/engine/units_counter.go b/engine/units_counter.go
index 7eca6a478..79cea1745 100644
--- a/engine/units_counter.go
+++ b/engine/units_counter.go
@@ -18,10 +18,6 @@ along with this program. If not, see
package engine
-import (
- "github.com/cgrates/cgrates/utils"
-)
-
// Amount of a trafic of a certain type
type UnitCounter struct {
CounterType string // *event or *balance
@@ -106,48 +102,3 @@ func (uc *UnitCounter) CopyCounterValues(oldUc *UnitCounter) bool {
}
type UnitCounters map[string][]*UnitCounter
-
-func (ucs UnitCounters) addUnits(amount float64, kind string, cc *CallCost, b *Balance) {
- counters, found := ucs[kind]
- if !found {
- return
- }
- for _, uc := range counters {
- if uc == nil { // safeguard
- continue
- }
- if uc.CounterType == "" {
- uc.CounterType = utils.MetaCounterEvent
- }
- for _, c := range uc.Counters {
- if uc.CounterType == utils.MetaCounterEvent && cc != nil && cc.MatchCCFilter(c.Filter) {
- c.Value += amount
- continue
- }
-
- if uc.CounterType == utils.MetaBalance && b != nil && b.MatchFilter(c.Filter, true, false) {
- c.Value += amount
- continue
- }
- }
-
- }
-}
-
-func (ucs UnitCounters) resetCounters(a *Action) {
- for key, counters := range ucs {
- if a != nil && a.Balance.Type != nil && a.Balance.GetType() != key {
- continue
- }
- for _, c := range counters {
- if c == nil { // safeguard
- continue
- }
- for _, cf := range c.Counters {
- if a == nil || a.Balance == nil || cf.Filter.Equal(a.Balance) {
- cf.Value = 0
- }
- }
- }
- }
-}
diff --git a/migrator/accounts.go b/migrator/accounts.go
deleted file mode 100755
index b596f6fb1..000000000
--- a/migrator/accounts.go
+++ /dev/null
@@ -1,439 +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 (
- "errors"
- "fmt"
- "log"
- "strings"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-const (
- v1AccountDBPrefix = "ubl_"
- v1AccountTBL = "userbalances"
-)
-
-func (m *Migrator) migrateCurrentAccounts() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.AccountPrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.AccountPrefix)
- acc, err := m.dmIN.DataManager().GetAccount(idg)
- if err != nil {
- return err
- }
- if acc == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetAccount(acc); err != nil {
- return err
- }
- if err := m.dmIN.DataManager().RemoveAccount(idg); err != nil {
- return err
- }
- m.stats[utils.Accounts]++
- }
- return
-}
-
-func (m *Migrator) removeV1Accounts() (err error) {
- var v1Acnt *v1Account
- for {
- v1Acnt, err = m.dmIN.getv1Account()
- if err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if err == utils.ErrNoMoreData {
- break
- }
- if err = m.dmIN.remV1Account(v1Acnt.Id); err != nil {
- return err
- }
- }
- return
-}
-
-func (m *Migrator) migrateV1Accounts() (v3Acnt *engine.Account, err error) {
- var v1Acnt *v1Account
- v1Acnt, err = m.dmIN.getv1Account()
- if err != nil {
- return nil, err
- } else if v1Acnt == nil {
- return nil, errors.New("Account is nil")
- }
- v3Acnt = v1Acnt.V1toV3Account()
- return
-}
-
-func (m *Migrator) removeV2Accounts() (err error) {
- var v2Acnt *v2Account
- for {
- v2Acnt, err = m.dmIN.getv2Account()
- if err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if err == utils.ErrNoMoreData {
- break
- }
- if err = m.dmIN.remV2Account(v2Acnt.ID); err != nil {
- return
- }
- }
- return
-}
-
-func (m *Migrator) migrateV2Accounts() (v3Acnt *engine.Account, err error) {
- var v2Acnt *v2Account
- v2Acnt, err = m.dmIN.getv2Account()
- if err != nil {
- return nil, err
- } else if v2Acnt == nil {
- return nil, errors.New("Account is nil")
- }
- v3Acnt = v2Acnt.V2toV3Account()
- return
-}
-
-func (m *Migrator) migrateAccounts() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.Accounts); err != nil {
- return
- }
- migrated := true
- migratedFrom := 0
- var v3Acnt *engine.Account
- for {
- version := vrs[utils.Accounts]
- migratedFrom = int(version)
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.Accounts]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentAccounts(); err != nil {
- return
- }
- version = 3
- case 1: //migrate v1 to v3
- if v3Acnt, err = m.migrateV1Accounts(); err != nil && err != utils.ErrNoMoreData {
- return err
- } else if err == utils.ErrNoMoreData {
- break
- }
- version = 3
- case 2: //migrate v2 to v3
- if v3Acnt, err = m.migrateV2Accounts(); err != nil && err != utils.ErrNoMoreData {
- return
- } else if err == utils.ErrNoMoreData {
- break
- }
- version = 3
- }
- if version == current[utils.Accounts] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
-
- if !m.dryRun {
- if err = m.dmOut.DataManager().SetAccount(v3Acnt); err != nil {
- return
- }
- }
- m.stats[utils.Accounts]++
-
- }
- if m.dryRun || !migrated {
- return nil
- }
- // Remove old accounts from dbIn (only if dbIn != dbOut )
- if !m.sameDataDB {
- switch migratedFrom {
- case 1:
- if err = m.removeV1Accounts(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- case 2:
- if err = m.removeV2Accounts(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- }
- }
-
- // All done, update version wtih current one
- if err = m.setVersions(utils.Accounts); err != nil {
- return err
- }
- return m.ensureIndexesDataDB(engine.ColAcc)
-}
-
-type v1Account struct {
- Id string
- BalanceMap map[string]v1BalanceChain
- UnitCounters []*v1UnitsCounter
- ActionTriggers v1ActionTriggers
- AllowNegative bool
- Disabled bool
-}
-
-type v1BalanceChain []*v1Balance
-
-type v1Balance struct {
- Uuid string //system wide unique
- Id string // account wide unique
- Value float64
- ExpirationDate time.Time
- Weight float64
- DestinationIds string
- RatingSubject string
- Category string
- SharedGroup string
- Timings []*engine.RITiming
- TimingIDs string
- Disabled bool
-}
-
-type v1UnitsCounter struct {
- Direction string
- BalanceType string
- Balances v1BalanceChain // first balance is the general one (no destination)
-}
-
-type v2Account struct {
- ID string
- BalanceMap map[string]engine.Balances
- UnitCounters engine.UnitCounters
- ActionTriggers engine.ActionTriggers
- AllowNegative bool
- Disabled bool
- executingTriggers bool
-}
-
-func (b *v1Balance) IsDefault() bool {
- return (b.DestinationIds == "" || b.DestinationIds == utils.MetaAny) &&
- b.RatingSubject == "" &&
- b.Category == "" &&
- b.ExpirationDate.IsZero() &&
- b.SharedGroup == "" &&
- b.Weight == 0 &&
- b.Disabled == false
-}
-
-func (v1Acc v1Account) V1toV3Account() (ac *engine.Account) {
- // transfer data into new structure
- ac = &engine.Account{
- ID: v1Acc.Id,
- BalanceMap: make(map[string]engine.Balances, len(v1Acc.BalanceMap)),
- UnitCounters: make(engine.UnitCounters, len(v1Acc.UnitCounters)),
- ActionTriggers: make(engine.ActionTriggers, len(v1Acc.ActionTriggers)),
- AllowNegative: v1Acc.AllowNegative,
- Disabled: v1Acc.Disabled,
- }
- idElements := strings.Split(ac.ID, utils.ConcatenatedKeySep)
- if len(idElements) != 3 {
- log.Printf("Malformed account ID %s", v1Acc.Id)
- }
- ac.ID = utils.ConcatenatedKey(idElements[1], idElements[2])
- // balances
- for oldBalKey, oldBalChain := range v1Acc.BalanceMap {
- keyElements := strings.Split(oldBalKey, utils.Meta)
- newBalKey := utils.Meta + keyElements[1]
- ac.BalanceMap[newBalKey] = make(engine.Balances, len(oldBalChain))
- for index, oldBal := range oldBalChain {
- balVal := oldBal.Value
- if newBalKey == utils.MetaVoice {
- balVal = utils.Round(balVal/float64(time.Second),
- config.CgrConfig().GeneralCfg().RoundingDecimals,
- utils.MetaRoundingMiddle)
- }
- // check default to set new id
- ac.BalanceMap[newBalKey][index] = &engine.Balance{
- Uuid: oldBal.Uuid,
- ID: oldBal.Id,
- Value: balVal,
- ExpirationDate: oldBal.ExpirationDate,
- Weight: oldBal.Weight,
- DestinationIDs: utils.ParseStringMap(oldBal.DestinationIds),
- RatingSubject: oldBal.RatingSubject,
- Categories: utils.ParseStringMap(oldBal.Category),
- SharedGroups: utils.ParseStringMap(oldBal.SharedGroup),
- Timings: oldBal.Timings,
- TimingIDs: utils.ParseStringMap(oldBal.TimingIDs),
- Disabled: oldBal.Disabled,
- Factor: engine.ValueFactor{},
- }
- }
- }
- // unit counters
- for _, oldUc := range v1Acc.UnitCounters {
- newUc := &engine.UnitCounter{Counters: make(engine.CounterFilters, len(oldUc.Balances))}
- for index, oldUcBal := range oldUc.Balances {
- bf := &engine.BalanceFilter{}
- if oldUcBal.Uuid != "" {
- bf.Uuid = utils.StringPointer(oldUcBal.Uuid)
- }
- if oldUcBal.Id != "" {
- bf.ID = utils.StringPointer(oldUcBal.Id)
- }
- if oldUc.BalanceType != "" {
- bf.Type = utils.StringPointer(oldUc.BalanceType)
- }
- if !oldUcBal.ExpirationDate.IsZero() {
- bf.ExpirationDate = utils.TimePointer(oldUcBal.ExpirationDate)
- }
- if oldUcBal.Weight != 0 {
- bf.Weight = utils.Float64Pointer(oldUcBal.Weight)
- }
- if oldUcBal.DestinationIds != "" {
- bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.DestinationIds))
- }
- if oldUcBal.RatingSubject != "" {
- bf.RatingSubject = utils.StringPointer(oldUcBal.RatingSubject)
- }
- if oldUcBal.Category != "" {
- bf.Categories = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.Category))
- }
- if oldUcBal.SharedGroup != "" {
- bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.SharedGroup))
- }
- if oldUcBal.TimingIDs != "" {
- bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.TimingIDs))
- }
- if oldUcBal.Disabled != false {
- bf.Disabled = utils.BoolPointer(oldUcBal.Disabled)
- }
- bf.Timings = oldUcBal.Timings
- cf := &engine.CounterFilter{
- Value: oldUcBal.Value,
- Filter: bf,
- }
- newUc.Counters[index] = cf
- }
- ac.UnitCounters[oldUc.BalanceType] = append(ac.UnitCounters[oldUc.BalanceType], newUc)
- }
- //action triggers
- for index, oldAtr := range v1Acc.ActionTriggers {
- at := &engine.ActionTrigger{
- UniqueID: oldAtr.Id,
- ThresholdType: oldAtr.ThresholdType,
- ThresholdValue: oldAtr.ThresholdValue,
- Recurrent: oldAtr.Recurrent,
- MinSleep: oldAtr.MinSleep,
- Weight: oldAtr.Weight,
- ActionsID: oldAtr.ActionsId,
- MinQueuedItems: oldAtr.MinQueuedItems,
- Executed: oldAtr.Executed,
- }
- bf := &engine.BalanceFilter{}
- if oldAtr.BalanceId != "" {
- bf.ID = utils.StringPointer(oldAtr.BalanceId)
- }
- if oldAtr.BalanceType != "" {
- bf.Type = utils.StringPointer(oldAtr.BalanceType)
- }
- if oldAtr.BalanceRatingSubject != "" {
- bf.RatingSubject = utils.StringPointer(oldAtr.BalanceRatingSubject)
- }
- if oldAtr.BalanceDestinationIds != "" {
- bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceDestinationIds))
- }
- if oldAtr.BalanceTimingTags != "" {
- bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceTimingTags))
- }
- if oldAtr.BalanceCategory != "" {
- bf.Categories = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceCategory))
- }
- if oldAtr.BalanceSharedGroup != "" {
- bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceSharedGroup))
- }
- if oldAtr.BalanceWeight != 0 {
- bf.Weight = utils.Float64Pointer(oldAtr.BalanceWeight)
- }
- if !oldAtr.BalanceExpirationDate.IsZero() {
- bf.ExpirationDate = utils.TimePointer(oldAtr.BalanceExpirationDate)
- }
- at.Balance = bf
- ac.ActionTriggers[index] = at
- if ac.ActionTriggers[index].ThresholdType == "*min_counter" ||
- ac.ActionTriggers[index].ThresholdType == "*max_counter" {
- ac.ActionTriggers[index].ThresholdType = strings.Replace(ac.ActionTriggers[index].ThresholdType, "_", "_event_", 1)
- }
- }
- return
-}
-
-func (v2Acc v2Account) V2toV3Account() (ac *engine.Account) {
- ac = &engine.Account{
- ID: v2Acc.ID,
- BalanceMap: make(map[string]engine.Balances, len(v2Acc.BalanceMap)),
- UnitCounters: make(engine.UnitCounters, len(v2Acc.UnitCounters)),
- ActionTriggers: make(engine.ActionTriggers, len(v2Acc.ActionTriggers)),
- AllowNegative: v2Acc.AllowNegative,
- Disabled: v2Acc.Disabled,
- }
- // balances
- for balType, oldBalChain := range v2Acc.BalanceMap {
- ac.BalanceMap[balType] = make(engine.Balances, len(oldBalChain))
- for index, oldBal := range oldBalChain {
- balVal := oldBal.Value
- if balType == utils.MetaVoice {
- balVal = utils.Round(balVal*float64(time.Second),
- config.CgrConfig().GeneralCfg().RoundingDecimals,
- utils.MetaRoundingMiddle)
- }
- // check default to set new id
- ac.BalanceMap[balType][index] = &engine.Balance{
- Uuid: oldBal.Uuid,
- ID: oldBal.ID,
- Value: balVal,
- ExpirationDate: oldBal.ExpirationDate,
- Weight: oldBal.Weight,
- DestinationIDs: oldBal.DestinationIDs,
- RatingSubject: oldBal.RatingSubject,
- Categories: oldBal.Categories,
- SharedGroups: oldBal.SharedGroups,
- Timings: oldBal.Timings,
- TimingIDs: oldBal.TimingIDs,
- Disabled: oldBal.Disabled,
- Factor: oldBal.Factor,
- }
- }
- }
- // unit counters
- ac.UnitCounters = v2Acc.UnitCounters
- //action triggers
- ac.ActionTriggers = v2Acc.ActionTriggers
- return
-}
diff --git a/migrator/accounts_it_test.go b/migrator/accounts_it_test.go
deleted file mode 100755
index 17138026e..000000000
--- a/migrator/accounts_it_test.go
+++ /dev/null
@@ -1,373 +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 (
- "flag"
- "log"
- "path"
- "reflect"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- accPathIn string
- accPathOut string
- accCfgIn *config.CGRConfig
- accCfgOut *config.CGRConfig
- accMigrator *Migrator
- accAction string
- dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
- sTestsAccIT = []func(t *testing.T){
- testAccITConnect,
- testAccITFlush,
- testAccITMigrateAndMove,
- }
-)
-
-func TestAccountMigrateITRedis(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Migrate
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMigrateRedis", stest)
- }
- accMigrator.Close()
-}
-
-func TestAccountMigrateITMongo(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Migrate
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMigrateMongo", stest)
- }
- accMigrator.Close()
-}
-
-func TestAccountITMove(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Move
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMove", stest)
- }
- accMigrator.Close()
-}
-
-func TestAccountITMigrateMongo2Redis(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Migrate
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMigrateMongo2Redis", stest)
- }
- accMigrator.Close()
-}
-
-func TestAccountITMoveEncoding(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Move
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMove", stest)
- }
- accMigrator.Close()
-}
-
-func TestAccountITMoveEncoding2(t *testing.T) {
- var err error
- accPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- accCfgIn, err = config.NewCGRConfigFromPath(accPathIn)
- if err != nil {
- t.Fatal(err)
- }
- accPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- accCfgOut, err = config.NewCGRConfigFromPath(accPathOut)
- if err != nil {
- t.Fatal(err)
- }
- accAction = utils.Move
- for _, stest := range sTestsAccIT {
- t.Run("TestAccountITMove", stest)
- }
- accMigrator.Close()
-}
-
-func testAccITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(accCfgIn.DataDbCfg().Type,
- accCfgIn.DataDbCfg().Host, accCfgIn.DataDbCfg().Port,
- accCfgIn.DataDbCfg().Name, accCfgIn.DataDbCfg().User,
- accCfgIn.DataDbCfg().Password, accCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), accCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(accCfgOut.DataDbCfg().Type,
- accCfgOut.DataDbCfg().Host, accCfgOut.DataDbCfg().Port,
- accCfgOut.DataDbCfg().Name, accCfgOut.DataDbCfg().User,
- accCfgOut.DataDbCfg().Password, accCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), accCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(accPathIn, accPathOut) {
- accMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- accMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testAccITFlush(t *testing.T) {
- accMigrator.dmOut.DataManager().DataDB().Flush(utils.EmptyString)
- if err := engine.SetDBVersions(accMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- accMigrator.dmIN.DataManager().DataDB().Flush(utils.EmptyString)
- if err := engine.SetDBVersions(accMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testAccITMigrateAndMove(t *testing.T) {
- timingSlice := []*engine.RITiming{
- {
- Years: utils.Years{},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- },
- }
- v1b := &v1Balance{
- Value: 100000,
- Weight: 10,
- DestinationIds: "NAT",
- ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Timings: timingSlice,
- }
- v1Acc := &v1Account{
- Id: "*OUT:CUSTOMER_1:rif",
- BalanceMap: map[string]v1BalanceChain{
- utils.MetaData: {v1b},
- utils.MetaVoice: {v1b},
- utils.MetaMonetary: {
- &v1Balance{Value: 21,
- ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Timings: timingSlice}}}}
-
- v2d := &engine.Balance{
- Uuid: utils.EmptyString, ID: utils.EmptyString,
- Value: 100000,
- ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Weight: 10,
- DestinationIDs: utils.StringMap{"NAT": true},
- RatingSubject: utils.EmptyString,
- Categories: utils.NewStringMap(),
- SharedGroups: utils.NewStringMap(),
- Timings: timingSlice,
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{}}
- v2b := &engine.Balance{
- Uuid: utils.EmptyString, ID: utils.EmptyString,
- Value: 0.0001,
- ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Weight: 10,
- DestinationIDs: utils.StringMap{"NAT": true},
- RatingSubject: utils.EmptyString,
- Categories: utils.NewStringMap(),
- SharedGroups: utils.NewStringMap(),
- Timings: timingSlice,
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{}}
- m2 := &engine.Balance{
- Uuid: utils.EmptyString,
- ID: utils.EmptyString,
- Value: 21,
- ExpirationDate: time.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- DestinationIDs: utils.NewStringMap(""),
- RatingSubject: utils.EmptyString,
- Categories: utils.NewStringMap(),
- SharedGroups: utils.NewStringMap(),
- Timings: timingSlice,
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{}}
- testAccount := &engine.Account{
- ID: "CUSTOMER_1:rif",
- BalanceMap: map[string]engine.Balances{
- utils.MetaData: {v2d},
- utils.MetaVoice: {v2b},
- utils.MetaMonetary: {m2}},
- UnitCounters: engine.UnitCounters{},
- ActionTriggers: engine.ActionTriggers{},
- }
- switch accAction {
- case utils.Migrate:
- // set v1Account
- err := accMigrator.dmIN.setV1Account(v1Acc)
- if err != nil {
- t.Error("Error when setting v1 Accounts ", err.Error())
- }
- //set version for account : 1
- currentVersion := engine.Versions{
- utils.StatS: 2,
- utils.Thresholds: 2,
- utils.Accounts: 1,
- utils.Actions: 2,
- utils.ActionTriggers: 2,
- utils.ActionPlans: 2,
- utils.SharedGroups: 2,
- }
- err = accMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for Accounts ", err.Error())
- }
- //check if version was set correctly
- if vrs, err := accMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.Accounts] != 1 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.Accounts])
- }
- //migrate account
- err, _ = accMigrator.Migrate([]string{utils.MetaAccounts})
- if err != nil {
- t.Error("Error when migrating Accounts ", err.Error())
- }
- //check if version was updated
- if vrs, err := accMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.Accounts] != 3 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.Accounts])
- }
- //check if account was migrate correctly
- result, err := accMigrator.dmOut.DataManager().GetAccount(testAccount.ID)
- if err != nil {
- t.Error("Error when getting Accounts ", err.Error())
- }
- if !reflect.DeepEqual(testAccount.ID, result.ID) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.ID, result.ID)
- } else if !reflect.DeepEqual(testAccount.ActionTriggers, result.ActionTriggers) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.ActionTriggers, result.ActionTriggers)
- } else if !reflect.DeepEqual(testAccount.BalanceMap, result.BalanceMap) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap, result.BalanceMap)
- } else if !reflect.DeepEqual(testAccount.UnitCounters, result.UnitCounters) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.UnitCounters, result.UnitCounters)
- } else if accMigrator.stats[utils.Accounts] != 1 {
- t.Errorf("Expecting: 1, received: %+v", accMigrator.stats[utils.Accounts])
- }
- case utils.Move:
- //set an account in dmIN
- if err := accMigrator.dmIN.DataManager().SetAccount(testAccount); err != nil {
- t.Error(err)
- }
- //set versions for account
- currentVersion := engine.CurrentDataDBVersions()
- err := accMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for Accounts ", err.Error())
- }
- //migrate accounts
- err, _ = accMigrator.Migrate([]string{utils.MetaAccounts})
- if err != nil {
- t.Error("Error when accMigratorrating Accounts ", err.Error())
- }
- //check if account was migrate correctly
- result, err := accMigrator.dmOut.DataManager().GetAccount(testAccount.ID)
- if err != nil {
- t.Error(err)
- }
- if result != nil {
- if !reflect.DeepEqual(testAccount.ID, result.ID) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.ID, result.ID)
- } else if !reflect.DeepEqual(testAccount.ActionTriggers, result.ActionTriggers) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.ActionTriggers, result.ActionTriggers)
- } else if !reflect.DeepEqual(testAccount.BalanceMap, result.BalanceMap) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap, result.BalanceMap)
- } else if !reflect.DeepEqual(testAccount.UnitCounters, result.UnitCounters) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.UnitCounters, result.UnitCounters)
- }
- } else {
- t.Errorf("Expecting to be not nil")
- }
- //check if old account was deleted
- result, err = accMigrator.dmIN.DataManager().GetAccount(testAccount.ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- } else if accMigrator.stats[utils.Accounts] != 1 {
- t.Errorf("Expecting: 1, received: %+v", accMigrator.stats[utils.Accounts])
- }
-
- }
-}
diff --git a/migrator/accounts_test.go b/migrator/accounts_test.go
deleted file mode 100755
index cebcd69e8..000000000
--- a/migrator/accounts_test.go
+++ /dev/null
@@ -1,123 +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 (
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestV1AccountAsAccount(t *testing.T) {
- d1b := &v1Balance{
- Value: 100000,
- Weight: 10,
- DestinationIds: "NAT",
- Timings: []*engine.RITiming{
- &engine.RITiming{
- StartTime: "00:00:00",
- },
- },
- }
- v1b := &v1Balance{
- Value: 100000,
- Weight: 10,
- DestinationIds: "NAT",
- Timings: []*engine.RITiming{
- &engine.RITiming{
- StartTime: "00:00:00",
- },
- },
- }
- v1Acc := &v1Account{
- Id: "*OUT:CUSTOMER_1:rif",
- BalanceMap: map[string]v1BalanceChain{
- utils.MetaData: v1BalanceChain{d1b},
- utils.MetaVoice: v1BalanceChain{v1b},
- utils.MetaMonetary: v1BalanceChain{&v1Balance{
- Value: 21,
- Timings: []*engine.RITiming{
- &engine.RITiming{
- StartTime: "00:00:00",
- },
- },
- }},
- },
- }
- d2 := &engine.Balance{
- Uuid: "",
- ID: "",
- Value: 100000,
- Weight: 10,
- DestinationIDs: utils.StringMap{"NAT": true},
- RatingSubject: "",
- Categories: utils.NewStringMap(""),
- SharedGroups: utils.NewStringMap(""),
- Timings: []*engine.RITiming{&engine.RITiming{StartTime: "00:00:00"}},
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{},
- }
- v2 := &engine.Balance{
- Uuid: "",
- ID: "",
- Value: 0.0001,
- Weight: 10,
- DestinationIDs: utils.StringMap{"NAT": true},
- RatingSubject: "",
- Categories: utils.NewStringMap(""),
- SharedGroups: utils.NewStringMap(""),
- Timings: []*engine.RITiming{&engine.RITiming{StartTime: "00:00:00"}},
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{},
- }
- m2 := &engine.Balance{
- Uuid: "",
- ID: "",
- Value: 21,
- DestinationIDs: utils.NewStringMap(""),
- RatingSubject: "",
- Categories: utils.NewStringMap(""),
- SharedGroups: utils.NewStringMap(""),
- Timings: []*engine.RITiming{&engine.RITiming{StartTime: "00:00:00"}},
- TimingIDs: utils.NewStringMap(""),
- Factor: engine.ValueFactor{},
- }
- testAccount := &engine.Account{
- ID: "CUSTOMER_1:rif",
- BalanceMap: map[string]engine.Balances{
- utils.MetaData: engine.Balances{d2},
- utils.MetaVoice: engine.Balances{v2},
- utils.MetaMonetary: engine.Balances{m2},
- },
- UnitCounters: engine.UnitCounters{},
- ActionTriggers: engine.ActionTriggers{},
- }
- if def := v1b.IsDefault(); def != false {
- t.Errorf("Expecting: false, received: true")
- }
- newAcc := v1Acc.V1toV3Account()
- if !reflect.DeepEqual(testAccount.BalanceMap["*monetary"][0], newAcc.BalanceMap["*monetary"][0]) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap["*monetary"][0], newAcc.BalanceMap["*monetary"][0])
- } else if !reflect.DeepEqual(testAccount.BalanceMap["*voice"][0], newAcc.BalanceMap["*voice"][0]) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap["*voice"][0], newAcc.BalanceMap["*voice"][0])
- } else if !reflect.DeepEqual(testAccount.BalanceMap["*data"][0], newAcc.BalanceMap["*data"][0]) {
- t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap["*data"][0], newAcc.BalanceMap["*data"][0])
- }
-}
diff --git a/migrator/action.go b/migrator/action.go
deleted file mode 100644
index e9827c953..000000000
--- a/migrator/action.go
+++ /dev/null
@@ -1,202 +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"
-)
-
-type v1Action struct {
- Id string
- ActionType string
- BalanceType string
- Direction string
- ExtraParameters string
- ExpirationString string
- Weight float64
- Balance *v1Balance
-}
-
-type v1Actions []*v1Action
-
-func (m *Migrator) migrateCurrentActions() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.ActionPrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.ActionPrefix)
- acts, err := m.dmIN.DataManager().GetActions(idg, true, utils.NonTransactional)
- if err != nil {
- return err
- }
- if acts == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetActions(idg, acts, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.Actions]++
- }
- return
-}
-
-func (m *Migrator) removeV1Actions() (err error) {
- var v1 *v1Actions
- for {
- if v1, err = m.dmIN.getV1Actions(); err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if v1 == nil {
- return nil
- }
- if err = m.dmIN.remV1Actions(*v1); err != nil {
- return err
- }
- }
-}
-
-func (m *Migrator) migrateV1Actions() (acts engine.Actions, err error) {
- var v1ACs *v1Actions
-
- if v1ACs, err = m.dmIN.getV1Actions(); err != nil {
- return nil, err
- }
- if *v1ACs == nil {
- return
- }
- for _, v1ac := range *v1ACs {
- act := v1ac.AsAction()
- acts = append(acts, act)
-
- }
-
- return
-}
-
-func (m *Migrator) migrateActions() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.Actions); err != nil {
- return
- }
- migrated := true
- var acts engine.Actions
- for {
- version := vrs[utils.Actions]
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.Actions]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentActions(); err != nil {
- return
- }
- case 1:
- if acts, err = m.migrateV1Actions(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- version = 2
- }
- if version == current[utils.Actions] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
- if !m.dryRun {
- if err = m.dmOut.DataManager().SetActions(acts[0].Id, acts, utils.NonTransactional); err != nil {
- return
- }
- }
- m.stats[utils.Actions]++
- }
-
- if m.dryRun || !migrated {
- return nil
- }
- // remove old actions
-
- // All done, update version wtih current one
- if err = m.setVersions(utils.Actions); err != nil {
- return
- }
-
- return m.ensureIndexesDataDB(engine.ColAct)
-}
-
-func (v1Act v1Action) AsAction() (act *engine.Action) {
- act = &engine.Action{
- Id: v1Act.Id,
- ActionType: v1Act.ActionType,
- ExtraParameters: v1Act.ExtraParameters,
- ExpirationString: v1Act.ExpirationString,
- Weight: v1Act.Weight,
- Balance: &engine.BalanceFilter{},
- }
- bf := act.Balance
- if v1Act.Balance.Uuid != "" {
- bf.Uuid = utils.StringPointer(v1Act.Balance.Uuid)
- }
- if v1Act.Balance.Id != "" {
- bf.ID = utils.StringPointer(v1Act.Balance.Id)
- }
- if v1Act.BalanceType != "" {
- bf.Type = utils.StringPointer(v1Act.BalanceType)
- }
- if v1Act.Balance.Value != 0 {
- bf.Value = &utils.ValueFormula{Static: v1Act.Balance.Value}
- }
- if v1Act.Balance.RatingSubject != "" {
- bf.RatingSubject = utils.StringPointer(v1Act.Balance.RatingSubject)
- }
- if v1Act.Balance.DestinationIds != "" {
- bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(v1Act.Balance.DestinationIds))
- }
- if v1Act.Balance.TimingIDs != "" {
- bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(v1Act.Balance.TimingIDs))
- }
- if v1Act.Balance.Category != "" {
- bf.Categories = utils.StringMapPointer(utils.ParseStringMap(v1Act.Balance.Category))
- }
- if v1Act.Balance.SharedGroup != "" {
- bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(v1Act.Balance.SharedGroup))
- }
- if v1Act.Balance.Weight != 0 {
- bf.Weight = utils.Float64Pointer(v1Act.Balance.Weight)
- }
- if v1Act.Balance.Disabled != false {
- bf.Disabled = utils.BoolPointer(v1Act.Balance.Disabled)
- }
- if !v1Act.Balance.ExpirationDate.IsZero() {
- bf.ExpirationDate = utils.TimePointer(v1Act.Balance.ExpirationDate)
- }
- bf.Timings = v1Act.Balance.Timings
- return
-}
diff --git a/migrator/action_it_test.go b/migrator/action_it_test.go
deleted file mode 100644
index 30818499c..000000000
--- a/migrator/action_it_test.go
+++ /dev/null
@@ -1,296 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- actPathIn string
- actPathOut string
- actCfgIn *config.CGRConfig
- actCfgOut *config.CGRConfig
- actMigrator *Migrator
- actAction string
-)
-
-var sTestsActIT = []func(t *testing.T){
- testActITConnect,
- testActITFlush,
- testActITMigrateAndMove,
-}
-
-func TestActionITRedis(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Migrate
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMigrateRedis", stest)
- }
- actMigrator.Close()
-}
-
-func TestActionITMongo(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Migrate
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMigrateMongo", stest)
- }
- actMigrator.Close()
-}
-
-func TestActionITMove(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Move
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMove", stest)
- }
- actMigrator.Close()
-}
-
-func TestActionITMoveEncoding(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Move
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMoveEncoding", stest)
- }
- actMigrator.Close()
-}
-
-func TestActionITMigrateMongo2Redis(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Migrate
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMigrateMongo2Redis", stest)
- }
- actMigrator.Close()
-}
-
-func TestActionITMoveEncoding2(t *testing.T) {
- var err error
- actPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actCfgIn, err = config.NewCGRConfigFromPath(actPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- actCfgOut, err = config.NewCGRConfigFromPath(actPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actAction = utils.Move
- for _, stest := range sTestsActIT {
- t.Run("TestActionITMoveEncoding2", stest)
- }
- actMigrator.Close()
-}
-
-func testActITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(actCfgIn.DataDbCfg().Type,
- actCfgIn.DataDbCfg().Host, actCfgIn.DataDbCfg().Port,
- actCfgIn.DataDbCfg().Name, actCfgIn.DataDbCfg().User,
- actCfgIn.DataDbCfg().Password, actCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(actCfgOut.DataDbCfg().Type,
- actCfgOut.DataDbCfg().Host, actCfgOut.DataDbCfg().Port,
- actCfgOut.DataDbCfg().Name, actCfgOut.DataDbCfg().User,
- actCfgOut.DataDbCfg().Password, actCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(actPathIn, actPathOut) {
- actMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- actMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testActITFlush(t *testing.T) {
- actMigrator.dmOut.DataManager().DataDB().Flush("")
- actMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(actMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- if err := engine.SetDBVersions(actMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testActITMigrateAndMove(t *testing.T) {
- timingSlice := []*engine.RITiming{
- {
- Years: utils.Years{},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- },
- }
-
- v1act := &v1Action{
- Id: "test",
- ActionType: "",
- BalanceType: "",
- Direction: "INBOUND",
- ExtraParameters: "",
- ExpirationString: "",
- Balance: &v1Balance{
- Timings: timingSlice,
- },
- }
-
- v1acts := &v1Actions{
- v1act,
- }
-
- act := &engine.Actions{
- &engine.Action{
- Id: "test",
- ActionType: "",
- ExtraParameters: "",
- ExpirationString: "",
- Weight: 0.00,
- Balance: &engine.BalanceFilter{
- Timings: timingSlice,
- },
- },
- }
- switch actAction {
- case utils.Migrate:
- err := actMigrator.dmIN.setV1Actions(v1acts)
- if err != nil {
- t.Error("Error when setting v1 Actions ", err.Error())
- }
- currentVersion := engine.Versions{
- utils.StatS: 2,
- utils.Thresholds: 2,
- utils.Accounts: 2,
- utils.Actions: 1,
- utils.ActionTriggers: 2,
- utils.ActionPlans: 2,
- utils.SharedGroups: 2,
- }
- err = actMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for Actions ", err.Error())
- }
- err, _ = actMigrator.Migrate([]string{utils.MetaActions})
- if err != nil {
- t.Error("Error when migrating Actions ", err.Error())
- }
- result, err := actMigrator.dmOut.DataManager().GetActions(v1act.Id, true, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting Actions ", err.Error())
- }
- if !reflect.DeepEqual(act, &result) {
- t.Errorf("Expecting: %+v, received: %+v", act, &result)
- } else if actMigrator.stats[utils.Actions] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actMigrator.stats[utils.Actions])
- }
- case utils.Move:
- if err := actMigrator.dmIN.DataManager().SetActions(v1act.Id, *act, utils.NonTransactional); err != nil {
- t.Error("Error when setting ActionPlan ", err.Error())
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := actMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for Actions ", err.Error())
- }
- err, _ = actMigrator.Migrate([]string{utils.MetaActions})
- if err != nil {
- t.Error("Error when migrating Actions ", err.Error())
- }
- result, err := actMigrator.dmOut.DataManager().GetActions(v1act.Id, true, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting Actions ", err.Error())
- }
- if !reflect.DeepEqual(act, &result) {
- t.Errorf("Expecting: %+v, received: %+v", act, &result)
- } else if actMigrator.stats[utils.Actions] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actMigrator.stats[utils.Actions])
- }
- }
-}
diff --git a/migrator/action_plan.go b/migrator/action_plan.go
deleted file mode 100644
index 3e4b22bf2..000000000
--- a/migrator/action_plan.go
+++ /dev/null
@@ -1,214 +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"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-type v1ActionPlan struct {
- Uuid string // uniquely identify the timing
- Id string // informative purpose only
- AccountIds []string
- Timing *engine.RateInterval
- Weight float64
- ActionsId string
- actions v1Actions
- stCache time.Time // cached time of the next start
-}
-
-type v1ActionPlans []*v1ActionPlan
-
-func (at *v1ActionPlan) IsASAP() bool {
- if at.Timing == nil {
- return false
- }
- return at.Timing.Timing.StartTime == utils.MetaASAP
-}
-
-func (m *Migrator) migrateCurrentActionPlans() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.ActionPlanPrefix)
- if err != nil {
- return
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.ActionPlanPrefix)
- var acts *engine.ActionPlan
- if acts, err = m.dmIN.DataManager().GetActionPlan(idg, true, utils.NonTransactional); err != nil {
- return
- }
- if acts == nil || m.dryRun {
- continue
- }
- if err = m.dmOut.DataManager().SetActionPlan(idg, acts, true, utils.NonTransactional); err != nil {
- return
- }
- if err = m.dmIN.DataManager().RemoveActionPlan(idg, utils.NonTransactional); err != nil {
- return
- }
- m.stats[utils.ActionPlans]++
- }
- return
-}
-func (m *Migrator) removeV1ActionPlans() (err error) {
- var v1 *v1ActionPlans
- for {
- if v1, err = m.dmIN.getV1ActionPlans(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- if v1 == nil {
- return nil
- }
- if err = m.dmIN.remV1ActionPlans(v1); err != nil {
- return
- }
- }
-}
-
-func (m *Migrator) migrateV1ActionPlans() (v2 []*engine.ActionPlan, err error) {
- var v1APs *v1ActionPlans
- v1APs, err = m.dmIN.getV1ActionPlans()
- if err != nil {
- return nil, err
- }
- for _, v1ap := range *v1APs {
- v2 = append(v2, v1ap.AsActionPlan())
- }
- return
-}
-
-func (m *Migrator) migrateActionPlans() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.ActionPlans); err != nil {
- return
- }
- if m.dmIN.DataManager().DataDB().GetStorageType() == utils.Redis { // if redis rebuild action plans indexes
- redisDB, can := m.dmIN.DataManager().DataDB().(*engine.RedisStorage)
- if !can {
- return fmt.Errorf("Storage type %s could not be casted to <*engine.RedisStorage>", m.dmIN.DataManager().DataDB().GetStorageType())
- }
- if err = redisDB.RebbuildActionPlanKeys(); err != nil {
- return
- }
- }
- migrated := true
- migratedFrom := 0
- var v3 []*engine.ActionPlan
- for {
- version := vrs[utils.ActionPlans]
- migratedFrom = int(version)
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.ActionPlans]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentActionPlans(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- case 1:
- if v3, err = m.migrateV1ActionPlans(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- version = 3
- case 2: // neded to rebuild action plan indexes for redis
- // All done, update version wtih current one
- vrs := engine.Versions{utils.ActionPlans: engine.CurrentDataDBVersions()[utils.ActionPlans]}
- if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when updating ActionPlans version into dataDB", err.Error()))
- }
- version = 3
- }
- if version == current[utils.ActionPlans] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
-
- if !m.dryRun {
- //set action plan
- for _, ap := range v3 {
- if err = m.dmOut.DataManager().SetActionPlan(ap.Id, ap, true, utils.NonTransactional); err != nil {
- return
- }
- }
- }
- m.stats[utils.ActionPlans]++
- }
- if m.dryRun || !migrated {
- return nil
- }
- // remove old action plans
- if !m.sameDataDB {
- if migratedFrom == 1 {
- if err = m.removeV1ActionPlans(); err != nil {
- return
- }
- }
- }
-
- // All done, update version wtih current one
- if err = m.setVersions(utils.ActionPlans); err != nil {
- return err
- }
- return m.ensureIndexesDataDB(engine.ColApl)
-}
-
-func (v1AP v1ActionPlan) AsActionPlan() (ap *engine.ActionPlan) {
- for idx, actionID := range v1AP.AccountIds {
- idElements := strings.Split(actionID, "_")
- if len(idElements) != 2 {
- continue
- }
- v1AP.AccountIds[idx] = idElements[1]
- }
- ap = &engine.ActionPlan{
- Id: v1AP.Id,
- AccountIDs: make(utils.StringMap),
- }
- if x := v1AP.IsASAP(); !x {
- for _, accID := range v1AP.AccountIds {
- if _, exists := ap.AccountIDs[accID]; !exists {
- ap.AccountIDs[accID] = true
- }
- }
- }
- ap.ActionTimings = append(ap.ActionTimings, &engine.ActionTiming{
- Uuid: utils.GenUUID(),
- Timing: v1AP.Timing,
- ActionsID: v1AP.ActionsId,
- Weight: v1AP.Weight,
- })
- return
-}
diff --git a/migrator/action_plan_it_test.go b/migrator/action_plan_it_test.go
deleted file mode 100644
index ebed0c2bb..000000000
--- a/migrator/action_plan_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 migrator
-
-import (
- "log"
- "path"
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- actPlnPathIn string
- actPlnPathOut string
- actPlnCfgIn *config.CGRConfig
- actPlnCfgOut *config.CGRConfig
- actPlnMigrator *Migrator
- actActionPlan string
-)
-
-var sTestsActPlnIT = []func(t *testing.T){
- testActPlnITConnect,
- testActPlnITFlush,
- testActPlnITMigrateAndMove,
-}
-
-func TestActionPlanITRedis(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Migrate
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMigrateRedis", stest)
- }
- actPlnMigrator.Close()
-}
-
-func TestActionPlanITMongo(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Migrate
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMigrateMongo", stest)
- }
- actPlnMigrator.Close()
-}
-
-func TestActionPlanITMove(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Move
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMove", stest)
- }
- actPlnMigrator.Close()
-}
-
-func TestActionPlanITMigrateMongo2Redis(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Migrate
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMigrateMongo2Redis", stest)
- }
- actPlnMigrator.Close()
-}
-
-func TestActionPlanITMoveEncoding(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Move
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMoveEncoding", stest)
- }
- actPlnMigrator.Close()
-}
-
-func TestActionPlanITMoveEncoding2(t *testing.T) {
- var err error
- actPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actPlnCfgIn, err = config.NewCGRConfigFromPath(actPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- actPlnCfgOut, err = config.NewCGRConfigFromPath(actPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionPlan = utils.Move
- for _, stest := range sTestsActPlnIT {
- t.Run("TestActionPlanITMoveEncoding2", stest)
- }
- actPlnMigrator.Close()
-}
-
-func testActPlnITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(actPlnCfgIn.DataDbCfg().Type,
- actPlnCfgIn.DataDbCfg().Host, actPlnCfgIn.DataDbCfg().Port,
- actPlnCfgIn.DataDbCfg().Name, actPlnCfgIn.DataDbCfg().User,
- actPlnCfgIn.DataDbCfg().Password, actPlnCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actPlnCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(actPlnCfgOut.DataDbCfg().Type,
- actPlnCfgOut.DataDbCfg().Host, actPlnCfgOut.DataDbCfg().Port,
- actPlnCfgOut.DataDbCfg().Name, actPlnCfgOut.DataDbCfg().User,
- actPlnCfgOut.DataDbCfg().Password, actPlnCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actPlnCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(actPlnPathIn, actPlnPathOut) {
- actPlnMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- actPlnMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testActPlnITFlush(t *testing.T) {
- actPlnMigrator.dmOut.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(actPlnMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- actPlnMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(actPlnMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testActPlnITMigrateAndMove(t *testing.T) {
- timingSlice := &engine.RITiming{
- Years: utils.Years{},
- Months: utils.Months{},
- MonthDays: utils.MonthDays{},
- WeekDays: utils.WeekDays{},
- }
-
- v1actPln := &v1ActionPlans{
- &v1ActionPlan{
- Id: "test",
- AccountIds: []string{"one"},
- Timing: &engine.RateInterval{
- Timing: timingSlice,
- },
- },
- }
-
- actPln := &engine.ActionPlan{
- Id: "test",
- AccountIDs: utils.StringMap{"one": true},
- ActionTimings: []*engine.ActionTiming{
- {
- Timing: &engine.RateInterval{
- Timing: timingSlice,
- },
- },
- },
- }
-
- switch actActionPlan {
- case utils.Migrate:
- err := actPlnMigrator.dmIN.setV1ActionPlans(v1actPln)
- if err != nil {
- t.Error("Error when setting v1 ActionPlan ", err.Error())
- }
- currentVersion := engine.Versions{
- utils.StatS: 2, utils.Thresholds: 2,
- utils.Accounts: 2, utils.Actions: 2,
- utils.ActionTriggers: 2,
- utils.ActionPlans: 1,
- utils.SharedGroups: 2,
- }
- err = actPlnMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for ActionPlan ", err.Error())
- }
- err, _ = actPlnMigrator.Migrate([]string{utils.MetaActionPlans})
- if err != nil {
- t.Error("Error when migrating ActionPlan ", err.Error())
- }
- result, err := actPlnMigrator.dmOut.DataManager().GetActionPlan((*v1actPln)[0].Id, true, utils.NonTransactional)
- if err != nil {
- t.Fatal("Error when getting ActionPlan ", err.Error())
- }
- // compared fields, uuid is generated in ActionTiming
- if !reflect.DeepEqual(actPln.Id, result.Id) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.Id, result.Id)
- } else if !reflect.DeepEqual(actPln.AccountIDs, result.AccountIDs) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.AccountIDs, result.AccountIDs)
- } else if !reflect.DeepEqual(actPln.ActionTimings[0].Timing, result.ActionTimings[0].Timing) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.ActionTimings[0].Timing, result.ActionTimings[0].Timing)
- } else if actPlnMigrator.stats[utils.ActionPlans] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actPlnMigrator.stats[utils.ActionPlans])
- }
- case utils.Move:
- if err := actPlnMigrator.dmIN.DataManager().SetActionPlan((*v1actPln)[0].Id, actPln, true, utils.NonTransactional); err != nil {
- t.Error("Error when setting ActionPlan ", err.Error())
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := actPlnMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for ActionPlan ", err.Error())
- }
- err, _ = actPlnMigrator.Migrate([]string{utils.MetaActionPlans})
- if err != nil {
- t.Error("Error when migrating ActionPlan ", err.Error())
- }
- result, err := actPlnMigrator.dmOut.DataManager().GetActionPlan((*v1actPln)[0].Id, true, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting ActionPlan ", err.Error())
- }
- // compared fields, uuid is generated in ActionTiming
- if !reflect.DeepEqual(actPln.Id, result.Id) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.Id, result.Id)
- } else if !reflect.DeepEqual(actPln.AccountIDs, result.AccountIDs) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.AccountIDs, result.AccountIDs)
- } else if !reflect.DeepEqual(actPln.ActionTimings[0].Timing, result.ActionTimings[0].Timing) {
- t.Errorf("Expecting: %+v, received: %+v", actPln.ActionTimings[0].Timing, result.ActionTimings[0].Timing)
- }
- result, err = actPlnMigrator.dmIN.DataManager().GetActionPlan((*v1actPln)[0].Id, true, utils.NonTransactional)
- if err != utils.ErrNotFound {
- t.Error(err)
- } else if actPlnMigrator.stats[utils.ActionPlans] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actPlnMigrator.stats[utils.ActionPlans])
- }
- }
-}
diff --git a/migrator/action_plan_test.go b/migrator/action_plan_test.go
deleted file mode 100644
index 9b7722291..000000000
--- a/migrator/action_plan_test.go
+++ /dev/null
@@ -1,53 +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 (
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestV1ActionPlanAsActionPlan(t *testing.T) {
- v1ap := &v1ActionPlan{
- Id: "test",
- AccountIds: []string{"one"},
- Timing: &engine.RateInterval{Timing: new(engine.RITiming)},
- }
- ap := &engine.ActionPlan{
- Id: "test",
- AccountIDs: utils.StringMap{"one": true},
- ActionTimings: []*engine.ActionTiming{
- &engine.ActionTiming{
- Timing: &engine.RateInterval{
- Timing: new(engine.RITiming),
- },
- },
- },
- }
- newap := v1ap.AsActionPlan()
- if ap.Id != newap.Id || !reflect.DeepEqual(ap.AccountIDs, newap.AccountIDs) {
- t.Errorf("Expecting: %+v, received: %+v", *ap, newap)
- } else if !reflect.DeepEqual(ap.ActionTimings[0].Timing, newap.ActionTimings[0].Timing) {
- t.Errorf("Expecting: %+v, received: %+v", ap.ActionTimings[0].Timing, newap.ActionTimings[0].Timing)
- } else if ap.ActionTimings[0].Weight != newap.ActionTimings[0].Weight || ap.ActionTimings[0].ActionsID != newap.ActionTimings[0].ActionsID {
- t.Errorf("Expecting: %+v, received: %+v", ap.ActionTimings[0].Weight, newap.ActionTimings[0].Weight)
- }
-}
diff --git a/migrator/action_test.go b/migrator/action_test.go
deleted file mode 100644
index e80b26d24..000000000
--- a/migrator/action_test.go
+++ /dev/null
@@ -1,88 +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 (
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/utils"
-
- "github.com/cgrates/cgrates/engine"
-)
-
-func TestV1ActionsAsActions(t *testing.T) {
- v1act := &v1Action{
- Id: "",
- ActionType: "",
- BalanceType: "",
- Direction: "INBOUND",
- ExtraParameters: "",
- ExpirationString: "",
- Balance: &v1Balance{},
- }
- act := &engine.Action{
- Id: "",
- ActionType: "",
- ExtraParameters: "",
- ExpirationString: "",
- Weight: 0.00,
- Balance: &engine.BalanceFilter{},
- }
- newact := v1act.AsAction()
- if !reflect.DeepEqual(act, newact) {
- t.Errorf("Expecting: %+v, received: %+v", act, newact)
- }
-}
-
-func TestV1ActionsAsActions2(t *testing.T) {
- v1act := &v1Action{
- Id: "ID",
- ActionType: "*log",
- BalanceType: utils.MetaMonetary,
- ExtraParameters: "",
- ExpirationString: "",
- Balance: &v1Balance{
- Uuid: "UUID1",
- Id: utils.MetaDefault,
- Value: 10,
- Weight: 30,
- Category: utils.Call,
- },
- }
-
- act := &engine.Action{
- Id: "ID",
- ActionType: "*log",
- ExtraParameters: "",
- ExpirationString: "",
- Weight: 0.00,
- Balance: &engine.BalanceFilter{
- Uuid: utils.StringPointer("UUID1"),
- ID: utils.StringPointer(utils.MetaDefault),
- Type: utils.StringPointer(utils.MetaMonetary),
- Value: &utils.ValueFormula{Static: 10},
- Weight: utils.Float64Pointer(30),
- Categories: utils.StringMapPointer(utils.ParseStringMap(utils.Call)),
- },
- }
- newact := v1act.AsAction()
- if !reflect.DeepEqual(act, newact) {
- t.Errorf("Expecting: %+v, received: %+v", act, newact)
- }
-}
diff --git a/migrator/action_trigger.go b/migrator/action_trigger.go
deleted file mode 100644
index cad32ebea..000000000
--- a/migrator/action_trigger.go
+++ /dev/null
@@ -1,227 +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"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-type v1ActionTrigger struct {
- Id string // for visual identification
- ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance
- ThresholdValue float64
- Recurrent bool // reset eexcuted flag each run
- MinSleep time.Duration // Minimum duration between two executions in case of recurrent triggers
- BalanceId string
- BalanceType string
- BalanceDirection string
- BalanceDestinationIds string // filter for balance
- BalanceWeight float64 // filter for balance
- BalanceExpirationDate time.Time // filter for balance
- BalanceTimingTags string // filter for balance
- BalanceRatingSubject string // filter for balance
- BalanceCategory string // filter for balance
- BalanceSharedGroup string // filter for balance
- Weight float64
- ActionsId string
- MinQueuedItems int // Trigger actions only if this number is hit (stats only)
- Executed bool
- lastExecutionTime time.Time
-}
-
-type v1ActionTriggers []*v1ActionTrigger
-
-func (m *Migrator) migrateCurrentActionTrigger() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.ActionTriggerPrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.ActionTriggerPrefix)
- acts, err := m.dmIN.DataManager().GetActionTriggers(idg, true, utils.NonTransactional)
- if err != nil {
- return err
- }
- if acts == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetActionTriggers(idg, acts, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.ActionTriggers]++
-
- }
- return
-}
-
-func (m *Migrator) migrateV1ActionTrigger() (acts engine.ActionTriggers, err error) {
- var v1ACTs *v1ActionTriggers
- v1ACTs, err = m.dmIN.getV1ActionTriggers()
- if err != nil {
- return nil, err
- }
- if v1ACTs == nil {
- return nil, nil
- }
- for _, v1ac := range *v1ACTs {
- act := v1ac.AsActionTrigger()
- acts = append(acts, act)
- }
- if m.dryRun {
- return
- }
- return
-}
-
-func (m *Migrator) removeV1ActionTriggers() (err error) {
- var v1ACTs *v1ActionTriggers
- for {
- if v1ACTs, err = m.dmIN.getV1ActionTriggers(); err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if v1ACTs == nil {
- return nil
- }
- if err = m.dmIN.remV1ActionTriggers(v1ACTs); err != nil {
- return err
- }
- }
-}
-
-func (m *Migrator) migrateActionTriggers() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.ActionTriggers); err != nil {
- return
- }
- migrated := true
- migratedFrom := 0
- var v2 engine.ActionTriggers
- for {
- version := vrs[utils.ActionTriggers]
- migratedFrom = int(version)
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.ActionTriggers]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentActionTrigger(); err != nil {
- return
- }
- case 1:
- if v2, err = m.migrateV1ActionTrigger(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- version = 2
- }
- if version == current[utils.ActionTriggers] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
- if !m.dryRun {
- //set action triggers
- if err = m.dmOut.DataManager().SetActionTriggers(v2[0].ID, v2, utils.NonTransactional); err != nil {
- return
- }
- }
- m.stats[utils.ActionTriggers]++
- }
- if m.dryRun || !migrated {
- return nil
- }
- // remove old action triggers
- if !m.sameDataDB {
- if migratedFrom == 1 {
- if err = m.removeV1ActionTriggers(); err != nil {
- return
- }
- }
- }
-
- // All done, update version wtih current one
- if err = m.setVersions(utils.ActionTriggers); err != nil {
- return
- }
-
- return m.ensureIndexesDataDB(engine.ColAtr)
-}
-
-func (v1Act v1ActionTrigger) AsActionTrigger() (at *engine.ActionTrigger) {
- at = &engine.ActionTrigger{
- ID: v1Act.Id,
- ThresholdType: v1Act.ThresholdType,
- ThresholdValue: v1Act.ThresholdValue,
- Recurrent: v1Act.Recurrent,
- MinSleep: v1Act.MinSleep,
- Weight: v1Act.Weight,
- ActionsID: v1Act.ActionsId,
- MinQueuedItems: v1Act.MinQueuedItems,
- Executed: v1Act.Executed,
- }
- bf := &engine.BalanceFilter{}
- if v1Act.BalanceId != "" {
- bf.ID = utils.StringPointer(v1Act.BalanceId)
- }
- if v1Act.BalanceType != "" {
- bf.Type = utils.StringPointer(v1Act.BalanceType)
- }
- if v1Act.BalanceRatingSubject != "" {
- bf.RatingSubject = utils.StringPointer(v1Act.BalanceRatingSubject)
- }
- if v1Act.BalanceDestinationIds != "" {
- bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(v1Act.BalanceDestinationIds))
- }
- if v1Act.BalanceTimingTags != "" {
- bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(v1Act.BalanceTimingTags))
- }
- if v1Act.BalanceCategory != "" {
- bf.Categories = utils.StringMapPointer(utils.ParseStringMap(v1Act.BalanceCategory))
- }
- if v1Act.BalanceSharedGroup != "" {
- bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(v1Act.BalanceSharedGroup))
- }
- if v1Act.BalanceWeight != 0 {
- bf.Weight = utils.Float64Pointer(v1Act.BalanceWeight)
- }
- if !v1Act.BalanceExpirationDate.IsZero() {
- bf.ExpirationDate = utils.TimePointer(v1Act.BalanceExpirationDate)
- at.ExpirationDate = v1Act.BalanceExpirationDate
- at.LastExecutionTime = v1Act.BalanceExpirationDate
- at.ActivationDate = v1Act.BalanceExpirationDate
- }
- at.Balance = bf
- if at.ThresholdType == "*min_counter" ||
- at.ThresholdType == "*max_counter" {
- at.ThresholdType = strings.Replace(at.ThresholdType, "_", "_event_", 1)
- }
- return
-}
diff --git a/migrator/action_trigger_it_test.go b/migrator/action_trigger_it_test.go
deleted file mode 100644
index c846b7f04..000000000
--- a/migrator/action_trigger_it_test.go
+++ /dev/null
@@ -1,261 +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"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- actTrgPathIn string
- actTrgPathOut string
- actTrgCfgIn *config.CGRConfig
- actTrgCfgOut *config.CGRConfig
- actTrgMigrator *Migrator
- actActionTrigger string
-)
-
-var sTestsActTrgIT = []func(t *testing.T){
- testActTrgITConnect,
- testActTrgITFlush,
- testActTrgITMigrateAndMove,
-}
-
-func TestActionTriggerITRedis(t *testing.T) {
- var err error
- actTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actTrgCfgIn, err = config.NewCGRConfigFromPath(actTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actTrgCfgOut, err = config.NewCGRConfigFromPath(actTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionTrigger = utils.Migrate
- for _, stest := range sTestsActTrgIT {
- t.Run("TestActionTriggerITMigrateRedis", stest)
- }
- actTrgMigrator.Close()
-}
-
-func TestActionTriggerITMongo(t *testing.T) {
- var err error
- actTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actTrgCfgIn, err = config.NewCGRConfigFromPath(actTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actTrgCfgOut, err = config.NewCGRConfigFromPath(actTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionTrigger = utils.Migrate
- for _, stest := range sTestsActTrgIT {
- t.Run("TestActionTriggerITMigrateMongo", stest)
- }
- actTrgMigrator.Close()
-}
-
-func TestActionTriggerITMove(t *testing.T) {
- var err error
- actTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actTrgCfgIn, err = config.NewCGRConfigFromPath(actTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actTrgCfgOut, err = config.NewCGRConfigFromPath(actTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionTrigger = utils.Move
- for _, stest := range sTestsActTrgIT {
- t.Run("TestActionTriggerITMove", stest)
- }
- actTrgMigrator.Close()
-}
-
-func TestActionTriggerITMoveEncoding(t *testing.T) {
- var err error
- actTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- actTrgCfgIn, err = config.NewCGRConfigFromPath(actTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- actTrgCfgOut, err = config.NewCGRConfigFromPath(actTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionTrigger = utils.Move
- for _, stest := range sTestsActTrgIT {
- t.Run("TestActionTriggerITMoveEncoding", stest)
- }
- actTrgMigrator.Close()
-}
-
-func TestActionTriggerITMoveEncoding2(t *testing.T) {
- var err error
- actTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- actTrgCfgIn, err = config.NewCGRConfigFromPath(actTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- actTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- actTrgCfgOut, err = config.NewCGRConfigFromPath(actTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- actActionTrigger = utils.Move
- for _, stest := range sTestsActTrgIT {
- t.Run("TestActionTriggerITMoveEncoding2", stest)
- }
- actTrgMigrator.Close()
-}
-
-func testActTrgITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(actTrgCfgIn.DataDbCfg().Type,
- actTrgCfgIn.DataDbCfg().Host, actTrgCfgIn.DataDbCfg().Port,
- actTrgCfgIn.DataDbCfg().Name, actTrgCfgIn.DataDbCfg().User,
- actTrgCfgIn.DataDbCfg().Password, actTrgCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actTrgCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(actTrgCfgOut.DataDbCfg().Type,
- actTrgCfgOut.DataDbCfg().Host, actTrgCfgOut.DataDbCfg().Port,
- actTrgCfgOut.DataDbCfg().Name, actTrgCfgOut.DataDbCfg().User,
- actTrgCfgOut.DataDbCfg().Password, actTrgCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), actTrgCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(actTrgPathIn, actTrgPathOut) {
- actTrgMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- actTrgMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testActTrgITFlush(t *testing.T) {
- actTrgMigrator.dmOut.DataManager().DataDB().Flush("")
- actTrgMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(actTrgMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testActTrgITMigrateAndMove(t *testing.T) {
- tim := time.Date(2012, time.February, 27, 23, 59, 59, 0, time.UTC)
- v1actTrg := &v1ActionTriggers{
- &v1ActionTrigger{
- Id: "Test",
- BalanceType: "*monetary",
- BalanceDirection: "*out",
- ThresholdType: "*max_balance",
- ThresholdValue: 2,
- ActionsId: "TEST_ACTIONS",
- Executed: true,
- BalanceExpirationDate: tim,
- },
- }
- actTrg := engine.ActionTriggers{
- &engine.ActionTrigger{
- ID: "Test",
- Balance: &engine.BalanceFilter{
- ExpirationDate: utils.TimePointer(tim),
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ExpirationDate: tim,
- LastExecutionTime: tim,
- ActivationDate: tim,
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true,
- },
- }
-
- switch actActionTrigger {
- case utils.Migrate:
- err := actTrgMigrator.dmIN.setV1ActionTriggers(v1actTrg)
- if err != nil {
- t.Error("Error when setting v1 ActionTriggers ", err.Error())
- }
- currentVersion := engine.Versions{utils.StatS: 2, utils.Thresholds: 2, utils.Accounts: 2, utils.Actions: 2, utils.ActionTriggers: 1, utils.ActionPlans: 2, utils.SharedGroups: 2}
- err = actTrgMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for ActionTriggers ", err.Error())
- }
- err, _ = actTrgMigrator.Migrate([]string{utils.MetaActionTriggers})
- if err != nil {
- t.Error("Error when migrating ActionTriggers ", err.Error())
- }
- result, err := actTrgMigrator.dmOut.DataManager().GetActionTriggers((*v1actTrg)[0].Id, false, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting ActionTriggers ", err.Error())
- }
- if !reflect.DeepEqual(actTrg, result) {
- t.Errorf("Expecting: %+v,\nReceived: %+v", utils.ToJSON(actTrg), utils.ToJSON(result))
- } else if actTrgMigrator.stats[utils.ActionTriggers] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actTrgMigrator.stats[utils.ActionTriggers])
- }
- case utils.Move:
- if err := actTrgMigrator.dmIN.DataManager().SetActionTriggers((*v1actTrg)[0].Id, actTrg, utils.NonTransactional); err != nil {
- t.Error("Error when setting ActionTriggers ", err.Error())
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := actTrgMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for ActionTriggers ", err.Error())
- }
- err, _ = actTrgMigrator.Migrate([]string{utils.MetaActionTriggers})
- if err != nil {
- t.Error("Error when migrating ActionTriggers ", err.Error())
- }
- result, err := actTrgMigrator.dmOut.DataManager().GetActionTriggers((*v1actTrg)[0].Id, false, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting ActionTriggers ", err.Error())
- }
- if !reflect.DeepEqual(actTrg, result) {
- t.Errorf("Expecting: %+v, received: %+v", actTrg, result)
- }
- if actTrgMigrator.stats[utils.ActionTriggers] != 1 {
- t.Errorf("Expecting: 1, received: %+v", actTrgMigrator.stats[utils.ActionTriggers])
- }
- }
-}
diff --git a/migrator/action_trigger_test.go b/migrator/action_trigger_test.go
deleted file mode 100644
index b34c35507..000000000
--- a/migrator/action_trigger_test.go
+++ /dev/null
@@ -1,60 +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 (
- "reflect"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestV1ActionTriggersAsActionTriggers(t *testing.T) {
- tim := time.Date(0001, time.January, 1, 2, 0, 0, 0, time.UTC)
- v1atrs := &v1ActionTrigger{
- Id: "Test",
- BalanceType: "*monetary",
- BalanceDirection: "*out",
- ThresholdType: "*max_balance",
- ThresholdValue: 2,
- ActionsId: "TEST_ACTIONS",
- Executed: true,
- BalanceExpirationDate: tim,
- }
- atrs := &engine.ActionTrigger{
- ID: "Test",
- Balance: &engine.BalanceFilter{
- ExpirationDate: utils.TimePointer(tim),
- Type: utils.StringPointer(utils.MetaMonetary),
- },
- ExpirationDate: tim,
- LastExecutionTime: tim,
- ActivationDate: tim,
- ThresholdType: utils.TriggerMaxBalance,
- ThresholdValue: 2,
- ActionsID: "TEST_ACTIONS",
- Executed: true,
- }
-
- newatrs := v1atrs.AsActionTrigger()
- if !reflect.DeepEqual(atrs, newatrs) {
- t.Errorf("Expecting: %+v, received: %+v", atrs, newatrs)
- }
-}
diff --git a/migrator/alias.go b/migrator/alias.go
deleted file mode 100644
index 9d467a9bf..000000000
--- a/migrator/alias.go
+++ /dev/null
@@ -1,215 +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 (
-
- //"log"
- "fmt"
- "strings"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-type v1Alias struct {
- Direction string
- Tenant string
- Category string
- Account string
- Subject string
- Context string
- Values v1AliasValues
-}
-
-var (
- AliasesPrefix = "als_"
- Alias = "Alias"
-)
-
-type v1AliasValues []*v1AliasValue
-
-type v1AliasValue struct {
- DestinationId string //=Destination
- Pairs v1AliasPairs
- Weight float64
-}
-
-type v1AliasPairs map[string]map[string]string
-
-func (al *v1Alias) SetId(id string) error {
- vals := strings.Split(id, utils.ConcatenatedKeySep)
- if len(vals) != 6 {
- return utils.ErrInvalidKey
- }
- al.Direction = vals[0]
- al.Tenant = vals[1]
- al.Category = vals[2]
- al.Account = vals[3]
- al.Subject = vals[4]
- al.Context = vals[5]
- return nil
-}
-
-func (al *v1Alias) GetId() string {
- return utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, al.Account, al.Subject, al.Context)
-}
-
-func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.AttributeProfile {
- out := &engine.AttributeProfile{
- Tenant: alias.Tenant,
- ID: alias.GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: make([]*engine.Attribute, 0),
- Blocker: false,
- Weight: 20, // should have prio against attributes out of users
- }
- if len(out.Tenant) == 0 || out.Tenant == utils.MetaAny {
- out.Tenant = defaultTenant
- }
- if len(alias.Category) != 0 && alias.Category != utils.MetaAny {
- out.FilterIDs = append(out.FilterIDs,
- fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.Category, alias.Category))
- }
- if len(alias.Account) != 0 && alias.Account != utils.MetaAny {
- out.FilterIDs = append(out.FilterIDs,
- fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.AccountField, alias.Account))
- }
- if len(alias.Subject) != 0 && alias.Subject != utils.MetaAny {
- out.FilterIDs = append(out.FilterIDs,
- fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.Subject, alias.Subject))
- }
- var destination string
- for _, av := range alias.Values {
- if len(destination) == 0 || destination == utils.MetaAny {
- destination = av.DestinationId
- }
- for fieldName, vals := range av.Pairs {
- for initial, substitute := range vals {
- var fld string
- if fieldName == utils.Tenant {
- fieldName = utils.MetaTenant
- fld = utils.MetaTenant
- } else if fieldName != utils.EmptyString {
- fld = utils.MetaReq + utils.NestingSep + fieldName
- } else {
- continue // ignore empty fieldNames
- }
- attr := &engine.Attribute{
- Path: fld,
- Type: utils.MetaVariable, //default type for Attribute
- Value: config.NewRSRParsersMustCompile(substitute, utils.InfieldSep),
- }
- out.Attributes = append(out.Attributes, attr)
- // Add attribute filters if needed
- if initial == "" || initial == utils.MetaAny {
- continue
- }
- if fieldName == utils.MetaTenant { // no filter for tenant
- continue
- }
- if fieldName == utils.Category && alias.Category == initial {
- continue
- }
- if fieldName == utils.AccountField && alias.Account == initial {
- continue
- }
- if fieldName == utils.Subject && alias.Subject == initial {
- continue
- }
- attr.FilterIDs = append(attr.FilterIDs,
- fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+fieldName, initial))
- }
- }
- }
- if len(destination) != 0 && destination != utils.MetaAny {
- out.FilterIDs = append(out.FilterIDs,
- fmt.Sprintf("%s:~%s:%s", utils.MetaDestinations, utils.MetaReq+utils.NestingSep+utils.Destination, destination))
- }
- return out
-}
-
-func (m *Migrator) removeAlias2Attributes() (err error) {
- for {
- alias, err := m.dmIN.getV1Alias()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return err
- }
- if err := m.dmIN.remV1Alias(alias.GetId()); err != nil {
- return err
- }
- }
- return
-}
-
-func (m *Migrator) migrateAlias2Attributes() (err error) {
- cfg := config.CgrConfig()
-
- defaultTenant := cfg.GeneralCfg().DefaultTenant
- for {
- alias, err := m.dmIN.getV1Alias()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return err
- }
- if alias == nil || m.dryRun {
- continue
- }
- attr := alias2AtttributeProfile(alias, defaultTenant)
- if len(attr.Attributes) == 0 {
- continue
- }
- if err := m.dmOut.DataManager().SetAttributeProfile(attr, true); err != nil {
- return err
- }
- m.stats[Alias]++
- }
- if m.dryRun {
- return
- }
- if !m.sameDataDB {
- if err = m.removeAlias2Attributes(); err != nil {
- return
- }
- }
- // All done, update version wtih current one
- vrs := engine.Versions{Alias: 0} //engine.CurrentDataDBVersions()[utils.Alias]}
- if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when updating Alias version into dataDB", err.Error()))
- }
- return
-}
-
-func (m *Migrator) migrateAlias() (err error) {
- if err = m.migrateAlias2Attributes(); err != nil {
- return
- }
- return m.ensureIndexesDataDB(engine.ColAttr)
-}
diff --git a/migrator/alias_it_test.go b/migrator/alias_it_test.go
deleted file mode 100644
index d73d0493e..000000000
--- a/migrator/alias_it_test.go
+++ /dev/null
@@ -1,237 +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"
- "sort"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- inPath string
- outPath string
- alsCfgIn *config.CGRConfig
- alsCfgOut *config.CGRConfig
- alsMigrator *Migrator
-)
-
-var sTestsAlsIT = []func(t *testing.T){
- testAlsITConnect,
- testAlsITFlush,
- testAlsITMigrateAndMove,
-}
-
-func TestAliasMigrateITRedis(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- testStart("TestAliasMigrateITRedis", t)
-}
-
-func TestAliasMigrateITMongo(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- testStart("TestAliasMigrateITMongo", t)
-}
-
-func TestAliasITMigrateMongo2Redis(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- testStart("TestAliasITMigrateMongo2Redis", t)
-}
-
-func testStart(testName string, t *testing.T) {
- var err error
- if alsCfgIn, err = config.NewCGRConfigFromPath(inPath); err != nil {
- t.Fatal(err)
- }
- if alsCfgOut, err = config.NewCGRConfigFromPath(outPath); err != nil {
- t.Fatal(err)
- }
- for _, stest := range sTestsAlsIT {
- t.Run(testName, stest)
- }
- alsMigrator.Close()
-}
-
-func testAlsITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(alsCfgIn.DataDbCfg().Type,
- alsCfgIn.DataDbCfg().Host, alsCfgIn.DataDbCfg().Port,
- alsCfgIn.DataDbCfg().Name, alsCfgIn.DataDbCfg().User,
- alsCfgIn.DataDbCfg().Password, alsCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), alsCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(alsCfgOut.DataDbCfg().Type,
- alsCfgOut.DataDbCfg().Host, alsCfgOut.DataDbCfg().Port,
- alsCfgOut.DataDbCfg().Name, alsCfgOut.DataDbCfg().User,
- alsCfgOut.DataDbCfg().Password, alsCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), alsCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(inPath, outPath) {
- alsMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- alsMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testAlsITFlush(t *testing.T) {
- alsMigrator.dmOut.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(alsMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- alsMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(alsMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testAlsITMigrateAndMove(t *testing.T) {
- alias := &v1Alias{
- Tenant: utils.MetaAny,
- Direction: "*out",
- Category: utils.MetaAny,
- Account: "1001",
- Subject: "call_1001",
- Context: "*rated",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: "DST_1003",
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "1001": "1002",
- },
- "Category": map[string]string{
- "call_1001": "call_1002",
- },
- },
- Weight: 10,
- },
- },
- }
- attrProf := &engine.AttributeProfile{
- Tenant: "cgrates.org",
- ID: alias.GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~*req.Account:1001",
- "*string:~*req.Subject:call_1001",
- "*destinations:~*req.Destination:DST_1003",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- {
- FilterIDs: []string{"*string:~*req.Category:call_1001"},
- Path: utils.MetaReq + utils.NestingSep + "Category",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1002", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- }
- attrProf.Compile()
-
- err := alsMigrator.dmIN.setV1Alias(alias)
- if err != nil {
- t.Error("Error when setting v1 Alias ", err.Error())
- }
- currentVersion := engine.Versions{Alias: 1}
- err = alsMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for Alias ", err.Error())
- }
- //check if version was set correctly
- if vrs, err := alsMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[Alias] != 1 {
- t.Errorf("Unexpected version returned: %d", vrs[Alias])
- }
- //migrate alias
- err, _ = alsMigrator.Migrate([]string{MetaAliases})
- if err != nil {
- t.Error("Error when migrating Alias ", err.Error())
- }
- //check if version was updated
- if vrs, err := alsMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[Alias] != 0 {
- t.Errorf("Unexpected version returned: %d", vrs[Alias])
- }
- //check if alias was migrate correctly
- result, err := alsMigrator.dmOut.DataManager().DataDB().GetAttributeProfileDrv("cgrates.org", alias.GetId())
- if err != nil {
- t.Fatalf("Error when getting Attributes %v", err.Error())
- }
- result.Compile()
- sort.Slice(result.Attributes, func(i, j int) bool {
- if result.Attributes[i].Path == result.Attributes[j].Path {
- return result.Attributes[i].FilterIDs[0] < result.Attributes[j].FilterIDs[0]
- }
- return result.Attributes[i].Path < result.Attributes[j].Path
- }) // only for test; map returns random keys
- if !reflect.DeepEqual(*attrProf, *result) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result))
- }
- //check if old account was deleted (only if dmIN != dmOut)
- if !alsMigrator.sameDataDB {
- if _, err = alsMigrator.dmIN.getV1Alias(); err != utils.ErrNoMoreData {
- t.Error("Error should be not found : ", err)
- }
- }
-
- expAlsIdx := map[string]utils.StringSet{
- "*string:*req.Account:1001": {
- "*out:*any:*any:1001:call_1001:*rated": struct{}{},
- },
- "*string:*req.Subject:call_1001": {
- "*out:*any:*any:1001:call_1001:*rated": struct{}{},
- },
- }
- if alsidx, err := alsMigrator.dmOut.DataManager().GetIndexes(
- utils.CacheAttributeFilterIndexes, utils.ConcatenatedKey("cgrates.org", utils.MetaAny),
- "", false, false); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expAlsIdx, alsidx) {
- t.Errorf("Expected %v, received: %v", utils.ToJSON(expAlsIdx), utils.ToJSON(alsidx))
- } else if alsMigrator.stats[Alias] != 1 {
- t.Errorf("Expected 1, received: %v", alsMigrator.stats[Alias] != 1)
- }
-}
diff --git a/migrator/alias_test.go b/migrator/alias_test.go
deleted file mode 100644
index 98f685f71..000000000
--- a/migrator/alias_test.go
+++ /dev/null
@@ -1,318 +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 (
- "reflect"
- "sort"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var defaultTenant = "cgrates.org"
-
-func TestAlias2AtttributeProfile(t *testing.T) {
- aliases := map[int]*v1Alias{
- 0: {
- Tenant: utils.MetaAny,
- Direction: utils.MetaOut,
- Category: utils.MetaAny,
- Account: utils.MetaAny,
- Subject: utils.MetaAny,
- Context: "*rating",
- Values: v1AliasValues{},
- },
- 1: {
- Tenant: utils.MetaAny,
- Direction: utils.MetaOut,
- Category: utils.MetaAny,
- Account: utils.MetaAny,
- Subject: utils.MetaAny,
- Context: "*rating",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: utils.MetaAny,
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "1001": "1002",
- },
- },
- Weight: 20,
- },
- },
- },
- 2: {
- Tenant: utils.MetaAny,
- Direction: utils.MetaOut,
- Category: utils.MetaAny,
- Account: utils.MetaAny,
- Subject: utils.MetaAny,
- Context: "*rating",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: utils.MetaAny,
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "1001": "1002",
- "1003": "1004",
- },
- },
- Weight: 10,
- },
- },
- },
- 3: {
- Tenant: "",
- Direction: "",
- Category: "",
- Account: "",
- Subject: "",
- Context: "",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: utils.MetaAny,
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "1001": "1002",
- "1003": "1004",
- },
- },
- Weight: 10,
- },
- },
- },
- 4: {
- Tenant: "notDefaultTenant",
- Direction: "*out",
- Category: "*voice",
- Account: "1001",
- Subject: utils.MetaAny,
- Context: "*rated",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: "DST_1003",
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "": "1002",
- },
- "Subject": map[string]string{
- "": "call_1001",
- },
- },
- Weight: 10,
- },
- },
- },
- 5: {
- Tenant: "notDefaultTenant",
- Direction: "*out",
- Category: utils.MetaAny,
- Account: "1001",
- Subject: "call_1001",
- Context: "*rated",
- Values: v1AliasValues{
- &v1AliasValue{
- DestinationId: "DST_1003",
- Pairs: map[string]map[string]string{
- "Account": map[string]string{
- "1001": "1002",
- },
- "Category": map[string]string{
- "call_1001": "call_1002",
- },
- },
- Weight: 10,
- },
- },
- },
- 6: {
- Tenant: utils.MetaAny,
- Category: "somecateg_5141",
- Account: utils.MetaAny,
- Subject: utils.MetaAny,
- Context: "*rated",
- Values: v1AliasValues{
- &v1AliasValue{
- Pairs: map[string]map[string]string{
- utils.Category: map[string]string{
- "somecateg_5141": "somecateg_roam_fromz4",
- },
- },
- },
- },
- },
- }
- expected := map[int]*engine.AttributeProfile{
- 0: {
- Tenant: defaultTenant,
- ID: aliases[0].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: make([]*engine.Attribute, 0),
- Blocker: false,
- Weight: 20,
- },
- 1: {
- Tenant: defaultTenant,
- ID: aliases[1].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- FilterIDs: []string{"*string:~*req.Account:1001"},
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- },
- 2: {
- Tenant: defaultTenant,
- ID: aliases[2].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- FilterIDs: []string{"*string:~*req.Account:1001"},
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- {
- FilterIDs: []string{"*string:~*req.Account:1003"},
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1004", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- },
- 3: {
- Tenant: defaultTenant,
- ID: aliases[3].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- FilterIDs: []string{"*string:~*req.Account:1001"},
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- {
- FilterIDs: []string{"*string:~*req.Account:1003"},
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1004", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- },
- 4: {
- Tenant: "notDefaultTenant",
- ID: aliases[4].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~*req.Category:*voice",
- "*string:~*req.Account:1001",
- "*destinations:~*req.Destination:DST_1003",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "Subject",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1001", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- },
- 5: {
- Tenant: "notDefaultTenant",
- ID: aliases[5].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~*req.Account:1001",
- "*string:~*req.Subject:call_1001",
- "*destinations:~*req.Destination:DST_1003",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + "Account",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "Category",
- Type: utils.MetaVariable,
- FilterIDs: []string{"*string:~*req.Category:call_1001"},
- Value: config.NewRSRParsersMustCompile("call_1002", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 20,
- },
- 6: {
- Tenant: "cgrates.org",
- ID: aliases[6].GetId(),
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~*req.Category:somecateg_5141",
- },
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Category,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("somecateg_roam_fromz4", utils.InfieldSep),
- },
- },
- Weight: 20,
- },
- }
- for i := range expected {
- rply := alias2AtttributeProfile(aliases[i], defaultTenant)
- sort.Slice(rply.Attributes, func(i, j int) bool {
- if rply.Attributes[i].Path == rply.Attributes[j].Path {
- return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0]
- }
- return rply.Attributes[i].Path < rply.Attributes[j].Path
- }) // only for test; map returns random keys
- if !reflect.DeepEqual(expected[i], rply) {
- t.Errorf("For %v expected: %s ,received: %s ", i, utils.ToJSON(expected[i]), utils.ToJSON(rply))
- }
- }
-}
diff --git a/migrator/cdrs.go b/migrator/cdrs.go
index 9fe05fdc4..918e0283a 100755
--- a/migrator/cdrs.go
+++ b/migrator/cdrs.go
@@ -144,7 +144,6 @@ type v1Cdrs struct {
Rated bool // Mark the CDR as rated so we do not process it during rating
CostSource string // The source of this cost
Cost float64
- CostDetails *engine.CallCost // Attach the cost details to CDR when possible
}
func (v1Cdr *v1Cdrs) V1toV2Cdr() (cdr *engine.CDR) {
@@ -171,7 +170,6 @@ func (v1Cdr *v1Cdrs) V1toV2Cdr() (cdr *engine.CDR) {
PreRated: v1Cdr.Rated,
CostSource: v1Cdr.CostSource,
Cost: v1Cdr.Cost,
- CostDetails: engine.NewEventCostFromCallCost(v1Cdr.CostDetails, v1Cdr.CGRID, v1Cdr.RunID),
}
if v1Cdr.ExtraFields != nil {
for key, value := range v1Cdr.ExtraFields {
@@ -207,11 +205,6 @@ func NewV1CDRFromCDRSql(cdrSql *engine.CDRsql) (cdr *v1Cdrs, err error) {
return nil, err
}
}
- if cdrSql.CostDetails != "" {
- if err = json.Unmarshal([]byte(cdrSql.CostDetails), &cdr.CostDetails); err != nil {
- return nil, err
- }
- }
return
}
@@ -235,7 +228,6 @@ func (cdr *v1Cdrs) AsCDRsql() (cdrSql *engine.CDRsql) {
cdrSql.ExtraFields = utils.ToJSON(cdr.ExtraFields)
cdrSql.CostSource = cdr.CostSource
cdrSql.Cost = cdr.Cost
- cdrSql.CostDetails = utils.ToJSON(cdr.CostDetails)
cdrSql.ExtraInfo = cdr.ExtraInfo
cdrSql.CreatedAt = time.Now()
return
diff --git a/migrator/derived_chargers.go b/migrator/derived_chargers.go
deleted file mode 100644
index 96e7ef107..000000000
--- a/migrator/derived_chargers.go
+++ /dev/null
@@ -1,251 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var dcGetMapKeys = func(m utils.StringMap) (keys []string) {
- keys = make([]string, len(m))
- i := 0
- for k := range m {
- keys[i] = k
- i++
- }
- // sort.Strings(keys)
- return keys
-}
-
-type v1DerivedCharger struct {
- RunID string // Unique runId in the chain
- RunFilters string // Only run the charger if all the filters match
-
- RequestTypeField string // Field containing request type info, number in case of csv source, '^' as prefix in case of static values
- DirectionField string // Field containing direction info
- TenantField string // Field containing tenant info
- CategoryField string // Field containing tor info
- AccountField string // Field containing account information
- SubjectField string // Field containing subject information
- DestinationField string // Field containing destination information
- SetupTimeField string // Field containing setup time information
- PDDField string // Field containing setup time information
- AnswerTimeField string // Field containing answer time information
- UsageField string // Field containing usage information
- SupplierField string // Field containing supplier information
- DisconnectCauseField string // Field containing disconnect cause information
- CostField string // Field containing cost information
- PreRatedField string // Field marking rated request in CDR
-}
-
-type v1DerivedChargers struct {
- DestinationIDs utils.StringMap
- Chargers []*v1DerivedCharger
-}
-
-type v1DerivedChargersWithKey struct {
- Key string
- Value *v1DerivedChargers
-}
-
-func fieldinfo2Attribute(attr []*engine.Attribute, fieldName, fieldInfo string) (a []*engine.Attribute) {
- var rp config.RSRParsers
- if fieldInfo == utils.MetaDefault || len(fieldInfo) == 0 {
- return attr
- }
- if strings.HasPrefix(fieldInfo, utils.StaticValuePrefix) {
- fieldInfo = fieldInfo[1:]
- }
- var err error
- if rp, err = config.NewRSRParsers(fieldInfo, utils.InfieldSep); err != nil {
- utils.Logger.Err(fmt.Sprintf("On Migrating rule: <%s>, error: %s", fieldInfo, err.Error()))
- return attr
- }
- var path string
- if fieldName == utils.EmptyString {
- return attr // do not append attribute if fieldName is empty
- }
- path = utils.MetaReq + utils.NestingSep + fieldName
- return append(attr, &engine.Attribute{
- Path: path,
- Value: rp,
- Type: utils.MetaVariable,
- })
-}
-
-func derivedChargers2AttributeProfile(dc *v1DerivedCharger, tenant, key string, filters []string) (attr *engine.AttributeProfile) {
- attr = &engine.AttributeProfile{
- Tenant: tenant,
- ID: key,
- Contexts: []string{utils.MetaChargers},
- FilterIDs: filters,
- ActivationInterval: nil,
- Attributes: make([]*engine.Attribute, 0),
- Blocker: false,
- Weight: 10,
- }
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.RequestType, dc.RequestTypeField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Direction, dc.DirectionField) //still in use?
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Tenant, dc.TenantField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Category, dc.CategoryField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.AccountField, dc.AccountField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Subject, dc.SubjectField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Destination, dc.DestinationField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.SetupTime, dc.SetupTimeField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.PDD, dc.PDDField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.AnswerTime, dc.AnswerTimeField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Usage, dc.UsageField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, SUPPLIER, dc.SupplierField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.DisconnectCause, dc.DisconnectCauseField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.Cost, dc.CostField)
- attr.Attributes = fieldinfo2Attribute(attr.Attributes, utils.PreRated, dc.PreRatedField)
- return
-}
-
-func derivedChargers2Charger(dc *v1DerivedCharger, tenant string, key string, filters []string) (ch *engine.ChargerProfile) {
- ch = &engine.ChargerProfile{
- Tenant: tenant,
- ID: key,
- FilterIDs: filters,
- ActivationInterval: nil,
- RunID: dc.RunID,
- AttributeIDs: make([]string, 0),
- Weight: 10,
- }
-
- filter := dc.RunFilters
- if len(filter) != 0 {
- if strings.HasPrefix(filter, utils.StaticValuePrefix) {
- filter = filter[1:]
- }
- if strings.HasPrefix(filter, utils.DynamicDataPrefix) {
- filter = filter[1:]
- }
- flt, err := migrateInlineFilterV4([]string{"*rsr::" + utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + filter})
- if err != nil {
- return
- }
- ch.FilterIDs = append(ch.FilterIDs, flt...)
- }
- return
-}
-
-func (m *Migrator) derivedChargers2Chargers(dck *v1DerivedChargersWithKey) (err error) {
- // (direction, tenant, category, account, subject)
- skey := utils.SplitConcatenatedKey(dck.Key)
- destination := ""
- if len(dck.Value.DestinationIDs) != 0 {
- destination = fmt.Sprintf("%s:~%s:", utils.MetaDestinations, utils.MetaReq+utils.NestingSep+utils.Destination)
- keys := dcGetMapKeys(dck.Value.DestinationIDs)
- destination += strings.Join(keys, utils.PipeSep)
- }
- filter := make([]string, 0)
-
- if len(destination) != 0 {
- filter = append(filter, destination)
- }
- if len(skey[2]) != 0 && skey[2] != utils.MetaAny {
- filter = append(filter, fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.Category, skey[2]))
- }
- if len(skey[3]) != 0 && skey[3] != utils.MetaAny {
- filter = append(filter, fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.AccountField, skey[3]))
- }
- if len(skey[4]) != 0 && skey[4] != utils.MetaAny {
- filter = append(filter, fmt.Sprintf("%s:~%s:%s", utils.MetaString, utils.MetaReq+utils.NestingSep+utils.Subject, skey[4]))
- }
- for i, dc := range dck.Value.Chargers {
- attr := derivedChargers2AttributeProfile(dc, skey[1], fmt.Sprintf("%s_%v", dck.Key, i), filter)
- ch := derivedChargers2Charger(dc, skey[1], fmt.Sprintf("%s_%v", dck.Key, i), filter)
- if len(attr.Attributes) != 0 {
- if err = m.dmOut.DataManager().SetAttributeProfile(attr, true); err != nil {
- return err
- }
- ch.AttributeIDs = append(ch.AttributeIDs, attr.ID)
- }
- if err = m.dmOut.DataManager().SetChargerProfile(ch, true); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (m *Migrator) removeV1DerivedChargers() (err error) {
- for {
- var dck *v1DerivedChargersWithKey
- dck, err = m.dmIN.getV1DerivedChargers()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return
- }
- if err = m.dmIN.remV1DerivedChargers(dck.Key); err != nil {
- return
- }
- }
- return
-}
-
-func (m *Migrator) migrateV1DerivedChargers() (err error) {
- for {
- var dck *v1DerivedChargersWithKey
- dck, err = m.dmIN.getV1DerivedChargers()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return
- }
- if dck == nil || m.dryRun {
- continue
- }
- if err = m.derivedChargers2Chargers(dck); err != nil {
- return
- }
-
- m.stats[utils.DerivedChargersV]++
- }
- if m.dryRun {
- return
- }
- if err = m.removeV1DerivedChargers(); err != nil && err != utils.ErrNoMoreData {
- return
- }
- // All done, update version wtih current one
- vrs := engine.Versions{utils.DerivedChargersV: 0}
- if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when updating DerivedChargers version into dataDB", err.Error()))
- }
- return
-}
-
-func (m *Migrator) migrateDerivedChargers() (err error) {
- if err = m.migrateV1DerivedChargers(); err != nil {
- return
- }
- return m.ensureIndexesDataDB(engine.ColCpp, engine.ColAttr)
-}
diff --git a/migrator/derived_chargers_it_test.go b/migrator/derived_chargers_it_test.go
deleted file mode 100644
index 11c499c58..000000000
--- a/migrator/derived_chargers_it_test.go
+++ /dev/null
@@ -1,264 +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 (
- "fmt"
- "log"
- "path"
- "reflect"
- "sort"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- dcCfgIn *config.CGRConfig
- dcCfgOut *config.CGRConfig
- dcMigrator *Migrator
-)
-
-var sTestsDCIT = []func(t *testing.T){
- testDCITConnect,
- testDCITFlush,
- testDCITMigrateAndMove,
-}
-
-func TestDerivedChargersVMigrateITRedis(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- testStartDC("TestDerivedChargersVMigrateITRedis", t)
-}
-
-func TestDerivedChargersVMigrateITMongo(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- testStartDC("TestDerivedChargersVMigrateITMongo", t)
-}
-
-func TestDerivedChargersVITMigrateMongo2Redis(t *testing.T) {
- inPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
- outPath = path.Join(*dataDir, "conf", "samples", "tutmysql")
- testStartDC("TestDerivedChargersVITMigrateMongo2Redis", t)
-}
-
-func testStartDC(testName string, t *testing.T) {
- var err error
- if dcCfgIn, err = config.NewCGRConfigFromPath(inPath); err != nil {
- t.Fatal(err)
- }
- if dcCfgOut, err = config.NewCGRConfigFromPath(outPath); err != nil {
- t.Fatal(err)
- }
- for _, stest := range sTestsDCIT {
- t.Run(testName, stest)
- }
- dcMigrator.Close()
-}
-
-func testDCITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(dcCfgIn.DataDbCfg().Type,
- dcCfgIn.DataDbCfg().Host, dcCfgIn.DataDbCfg().Port,
- dcCfgIn.DataDbCfg().Name, dcCfgIn.DataDbCfg().User,
- dcCfgIn.DataDbCfg().Password, dcCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), dcCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(dcCfgOut.DataDbCfg().Type,
- dcCfgOut.DataDbCfg().Host, dcCfgOut.DataDbCfg().Port,
- dcCfgOut.DataDbCfg().Name, dcCfgOut.DataDbCfg().User,
- dcCfgOut.DataDbCfg().Password, dcCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), dcCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(inPath, outPath) {
- dcMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- dcMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testDCITFlush(t *testing.T) {
- dcMigrator.dmOut.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(dcMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- dcMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(dcMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testDCITMigrateAndMove(t *testing.T) {
- dcGetMapKeys = func(m utils.StringMap) (keys []string) { //make sure destination are in order
- keys = make([]string, len(m))
- i := 0
- for k := range m {
- keys[i] = k
- i += 1
- }
- sort.Strings(keys)
- return keys
- }
- derivch := &v1DerivedChargersWithKey{
- Key: utils.ConcatenatedKey("*out", defaultTenant, utils.MetaAny, "1003", utils.MetaAny),
- Value: &v1DerivedChargers{
- DestinationIDs: utils.StringMap{"1001": true, "1002": true, "1003": true},
- Chargers: []*v1DerivedCharger{
- {
- RunID: "RunID",
- RunFilters: "~filterhdr1(.+)",
-
- RequestTypeField: utils.MetaDefault,
- CategoryField: utils.MetaDefault,
- AccountField: "^1004",
- SubjectField: "call_1003",
- },
- },
- },
- }
- attrProf := &engine.AttributeProfile{
- Tenant: "cgrates.org",
- ID: fmt.Sprintf("%s_%v", derivch.Key, 0),
- Contexts: []string{utils.MetaChargers},
- FilterIDs: []string{
- "*destinations:~*req.Destination:1001|1002|1003",
- "*string:~*req.Account:1003",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1004", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Subject,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1003", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- }
- attrProf.Compile()
- charger := &engine.ChargerProfile{
- Tenant: defaultTenant,
- ID: fmt.Sprintf("%s_%v", derivch.Key, 0),
- FilterIDs: []string{
- "*destinations:~*req.Destination:1001|1002|1003",
- "*string:~*req.Account:1003",
- "*rsr:~*req.filterhdr1:.+",
- },
- ActivationInterval: nil,
- RunID: "RunID",
- AttributeIDs: []string{attrProf.ID},
- Weight: 10,
- }
-
- err := dcMigrator.dmIN.setV1DerivedChargers(derivch)
- if err != nil {
- t.Error("Error when setting v1 DerivedChargersV ", err.Error())
- }
- currentVersion := engine.Versions{utils.DerivedChargersV: 1}
- err = dcMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for DerivedChargersV ", err.Error())
- }
- //check if version was set correctly
- if vrs, err := dcMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.DerivedChargersV] != 1 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.DerivedChargersV])
- }
- //migrate derivch
- err, _ = dcMigrator.Migrate([]string{utils.MetaDerivedChargersV})
- if err != nil {
- t.Error("Error when migrating DerivedChargersV ", err.Error())
- }
- //check if version was updated
- if vrs, err := dcMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.DerivedChargersV] != 0 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.DerivedChargersV])
- }
- //check if derivch was migrate correctly
- result, err := dcMigrator.dmOut.DataManager().DataDB().GetAttributeProfileDrv(defaultTenant, attrProf.ID)
- if err != nil {
- t.Fatalf("Error when getting Attributes %v", err.Error())
- }
- result.Compile()
- sort.Slice(result.Attributes, func(i, j int) bool {
- return result.Attributes[i].Path < result.Attributes[j].Path
- }) // only for test; map returns random keys
- if !reflect.DeepEqual(*attrProf, *result) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result))
- }
- result2, err := dcMigrator.dmOut.DataManager().DataDB().GetChargerProfileDrv(defaultTenant, charger.ID)
- if err != nil {
- t.Fatalf("Error when getting Attributes %v", err.Error())
- }
- if !reflect.DeepEqual(*charger, *result2) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(charger), utils.ToJSON(result2))
- }
-
- //check if old account was deleted
- if _, err = dcMigrator.dmIN.getV1DerivedChargers(); err != utils.ErrNoMoreData {
- t.Error("Error should be not found : ", err)
- }
- expDcIdx := map[string]utils.StringSet{
- "*string:*req.Account:1003": {
- "*out:cgrates.org:*any:1003:*any_0": struct{}{},
- },
- }
- if dcidx, err := dcMigrator.dmOut.DataManager().GetIndexes(
- utils.CacheAttributeFilterIndexes,
- utils.ConcatenatedKey("cgrates.org", utils.MetaChargers),
- "", true, true); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expDcIdx, dcidx) {
- t.Errorf("Expected %v, received: %v", utils.ToJSON(expDcIdx), utils.ToJSON(dcidx))
- }
- expDcIdx = map[string]utils.StringSet{
- "*string:*req.Account:1003": {
- "*out:cgrates.org:*any:1003:*any_0": struct{}{},
- },
- }
- if dcidx, err := dcMigrator.dmOut.DataManager().GetIndexes(
- utils.CacheChargerFilterIndexes,
- utils.ConcatenatedKey("cgrates.org", utils.MetaChargers),
- "", true, true); err == nil || err.Error() != utils.ErrNotFound.Error() {
- t.Errorf("Expected error %v, received: %v with reply: %v", utils.ErrNotFound, err, utils.ToJSON(dcidx))
- } else if dcMigrator.stats[utils.DerivedChargersV] != 1 {
- t.Errorf("Expected 1, received: %v", dcMigrator.stats[utils.DerivedChargersV])
- }
-
-}
diff --git a/migrator/derived_chargers_test.go b/migrator/derived_chargers_test.go
deleted file mode 100644
index 931bae270..000000000
--- a/migrator/derived_chargers_test.go
+++ /dev/null
@@ -1,258 +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 (
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestFieldinfo2Attribute(t *testing.T) {
- type testA struct {
- Path string
- FieldInfo string
- Initial []*engine.Attribute
- Expected []*engine.Attribute
- }
- tests := []testA{
- {
- Path: utils.AccountField,
- FieldInfo: utils.MetaDefault,
- Initial: make([]*engine.Attribute, 0),
- Expected: make([]*engine.Attribute, 0),
- },
- {
- Path: utils.AccountField,
- FieldInfo: "",
- Initial: make([]*engine.Attribute, 0),
- Expected: make([]*engine.Attribute, 0),
- },
- {
- Path: utils.AccountField,
- FieldInfo: "^1003",
- Initial: make([]*engine.Attribute, 0),
- Expected: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1003", utils.InfieldSep),
- },
- },
- },
- {
- Path: utils.Subject,
- FieldInfo: `~effective_caller_id_number:s/(\d+)/+$1/`,
- Initial: make([]*engine.Attribute, 0),
- Expected: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Subject,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile(`~effective_caller_id_number:s/(\d+)/+$1/`, utils.InfieldSep),
- },
- },
- },
- {
- Path: utils.Subject,
- FieldInfo: "^call_1003",
- Initial: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1003", utils.InfieldSep),
- },
- },
- Expected: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1003", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Subject,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1003", utils.InfieldSep),
- },
- },
- },
- }
- for i, v := range tests {
- if rply := fieldinfo2Attribute(v.Initial, v.Path, v.FieldInfo); !reflect.DeepEqual(v.Expected, rply) {
- t.Errorf("For %v expected: %s ,recieved: %s", i, utils.ToJSON(v.Expected), utils.ToJSON(rply))
- }
- }
-}
-
-func TestDerivedChargers2AttributeProfile(t *testing.T) {
- type testC struct {
- DC *v1DerivedCharger
- Tenant string
- Key string
- Filters []string
- Expected *engine.AttributeProfile
- }
- tests := []testC{
- {
- DC: &v1DerivedCharger{
- RequestTypeField: utils.MetaDefault,
- CategoryField: "^*voice",
- AccountField: "^1003",
- },
- Tenant: defaultTenant,
- Key: "key1",
- Filters: make([]string, 0),
- Expected: &engine.AttributeProfile{
- Tenant: defaultTenant,
- ID: "key1",
- Contexts: []string{utils.MetaChargers},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Category,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*voice", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1003", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- },
- {
- DC: &v1DerivedCharger{
- RequestTypeField: utils.MetaDefault,
- CategoryField: "^*voice",
- AccountField: "^1003",
- SubjectField: "call_1003_to_1004",
- DestinationField: "^1004",
- },
- Tenant: defaultTenant,
- Key: "key1",
- Filters: []string{"*string:~*req.Subject:1005"},
- Expected: &engine.AttributeProfile{
- Tenant: defaultTenant,
- ID: "key1",
- Contexts: []string{utils.MetaChargers},
- FilterIDs: []string{"*string:~*req.Subject:1005"},
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Category,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*voice", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.AccountField,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1003", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Subject,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1003_to_1004", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Destination,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("1004", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- },
- }
- for i, v := range tests {
- if rply := derivedChargers2AttributeProfile(v.DC, v.Tenant, v.Key, v.Filters); !reflect.DeepEqual(v.Expected, rply) {
- t.Errorf("For %v expected: %s ,recieved: %s", i, utils.ToJSON(v.Expected), utils.ToJSON(rply))
- }
- }
-}
-
-func TestDerivedChargers2Charger(t *testing.T) {
- type testB struct {
- DC *v1DerivedCharger
- Tenant string
- Key string
- Filters []string
- Expected *engine.ChargerProfile
- }
- tests := []testB{
- {
- DC: &v1DerivedCharger{
- RunID: "runID",
- RunFilters: "~Header4:s/a/${1}b/{*duration_seconds&*round:2}(b&c)",
- RequestTypeField: utils.MetaDefault,
- CategoryField: "^*voice",
- AccountField: "^1003",
- },
- Tenant: defaultTenant,
- Key: "key2",
- Filters: []string{
- "*string:~*req.Category:*voice1",
- "*string:~*req.Account:1001",
- },
- Expected: &engine.ChargerProfile{
- Tenant: defaultTenant,
- ID: "key2",
- FilterIDs: []string{
- "*string:~*req.Category:*voice1",
- "*string:~*req.Account:1001",
- "*rsr:~*req.Header4:b|c",
- },
- ActivationInterval: nil,
- RunID: "runID",
- AttributeIDs: make([]string, 0),
- Weight: 10,
- },
- },
- {
- DC: &v1DerivedCharger{
- RunID: "runID2",
- RunFilters: "~Account(^1003)",
- AccountField: "^1003",
- },
- Tenant: defaultTenant,
- Key: "key2",
- Filters: []string{},
- Expected: &engine.ChargerProfile{
- Tenant: defaultTenant,
- ID: "key2",
- FilterIDs: []string{"*rsr:~*req.Account:^1003"},
- ActivationInterval: nil,
- RunID: "runID2",
- AttributeIDs: make([]string, 0),
- Weight: 10,
- },
- },
- }
- for i, v := range tests {
- if rply := derivedChargers2Charger(v.DC, v.Tenant, v.Key, v.Filters); !reflect.DeepEqual(v.Expected, rply) {
- t.Errorf("For %v expected: %s ,\n recieved: %s", i, utils.ToJSON(v.Expected), utils.ToJSON(rply))
- }
- }
-}
diff --git a/migrator/migrator.go b/migrator/migrator.go
index 00c057f1a..970ce1774 100755
--- a/migrator/migrator.go
+++ b/migrator/migrator.go
@@ -44,8 +44,6 @@ func NewMigrator(dmIN, dmOut MigratorDataDB,
return m, err
}
-const MetaAliases = "*aliases"
-
type Migrator struct {
dmIN MigratorDataDB
dmOut MigratorDataDB
@@ -107,18 +105,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
}
case utils.MetaCDRs:
err = m.migrateCDRs()
- case utils.MetaSessionsCosts:
- err = m.migrateSessionSCosts()
- case utils.MetaAccounts:
- err = m.migrateAccounts()
- case utils.MetaActionPlans:
- err = m.migrateActionPlans()
- case utils.MetaActionTriggers:
- err = m.migrateActionTriggers()
- case utils.MetaActions:
- err = m.migrateActions()
- case utils.MetaSharedGroups:
- err = m.migrateSharedGroups()
case utils.MetaStats:
err = m.migrateStats()
case utils.MetaThresholds:
@@ -132,10 +118,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
case utils.MetaAccountProfiles:
err = m.migrateAccountProfiles()
//only Move
- case utils.MetaRatingPlans:
- err = m.migrateRatingPlans()
- case utils.MetaRatingProfiles:
- err = m.migrateRatingProfiles()
case utils.MetaActionProfiles:
err = m.migrateActionProfiles()
case utils.MetaDestinations:
@@ -148,51 +130,27 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
err = m.migrateResources()
case utils.MetaRateProfiles:
err = m.migrateRateProfiles()
- case MetaAliases:
- err = m.migrateAlias()
- case utils.MetaUsers:
- err = m.migrateUser()
case utils.MetaSubscribers:
err = m.migrateSubscribers()
- case utils.MetaDerivedChargersV:
- err = m.migrateDerivedChargers()
case utils.MetaChargers:
err = m.migrateChargers()
case utils.MetaDispatchers:
err = m.migrateDispatchers()
//TPs
- case utils.MetaTpRatingPlans:
- err = m.migrateTPratingplans()
case utils.MetaTpFilters:
err = m.migrateTPfilters()
- case utils.MetaTpDestinationRates:
- err = m.migrateTPdestinationrates()
- case utils.MetaTpActionTriggers:
- err = m.migrateTPactiontriggers()
- case utils.MetaTpAccountActions:
- err = m.migrateTPaccountacction()
- case utils.MetaTpActionPlans:
- err = m.migrateTPactionplans()
- case utils.MetaTpActions:
- err = m.migrateTPactions()
case utils.MetaTpThresholds:
err = m.migrateTPthresholds()
case utils.MetaTpRoutes:
err = m.migrateTPRoutes()
case utils.MetaTpStats:
err = m.migrateTPstats()
- case utils.MetaTpSharedGroups:
- err = m.migrateTPsharedgroups()
- case utils.MetaTpRatingProfiles:
- err = m.migrateTPratingprofiles()
case utils.MetaTpRateProfiles:
err = m.migrateTPRateProfiles()
case utils.MetaTpActionProfiles:
err = m.migrateTPActionProfiles()
case utils.MetaTpResources:
err = m.migrateTPresources()
- case utils.MetaTpRates:
- err = m.migrateTPrates()
case utils.MetaTpTimings:
err = m.migrateTpTimings()
case utils.MetaTpDestinations:
@@ -205,21 +163,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
err = m.migrateLoadIDs()
//DATADB ALL
case utils.MetaDataDB:
- if err := m.migrateAccounts(); err != nil {
- log.Print("ERROR: ", utils.MetaAccounts, " ", err)
- }
- if err := m.migrateActionPlans(); err != nil {
- log.Print("ERROR: ", utils.MetaActionPlans, " ", err)
- }
- if err := m.migrateActionTriggers(); err != nil {
- log.Print("ERROR: ", utils.MetaActionTriggers, " ", err)
- }
- if err := m.migrateActions(); err != nil {
- log.Print("ERROR: ", utils.MetaActions, " ", err)
- }
- if err := m.migrateSharedGroups(); err != nil {
- log.Print("ERROR: ", utils.MetaSharedGroups, " ", err)
- }
if err := m.migrateStats(); err != nil {
log.Print("ERROR: ", utils.MetaStats, " ", err)
}
@@ -232,12 +175,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
if err := m.migrateAttributeProfile(); err != nil {
log.Print("ERROR: ", utils.MetaAttributes, " ", err)
}
- if err := m.migrateRatingPlans(); err != nil {
- log.Print("ERROR: ", utils.MetaRatingPlans, " ", err)
- }
- if err := m.migrateRatingProfiles(); err != nil {
- log.Print("ERROR: ", utils.MetaRatingProfiles, " ", err)
- }
if err := m.migrateDestinations(); err != nil {
log.Print("ERROR: ", utils.MetaDestinations, " ", err)
}
@@ -253,18 +190,9 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
if err := m.migrateResources(); err != nil {
log.Print("ERROR: ", utils.MetaResources, " ", err)
}
- if err := m.migrateAlias(); err != nil {
- log.Print("ERROR: ", MetaAliases, " ", err)
- }
- if err := m.migrateUser(); err != nil {
- log.Print("ERROR: ", utils.MetaUsers, " ", err)
- }
if err := m.migrateSubscribers(); err != nil {
log.Print("ERROR: ", utils.MetaSubscribers, " ", err)
}
- if err := m.migrateDerivedChargers(); err != nil {
- log.Print("ERROR: ", utils.MetaDerivedChargersV, " ", err)
- }
if err := m.migrateDispatchers(); err != nil {
log.Print("ERROR: ", utils.MetaDispatchers, " ", err)
}
@@ -274,27 +202,9 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
err = nil
//STORDB ALL
case utils.MetaStorDB:
- if err := m.migrateTPratingplans(); err != nil {
- log.Print("ERROR: ", utils.MetaTpRatingPlans, " ", err)
- }
if err := m.migrateTPfilters(); err != nil {
log.Print("ERROR: ", utils.MetaTpFilters, " ", err)
}
- if err := m.migrateTPdestinationrates(); err != nil {
- log.Print("ERROR: ", utils.MetaTpDestinationRates, " ", err)
- }
- if err := m.migrateTPactiontriggers(); err != nil {
- log.Print("ERROR: ", utils.MetaTpActionTriggers, " ", err)
- }
- if err := m.migrateTPaccountacction(); err != nil {
- log.Print("ERROR: ", utils.MetaTpAccountActions, " ", err)
- }
- if err := m.migrateTPactionplans(); err != nil {
- log.Print("ERROR: ", utils.MetaTpActionPlans, " ", err)
- }
- if err := m.migrateTPactions(); err != nil {
- log.Print("ERROR: ", utils.MetaTpActions, " ", err)
- }
if err := m.migrateTPthresholds(); err != nil {
log.Print("ERROR: ", utils.MetaTpThresholds, " ", err)
}
@@ -304,18 +214,9 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
if err := m.migrateTPstats(); err != nil {
log.Print("ERROR: ", utils.MetaTpStats, " ", err)
}
- if err := m.migrateTPsharedgroups(); err != nil {
- log.Print("ERROR: ", utils.MetaTpSharedGroups, " ", err)
- }
- if err := m.migrateTPratingprofiles(); err != nil {
- log.Print("ERROR: ", utils.MetaTpRatingProfiles, " ", err)
- }
if err := m.migrateTPresources(); err != nil {
log.Print("ERROR: ", utils.MetaTpResources, " ", err)
}
- if err := m.migrateTPrates(); err != nil {
- log.Print("ERROR: ", utils.MetaTpRates, " ", err)
- }
if err := m.migrateTpTimings(); err != nil {
log.Print("ERROR: ", utils.MetaTpTimings, " ", err)
}
@@ -331,9 +232,6 @@ func (m *Migrator) Migrate(taskIDs []string) (err error, stats map[string]int) {
if err := m.migrateCDRs(); err != nil {
log.Print("ERROR: ", utils.MetaCDRs, " ", err)
}
- if err := m.migrateSessionSCosts(); err != nil {
- log.Print("ERROR: ", utils.MetaSessionsCosts, " ", err)
- }
err = nil
}
}
diff --git a/migrator/migrator_datadb.go b/migrator/migrator_datadb.go
index a3ea977fc..5fe885861 100644
--- a/migrator/migrator_datadb.go
+++ b/migrator/migrator_datadb.go
@@ -23,43 +23,15 @@ import (
)
type MigratorDataDB interface {
- getv1Account() (v1Acnt *v1Account, err error)
- setV1Account(x *v1Account) (err error)
- remV1Account(id string) (err error)
- getV1ActionPlans() (v1aps *v1ActionPlans, err error)
- setV1ActionPlans(x *v1ActionPlans) (err error)
- remV1ActionPlans(x *v1ActionPlans) (err error)
- getV1Actions() (v1acs *v1Actions, err error)
- setV1Actions(x *v1Actions) (err error)
- remV1Actions(x v1Actions) (err error)
- getV1ActionTriggers() (v1acts *v1ActionTriggers, err error)
- setV1ActionTriggers(x *v1ActionTriggers) (err error)
- remV1ActionTriggers(x *v1ActionTriggers) (err error)
- getV1SharedGroup() (v1acts *v1SharedGroup, err error)
- setV1SharedGroup(x *v1SharedGroup) (err error)
getV1Stats() (v1st *v1Stat, err error)
setV1Stats(x *v1Stat) (err error)
getV2Stats() (v2 *engine.StatQueue, err error)
setV2Stats(v2 *engine.StatQueue) (err error)
- getV2ActionTrigger() (v2at *v2ActionTrigger, err error)
- setV2ActionTrigger(x *v2ActionTrigger) (err error)
- getv2Account() (v2Acnt *v2Account, err error)
- setV2Account(x *v2Account) (err error)
- remV2Account(id string) (err error)
getV1AttributeProfile() (v1attrPrf *v1AttributeProfile, err error)
setV1AttributeProfile(x *v1AttributeProfile) (err error)
getV2ThresholdProfile() (v2T *v2Threshold, err error)
setV2ThresholdProfile(x *v2Threshold) (err error)
remV2ThresholdProfile(tenant, id string) (err error)
- getV1Alias() (v1a *v1Alias, err error)
- setV1Alias(al *v1Alias) (err error)
- remV1Alias(key string) (err error)
- getV1User() (v1u *v1UserProfile, err error)
- setV1User(us *v1UserProfile) (err error)
- remV1User(key string) (err error)
- getV1DerivedChargers() (v1d *v1DerivedChargersWithKey, err error)
- setV1DerivedChargers(dc *v1DerivedChargersWithKey) (err error)
- remV1DerivedChargers(key string) (err error)
getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error)
setV2AttributeProfile(x *v2AttributeProfile) (err error)
remV2AttributeProfile(tenant, id string) (err error)
diff --git a/migrator/migrator_stordb.go b/migrator/migrator_stordb.go
index a00544e78..9ca529359 100755
--- a/migrator/migrator_stordb.go
+++ b/migrator/migrator_stordb.go
@@ -28,9 +28,6 @@ type MigratorStorDB interface {
remV1CDRs(v1Cdr *v1Cdrs) (err error)
createV1SMCosts() (err error)
renameV1SMCosts() (err error)
- getV2SMCost() (v2Cost *v2SessionsCost, err error)
- setV2SMCost(v2Cost *v2SessionsCost) (err error)
- remV2SMCost(v2Cost *v2SessionsCost) (err error)
StorDB() engine.StorDB
close()
}
diff --git a/migrator/rating_plan.go b/migrator/rating_plan.go
deleted file mode 100644
index 812ffb53d..000000000
--- a/migrator/rating_plan.go
+++ /dev/null
@@ -1,97 +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) migrateCurrentRatingPlans() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.RatingPlanPrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.RatingPlanPrefix)
- rp, err := m.dmIN.DataManager().GetRatingPlan(idg, true, utils.NonTransactional)
- if err != nil {
- return err
- }
- if rp == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetRatingPlan(rp, utils.NonTransactional); err != nil {
- return err
- }
- if err := m.dmIN.DataManager().RemoveRatingPlan(idg, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.RatingPlan]++
- }
- return
-}
-
-func (m *Migrator) migrateRatingPlans() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.RatingPlan); err != nil {
- return
- }
-
- migrated := true
- for {
- version := vrs[utils.RatingPlan]
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.RatingPlan]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentRatingPlans(); err != nil {
- return
- }
- }
- if version == current[utils.RatingPlan] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
- // if !m.dryRun {
- // if err = m.dmIN.DataManager().SetRatingPlan(v2, true); err != nil {
- // return
- // }
- // }
- m.stats[utils.RatingPlan]++
- }
- // All done, update version wtih current one
- if err = m.setVersions(utils.RatingPlan); err != nil {
- return
- }
- return m.ensureIndexesDataDB(engine.ColRpl)
-}
diff --git a/migrator/rating_plan_it_test.go b/migrator/rating_plan_it_test.go
deleted file mode 100644
index 8f776bbad..000000000
--- a/migrator/rating_plan_it_test.go
+++ /dev/null
@@ -1,228 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- rtplPathIn string
- rtplPathOut string
- rtplCfgIn *config.CGRConfig
- rtplCfgOut *config.CGRConfig
- rtplMigrator *Migrator
- rtplAction string
-)
-
-var sTestsRtPlIT = []func(t *testing.T){
- testRtPlITConnect,
- testRtPlITFlush,
- testRtPlITMigrateAndMove,
-}
-
-func TestRatingPlanITMove1(t *testing.T) {
- var err error
- rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtplAction = utils.Move
- for _, stest := range sTestsRtPlIT {
- t.Run("TestRatingPlanITMove", stest)
- }
- rtplMigrator.Close()
-}
-
-func TestRatingPlanITMove2(t *testing.T) {
- var err error
- rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtplAction = utils.Move
- for _, stest := range sTestsRtPlIT {
- t.Run("TestRatingPlanITMove", stest)
- }
- rtplMigrator.Close()
-}
-
-func TestRatingPlanITMoveEncoding(t *testing.T) {
- var err error
- rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtplAction = utils.Move
- for _, stest := range sTestsRtPlIT {
- t.Run("TestRatingPlanITMoveEncoding", stest)
- }
- rtplMigrator.Close()
-}
-
-func TestRatingPlanITMoveEncoding2(t *testing.T) {
- var err error
- rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtplAction = utils.Move
- for _, stest := range sTestsRtPlIT {
- t.Run("TestRatingPlanITMoveEncoding2", stest)
- }
- rtplMigrator.Close()
-}
-
-func testRtPlITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(rtplCfgIn.DataDbCfg().Type,
- rtplCfgIn.DataDbCfg().Host, rtplCfgIn.DataDbCfg().Port,
- rtplCfgIn.DataDbCfg().Name, rtplCfgIn.DataDbCfg().User,
- rtplCfgIn.DataDbCfg().Password, rtplCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), ratePrfCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(rtplCfgOut.DataDbCfg().Type,
- rtplCfgOut.DataDbCfg().Host, rtplCfgOut.DataDbCfg().Port,
- rtplCfgOut.DataDbCfg().Name, rtplCfgOut.DataDbCfg().User,
- rtplCfgOut.DataDbCfg().Password, rtplCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), ratePrfCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if rtplPathIn == rtplPathOut {
- rtplMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- rtplMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testRtPlITFlush(t *testing.T) {
- if err := rtplMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
- t.Error(err)
- }
- if isEmpty, err := rtplMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
- t.Error(err)
- } else if isEmpty != true {
- t.Errorf("Expecting: true got :%+v", isEmpty)
- }
- if err := engine.SetDBVersions(rtplMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- if err := rtplMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
- t.Error(err)
- }
- if isEmpty, err := rtplMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
- t.Error(err)
- } else if isEmpty != true {
- t.Errorf("Expecting: true got :%+v", isEmpty)
- }
- if err := engine.SetDBVersions(rtplMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testRtPlITMigrateAndMove(t *testing.T) {
- rtplPlan := &engine.RatingPlan{
- Id: "RT_PLAN1",
- Timings: map[string]*engine.RITiming{},
- Ratings: map[string]*engine.RIRate{
- "asjkilj": &engine.RIRate{
- ConnectFee: 10,
- RoundingMethod: utils.MetaRoundingUp,
- RoundingDecimals: 1,
- MaxCost: 10,
- },
- },
- DestinationRates: map[string]engine.RPRateList{},
- }
- switch rtplAction {
- case utils.Migrate: // for the momment only one version of rating plans exists
- case utils.Move:
- if err := rtplMigrator.dmIN.DataManager().SetRatingPlan(rtplPlan, utils.NonTransactional); err != nil {
- t.Error(err)
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := rtplMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for RatingPlan ", err.Error())
- }
-
- _, err = rtplMigrator.dmOut.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-
- err, _ = rtplMigrator.Migrate([]string{utils.MetaRatingPlans})
- if err != nil {
- t.Error("Error when migrating RatingPlan ", err.Error())
- }
- result, err := rtplMigrator.dmOut.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
- if err != nil {
- t.Fatal(err)
- }
- if !reflect.DeepEqual(result, rtplPlan) {
- t.Errorf("Expecting: %+v, received: %+v", rtplPlan, result)
- }
- result, err = rtplMigrator.dmIN.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
- if err != utils.ErrNotFound {
- t.Error(err)
- } else if rtplMigrator.stats[utils.RatingPlan] != 1 {
- t.Errorf("Expected 1, received: %v", rtplMigrator.stats[utils.RatingPlan])
- }
- }
-}
diff --git a/migrator/rating_profile.go b/migrator/rating_profile.go
deleted file mode 100644
index 961e60d39..000000000
--- a/migrator/rating_profile.go
+++ /dev/null
@@ -1,97 +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) migrateCurrentRatingProfiles() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.RatingProfilePrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.RatingProfilePrefix)
- rp, err := m.dmIN.DataManager().GetRatingProfile(idg, true, utils.NonTransactional)
- if err != nil {
- return err
- }
- if rp == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetRatingProfile(rp, utils.NonTransactional); err != nil {
- return err
- }
- if err := m.dmIN.DataManager().RemoveRatingProfile(idg, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.RatingProfile]++
- }
- return
-}
-
-func (m *Migrator) migrateRatingProfiles() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.RatingProfile); err != nil {
- return
- }
-
- migrated := true
- for {
- version := vrs[utils.RatingProfile]
- for {
- switch version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.RatingProfile]:
- migrated = false
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentRatingProfiles(); err != nil {
- return err
- }
- }
- if version == current[utils.RatingProfile] || err == utils.ErrNoMoreData {
- break
- }
- }
- if err == utils.ErrNoMoreData || !migrated {
- break
- }
- // if !m.dryRun {
- // if err = m.dmIN.DataManager().SetRatingProfile(v2, true); err != nil {
- // return
- // }
- // }
- m.stats[utils.RatingProfile]++
- }
- // All done, update version wtih current one
- if err = m.setVersions(utils.RatingProfile); err != nil {
- return
- }
- return m.ensureIndexesDataDB(engine.ColRpf)
-}
diff --git a/migrator/rating_profile_it_test.go b/migrator/rating_profile_it_test.go
deleted file mode 100644
index f40ccaa8d..000000000
--- a/migrator/rating_profile_it_test.go
+++ /dev/null
@@ -1,226 +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"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- rtprflPathIn string
- rtprflPathOut string
- rtprflCfgIn *config.CGRConfig
- rtprflCfgOut *config.CGRConfig
- rtprflMigrator *Migrator
- rtprflAction string
-)
-
-var sTestsRtPrfIT = []func(t *testing.T){
- testRtPrfITConnect,
- testRtPrfITFlush,
- testRtPrfITMigrateAndMove,
-}
-
-func TestRatingProfileITMove1(t *testing.T) {
- var err error
- rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtprflAction = utils.Move
- for _, stest := range sTestsRtPrfIT {
- t.Run("TestRatingProfileITMove", stest)
- }
- rtprflMigrator.Close()
-}
-
-func TestRatingProfileITMove2(t *testing.T) {
- var err error
- rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtprflAction = utils.Move
- for _, stest := range sTestsRtPrfIT {
- t.Run("TestRatingProfileITMove", stest)
- }
- rtprflMigrator.Close()
-}
-
-func TestRatingProfileITMoveEncoding(t *testing.T) {
- var err error
- rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtprflAction = utils.Move
- for _, stest := range sTestsRtPrfIT {
- t.Run("TestRatingProfileITMoveEncoding", stest)
- }
- rtprflMigrator.Close()
-}
-
-func TestRatingProfileITMoveEncoding2(t *testing.T) {
- var err error
- rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
- if err != nil {
- t.Fatal(err)
- }
- rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
- if err != nil {
- t.Fatal(err)
- }
- rtprflAction = utils.Move
- for _, stest := range sTestsRtPrfIT {
- t.Run("TestRatingProfileITMoveEncoding2", stest)
- }
- rtprflMigrator.Close()
-}
-
-func testRtPrfITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(rtprflCfgIn.DataDbCfg().Type,
- rtprflCfgIn.DataDbCfg().Host, rtprflCfgIn.DataDbCfg().Port,
- rtprflCfgIn.DataDbCfg().Name, rtprflCfgIn.DataDbCfg().User,
- rtprflCfgIn.DataDbCfg().Password, rtprflCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), rtprflCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(rtprflCfgOut.DataDbCfg().Type,
- rtprflCfgOut.DataDbCfg().Host, rtprflCfgOut.DataDbCfg().Port,
- rtprflCfgOut.DataDbCfg().Name, rtprflCfgOut.DataDbCfg().User,
- rtprflCfgOut.DataDbCfg().Password, rtprflCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), rtplCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(rtprflPathIn, rtprflPathOut) {
- rtprflMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- rtprflMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testRtPrfITFlush(t *testing.T) {
- if err := rtprflMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
- t.Error(err)
- }
- if isEmpty, err := rtprflMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
- t.Error(err)
- } else if isEmpty != true {
- t.Errorf("Expecting: true got :%+v", isEmpty)
- }
- if err := engine.SetDBVersions(rtprflMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- if err := rtprflMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
- t.Error(err)
- }
- if isEmpty, err := rtprflMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
- t.Error(err)
- } else if isEmpty != true {
- t.Errorf("Expecting: true got :%+v", isEmpty)
- }
- if err := engine.SetDBVersions(rtprflMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testRtPrfITMigrateAndMove(t *testing.T) {
- rtprfl := &engine.RatingProfile{
- Id: "RT_Profile",
- RatingPlanActivations: engine.RatingPlanActivations{
- &engine.RatingPlanActivation{
- ActivationTime: time.Now().Round(time.Second).UTC(),
- RatingPlanId: "RP_PLAN1",
- FallbackKeys: []string{"1001"},
- },
- },
- }
- switch rtprflAction {
- case utils.Migrate: // for the momment only one version of rating plans exists
- case utils.Move:
- if err := rtprflMigrator.dmIN.DataManager().SetRatingProfile(rtprfl, utils.NonTransactional); err != nil {
- t.Error(err)
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := rtprflMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for RatingProfile ", err.Error())
- }
-
- _, err = rtprflMigrator.dmOut.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-
- err, _ = rtprflMigrator.Migrate([]string{utils.MetaRatingProfiles})
- if err != nil {
- t.Error("Error when migrating RatingProfile ", err.Error())
- }
- result, err := rtprflMigrator.dmOut.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
- if err != nil {
- t.Fatal(err)
- }
- if !reflect.DeepEqual(result, rtprfl) {
- t.Errorf("Expecting: %+v, received: %+v", rtprfl, result)
- }
- result, err = rtprflMigrator.dmIN.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
- if err != utils.ErrNotFound {
- t.Error(err)
- } else if rtprflMigrator.stats[utils.RatingProfile] != 1 {
- t.Errorf("Expected 1, received: %v", rtprflMigrator.stats[utils.RatingProfile])
- }
- }
-}
diff --git a/migrator/session_costs.go b/migrator/session_costs.go
deleted file mode 100644
index 93407694a..000000000
--- a/migrator/session_costs.go
+++ /dev/null
@@ -1,181 +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 (
- "encoding/json"
- "fmt"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func (m *Migrator) migrateCurrentSessionSCost() (err error) {
- if m.sameStorDB { // no move
- return
- }
- smCosts, err := m.storDBIn.StorDB().GetSMCosts("", "", "", "")
- if err != nil {
- return err
- }
- for _, smCost := range smCosts {
- if err := m.storDBOut.StorDB().SetSMCost(smCost); err != nil {
- return err
- }
- if err := m.storDBIn.StorDB().RemoveSMCost(smCost); err != nil {
- return err
- }
- }
- return
-}
-
-func (m *Migrator) migrateSessionSCosts() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- vrs, err = m.storDBIn.StorDB().GetVersions("")
- if err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when querying OutStorDB for versions", err.Error()))
- } else if len(vrs) == 0 {
- return utils.NewCGRError(utils.Migrator,
- utils.MandatoryIEMissingCaps,
- utils.UndefinedVersion,
- "version number is not defined for SessionsCosts model")
- }
- switch version := vrs[utils.SessionSCosts]; version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case 0, 1:
- if err = m.migrateV1SessionSCosts(); err != nil {
- return err
- }
- case 2:
- if err = m.migrateV2SessionSCosts(); err != nil {
- return err
- }
- case current[utils.SessionSCosts]:
- if err = m.migrateCurrentSessionSCost(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.SessionCostsTBL)
-}
-
-func (m *Migrator) migrateV1SessionSCosts() (err error) {
- if err = m.storDBIn.renameV1SMCosts(); err != nil {
- return err
- }
- if m.dryRun {
- return
- }
- vrs := engine.Versions{utils.SessionSCosts: 2}
- if err = m.storDBOut.StorDB().SetVersions(vrs, false); err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when updating SessionSCosts version into StorDB", err.Error()))
- }
- return
-}
-
-func (m *Migrator) migrateV2SessionSCosts() (err error) {
- var v2Cost *v2SessionsCost
- for {
- v2Cost, err = m.storDBIn.getV2SMCost()
- if err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if err == utils.ErrNoMoreData {
- break
- }
- if v2Cost == nil || m.dryRun {
- continue
- }
- smCost := v2Cost.V2toV3Cost()
- if err = m.storDBOut.StorDB().SetSMCost(smCost); err != nil {
- return err
- }
- if err = m.storDBIn.remV2SMCost(v2Cost); err != nil {
- return err
- }
- m.stats[utils.SessionSCosts]++
- }
- if m.dryRun {
- return
- }
- // All done, update version wtih current one
- if err = m.setVersions(utils.SessionSCosts); err != nil {
- return err
- }
- return
-}
-
-type v2SessionsCost struct {
- CGRID string
- RunID string
- OriginHost string
- OriginID string
- CostSource string
- Usage time.Duration
- CostDetails *engine.CallCost
-}
-
-func (v2Cost *v2SessionsCost) V2toV3Cost() (cost *engine.SMCost) {
- cost = &engine.SMCost{
- CGRID: v2Cost.CGRID,
- RunID: v2Cost.RunID,
- OriginHost: v2Cost.OriginHost,
- OriginID: v2Cost.OriginID,
- Usage: v2Cost.Usage,
- CostSource: v2Cost.CostSource,
- CostDetails: engine.NewEventCostFromCallCost(v2Cost.CostDetails, v2Cost.CGRID, v2Cost.RunID),
- }
- return
-}
-
-func NewV2SessionsCostFromSessionsCostSql(smSql *engine.SessionCostsSQL) (smV2 *v2SessionsCost, err error) {
- smV2 = new(v2SessionsCost)
- smV2.CGRID = smSql.Cgrid
- smV2.RunID = smSql.RunID
- smV2.OriginHost = smSql.OriginHost
- smV2.OriginID = smSql.OriginID
- smV2.CostSource = smSql.CostSource
- smV2.Usage = time.Duration(smSql.Usage)
- smV2.CostDetails = new(engine.CallCost)
- if err := json.Unmarshal([]byte(smSql.CostDetails), smV2.CostDetails); err != nil {
- return nil, err
- }
- return
-}
-
-func (v2Cost *v2SessionsCost) AsSessionsCostSql() (smSql *engine.SessionCostsSQL) {
- smSql = new(engine.SessionCostsSQL)
- smSql.Cgrid = v2Cost.CGRID
- smSql.RunID = v2Cost.RunID
- smSql.OriginHost = v2Cost.OriginHost
- smSql.OriginID = v2Cost.OriginID
- smSql.CostSource = v2Cost.CostSource
- smSql.CostDetails = utils.ToJSON(v2Cost.CostDetails)
- smSql.Usage = v2Cost.Usage.Nanoseconds()
- smSql.CreatedAt = time.Now()
- return
-}
diff --git a/migrator/session_costs_it_test.go b/migrator/session_costs_it_test.go
deleted file mode 100755
index 5541f6db7..000000000
--- a/migrator/session_costs_it_test.go
+++ /dev/null
@@ -1,218 +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"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- sCostPathIn string
- sCostPathOut string
- sCostCfgIn *config.CGRConfig
- sCostCfgOut *config.CGRConfig
- sCostMigrator *Migrator
- sCostAction string
-)
-
-var sTestssCostIT = []func(t *testing.T){
- testSessionCostITConnect,
- testSessionCostITRename,
- testSessionCostITFlush,
- testSessionCostITMigrate,
-}
-
-func TestSessionCostITMongo(t *testing.T) {
- var err error
- sCostPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- sCostCfgIn, err = config.NewCGRConfigFromPath(sCostPathIn)
- if err != nil {
- t.Error(err)
- }
- sCostPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- sCostCfgOut, err = config.NewCGRConfigFromPath(sCostPathOut)
- if err != nil {
- t.Error(err)
- }
- for _, stest := range sTestssCostIT {
- t.Run("TestSessionSCostITMigrateMongo", stest)
- }
- sCostMigrator.Close()
-}
-
-func TestSessionCostITMySql(t *testing.T) {
- var err error
- sCostPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- sCostCfgIn, err = config.NewCGRConfigFromPath(sCostPathIn)
- if err != nil {
- t.Error(err)
- }
- sCostPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- sCostCfgOut, err = config.NewCGRConfigFromPath(sCostPathOut)
- if err != nil {
- t.Error(err)
- }
- for _, stest := range sTestssCostIT {
- t.Run("TestSessionSCostITMigrateMySql", stest)
- }
- sCostMigrator.Close()
-}
-
-func testSessionCostITConnect(t *testing.T) {
- storDBIn, err := NewMigratorStorDB(sCostCfgIn.StorDbCfg().Type,
- sCostCfgIn.StorDbCfg().Host, sCostCfgIn.StorDbCfg().Port,
- sCostCfgIn.StorDbCfg().Name, sCostCfgIn.StorDbCfg().User,
- sCostCfgIn.StorDbCfg().Password, sCostCfgIn.GeneralCfg().DBDataEncoding,
- sCostCfgIn.StorDbCfg().StringIndexedFields, sCostCfgIn.StorDbCfg().PrefixIndexedFields,
- sCostCfgIn.StorDbCfg().Opts)
- if err != nil {
- t.Error(err)
- }
- storDBOut, err := NewMigratorStorDB(sCostCfgOut.StorDbCfg().Type,
- sCostCfgOut.StorDbCfg().Host, sCostCfgOut.StorDbCfg().Port,
- sCostCfgOut.StorDbCfg().Name, sCostCfgOut.StorDbCfg().User,
- sCostCfgOut.StorDbCfg().Password, sCostCfgOut.GeneralCfg().DBDataEncoding,
- sCostCfgIn.StorDbCfg().StringIndexedFields, sCostCfgIn.StorDbCfg().PrefixIndexedFields,
- sCostCfgOut.StorDbCfg().Opts)
- if err != nil {
- t.Error(err)
- }
- if actTrgPathIn == actTrgPathOut {
- sCostMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut,
- false, false, true, false)
- } else {
- sCostMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut,
- false, false, false, false)
- }
- if err != nil {
- t.Error(err)
- }
-}
-
-func testSessionCostITRename(t *testing.T) {
- var err error
- if err = sCostMigrator.storDBIn.createV1SMCosts(); err != nil {
- t.Error(err)
- }
- currentVersion := engine.Versions{
- utils.SessionSCosts: 1,
- }
- err = sCostMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for SessionsCosts ", err.Error())
- }
- if vrs, err := sCostMigrator.storDBIn.StorDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.SessionSCosts] != 1 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.SessionSCosts])
- }
- err, _ = sCostMigrator.Migrate([]string{utils.MetaSessionsCosts})
- if err != nil {
- t.Error("Error when migrating SessionsCosts ", err.Error())
- }
- if vrs, err := sCostMigrator.storDBOut.StorDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.SessionSCosts] != 2 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.SessionSCosts])
- } else if sCostMigrator.stats[utils.SessionSCosts] != 0 {
- t.Errorf("Expected 0, received: %v", sCostMigrator.stats[utils.SessionSCosts])
- }
-
-}
-
-func testSessionCostITFlush(t *testing.T) {
- if err := sCostMigrator.storDBOut.StorDB().Flush(
- path.Join(sCostCfgIn.DataFolderPath, "storage", sCostCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testSessionCostITMigrate(t *testing.T) {
- cc := &engine.CallCost{
- Cost: 1.23,
- Destination: "0723045326",
- Timespans: []*engine.TimeSpan{
- {
- TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC),
- TimeEnd: time.Date(2013, 9, 24, 10, 48, 10, 0, time.UTC),
- DurationIndex: 0,
- RateInterval: &engine.RateInterval{
- Rating: &engine.RIRate{
- Rates: engine.RateGroups{
- &engine.RGRate{
- GroupIntervalStart: 0,
- Value: 100,
- RateIncrement: 10 * time.Second,
- RateUnit: time.Second,
- },
- },
- },
- },
- },
- },
- ToR: utils.MetaVoice,
- }
- v2Cost := &v2SessionsCost{
- CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()),
- OriginID: "dsafdsaf",
- OriginHost: "192.168.1.1",
- RunID: utils.MetaDefault,
- Usage: 10,
- CostSource: utils.MetaSessionS,
- CostDetails: cc,
- }
- var err error
- if err = sCostMigrator.storDBIn.setV2SMCost(v2Cost); err != nil {
- t.Error(err)
- }
- currentVersion := engine.Versions{
- utils.SessionSCosts: 2,
- }
- err = sCostMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for SessionsCosts ", err.Error())
- }
- if vrs, err := sCostMigrator.storDBIn.StorDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.SessionSCosts] != 2 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.SessionSCosts])
- }
- err, _ = sCostMigrator.Migrate([]string{utils.MetaSessionsCosts})
- if err != nil {
- t.Error("Error when migrating SessionsCosts ", err.Error())
- }
- if rcvCosts, err := sCostMigrator.storDBOut.StorDB().GetSMCosts("", utils.MetaDefault, "", ""); err != nil {
- t.Error(err)
- } else if len(rcvCosts) != 1 {
- t.Errorf("Unexpected number of SessionsCosts returned: %d", len(rcvCosts))
- }
- if vrs, err := sCostMigrator.storDBOut.StorDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.SessionSCosts] != 3 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.SessionSCosts])
- }
-}
diff --git a/migrator/session_costs_test.go b/migrator/session_costs_test.go
deleted file mode 100644
index 3be06bf44..000000000
--- a/migrator/session_costs_test.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 (
- "reflect"
- "testing"
- "time"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestV2toV3Cost(t *testing.T) {
- cc := &engine.CallCost{
- Category: utils.Call,
- Tenant: "cgrates.org",
- Subject: "1001",
- Account: "1001",
- Destination: "1002",
- ToR: "ToR",
- Cost: 10,
- Timespans: engine.TimeSpans{
- &engine.TimeSpan{
- TimeStart: time.Now(),
- TimeEnd: time.Now().Add(time.Minute),
- Cost: 10,
- RateInterval: &engine.RateInterval{
- Rating: &engine.RIRate{
- Rates: engine.RateGroups{
- &engine.RGRate{
- GroupIntervalStart: 0,
- Value: 100,
- RateIncrement: 10 * time.Second,
- RateUnit: time.Second,
- },
- },
- },
- },
- },
- },
- RatedUsage: 10,
- AccountSummary: &engine.AccountSummary{
- Tenant: "cgrates.org",
- ID: "1001",
- BalanceSummaries: []*engine.BalanceSummary{
- &engine.BalanceSummary{
- UUID: "UUID",
- ID: "First",
- Type: utils.MetaMonetary,
- Value: 10,
- },
- },
- },
- }
- sv2 := v2SessionsCost{
- CGRID: "CGRID",
- RunID: utils.MetaDefault,
- OriginHost: utils.FreeSWITCHAgent,
- OriginID: "Origin1",
- CostSource: utils.MetaSessionS,
- Usage: time.Second,
- CostDetails: cc,
- }
- sv3 := &engine.SMCost{
- CGRID: "CGRID",
- RunID: utils.MetaDefault,
- OriginHost: utils.FreeSWITCHAgent,
- OriginID: "Origin1",
- Usage: time.Second,
- CostSource: utils.MetaSessionS,
- CostDetails: engine.NewEventCostFromCallCost(cc, "CGRID", utils.MetaDefault),
- }
- rply := sv2.V2toV3Cost()
- rply.CostDetails = sv3.CostDetails
- if !reflect.DeepEqual(sv3, rply) {
- t.Errorf("Expected: %s ,received: %s", utils.ToJSON(sv3), utils.ToJSON(rply))
- }
-}
diff --git a/migrator/sharedgroup.go b/migrator/sharedgroup.go
deleted file mode 100644
index 5a106237e..000000000
--- a/migrator/sharedgroup.go
+++ /dev/null
@@ -1,118 +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"
-)
-
-type v1SharedGroup struct {
- Id string
- AccountParameters map[string]*engine.SharingParameters
- MemberIds []string
-}
-
-func (m *Migrator) migrateCurrentSharedGroups() (err error) {
- var ids []string
- ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.SharedGroupPrefix)
- if err != nil {
- return err
- }
- for _, id := range ids {
- idg := strings.TrimPrefix(id, utils.SharedGroupPrefix)
- sgs, err := m.dmIN.DataManager().GetSharedGroup(idg, true, utils.NonTransactional)
- if err != nil {
- return err
- }
- if sgs == nil || m.dryRun {
- continue
- }
- if err := m.dmOut.DataManager().SetSharedGroup(sgs, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.SharedGroups]++
- }
- return
-}
-
-func (m *Migrator) migrateV1SharedGroups() (err error) {
- var v1SG *v1SharedGroup
- for {
- v1SG, err = m.dmIN.getV1SharedGroup()
- if err != nil && err != utils.ErrNoMoreData {
- return err
- }
- if err == utils.ErrNoMoreData {
- break
- }
- if v1SG == nil || m.dryRun {
- continue
- }
- acnt := v1SG.AsSharedGroup()
- if err = m.dmOut.DataManager().SetSharedGroup(acnt, utils.NonTransactional); err != nil {
- return err
- }
- m.stats[utils.SharedGroups]++
- }
- // All done, update version wtih current one
- if err = m.setVersions(utils.SharedGroups); err != nil {
- return err
- }
- return
-}
-
-func (m *Migrator) migrateSharedGroups() (err error) {
- var vrs engine.Versions
- current := engine.CurrentDataDBVersions()
- if vrs, err = m.getVersions(utils.SharedGroups); err != nil {
- return
- }
- switch version := vrs[utils.SharedGroups]; version {
- default:
- return fmt.Errorf("Unsupported version %v", version)
- case current[utils.SharedGroups]:
- if m.sameDataDB {
- break
- }
- if err = m.migrateCurrentSharedGroups(); err != nil {
- return err
- }
- case 1:
- if err = m.migrateV1SharedGroups(); err != nil {
- return err
- }
- }
- return m.ensureIndexesDataDB(engine.ColShg)
-}
-
-func (v1SG v1SharedGroup) AsSharedGroup() (sg *engine.SharedGroup) {
- sg = &engine.SharedGroup{
- Id: v1SG.Id,
- AccountParameters: v1SG.AccountParameters,
- MemberIds: make(utils.StringMap),
- }
- for _, accID := range v1SG.MemberIds {
- sg.MemberIds[accID] = true
- }
- return
-}
diff --git a/migrator/sharedgroup_it_test.go b/migrator/sharedgroup_it_test.go
deleted file mode 100644
index 5ba897f16..000000000
--- a/migrator/sharedgroup_it_test.go
+++ /dev/null
@@ -1,251 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- shrGrpPathIn string
- shrGrpPathOut string
- shrGrpCfgIn *config.CGRConfig
- shrGrpCfgOut *config.CGRConfig
- shrGrpMigrator *Migrator
- shrSharedGroup string
-)
-
-var sTestsShrGrpIT = []func(t *testing.T){
- testShrGrpITConnect,
- testShrGrpITFlush,
- testShrGrpITMigrateAndMove,
-}
-
-func TestSharedGroupITRedis(t *testing.T) {
- var err error
- shrGrpPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- shrGrpCfgIn, err = config.NewCGRConfigFromPath(shrGrpPathIn)
- if err != nil {
- t.Fatal(err)
- }
- shrGrpPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- shrGrpCfgOut, err = config.NewCGRConfigFromPath(shrGrpPathOut)
- if err != nil {
- t.Fatal(err)
- }
- shrSharedGroup = utils.Migrate
- for _, stest := range sTestsShrGrpIT {
- t.Run("TestSharedGroupITMigrateRedis", stest)
- }
- shrGrpMigrator.Close()
-}
-
-func TestSharedGroupITMongo(t *testing.T) {
- var err error
- shrGrpPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- shrGrpCfgIn, err = config.NewCGRConfigFromPath(shrGrpPathIn)
- if err != nil {
- t.Fatal(err)
- }
- shrGrpPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
- shrGrpCfgOut, err = config.NewCGRConfigFromPath(shrGrpPathOut)
- if err != nil {
- t.Fatal(err)
- }
- shrSharedGroup = utils.Migrate
- for _, stest := range sTestsShrGrpIT {
- t.Run("TestSharedGroupITMigrateMongo", stest)
- }
- shrGrpMigrator.Close()
-}
-
-func TestSharedGroupITMove(t *testing.T) {
- var err error
- shrGrpPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- shrGrpCfgIn, err = config.NewCGRConfigFromPath(shrGrpPathIn)
- if err != nil {
- t.Fatal(err)
- }
- shrGrpPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- shrGrpCfgOut, err = config.NewCGRConfigFromPath(shrGrpPathOut)
- if err != nil {
- t.Fatal(err)
- }
- shrSharedGroup = utils.Move
- for _, stest := range sTestsShrGrpIT {
- t.Run("TestSharedGroupITMove", stest)
- }
- shrGrpMigrator.Close()
-}
-
-func TestSharedGroupITMoveEncoding(t *testing.T) {
- var err error
- shrGrpPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- shrGrpCfgIn, err = config.NewCGRConfigFromPath(shrGrpPathIn)
- if err != nil {
- t.Fatal(err)
- }
- shrGrpPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
- shrGrpCfgOut, err = config.NewCGRConfigFromPath(shrGrpPathOut)
- if err != nil {
- t.Fatal(err)
- }
- shrSharedGroup = utils.Move
- for _, stest := range sTestsShrGrpIT {
- t.Run("TestSharedGroupITMoveEncoding", stest)
- }
- shrGrpMigrator.Close()
-}
-
-func TestSharedGroupITMoveEncoding2(t *testing.T) {
- var err error
- shrGrpPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
- shrGrpCfgIn, err = config.NewCGRConfigFromPath(shrGrpPathIn)
- if err != nil {
- t.Fatal(err)
- }
- shrGrpPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
- shrGrpCfgOut, err = config.NewCGRConfigFromPath(shrGrpPathOut)
- if err != nil {
- t.Fatal(err)
- }
- shrSharedGroup = utils.Move
- for _, stest := range sTestsShrGrpIT {
- t.Run("TestSharedGroupITMoveEncoding2", stest)
- }
- shrGrpMigrator.Close()
-}
-
-func testShrGrpITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(shrGrpCfgIn.DataDbCfg().Type,
- shrGrpCfgIn.DataDbCfg().Host, shrGrpCfgIn.DataDbCfg().Port,
- shrGrpCfgIn.DataDbCfg().Name, shrGrpCfgIn.DataDbCfg().User,
- shrGrpCfgIn.DataDbCfg().Password, shrGrpCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), shrGrpCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(shrGrpCfgOut.DataDbCfg().Type,
- shrGrpCfgOut.DataDbCfg().Host, shrGrpCfgOut.DataDbCfg().Port,
- shrGrpCfgOut.DataDbCfg().Name, shrGrpCfgOut.DataDbCfg().User,
- shrGrpCfgOut.DataDbCfg().Password, shrGrpCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), shrGrpCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- if reflect.DeepEqual(shrGrpPathIn, shrGrpPathOut) {
- shrGrpMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, true, false, false)
- } else {
- shrGrpMigrator, err = NewMigrator(dataDBIn, dataDBOut, nil, nil,
- false, false, false, false)
- }
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testShrGrpITFlush(t *testing.T) {
- shrGrpMigrator.dmOut.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(shrGrpMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testShrGrpITMigrateAndMove(t *testing.T) {
- v1shrGrp := &v1SharedGroup{
- Id: "Test",
- AccountParameters: map[string]*engine.SharingParameters{
- "test": {Strategy: "*highest"},
- },
- MemberIds: []string{"1", "2", "3"},
- }
- shrGrp := &engine.SharedGroup{
- Id: "Test",
- AccountParameters: map[string]*engine.SharingParameters{
- "test": {Strategy: "*highest"},
- },
- MemberIds: utils.NewStringMap("1", "2", "3"),
- }
-
- switch shrSharedGroup {
- case utils.Migrate:
- err := shrGrpMigrator.dmIN.setV1SharedGroup(v1shrGrp)
- if err != nil {
- t.Error("Error when setting v1 SharedGroup ", err.Error())
- }
- currentVersion := engine.Versions{
- utils.StatS: 2,
- utils.Thresholds: 2,
- utils.Accounts: 2,
- utils.Actions: 2,
- utils.ActionTriggers: 2,
- utils.ActionPlans: 2,
- utils.SharedGroups: 1,
- }
- err = shrGrpMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for SharedGroup ", err.Error())
- }
- err, _ = shrGrpMigrator.Migrate([]string{utils.MetaSharedGroups})
- if err != nil {
- t.Error("Error when migrating SharedGroup ", err.Error())
- }
- result, err := shrGrpMigrator.dmOut.DataManager().GetSharedGroup(v1shrGrp.Id, true, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting SharedGroup ", err.Error())
- }
- if !reflect.DeepEqual(shrGrp, result) {
- t.Errorf("Expecting: %+v, received: %+v", shrGrp, result)
- } else if shrGrpMigrator.stats[utils.SharedGroups] != 1 {
- t.Errorf("Expected 1, received: %v", shrGrpMigrator.stats[utils.SharedGroups])
- }
- case utils.Move:
- if err := shrGrpMigrator.dmIN.DataManager().SetSharedGroup(shrGrp, utils.NonTransactional); err != nil {
- t.Error("Error when setting SharedGroup ", err.Error())
- }
- currentVersion := engine.CurrentDataDBVersions()
- err := shrGrpMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for SharedGroup ", err.Error())
- }
- err, _ = shrGrpMigrator.Migrate([]string{utils.MetaSharedGroups})
- if err != nil {
- t.Error("Error when migrating SharedGroup ", err.Error())
- }
- result, err := shrGrpMigrator.dmOut.DataManager().GetSharedGroup(v1shrGrp.Id, true, utils.NonTransactional)
- if err != nil {
- t.Error("Error when getting SharedGroup ", err.Error())
- }
- if !reflect.DeepEqual(shrGrp, result) {
- t.Errorf("Expecting: %+v, received: %+v", shrGrp, result)
- } else if shrGrpMigrator.stats[utils.SharedGroups] != 1 {
- t.Errorf("Expected 1, received: %v", shrGrpMigrator.stats[utils.SharedGroups])
- }
- }
-}
diff --git a/migrator/sharedgroup_test.go b/migrator/sharedgroup_test.go
deleted file mode 100644
index a13afaa7f..000000000
--- a/migrator/sharedgroup_test.go
+++ /dev/null
@@ -1,48 +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 (
- "reflect"
- "testing"
-
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestV1SharedGroupAsSharedGroup(t *testing.T) {
- v1sg := &v1SharedGroup{
- Id: "Test",
- AccountParameters: map[string]*engine.SharingParameters{
- "test": &engine.SharingParameters{Strategy: "*highest"},
- },
- MemberIds: []string{"1", "2", "3"},
- }
- sg := &engine.SharedGroup{
- Id: "Test",
- AccountParameters: map[string]*engine.SharingParameters{
- "test": &engine.SharingParameters{Strategy: "*highest"},
- },
- MemberIds: utils.NewStringMap("1", "2", "3"),
- }
- newsg := v1sg.AsSharedGroup()
- if !reflect.DeepEqual(sg, newsg) {
- t.Errorf("Expecting: %+v, received: %+v", sg, newsg)
- }
-
-}
diff --git a/migrator/stats.go b/migrator/stats.go
index bb476213c..532abcc40 100644
--- a/migrator/stats.go
+++ b/migrator/stats.go
@@ -55,7 +55,6 @@ type v1Stat struct {
RatedAccount []string // CDRFieldFilter on RatedAccounts
RatedSubject []string // CDRFieldFilter on RatedSubjects
CostInterval []float64 // CDRFieldFilter on CostInterval, 2 or less items, (>=Cost,
package migrator
import (
- "strings"
-
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
@@ -51,286 +49,6 @@ func (v1rs *redisMigrator) DataManager() *engine.DataManager {
return v1rs.dm
}
-//Account methods
-//V1
-//get
-func (v1rs *redisMigrator) getv1Account() (v1Acnt *v1Account, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(v1AccountDBPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err := v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- v1Acnt = &v1Account{Id: v1rs.dataKeys[*v1rs.qryIdx]}
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, v1Acnt); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1Acnt, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1Account(x *v1Account) (err error) {
- key := v1AccountDBPrefix + x.Id
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV1Account(id string) (err error) {
- key := v1AccountDBPrefix + id
- return v1rs.rds.Cmd(nil, "DEL", key)
-}
-
-//V2
-//get
-func (v1rs *redisMigrator) getv2Account() (v2Acnt *v2Account, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.AccountPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err := v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- v2Acnt = &v2Account{ID: v1rs.dataKeys[*v1rs.qryIdx]}
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, v2Acnt); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v2Acnt, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV2Account(x *v2Account) (err error) {
- key := utils.AccountPrefix + x.ID
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV2Account(id string) (err error) {
- key := utils.AccountPrefix + id
- return v1rs.rds.Cmd(nil, "DEL", key)
-}
-
-//ActionPlans methods
-//get
-func (v1rs *redisMigrator) getV1ActionPlans() (v1aps *v1ActionPlans, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.ActionPlanPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err := v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1aps); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1aps, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1ActionPlans(x *v1ActionPlans) (err error) {
- key := utils.ActionPlanPrefix + (*x)[0].Id
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV1ActionPlans(x *v1ActionPlans) (err error) {
- key := utils.ActionPlanPrefix + (*x)[0].Id
- return v1rs.rds.Cmd(nil, "DEL", key)
-}
-
-//Actions methods
-//get
-func (v1rs *redisMigrator) getV1Actions() (v1acs *v1Actions, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.ActionPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1acs); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1acs, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1Actions(x *v1Actions) (err error) {
- key := utils.ActionPrefix + (*x)[0].Id
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV1Actions(x v1Actions) (err error) {
- key := utils.ActionPrefix + x[0].Id
- return v1rs.rds.Cmd(nil, "DEL", key)
-
-}
-
-//ActionTriggers methods
-//get
-func (v1rs *redisMigrator) getV1ActionTriggers() (v1acts *v1ActionTriggers, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.ActionTriggerPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1acts); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1acts, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1ActionTriggers(x *v1ActionTriggers) (err error) {
- key := utils.ActionTriggerPrefix + (*x)[0].Id
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV1ActionTriggers(x *v1ActionTriggers) (err error) {
- key := utils.ActionTriggerPrefix + (*x)[0].Id
- return v1rs.rds.Cmd(nil, "DEL", key)
-}
-
-//SharedGroup methods
-//get
-func (v1rs *redisMigrator) getV1SharedGroup() (v1sg *v1SharedGroup, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.SharedGroupPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1sg); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1sg, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1SharedGroup(x *v1SharedGroup) (err error) {
- key := utils.SharedGroupPrefix + x.Id
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
//Stats methods
//get
func (v1rs *redisMigrator) getV1Stats() (v1st *v1Stat, err error) {
@@ -438,47 +156,6 @@ func (v1rs *redisMigrator) setV2Stats(v2 *engine.StatQueue) (err error) {
return
}
-//Action methods
-//get
-func (v1rs *redisMigrator) getV2ActionTrigger() (v2at *v2ActionTrigger, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.ActionTriggerPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v2at); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v2at, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV2ActionTrigger(x *v2ActionTrigger) (err error) {
- key := utils.ActionTriggerPrefix + x.ID
- bit, err := v1rs.rds.Marshaler().Marshal(x)
- if err != nil {
- return err
- }
- if err = v1rs.rds.Cmd(nil, "SET", key, string(bit)); err != nil {
- return err
- }
- return
-}
-
//AttributeProfile methods
//get
func (v1rs *redisMigrator) getV1AttributeProfile() (v1attrPrf *v1AttributeProfile, err error) {
@@ -595,180 +272,6 @@ func (v1rs *redisMigrator) remV2ThresholdProfile(tenant, id string) (err error)
return v1rs.rds.Cmd(nil, "DEL", key)
}
-//ThresholdProfile methods
-//get
-func (v1rs *redisMigrator) getV1Alias() (v1a *v1Alias, err error) {
- v1a = &v1Alias{Values: make(v1AliasValues, 0)}
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(AliasesPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- key := v1rs.dataKeys[*v1rs.qryIdx]
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", key); err != nil {
- return nil, err
- }
- v1a.SetId(strings.TrimPrefix(key, AliasesPrefix))
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1a.Values); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- } else {
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
- }
- return v1a, nil
-}
-
-//set
-func (v1rs *redisMigrator) setV1Alias(al *v1Alias) (err error) {
- var result []byte
- result, err = v1rs.rds.Marshaler().Marshal(al.Values)
- if err != nil {
- return
- }
- key := AliasesPrefix + al.GetId()
- if err = v1rs.rds.Cmd(nil, "SET", key, string(result)); err != nil {
- return
- }
- return
-}
-
-//rem
-func (v1rs *redisMigrator) remV1Alias(key string) (err error) {
-
- // get alias for values list
-
- var values []byte
- if err = v1rs.rds.Cmd(&values, "GET",
- AliasesPrefix+key); err != nil {
- return
- } else if len(values) == 0 {
- err = utils.ErrNotFound
- return
- }
- al := &v1Alias{Values: make(v1AliasValues, 0)}
- al.SetId(key)
- if err = v1rs.rds.Marshaler().Unmarshal(values, &al.Values); err != nil {
- return err
- }
-
- err = v1rs.rds.Cmd(nil, "DEL", AliasesPrefix+key)
- if err != nil {
- return err
- }
- for _, value := range al.Values {
- tmpKey := utils.ConcatenatedKey(al.GetId(), value.DestinationId)
- for target, pairs := range value.Pairs {
- for _, alias := range pairs {
- revID := alias + target + al.Context
- err = v1rs.rds.Cmd(nil, "SREM", reverseAliasesPrefix+revID, tmpKey)
- if err != nil {
- return err
- }
- }
- }
- }
- return
-
- // return v1rs.rds.Cmd(nil, "DEL", key)
-}
-
-// User methods
-//get
-func (v1rs *redisMigrator) getV1User() (v1u *v1UserProfile, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.UsersPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- v1u = new(v1UserProfile)
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, v1u); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- return v1u, nil
- }
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
-}
-
-//set
-func (v1rs *redisMigrator) setV1User(us *v1UserProfile) (err error) {
- bit, err := v1rs.rds.Marshaler().Marshal(us)
- if err != nil {
- return err
- }
- return v1rs.rds.Cmd(nil, "SET", utils.UsersPrefix+us.GetId(), string(bit))
-}
-
-//rem
-func (v1rs *redisMigrator) remV1User(key string) (err error) {
- return v1rs.rds.Cmd(nil, "DEL", utils.UsersPrefix+key)
-}
-
-// DerivedChargers methods
-//get
-func (v1rs *redisMigrator) getV1DerivedChargers() (v1d *v1DerivedChargersWithKey, err error) {
- if v1rs.qryIdx == nil {
- v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.DerivedChargersPrefix)
- if err != nil {
- return
- } else if len(v1rs.dataKeys) == 0 {
- return nil, utils.ErrNoMoreData
- }
- v1rs.qryIdx = utils.IntPointer(0)
- }
- if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 {
- var strVal []byte
- if err = v1rs.rds.Cmd(&strVal, "GET", v1rs.dataKeys[*v1rs.qryIdx]); err != nil {
- return nil, err
- }
- v1d = new(v1DerivedChargersWithKey)
- v1d.Key = strings.TrimPrefix(v1rs.dataKeys[*v1rs.qryIdx], utils.DerivedChargersPrefix)
- v1d.Value = new(v1DerivedChargers)
- if err := v1rs.rds.Marshaler().Unmarshal(strVal, v1d.Value); err != nil {
- return nil, err
- }
- *v1rs.qryIdx = *v1rs.qryIdx + 1
- return v1d, nil
- }
- v1rs.qryIdx = nil
- return nil, utils.ErrNoMoreData
-}
-
-//set
-func (v1rs *redisMigrator) setV1DerivedChargers(dc *v1DerivedChargersWithKey) (err error) {
- if dc == nil || len(dc.Value.Chargers) == 0 {
- return v1rs.remV1DerivedChargers(dc.Key)
- }
- bit, err := v1rs.rds.Marshaler().Marshal(dc.Value)
- if err != nil {
- return err
- }
- return v1rs.rds.Cmd(nil, "SET", utils.DerivedChargersPrefix+dc.Key, string(bit))
-}
-
-//rem
-func (v1rs *redisMigrator) remV1DerivedChargers(key string) (err error) {
- return v1rs.rds.Cmd(nil, "DEL", utils.DerivedChargersPrefix+key)
-}
-
//AttributeProfile methods
//get
func (v1rs *redisMigrator) getV2AttributeProfile() (v2attrPrf *v2AttributeProfile, err error) {
diff --git a/migrator/storage_sql.go b/migrator/storage_sql.go
index d83cca2df..0313147c7 100755
--- a/migrator/storage_sql.go
+++ b/migrator/storage_sql.go
@@ -137,50 +137,3 @@ func (mgSQL *migratorSQL) createV1SMCosts() (err error) {
}
return
}
-
-func (mgSQL *migratorSQL) getV2SMCost() (v2Cost *v2SessionsCost, err error) {
- if mgSQL.rowIter == nil {
- mgSQL.rowIter, err = mgSQL.sqlStorage.Db.Query("SELECT * FROM session_costs")
- if err != nil {
- return nil, err
- }
- }
- scSql := new(engine.SessionCostsSQL)
- mgSQL.rowIter.Scan(&scSql)
- v2Cost, err = NewV2SessionsCostFromSessionsCostSql(scSql)
-
- if mgSQL.rowIter.Next() {
- v2Cost = nil
- mgSQL.rowIter = nil
- return nil, utils.ErrNoMoreData
- }
- return v2Cost, nil
-}
-
-func (mgSQL *migratorSQL) setV2SMCost(v2Cost *v2SessionsCost) (err error) {
- tx := mgSQL.sqlStorage.ExportGormDB().Begin()
- smSql := v2Cost.AsSessionsCostSql()
- smSql.CreatedAt = time.Now()
- saved := tx.Save(smSql)
- if saved.Error != nil {
- return saved.Error
- }
- tx.Commit()
- return
-}
-
-func (mgSQL *migratorSQL) remV2SMCost(v2Cost *v2SessionsCost) (err error) {
- tx := mgSQL.sqlStorage.ExportGormDB().Begin()
- var rmParam *engine.SessionCostsSQL
- if v2Cost != nil {
- rmParam = &engine.SessionCostsSQL{Cgrid: v2Cost.CGRID,
- RunID: v2Cost.RunID}
- }
- if err := tx.Where(rmParam).Delete(engine.SessionCostsSQL{}).Error; err != nil {
- tx.Rollback()
- return err
- }
- tx.Commit()
- return nil
-
-}
diff --git a/migrator/thresholds.go b/migrator/thresholds.go
index 6dbeaaa49..cd690b4a7 100644
--- a/migrator/thresholds.go
+++ b/migrator/thresholds.go
@@ -23,30 +23,10 @@ import (
"strings"
"time"
- "github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
-type v2ActionTrigger struct {
- ID string // original csv tag
- UniqueID string // individual id
- ThresholdType string //*min_event_counter, *max_event_counter, *min_balance_counter, *max_balance_counter, *min_balance, *max_balance, *balance_expired
- ThresholdValue float64
- Recurrent bool // reset excuted flag each run
- MinSleep time.Duration // Minimum duration between two executions in case of recurrent triggers
- ExpirationDate time.Time
- ActivationDate time.Time
- Balance *engine.BalanceFilter //filtru
- Weight float64
- ActionsID string
- MinQueuedItems int // Trigger actions only if this number is hit (stats only) MINHITS
- Executed bool
- LastExecutionTime time.Time
-}
-
-type v2ActionTriggers []*v2ActionTrigger
-
func (m *Migrator) migrateCurrentThresholds() (err error) {
var ids []string
//Thresholds
@@ -101,19 +81,6 @@ func (m *Migrator) migrateCurrentThresholds() (err error) {
return
}
-func (m *Migrator) migrateV2ActionTriggers() (thp *engine.ThresholdProfile, th *engine.Threshold, filter *engine.Filter, err error) {
- var v2ACT *v2ActionTrigger
- if v2ACT, err = m.dmIN.getV2ActionTrigger(); err != nil {
- return
- }
- if v2ACT.ID != "" {
- if thp, th, filter, err = v2ACT.AsThreshold(); err != nil {
- return
- }
- }
- return
-}
-
func (m *Migrator) removeV2Thresholds() (err error) {
var v2T *v2Threshold
for {
@@ -171,9 +138,6 @@ func (m *Migrator) migrateThresholds() (err error) {
return
}
case 1:
- if v3, th, filter, err = m.migrateV2ActionTriggers(); err != nil && err != utils.ErrNoMoreData {
- return
- }
version = 3
case 2:
if v3, err = m.migrateV2Thresholds(); err != nil && err != utils.ErrNoMoreData {
@@ -229,184 +193,6 @@ func (m *Migrator) migrateThresholds() (err error) {
return m.ensureIndexesDataDB(engine.ColTps)
}
-func (v2ATR v2ActionTrigger) AsThreshold() (thp *engine.ThresholdProfile, th *engine.Threshold, filter *engine.Filter, err error) {
- var filterIDS []string
- var filters []*engine.FilterRule
- if v2ATR.Balance.ID != nil && *v2ATR.Balance.ID != "" {
- //TO DO:
- // if v2ATR.Balance.ExpirationDate != nil { //MetaLess
- // x, err := engine.NewRequestFilter(utils.MetaTimings, "ExpirationDate", v2ATR.Balance.ExpirationDate)
- // if err != nil {
- // return nil, nil, err
- // }
- // filters = append(filters, x)
- // }
- // if v2ATR.Balance.Weight != nil { //MetaLess /MetaRSRFields
- // x, err := engine.NewRequestFilter(utils.MetaLessOrEqual, "Weight", []string{strconv.FormatFloat(*v2ATR.Balance.Weight, 'f', 6, 64)})
- // if err != nil {
- // return nil, nil, err
- // }
- // filters = append(filters, x)
- // }
- if v2ATR.Balance.DestinationIDs != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaDestinations, "DestinationIDs", v2ATR.Balance.DestinationIDs.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.RatingSubject != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "RatingSubject", []string{*v2ATR.Balance.RatingSubject})
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.Categories != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "Categories", v2ATR.Balance.Categories.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.SharedGroups != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "SharedGroups", v2ATR.Balance.SharedGroups.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.TimingIDs != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "TimingIDs", v2ATR.Balance.TimingIDs.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
-
- filter = &engine.Filter{
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- ID: *v2ATR.Balance.ID,
- Rules: filters}
- filterIDS = append(filterIDS, filter.ID)
-
- }
- thp = &engine.ThresholdProfile{
- ID: v2ATR.ID,
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- Weight: v2ATR.Weight,
- ActivationInterval: &utils.ActivationInterval{
- ActivationTime: v2ATR.ActivationDate,
- ExpiryTime: v2ATR.ExpirationDate},
- FilterIDs: []string{},
- MinSleep: v2ATR.MinSleep,
- }
- th = &engine.Threshold{
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- ID: v2ATR.ID,
- }
- return thp, th, filter, nil
-}
-
-func (m *Migrator) SasThreshold(v2ATR *engine.ActionTrigger) (err error) {
- var vrs engine.Versions
- if m.dmOut.DataManager().DataDB() == nil {
- return utils.NewCGRError(utils.Migrator,
- utils.MandatoryIEMissingCaps,
- utils.NoStorDBConnection,
- "no connection to datadb")
- }
- if v2ATR.ID != "" {
- thp, th, filter, err := AsThreshold2(*v2ATR)
- if err != nil {
- return err
- }
- if filter != nil {
- if err := m.dmOut.DataManager().SetFilter(filter, true); err != nil {
- return err
- }
- }
- if err := m.dmOut.DataManager().SetThreshold(th, 0, true); err != nil {
- return err
- }
- if err := m.dmOut.DataManager().SetThresholdProfile(thp, true); err != nil {
- return err
- }
- m.stats[utils.Thresholds]++
- }
- // All done, update version wtih current one
- vrs = engine.Versions{utils.Thresholds: engine.CurrentStorDBVersions()[utils.Thresholds]}
- if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil {
- return utils.NewCGRError(utils.Migrator,
- utils.ServerErrorCaps,
- err.Error(),
- fmt.Sprintf("error: <%s> when updating Thresholds version into dataDB", err.Error()))
- }
- return
-}
-
-func AsThreshold2(v2ATR engine.ActionTrigger) (thp *engine.ThresholdProfile, th *engine.Threshold, filter *engine.Filter, err error) {
- var filterIDS []string
- var filters []*engine.FilterRule
- if v2ATR.Balance.ID != nil && *v2ATR.Balance.ID != "" {
- if v2ATR.Balance.DestinationIDs != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaDestinations, "DestinationIDs", v2ATR.Balance.DestinationIDs.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.RatingSubject != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "RatingSubject", []string{*v2ATR.Balance.RatingSubject})
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.Categories != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "Categories", v2ATR.Balance.Categories.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.SharedGroups != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "SharedGroups", v2ATR.Balance.SharedGroups.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- if v2ATR.Balance.TimingIDs != nil { //MetaLess /RSRfields
- x, err := engine.NewFilterRule(utils.MetaPrefix, "TimingIDs", v2ATR.Balance.TimingIDs.Slice())
- if err != nil {
- return nil, nil, nil, err
- }
- filters = append(filters, x)
- }
- filter = &engine.Filter{
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- ID: *v2ATR.Balance.ID,
- Rules: filters}
- filterIDS = append(filterIDS, filter.ID)
- }
- th = &engine.Threshold{
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- ID: v2ATR.ID,
- }
-
- thp = &engine.ThresholdProfile{
- ID: v2ATR.ID,
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- Weight: v2ATR.Weight,
- ActivationInterval: &utils.ActivationInterval{ActivationTime: v2ATR.ActivationDate, ExpiryTime: v2ATR.ExpirationDate},
- FilterIDs: filterIDS,
- MinSleep: v2ATR.MinSleep,
- }
-
- return thp, th, filter, nil
-}
-
type v2Threshold struct {
Tenant string
ID string
diff --git a/migrator/tp_account_actions.go b/migrator/tp_account_actions.go
deleted file mode 100644
index edf171ca1..000000000
--- a/migrator/tp_account_actions.go
+++ /dev/null
@@ -1,70 +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) migrateCurrentTPaccountAcction() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPAccountActions)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- accAct, err := m.storDBIn.StorDB().GetTPAccountActions(&utils.TPAccountActions{TPid: tpid})
- if err != nil {
- return err
- }
- if accAct != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPAccountActions(accAct); err != nil {
- return err
- }
- for _, acc := range accAct {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPAccountActions, acc.TPid,
- map[string]string{"loadid": acc.LoadId, "tenant": acc.Tenant, "account": acc.Account}); err != nil {
- return err
- }
- }
- m.stats[utils.TpAccountActionsV]++
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPaccountacction() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpAccountActionsV); err != nil {
- return
- }
- switch vrs[utils.TpAccountActionsV] {
- case current[utils.TpAccountActionsV]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPaccountAcction(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPAccountActions)
-}
diff --git a/migrator/tp_account_actions_it_test.go b/migrator/tp_account_actions_it_test.go
deleted file mode 100644
index 944cd11a6..000000000
--- a/migrator/tp_account_actions_it_test.go
+++ /dev/null
@@ -1,149 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpAccActPathIn string
- tpAccActPathOut string
- tpAccActCfgIn *config.CGRConfig
- tpAccActCfgOut *config.CGRConfig
- tpAccActMigrator *Migrator
- tpAccountActions []*utils.TPAccountActions
-)
-
-var sTestsTpAccActIT = []func(t *testing.T){
- testTpAccActITConnect,
- testTpAccActITFlush,
- testTpAccActITPopulate,
- testTpAccActITMove,
- testTpAccActITCheckData,
-}
-
-func TestTpAccActMove(t *testing.T) {
- for _, stest := range sTestsTpAccActIT {
- t.Run("TestTpAccActMove", stest)
- }
- tpAccActMigrator.Close()
-}
-
-func testTpAccActITConnect(t *testing.T) {
- var err error
- tpAccActPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpAccActCfgIn, err = config.NewCGRConfigFromPath(tpAccActPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpAccActPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpAccActCfgOut, err = config.NewCGRConfigFromPath(tpAccActPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpAccActCfgIn.StorDbCfg().Type,
- tpAccActCfgIn.StorDbCfg().Host, tpAccActCfgIn.StorDbCfg().Port,
- tpAccActCfgIn.StorDbCfg().Name, tpAccActCfgIn.StorDbCfg().User,
- tpAccActCfgIn.StorDbCfg().Password, tpAccActCfgIn.GeneralCfg().DBDataEncoding,
- tpAccActCfgIn.StorDbCfg().StringIndexedFields, tpAccActCfgIn.StorDbCfg().PrefixIndexedFields,
- tpAccActCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpAccActCfgOut.StorDbCfg().Type,
- tpAccActCfgOut.StorDbCfg().Host, tpAccActCfgOut.StorDbCfg().Port,
- tpAccActCfgOut.StorDbCfg().Name, tpAccActCfgOut.StorDbCfg().User,
- tpAccActCfgOut.StorDbCfg().Password, tpAccActCfgOut.GeneralCfg().DBDataEncoding,
- tpAccActCfgIn.StorDbCfg().StringIndexedFields, tpAccActCfgIn.StorDbCfg().PrefixIndexedFields,
- tpAccActCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpAccActMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpAccActITFlush(t *testing.T) {
- if err := tpAccActMigrator.storDBIn.StorDB().Flush(
- path.Join(tpAccActCfgIn.DataFolderPath, "storage", tpAccActCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpAccActMigrator.storDBOut.StorDB().Flush(
- path.Join(tpAccActCfgOut.DataFolderPath, "storage", tpAccActCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpAccActITPopulate(t *testing.T) {
- tpAccountActions = []*utils.TPAccountActions{
- {
- TPid: "TPAcc",
- LoadId: "ID",
- Tenant: "cgrates.org",
- Account: "1001",
- ActionPlanId: "PREPAID_10",
- AllowNegative: true,
- Disabled: false,
- },
- }
- if err := tpAccActMigrator.storDBIn.StorDB().SetTPAccountActions(tpAccountActions); err != nil {
- t.Error("Error when setting TpAccountActions ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpAccActMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpAccountActions ", err.Error())
- }
-}
-
-func testTpAccActITMove(t *testing.T) {
- err, _ := tpAccActMigrator.Migrate([]string{utils.MetaTpAccountActions})
- if err != nil {
- t.Error("Error when migrating TpAccountActions ", err.Error())
- }
-}
-
-func testTpAccActITCheckData(t *testing.T) {
- filter := &utils.TPAccountActions{TPid: tpAccountActions[0].TPid}
- result, err := tpAccActMigrator.storDBOut.StorDB().GetTPAccountActions(filter)
- if err != nil {
- t.Error("Error when getting TpAccountActions ", err.Error())
- }
- if !reflect.DeepEqual(tpAccountActions[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v",
- utils.ToJSON(tpAccountActions[0]), utils.ToJSON(result[0]))
- }
- result, err = tpAccActMigrator.storDBIn.StorDB().GetTPAccountActions(filter)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_action_plans.go b/migrator/tp_action_plans.go
deleted file mode 100644
index 59f756d8f..000000000
--- a/migrator/tp_action_plans.go
+++ /dev/null
@@ -1,77 +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) migrateCurrentTPactionplans() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPActionPlans)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPActionPlans,
- utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
- actPln, err := m.storDBIn.StorDB().GetTPActionPlans(tpid, id)
- if err != nil {
- return err
- }
- if actPln != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPActionPlans(actPln); err != nil {
- return err
- }
- for _, act := range actPln {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPActionPlans,
- act.TPid, map[string]string{"tag": act.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpActionPlans]++
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPactionplans() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpActionPlans); err != nil {
- return
- }
- switch vrs[utils.TpActionPlans] {
- case current[utils.TpActionPlans]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPactionplans(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPActionPlans)
-}
diff --git a/migrator/tp_action_plans_it_test.go b/migrator/tp_action_plans_it_test.go
deleted file mode 100644
index 78658b820..000000000
--- a/migrator/tp_action_plans_it_test.go
+++ /dev/null
@@ -1,157 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpActPlnPathIn string
- tpActPlnPathOut string
- tpActPlnCfgIn *config.CGRConfig
- tpActPlnCfgOut *config.CGRConfig
- tpActPlnMigrator *Migrator
- tpActionPlans []*utils.TPActionPlan
-)
-
-var sTestsTpActPlnIT = []func(t *testing.T){
- testTpActPlnITConnect,
- testTpActPlnITFlush,
- testTpActPlnITPopulate,
- testTpActPlnITMove,
- testTpActPlnITCheckData,
-}
-
-func TestTpActPlnMove(t *testing.T) {
- for _, stest := range sTestsTpActPlnIT {
- t.Run("TestTpActPlnMove", stest)
- }
- tpActPlnMigrator.Close()
-}
-
-func testTpActPlnITConnect(t *testing.T) {
- var err error
- tpActPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpActPlnCfgIn, err = config.NewCGRConfigFromPath(tpActPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpActPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpActPlnCfgOut, err = config.NewCGRConfigFromPath(tpActPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpActPlnCfgIn.StorDbCfg().Type,
- tpActPlnCfgIn.StorDbCfg().Host, tpActPlnCfgIn.StorDbCfg().Port,
- tpActPlnCfgIn.StorDbCfg().Name, tpActPlnCfgIn.StorDbCfg().User,
- tpActPlnCfgIn.StorDbCfg().Password, tpActPlnCfgIn.GeneralCfg().DBDataEncoding,
- tpActPlnCfgIn.StorDbCfg().StringIndexedFields, tpActPlnCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActPlnCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpActPlnCfgOut.StorDbCfg().Type,
- tpActPlnCfgOut.StorDbCfg().Host, tpActPlnCfgOut.StorDbCfg().Port,
- tpActPlnCfgOut.StorDbCfg().Name, tpActPlnCfgOut.StorDbCfg().User,
- tpActPlnCfgOut.StorDbCfg().Password, tpActPlnCfgOut.GeneralCfg().DBDataEncoding,
- tpActPlnCfgIn.StorDbCfg().StringIndexedFields, tpActPlnCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActPlnCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpActPlnMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpActPlnITFlush(t *testing.T) {
- if err := tpActPlnMigrator.storDBIn.StorDB().Flush(
- path.Join(tpActPlnCfgIn.DataFolderPath, "storage", tpActPlnCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpActPlnMigrator.storDBOut.StorDB().Flush(
- path.Join(tpActPlnCfgOut.DataFolderPath, "storage", tpActPlnCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpActPlnITPopulate(t *testing.T) {
- tpActionPlans = []*utils.TPActionPlan{
- {
- TPid: "TPAcc",
- ID: "ID",
- ActionPlan: []*utils.TPActionTiming{
- {
- ActionsId: "AccId",
- TimingId: "TimingID",
- Weight: 10,
- },
- {
- ActionsId: "AccId2",
- TimingId: "TimingID2",
- Weight: 11,
- },
- },
- },
- }
- if err := tpActPlnMigrator.storDBIn.StorDB().SetTPActionPlans(tpActionPlans); err != nil {
- t.Error("Error when setting TpActionPlan ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpActPlnMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpActionPlan ", err.Error())
- }
-}
-
-func testTpActPlnITMove(t *testing.T) {
- err, _ := tpActPlnMigrator.Migrate([]string{utils.MetaTpActionPlans})
- if err != nil {
- t.Error("Error when migrating TpActionPlan ", err.Error())
- }
-}
-
-func testTpActPlnITCheckData(t *testing.T) {
- result, err := tpActPlnMigrator.storDBOut.StorDB().GetTPActionPlans(
- tpActionPlans[0].TPid, tpActionPlans[0].ID)
- if err != nil {
- t.Error("Error when getting TpActionPlan ", err.Error())
- }
- if !reflect.DeepEqual(tpActionPlans[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v",
- utils.ToJSON(tpActionPlans[0]), utils.ToJSON(result[0]))
- }
- result, err = tpActPlnMigrator.storDBIn.StorDB().GetTPActionPlans(
- tpActionPlans[0].TPid, tpActionPlans[0].ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_action_triggers.go b/migrator/tp_action_triggers.go
deleted file mode 100644
index c2c9382fe..000000000
--- a/migrator/tp_action_triggers.go
+++ /dev/null
@@ -1,76 +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) migrateCurrentTPactiontriggers() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPActionTriggers)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPActionTriggers, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
- actTrg, err := m.storDBIn.StorDB().GetTPActionTriggers(tpid, id)
- if err != nil {
- return err
- }
- if actTrg != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPActionTriggers(actTrg); err != nil {
- return err
- }
- for _, act := range actTrg {
- if err := m.storDBIn.StorDB().RemTpData(
- utils.TBLTPActionTriggers, act.TPid, map[string]string{"tag": act.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpActionTriggers] += 1
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPactiontriggers() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpActionTriggers); err != nil {
- return
- }
- switch vrs[utils.TpActionTriggers] {
- case current[utils.TpActionTriggers]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPactiontriggers(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPActionTriggers)
-}
diff --git a/migrator/tp_action_triggers_it_test.go b/migrator/tp_action_triggers_it_test.go
deleted file mode 100644
index d35178710..000000000
--- a/migrator/tp_action_triggers_it_test.go
+++ /dev/null
@@ -1,193 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpActTrgPathIn string
- tpActTrgPathOut string
- tpActTrgCfgIn *config.CGRConfig
- tpActTrgCfgOut *config.CGRConfig
- tpActTrgMigrator *Migrator
- tpActionTriggers []*utils.TPActionTriggers
-)
-
-var sTestsTpActTrgIT = []func(t *testing.T){
- testTpActTrgITConnect,
- testTpActTrgITFlush,
- testTpActTrgITPopulate,
- testTpActTrgITMove,
- testTpActTrgITCheckData,
-}
-
-func TestTpActTrgMove(t *testing.T) {
- for _, stest := range sTestsTpActTrgIT {
- t.Run("TestTpActTrgMove", stest)
- }
- tpActTrgMigrator.Close()
-}
-
-func testTpActTrgITConnect(t *testing.T) {
- var err error
- tpActTrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpActTrgCfgIn, err = config.NewCGRConfigFromPath(tpActTrgPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpActTrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpActTrgCfgOut, err = config.NewCGRConfigFromPath(tpActTrgPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpActTrgCfgIn.StorDbCfg().Type,
- tpActTrgCfgIn.StorDbCfg().Host, tpActTrgCfgIn.StorDbCfg().Port,
- tpActTrgCfgIn.StorDbCfg().Name, tpActTrgCfgIn.StorDbCfg().User,
- tpActTrgCfgIn.StorDbCfg().Password, tpActTrgCfgIn.GeneralCfg().DBDataEncoding,
- tpActTrgCfgIn.StorDbCfg().StringIndexedFields, tpActTrgCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActTrgCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpActTrgCfgOut.StorDbCfg().Type,
- tpActTrgCfgOut.StorDbCfg().Host, tpActTrgCfgOut.StorDbCfg().Port,
- tpActTrgCfgOut.StorDbCfg().Name, tpActTrgCfgOut.StorDbCfg().User,
- tpActTrgCfgOut.StorDbCfg().Password, tpActTrgCfgOut.GeneralCfg().DBDataEncoding,
- tpActTrgCfgIn.StorDbCfg().StringIndexedFields, tpActTrgCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActTrgCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpActTrgMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpActTrgITFlush(t *testing.T) {
- if err := tpActTrgMigrator.storDBIn.StorDB().Flush(
- path.Join(tpActTrgCfgIn.DataFolderPath, "storage", tpActTrgCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpActTrgMigrator.storDBOut.StorDB().Flush(
- path.Join(tpActTrgCfgOut.DataFolderPath, "storage", tpActTrgCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpActTrgITPopulate(t *testing.T) {
- tpActionTriggers = []*utils.TPActionTriggers{
- {
- TPid: "TPAct",
- ID: "ID",
- ActionTriggers: []*utils.TPActionTrigger{
- {
- Id: "ID",
- UniqueID: "",
- ThresholdType: "*max_event_counter",
- ThresholdValue: 5,
- Recurrent: false,
- MinSleep: "0",
- ExpirationDate: "",
- ActivationDate: "",
- BalanceId: "",
- BalanceType: "*monetary",
- BalanceDestinationIds: "FS_USERS",
- BalanceWeight: "",
- BalanceExpirationDate: "",
- BalanceTimingTags: "",
- BalanceRatingSubject: "",
- BalanceCategories: "",
- BalanceSharedGroups: "",
- BalanceBlocker: "",
- BalanceDisabled: "",
- ActionsId: "LOG_WARNING",
- Weight: 10,
- },
- {
- Id: "ID",
- UniqueID: "",
- ThresholdType: "*min_balance",
- ThresholdValue: 2,
- Recurrent: false,
- MinSleep: "0",
- ExpirationDate: "",
- ActivationDate: "",
- BalanceId: "",
- BalanceType: "*monetary",
- BalanceDestinationIds: "FS_USERS",
- BalanceWeight: "",
- BalanceExpirationDate: "",
- BalanceTimingTags: "",
- BalanceRatingSubject: "",
- BalanceCategories: "",
- BalanceSharedGroups: "",
- BalanceBlocker: "",
- BalanceDisabled: "",
- ActionsId: "LOG_WARNING",
- Weight: 10,
- },
- },
- },
- }
- if err := tpActTrgMigrator.storDBIn.StorDB().SetTPActionTriggers(tpActionTriggers); err != nil {
- t.Error("Error when setting TpActionTriggers ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpActTrgMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpActionTriggers ", err.Error())
- }
-}
-
-func testTpActTrgITMove(t *testing.T) {
- err, _ := tpActTrgMigrator.Migrate([]string{utils.MetaTpActionTriggers})
- if err != nil {
- t.Error("Error when migrating TpActionTriggers ", err.Error())
- }
-}
-
-func testTpActTrgITCheckData(t *testing.T) {
- result, err := tpActTrgMigrator.storDBOut.StorDB().GetTPActionTriggers(
- tpActionTriggers[0].TPid, tpActionTriggers[0].ID)
- if err != nil {
- t.Error("Error when getting TpActionTriggers ", err.Error())
- }
- if !reflect.DeepEqual(tpActionTriggers[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v",
- utils.ToJSON(tpActionTriggers[0]), utils.ToJSON(result[0]))
- }
- result, err = tpActTrgMigrator.storDBIn.StorDB().GetTPActionTriggers(
- tpActionTriggers[0].TPid, tpActionTriggers[0].ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_actions.go b/migrator/tp_actions.go
deleted file mode 100644
index 0929d3101..000000000
--- a/migrator/tp_actions.go
+++ /dev/null
@@ -1,75 +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) migrateCurrentTPactions() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPActions)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPActions, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
- action, err := m.storDBIn.StorDB().GetTPActions(tpid, id)
- if err != nil {
- return err
- }
- if action != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPActions(action); err != nil {
- return err
- }
- for _, act := range action {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPActions, act.TPid, map[string]string{"tag": act.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpActions] += 1
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPactions() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpActions); err != nil {
- return
- }
- switch vrs[utils.TpActions] {
- case current[utils.TpActions]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPactions(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPActions)
-}
diff --git a/migrator/tp_actions_it_test.go b/migrator/tp_actions_it_test.go
deleted file mode 100644
index 5a20613a8..000000000
--- a/migrator/tp_actions_it_test.go
+++ /dev/null
@@ -1,185 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpActPathIn string
- tpActPathOut string
- tpActCfgIn *config.CGRConfig
- tpActCfgOut *config.CGRConfig
- tpActMigrator *Migrator
- tpActions []*utils.TPActions
-)
-
-var sTestsTpActIT = []func(t *testing.T){
- testTpActITConnect,
- testTpActITFlush,
- testTpActITPopulate,
- testTpActITMove,
- testTpActITCheckData,
-}
-
-func TestTpActMove(t *testing.T) {
- for _, stest := range sTestsTpActIT {
- t.Run("TestTpActMove", stest)
- }
- tpActMigrator.Close()
-}
-
-func testTpActITConnect(t *testing.T) {
- var err error
- tpActPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpActCfgIn, err = config.NewCGRConfigFromPath(tpActPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpActPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpActCfgOut, err = config.NewCGRConfigFromPath(tpActPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpActCfgIn.StorDbCfg().Type,
- tpActCfgIn.StorDbCfg().Host, tpActCfgIn.StorDbCfg().Port,
- tpActCfgIn.StorDbCfg().Name, tpActCfgIn.StorDbCfg().User,
- tpActCfgIn.StorDbCfg().Password, tpActCfgIn.GeneralCfg().DBDataEncoding,
- tpActCfgIn.StorDbCfg().StringIndexedFields, tpActCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpActCfgOut.StorDbCfg().Type,
- tpActCfgOut.StorDbCfg().Host, tpActCfgOut.StorDbCfg().Port,
- tpActCfgOut.StorDbCfg().Name, tpActCfgOut.StorDbCfg().User,
- tpActCfgOut.StorDbCfg().Password, tpActCfgOut.GeneralCfg().DBDataEncoding,
- tpActCfgIn.StorDbCfg().StringIndexedFields, tpActCfgIn.StorDbCfg().PrefixIndexedFields,
- tpActCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpActMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpActITFlush(t *testing.T) {
- if err := tpActMigrator.storDBIn.StorDB().Flush(
- path.Join(tpActCfgIn.DataFolderPath, "storage", tpActCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpActMigrator.storDBOut.StorDB().Flush(
- path.Join(tpActCfgOut.DataFolderPath, "storage", tpActCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpActITPopulate(t *testing.T) {
- tpActions = []*utils.TPActions{
- {
- TPid: "TPAcc",
- ID: "ID",
- Actions: []*utils.TPAction{
- {
- Identifier: "*log",
- BalanceId: "BalID1",
- BalanceUuid: "",
- BalanceType: "*monetary",
- Units: "120",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "*any",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "11",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 11,
- },
- {
- Identifier: "*topup_reset",
- BalanceId: "BalID2",
- BalanceUuid: "",
- BalanceType: "*data",
- Units: "10",
- ExpiryTime: "*unlimited",
- Filter: "",
- TimingTags: "2014-01-14T00:00:00Z",
- DestinationIds: "DST_1002",
- RatingSubject: "SPECIAL_1002",
- Categories: "",
- SharedGroups: "SHARED_A",
- BalanceWeight: "10",
- ExtraParameters: "",
- BalanceBlocker: "false",
- BalanceDisabled: "false",
- Weight: 10,
- },
- },
- },
- }
- if err := tpActMigrator.storDBIn.StorDB().SetTPActions(tpActions); err != nil {
- t.Error("Error when setting TpActions ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpActMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpActions ", err.Error())
- }
-}
-
-func testTpActITMove(t *testing.T) {
- err, _ := tpActMigrator.Migrate([]string{utils.MetaTpActions})
- if err != nil {
- t.Error("Error when migrating TpActions ", err.Error())
- }
-}
-
-func testTpActITCheckData(t *testing.T) {
- result, err := tpActMigrator.storDBOut.StorDB().GetTPActions(
- tpActions[0].TPid, tpActions[0].ID)
- if err != nil {
- t.Error("Error when getting TpActions ", err.Error())
- }
- if !reflect.DeepEqual(tpActions[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v",
- utils.ToJSON(tpActions[0]), utils.ToJSON(result[0]))
- }
- result, err = tpActMigrator.storDBIn.StorDB().GetTPActions(
- tpActions[0].TPid, tpActions[0].ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_destination_rates.go b/migrator/tp_destination_rates.go
deleted file mode 100644
index 52201546a..000000000
--- a/migrator/tp_destination_rates.go
+++ /dev/null
@@ -1,75 +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) migrateCurrentTPdestinationrates() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPDestinationRates)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPDestinationRates, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
- destRate, err := m.storDBIn.StorDB().GetTPDestinationRates(tpid, id, nil)
- if err != nil {
- return err
- }
- if destRate != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPDestinationRates(destRate); err != nil {
- return err
- }
- for _, dest := range destRate {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPDestinationRates, dest.TPid, map[string]string{"tag": dest.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpDestinationRates] += 1
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPdestinationrates() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpDestinationRates); err != nil {
- return
- }
- switch vrs[utils.TpDestinationRates] {
- case current[utils.TpDestinationRates]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPdestinationrates(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPDestinationRates)
-}
diff --git a/migrator/tp_destination_rates_it_test.go b/migrator/tp_destination_rates_it_test.go
deleted file mode 100644
index a41a024ff..000000000
--- a/migrator/tp_destination_rates_it_test.go
+++ /dev/null
@@ -1,152 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpDstRtPathIn string
- tpDstRtPathOut string
- tpDstRtCfgIn *config.CGRConfig
- tpDstRtCfgOut *config.CGRConfig
- tpDstRtMigrator *Migrator
- tpDestinationRate []*utils.TPDestinationRate
-)
-
-var sTestsTpDstRtIT = []func(t *testing.T){
- testTpDstRtITConnect,
- testTpDstRtITFlush,
- testTpDstRtITPopulate,
- testTpDstRtITMove,
- testTpDstRtITCheckData,
-}
-
-func TestTpDstRtMove(t *testing.T) {
- for _, stest := range sTestsTpDstRtIT {
- t.Run("TestTpDstRtMove", stest)
- }
- tpDstRtMigrator.Close()
-}
-
-func testTpDstRtITConnect(t *testing.T) {
- var err error
- tpDstRtPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpDstRtCfgIn, err = config.NewCGRConfigFromPath(tpDstRtPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpDstRtPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpDstRtCfgOut, err = config.NewCGRConfigFromPath(tpDstRtPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpDstRtCfgIn.StorDbCfg().Type,
- tpDstRtCfgIn.StorDbCfg().Host, tpDstRtCfgIn.StorDbCfg().Port,
- tpDstRtCfgIn.StorDbCfg().Name, tpDstRtCfgIn.StorDbCfg().User,
- tpDstRtCfgIn.StorDbCfg().Password, tpDstRtCfgIn.GeneralCfg().DBDataEncoding,
- tpDstRtCfgIn.StorDbCfg().StringIndexedFields, tpDstRtCfgIn.StorDbCfg().PrefixIndexedFields,
- tpDstRtCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpDstRtCfgOut.StorDbCfg().Type,
- tpDstRtCfgOut.StorDbCfg().Host, tpDstRtCfgOut.StorDbCfg().Port,
- tpDstRtCfgOut.StorDbCfg().Name, tpDstRtCfgOut.StorDbCfg().User,
- tpDstRtCfgOut.StorDbCfg().Password, tpDstRtCfgOut.GeneralCfg().DBDataEncoding,
- tpDstRtCfgIn.StorDbCfg().StringIndexedFields, tpDstRtCfgIn.StorDbCfg().PrefixIndexedFields,
- tpDstRtCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpDstRtMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpDstRtITFlush(t *testing.T) {
- if err := tpDstRtMigrator.storDBIn.StorDB().Flush(
- path.Join(tpDstRtCfgIn.DataFolderPath, "storage", tpDstRtCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpDstRtMigrator.storDBOut.StorDB().Flush(
- path.Join(tpDstRtCfgOut.DataFolderPath, "storage", tpDstRtCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpDstRtITPopulate(t *testing.T) {
- tpDestinationRate = []*utils.TPDestinationRate{
- {
- TPid: utils.TestSQL,
- ID: "DR_FREESWITCH_USERS",
- DestinationRates: []*utils.DestinationRate{
- {
- DestinationId: "FS_USERS",
- RateId: "RT_FS_USERS",
- RoundingMethod: "*up",
- RoundingDecimals: 2},
- },
- },
- }
- if err := tpDstRtMigrator.storDBIn.StorDB().SetTPDestinationRates(tpDestinationRate); err != nil {
- t.Error("Error when setting TpDestinationRate ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpDstRtMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpDestinationRate ", err.Error())
- }
-}
-
-func testTpDstRtITMove(t *testing.T) {
- err, _ := tpDstRtMigrator.Migrate([]string{utils.MetaTpDestinationRates})
- if err != nil {
- t.Error("Error when migrating TpDestinationRate ", err.Error())
- }
-}
-
-func testTpDstRtITCheckData(t *testing.T) {
- result, err := tpDstRtMigrator.storDBOut.StorDB().GetTPDestinationRates(
- tpDestinationRate[0].TPid, tpDestinationRate[0].ID, nil)
- if err != nil {
- t.Error("Error when getting TpDestinationRate ", err.Error())
- }
- if !reflect.DeepEqual(tpDestinationRate[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v",
- utils.ToJSON(tpDestinationRate[0]), utils.ToJSON(result[0]))
- }
- result, err = tpDstRtMigrator.storDBIn.StorDB().GetTPDestinationRates(
- tpDestinationRate[0].TPid, tpDestinationRate[0].ID, nil)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_rates.go b/migrator/tp_rates.go
deleted file mode 100644
index 370c21692..000000000
--- a/migrator/tp_rates.go
+++ /dev/null
@@ -1,76 +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) migrateCurrentTPrates() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPRates)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPRates, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
-
- rates, err := m.storDBIn.StorDB().GetTPRates(tpid, id)
- if err != nil {
- return err
- }
- if rates != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPRates(rates); err != nil {
- return err
- }
- for _, rate := range rates {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPRates, rate.TPid, map[string]string{"tag": rate.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpRates] += 1
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPrates() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpRates); err != nil {
- return
- }
- switch vrs[utils.TpRates] {
- case current[utils.TpRates]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPrates(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPRates)
-}
diff --git a/migrator/tp_rates_it_test.go b/migrator/tp_rates_it_test.go
deleted file mode 100644
index 66cc09278..000000000
--- a/migrator/tp_rates_it_test.go
+++ /dev/null
@@ -1,166 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpRatesPathIn string
- tpRatesPathOut string
- tpRatesCfgIn *config.CGRConfig
- tpRatesCfgOut *config.CGRConfig
- tpRatesMigrator *Migrator
- tpRates []*utils.TPRateRALs
-)
-
-var sTestsTpRatesIT = []func(t *testing.T){
- testTpRatesITConnect,
- testTpRatesITFlush,
- testTpRatesITPopulate,
- testTpRatesITMove,
- testTpRatesITCheckData,
-}
-
-func TestTpRatesMove(t *testing.T) {
- for _, stest := range sTestsTpRatesIT {
- t.Run("testTpRatesMove", stest)
- }
- tpRatesMigrator.Close()
-}
-
-func testTpRatesITConnect(t *testing.T) {
- var err error
- tpRatesPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpRatesCfgIn, err = config.NewCGRConfigFromPath(tpRatesPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpRatesPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpRatesCfgOut, err = config.NewCGRConfigFromPath(tpRatesPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpRatesCfgIn.StorDbCfg().Type,
- tpRatesCfgIn.StorDbCfg().Host, tpRatesCfgIn.StorDbCfg().Port,
- tpRatesCfgIn.StorDbCfg().Name, tpRatesCfgIn.StorDbCfg().User,
- tpRatesCfgIn.StorDbCfg().Password, tpRatesCfgIn.GeneralCfg().DBDataEncoding,
- tpRatesCfgIn.StorDbCfg().StringIndexedFields, tpRatesCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatesCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpRatesCfgOut.StorDbCfg().Type,
- tpRatesCfgOut.StorDbCfg().Host, tpRatesCfgOut.StorDbCfg().Port,
- tpRatesCfgOut.StorDbCfg().Name, tpRatesCfgOut.StorDbCfg().User,
- tpRatesCfgOut.StorDbCfg().Password, tpRatesCfgOut.GeneralCfg().DBDataEncoding,
- tpRatesCfgIn.StorDbCfg().StringIndexedFields, tpRatesCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatesCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpRatesMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpRatesITFlush(t *testing.T) {
- if err := tpRatesMigrator.storDBIn.StorDB().Flush(
- path.Join(tpRatesCfgIn.DataFolderPath, "storage", tpRatesCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpRatesMigrator.storDBOut.StorDB().Flush(
- path.Join(tpRatesCfgOut.DataFolderPath, "storage", tpRatesCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpRatesITPopulate(t *testing.T) {
- tpRates = []*utils.TPRateRALs{
- {
- TPid: "TPidTpRate",
- ID: "RT_FS_USERS",
- RateSlots: []*utils.RateSlot{
- {
- ConnectFee: 12,
- Rate: 3,
- RateUnit: "6s",
- RateIncrement: "6s",
- GroupIntervalStart: "0s",
- },
- {
- ConnectFee: 12,
- Rate: 3,
- RateUnit: "4s",
- RateIncrement: "6s",
- GroupIntervalStart: "1s",
- },
- },
- },
- }
- if err := tpRatesMigrator.storDBIn.StorDB().SetTPRates(tpRates); err != nil {
- t.Error("Error when setting TpRate ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpRatesMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpRate ", err.Error())
- }
-}
-
-func testTpRatesITMove(t *testing.T) {
- err, _ := tpRatesMigrator.Migrate([]string{utils.MetaTpRates})
- if err != nil {
- t.Error("Error when migrating TpRate ", err.Error())
- }
-}
-
-func testTpRatesITCheckData(t *testing.T) {
- result, err := tpRatesMigrator.storDBOut.StorDB().GetTPRates(
- tpRates[0].TPid, tpRates[0].ID)
- if err != nil {
- t.Error("Error when getting TpRate ", err.Error())
- }
- if err := tpRates[0].RateSlots[0].SetDurations(); err != nil {
- t.Error(err)
- }
- if err := tpRates[0].RateSlots[1].SetDurations(); err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(tpRates[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v", tpRates[0], result[0])
- }
- result, err = tpRatesMigrator.storDBIn.StorDB().GetTPRates(
- tpRates[0].TPid, tpRates[0].ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_rating_plans.go b/migrator/tp_rating_plans.go
deleted file mode 100644
index 7b9b1cd02..000000000
--- a/migrator/tp_rating_plans.go
+++ /dev/null
@@ -1,77 +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) migrateCurrentTPratingplans() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPRatingPlans)
- if err != nil {
- return err
- }
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPRatingPlans, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- if len(ids) != 0 {
- for _, id := range ids {
- ratingPlan, err := m.storDBIn.StorDB().GetTPRatingPlans(tpid, id, nil)
- if err != nil {
- return err
- }
- if ratingPlan != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPRatingPlans(ratingPlan); err != nil {
- return err
- }
- for _, ratPln := range ratingPlan {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPRatingPlans, ratPln.TPid, map[string]string{"tag": ratPln.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpRatingPlans] += 1
- }
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPratingplans() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpRatingPlans); err != nil {
- return
- }
- switch vrs[utils.TpRatingPlans] {
- case current[utils.TpRatingPlans]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPratingplans(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPRatingPlans)
-}
diff --git a/migrator/tp_rating_plans_it_test.go b/migrator/tp_rating_plans_it_test.go
deleted file mode 100644
index 8f5de6e7a..000000000
--- a/migrator/tp_rating_plans_it_test.go
+++ /dev/null
@@ -1,173 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpRatPlnPathIn string
- tpRatPlnPathOut string
- tpRatPlnCfgIn *config.CGRConfig
- tpRatPlnCfgOut *config.CGRConfig
- tpRatPlnMigrator *Migrator
- tpRatingPlan []*utils.TPRatingPlan
-)
-
-var sTestsTpRatPlnIT = []func(t *testing.T){
- testTpRatPlnITConnect,
- testTpRatPlnITFlush,
- testTpRatPlnITPopulate,
- testTpRatPlnITMove,
- testTpRatPlnITCheckData,
-}
-
-func TestTpRatPlnMove(t *testing.T) {
- for _, stest := range sTestsTpRatPlnIT {
- t.Run("testTpRatPlnMove", stest)
- }
- tpRatPlnMigrator.Close()
-}
-
-func testTpRatPlnITConnect(t *testing.T) {
- var err error
- tpRatPlnPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpRatPlnCfgIn, err = config.NewCGRConfigFromPath(tpRatPlnPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpRatPlnPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpRatPlnCfgOut, err = config.NewCGRConfigFromPath(tpRatPlnPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpRatPlnCfgIn.StorDbCfg().Type,
- tpRatPlnCfgIn.StorDbCfg().Host, tpRatPlnCfgIn.StorDbCfg().Port,
- tpRatPlnCfgIn.StorDbCfg().Name, tpRatPlnCfgIn.StorDbCfg().User,
- tpRatPlnCfgIn.StorDbCfg().Password, tpRatPlnCfgIn.GeneralCfg().DBDataEncoding,
- tpRatPlnCfgIn.StorDbCfg().StringIndexedFields, tpRatPlnCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatPlnCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpRatPlnCfgOut.StorDbCfg().Type,
- tpRatPlnCfgOut.StorDbCfg().Host, tpRatPlnCfgOut.StorDbCfg().Port,
- tpRatPlnCfgOut.StorDbCfg().Name, tpRatPlnCfgOut.StorDbCfg().User,
- tpRatPlnCfgOut.StorDbCfg().Password, tpRatPlnCfgOut.GeneralCfg().DBDataEncoding,
- tpRatPlnCfgIn.StorDbCfg().StringIndexedFields, tpRatPlnCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatPlnCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpRatPlnMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpRatPlnITFlush(t *testing.T) {
- if err := tpRatPlnMigrator.storDBIn.StorDB().Flush(
- path.Join(tpRatPlnCfgIn.DataFolderPath, "storage", tpRatPlnCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpRatPlnMigrator.storDBOut.StorDB().Flush(
- path.Join(tpRatPlnCfgOut.DataFolderPath, "storage", tpRatPlnCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpRatPlnITPopulate(t *testing.T) {
- tpRatingPlan = []*utils.TPRatingPlan{
- {
- TPid: "TPRP1",
- ID: "IDPlan2",
- RatingPlanBindings: []*utils.TPRatingPlanBinding{
- {
- DestinationRatesId: "RateId",
- TimingId: "TimingID",
- Weight: 12,
- },
- {
- DestinationRatesId: "DR_FREESWITCH_USERS",
- TimingId: "ALWAYS",
- Weight: 10,
- },
- },
- },
- }
- if err := tpRatPlnMigrator.storDBIn.StorDB().SetTPRatingPlans(tpRatingPlan); err != nil {
- t.Error("Error when setting TpRatingPlans ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpRatPlnMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpRatingPlans ", err.Error())
- }
-}
-
-func testTpRatPlnITMove(t *testing.T) {
- err, _ := tpRatPlnMigrator.Migrate([]string{utils.MetaTpRatingPlans})
- if err != nil {
- t.Error("Error when migrating TpRatingPlans ", err.Error())
- }
-}
-
-func testTpRatPlnITCheckData(t *testing.T) {
- reverseRatingPlanBindings := []*utils.TPRatingPlanBinding{
- {
- DestinationRatesId: "DR_FREESWITCH_USERS",
- TimingId: "ALWAYS",
- Weight: 10,
- },
- {
- DestinationRatesId: "RateId",
- TimingId: "TimingID",
- Weight: 12,
- },
- }
- result, err := tpRatPlnMigrator.storDBOut.StorDB().GetTPRatingPlans(
- tpRatingPlan[0].TPid, tpRatingPlan[0].ID, nil)
- if err != nil {
- t.Error("Error when getting TpRatingPlans ", err.Error())
- }
- if !reflect.DeepEqual(tpRatingPlan[0].TPid, result[0].TPid) {
- t.Errorf("Expecting: %+v, received: %+v", tpRatingPlan[0].TPid, result[0].TPid)
- } else if !reflect.DeepEqual(tpRatingPlan[0].ID, result[0].ID) {
- t.Errorf("Expecting: %+v, received: %+v", tpRatingPlan[0].ID, result[0].ID)
- } else if !reflect.DeepEqual(tpRatingPlan[0].RatingPlanBindings, result[0].RatingPlanBindings) &&
- !reflect.DeepEqual(result[0].RatingPlanBindings, reverseRatingPlanBindings) {
- t.Errorf("Expecting: %+v, received: %+v", reverseRatingPlanBindings, result[0].RatingPlanBindings)
- }
- result, err = tpRatPlnMigrator.storDBIn.StorDB().GetTPRatingPlans(
- tpRatingPlan[0].TPid, tpRatingPlan[0].ID, nil)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_rating_profiles.go b/migrator/tp_rating_profiles.go
deleted file mode 100644
index 742319738..000000000
--- a/migrator/tp_rating_profiles.go
+++ /dev/null
@@ -1,74 +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) migrateCurrentTPratingprofiles() (err error) {
-
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPRatingProfiles)
- if err != nil {
- return err
- }
-
- for _, tpid := range tpids {
- ratingProfile, err := m.storDBIn.StorDB().GetTPRatingProfiles(&utils.TPRatingProfile{TPid: tpid})
- if err != nil {
- return err
- }
- if ratingProfile != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPRatingProfiles(ratingProfile); err != nil {
- return err
- }
- for _, ratPrf := range ratingProfile {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPRatingProfiles, ratPrf.TPid,
- map[string]string{"loadid": ratPrf.LoadId,
- "tenant": ratPrf.Tenant, "category": ratPrf.Category,
- "subject": ratPrf.Subject}); err != nil {
- return err
- }
- }
- m.stats[utils.TpRatingProfiles] += 1
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPratingprofiles() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpRatingProfiles); err != nil {
- return
- }
- switch vrs[utils.TpRatingProfiles] {
- case current[utils.TpRatingProfiles]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPratingprofiles(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPRatingProfiles)
-}
diff --git a/migrator/tp_rating_profiles_it_test.go b/migrator/tp_rating_profiles_it_test.go
deleted file mode 100644
index 6b57af529..000000000
--- a/migrator/tp_rating_profiles_it_test.go
+++ /dev/null
@@ -1,158 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpRatPrfPathIn string
- tpRatPrfPathOut string
- tpRatPrfCfgIn *config.CGRConfig
- tpRatPrfCfgOut *config.CGRConfig
- tpRatPrfMigrator *Migrator
- tpRatingProfile []*utils.TPRatingProfile
-)
-
-var sTestsTpRatPrfIT = []func(t *testing.T){
- testTpRatPrfITConnect,
- testTpRatPrfITFlush,
- testTpRatPrfITPopulate,
- testTpRatPrfITMove,
- testTpRatPrfITCheckData,
-}
-
-func TestTpRatPrfMove(t *testing.T) {
- for _, stest := range sTestsTpRatPrfIT {
- t.Run("testTpRatPrfMove", stest)
- }
- tpRatPrfMigrator.Close()
-}
-
-func testTpRatPrfITConnect(t *testing.T) {
- var err error
- tpRatPrfPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpRatPrfCfgIn, err = config.NewCGRConfigFromPath(tpRatPrfPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpRatPrfPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpRatPrfCfgOut, err = config.NewCGRConfigFromPath(tpRatPrfPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpRatPrfCfgIn.StorDbCfg().Type,
- tpRatPrfCfgIn.StorDbCfg().Host, tpRatPrfCfgIn.StorDbCfg().Port,
- tpRatPrfCfgIn.StorDbCfg().Name, tpRatPrfCfgIn.StorDbCfg().User,
- tpRatPrfCfgIn.StorDbCfg().Password, tpRatPrfCfgIn.GeneralCfg().DBDataEncoding,
- tpRatPrfCfgIn.StorDbCfg().StringIndexedFields, tpRatPrfCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatPrfCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpRatPrfCfgOut.StorDbCfg().Type,
- tpRatPrfCfgOut.StorDbCfg().Host, tpRatPrfCfgOut.StorDbCfg().Port,
- tpRatPrfCfgOut.StorDbCfg().Name, tpRatPrfCfgOut.StorDbCfg().User,
- tpRatPrfCfgOut.StorDbCfg().Password, tpRatPrfCfgOut.GeneralCfg().DBDataEncoding,
- tpRatPrfCfgIn.StorDbCfg().StringIndexedFields, tpRatPrfCfgIn.StorDbCfg().PrefixIndexedFields,
- tpRatPrfCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpRatPrfMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpRatPrfITFlush(t *testing.T) {
- if err := tpRatPrfMigrator.storDBIn.StorDB().Flush(
- path.Join(tpRatPrfCfgIn.DataFolderPath, "storage", tpRatPrfCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpRatPrfMigrator.storDBOut.StorDB().Flush(
- path.Join(tpRatPrfCfgOut.DataFolderPath, "storage", tpRatPrfCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpRatPrfITPopulate(t *testing.T) {
- tpRatingProfile = []*utils.TPRatingProfile{
- {
- TPid: "TPRProf1",
- LoadId: "RPrf",
- Tenant: "Tenant1",
- Category: "Category",
- Subject: "Subject",
- RatingPlanActivations: []*utils.TPRatingActivation{
- {
- ActivationTime: "2014-07-29T15:00:00Z",
- RatingPlanId: "PlanOne",
- FallbackSubjects: "FallBack",
- },
- {
- ActivationTime: "2015-07-29T10:00:00Z",
- RatingPlanId: "PlanTwo",
- FallbackSubjects: "FallOut",
- },
- },
- },
- }
- if err := tpRatPrfMigrator.storDBIn.StorDB().SetTPRatingProfiles(tpRatingProfile); err != nil {
- t.Error("Error when setting TpRatingProfiles ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpRatPrfMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpRatingProfiles ", err.Error())
- }
-}
-
-func testTpRatPrfITMove(t *testing.T) {
- err, _ := tpRatPrfMigrator.Migrate([]string{utils.MetaTpRatingProfiles})
- if err != nil {
- t.Error("Error when migrating TpRatingProfiles ", err.Error())
- }
-}
-
-func testTpRatPrfITCheckData(t *testing.T) {
- filter := &utils.TPRatingProfile{TPid: tpRatingProfile[0].TPid, LoadId: tpRatingProfile[0].LoadId}
- result, err := tpRatPrfMigrator.storDBOut.StorDB().GetTPRatingProfiles(filter)
- if err != nil {
- t.Error("Error when getting TpRatingProfiles ", err.Error())
- }
- if !reflect.DeepEqual(tpRatingProfile[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v", tpRatingProfile[0], result[0])
- }
- result, err = tpRatPrfMigrator.storDBIn.StorDB().GetTPRatingProfiles(filter)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/tp_shared_groups.go b/migrator/tp_shared_groups.go
deleted file mode 100644
index f840316fe..000000000
--- a/migrator/tp_shared_groups.go
+++ /dev/null
@@ -1,78 +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) migrateCurrentTPsharedgroups() (err error) {
- tpids, err := m.storDBIn.StorDB().GetTpIds(utils.TBLTPSharedGroups)
- if err != nil {
- return err
- }
-
- for _, tpid := range tpids {
- ids, err := m.storDBIn.StorDB().GetTpTableIds(tpid, utils.TBLTPSharedGroups, utils.TPDistinctIds{"tag"}, map[string]string{}, nil)
- if err != nil {
- return err
- }
- for _, id := range ids {
-
- sharedGroup, err := m.storDBIn.StorDB().GetTPSharedGroups(tpid, id)
- if err != nil {
- return err
- }
- if sharedGroup != nil {
- if m.dryRun != true {
- if err := m.storDBOut.StorDB().SetTPSharedGroups(sharedGroup); err != nil {
- return err
- }
- for _, shrGr := range sharedGroup {
- if err := m.storDBIn.StorDB().RemTpData(utils.TBLTPSharedGroups, shrGr.TPid,
- map[string]string{"id": shrGr.ID}); err != nil {
- return err
- }
- }
- m.stats[utils.TpSharedGroups] += 1
- }
- }
- }
- }
- return
-}
-
-func (m *Migrator) migrateTPsharedgroups() (err error) {
- var vrs engine.Versions
- current := engine.CurrentStorDBVersions()
- if vrs, err = m.getVersions(utils.TpSharedGroups); err != nil {
- return
- }
- switch vrs[utils.TpSharedGroups] {
- case current[utils.TpSharedGroups]:
- if m.sameStorDB {
- break
- }
- if err := m.migrateCurrentTPsharedgroups(); err != nil {
- return err
- }
- }
- return m.ensureIndexesStorDB(utils.TBLTPResources)
-}
diff --git a/migrator/tp_shared_groups_it_test.go b/migrator/tp_shared_groups_it_test.go
deleted file mode 100644
index 6aa19bca8..000000000
--- a/migrator/tp_shared_groups_it_test.go
+++ /dev/null
@@ -1,157 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- tpShrGrPathIn string
- tpShrGrPathOut string
- tpShrGrCfgIn *config.CGRConfig
- tpShrGrCfgOut *config.CGRConfig
- tpShrGrMigrator *Migrator
- tpSharedGroups []*utils.TPSharedGroups
-)
-
-var sTestsTpShrGrIT = []func(t *testing.T){
- testTpShrGrITConnect,
- testTpShrGrITFlush,
- testTpShrGrITPopulate,
- testTpShrGrITMove,
- testTpShrGrITCheckData,
-}
-
-func TestTpShrGrMove(t *testing.T) {
- for _, stest := range sTestsTpShrGrIT {
- t.Run("testTpShrGrMove", stest)
- }
- tpShrGrMigrator.Close()
-}
-
-func testTpShrGrITConnect(t *testing.T) {
- var err error
- tpShrGrPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
- tpShrGrCfgIn, err = config.NewCGRConfigFromPath(tpShrGrPathIn)
- if err != nil {
- t.Fatal(err)
- }
- tpShrGrPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
- tpShrGrCfgOut, err = config.NewCGRConfigFromPath(tpShrGrPathOut)
- if err != nil {
- t.Fatal(err)
- }
- storDBIn, err := NewMigratorStorDB(tpShrGrCfgIn.StorDbCfg().Type,
- tpShrGrCfgIn.StorDbCfg().Host, tpShrGrCfgIn.StorDbCfg().Port,
- tpShrGrCfgIn.StorDbCfg().Name, tpShrGrCfgIn.StorDbCfg().User,
- tpShrGrCfgIn.StorDbCfg().Password, tpShrGrCfgIn.GeneralCfg().DBDataEncoding,
- tpShrGrCfgIn.StorDbCfg().StringIndexedFields, tpShrGrCfgIn.StorDbCfg().PrefixIndexedFields,
- tpShrGrCfgIn.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- storDBOut, err := NewMigratorStorDB(tpShrGrCfgOut.StorDbCfg().Type,
- tpShrGrCfgOut.StorDbCfg().Host, tpShrGrCfgOut.StorDbCfg().Port,
- tpShrGrCfgOut.StorDbCfg().Name, tpShrGrCfgOut.StorDbCfg().User,
- tpShrGrCfgOut.StorDbCfg().Password, tpShrGrCfgOut.GeneralCfg().DBDataEncoding,
- tpShrGrCfgIn.StorDbCfg().StringIndexedFields, tpShrGrCfgIn.StorDbCfg().PrefixIndexedFields,
- tpShrGrCfgOut.StorDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- tpShrGrMigrator, err = NewMigrator(nil, nil, storDBIn, storDBOut, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testTpShrGrITFlush(t *testing.T) {
- if err := tpShrGrMigrator.storDBIn.StorDB().Flush(
- path.Join(tpShrGrCfgIn.DataFolderPath, "storage", tpShrGrCfgIn.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-
- if err := tpShrGrMigrator.storDBOut.StorDB().Flush(
- path.Join(tpShrGrCfgOut.DataFolderPath, "storage", tpShrGrCfgOut.StorDbCfg().Type)); err != nil {
- t.Error(err)
- }
-}
-
-func testTpShrGrITPopulate(t *testing.T) {
- tpSharedGroups = []*utils.TPSharedGroups{
- {
- TPid: "TPS1",
- ID: "Group1",
- SharedGroups: []*utils.TPSharedGroup{
- {
- Account: "AccOne",
- Strategy: "StrategyOne",
- RatingSubject: "SubOne",
- },
- {
- Account: "AccTow",
- Strategy: "StrategyTwo",
- RatingSubject: "SubTwo",
- },
- },
- },
- }
- if err := tpShrGrMigrator.storDBIn.StorDB().SetTPSharedGroups(tpSharedGroups); err != nil {
- t.Error("Error when setting TpSharedGroups ", err.Error())
- }
- currentVersion := engine.CurrentStorDBVersions()
- err := tpShrGrMigrator.storDBIn.StorDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for TpSharedGroups ", err.Error())
- }
-}
-
-func testTpShrGrITMove(t *testing.T) {
- err, _ := tpShrGrMigrator.Migrate([]string{utils.MetaTpSharedGroups})
- if err != nil {
- t.Error("Error when migrating TpSharedGroups ", err.Error())
- }
-}
-
-func testTpShrGrITCheckData(t *testing.T) {
- //filter := &utils.TPSharedGroups{TPid: tpSharedGroups[0].TPid}
- result, err := tpShrGrMigrator.storDBOut.StorDB().GetTPSharedGroups(
- tpSharedGroups[0].TPid, tpSharedGroups[0].ID)
- if err != nil {
- t.Error("Error when getting TpSharedGroups ", err.Error())
- }
- if !reflect.DeepEqual(tpSharedGroups[0], result[0]) {
- t.Errorf("Expecting: %+v, received: %+v", tpSharedGroups[0], result[0])
- }
- result, err = tpShrGrMigrator.storDBIn.StorDB().GetTPSharedGroups(
- tpSharedGroups[0].TPid, tpSharedGroups[0].ID)
- if err != utils.ErrNotFound {
- t.Error(err)
- }
-}
diff --git a/migrator/user.go b/migrator/user.go
deleted file mode 100644
index 93aed5eb3..000000000
--- a/migrator/user.go
+++ /dev/null
@@ -1,152 +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/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-type v1UserProfile struct {
- Tenant string
- UserName string
- Masked bool //disable if true
- Profile map[string]string
- Weight float64
-}
-
-func (ud *v1UserProfile) GetId() string {
- return utils.ConcatenatedKey(ud.Tenant, ud.UserName)
-}
-
-func (ud *v1UserProfile) SetId(id string) error {
- vals := strings.Split(id, utils.ConcatenatedKeySep)
- if len(vals) != 2 {
- return utils.ErrInvalidKey
- }
- ud.Tenant = vals[0]
- ud.UserName = vals[1]
- return nil
-}
-
-func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributeProfile) {
- usrFltr := config.CgrConfig().MigratorCgrCfg().UsersFilters
- attr = &engine.AttributeProfile{
- Tenant: config.CgrConfig().GeneralCfg().DefaultTenant,
- ID: user.UserName,
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: make([]*engine.Attribute, 0),
- Blocker: false,
- Weight: user.Weight,
- }
- if user.Tenant != attr.Tenant {
- attr.Attributes = append(attr.Attributes, &engine.Attribute{
- Path: utils.MetaTenant,
- Value: config.NewRSRParsersMustCompile(user.Tenant, utils.InfieldSep),
- Type: utils.MetaConstant,
- })
- }
- for fieldName, substitute := range user.Profile {
- if fieldName == "ReqType" { // old style
- fieldName = utils.RequestType
- }
- if utils.IsSliceMember(usrFltr, fieldName) {
- attr.FilterIDs = append(attr.FilterIDs, fmt.Sprintf("*string:~%s:%s", fieldName, substitute))
- continue
- }
- var path string
- if fieldName != utils.EmptyString {
- path = utils.MetaReq + utils.NestingSep + fieldName
- } else {
- continue // ignore empty filedNames
- }
- attr.Attributes = append(attr.Attributes, &engine.Attribute{
- Path: path,
- Value: config.NewRSRParsersMustCompile(substitute, utils.InfieldSep),
- Type: utils.MetaVariable,
- })
- }
- return
-}
-
-func (m *Migrator) removeV1UserProfile() (err error) {
- for {
- user, err := m.dmIN.getV1User()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return err
- }
- if user == nil || user.Masked || m.dryRun {
- continue
- }
- if err := m.dmIN.remV1User(user.GetId()); err != nil {
- return err
- }
- }
- return
-}
-
-func (m *Migrator) migrateV1User2AttributeProfile() (err error) {
- for {
- user, err := m.dmIN.getV1User()
- if err == utils.ErrNoMoreData {
- break
- }
- if err != nil {
- return err
- }
- if user == nil || user.Masked || m.dryRun {
- continue
- }
- attr := userProfile2attributeProfile(user)
- if len(attr.Attributes) == 0 {
- continue
- }
- if err := m.dmOut.DataManager().SetAttributeProfile(attr, true); err != nil {
- return err
- }
- m.stats[utils.User]++
- }
- if m.dryRun {
- return
- }
- if err = m.removeV1UserProfile(); err != nil {
- return
- }
- // All done, update version wtih current one
- if err = m.setVersions(utils.User); err != nil {
- return err
- }
- return
-}
-
-func (m *Migrator) migrateUser() (err error) {
- if err = m.migrateV1User2AttributeProfile(); err != nil {
- return err
- }
- return m.ensureIndexesDataDB(engine.ColAttr)
-}
diff --git a/migrator/user_it_test.go b/migrator/user_it_test.go
deleted file mode 100644
index fbd1e2be2..000000000
--- a/migrator/user_it_test.go
+++ /dev/null
@@ -1,209 +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"
- "sort"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-var (
- usrCfgIn *config.CGRConfig
- usrCfgOut *config.CGRConfig
- usrMigrator *Migrator
-)
-
-var sTestsUsrIT = []func(t *testing.T){
- testUsrITConnect,
- testUsrITFlush,
- testUsrITMigrateAndMove,
-}
-
-func TestUserMigrateITRedis(t *testing.T) {
- inPath := path.Join(*dataDir, "conf", "samples", "tutmysql")
- testUsrStart("TestUserMigrateITRedis", inPath, inPath, t)
-}
-
-func TestUserMigrateITMongo(t *testing.T) {
- inPath := path.Join(*dataDir, "conf", "samples", "tutmongo")
- testUsrStart("TestUserMigrateITMongo", inPath, inPath, t)
-}
-
-func TestUserITMigrateMongo2Redis(t *testing.T) {
- inPath := path.Join(*dataDir, "conf", "samples", "tutmongo")
- outPath := path.Join(*dataDir, "conf", "samples", "tutmysql")
- testUsrStart("TestUserITMigrateMongo2Redis", inPath, outPath, t)
-}
-
-func testUsrStart(testName, inPath, outPath string, t *testing.T) {
- var err error
- if usrCfgIn, err = config.NewCGRConfigFromPath(inPath); err != nil {
- t.Fatal(err)
- }
- config.SetCgrConfig(usrCfgIn)
- if usrCfgOut, err = config.NewCGRConfigFromPath(outPath); err != nil {
- t.Fatal(err)
- }
- for _, stest := range sTestsUsrIT {
- t.Run(testName, stest)
- }
- usrMigrator.Close()
-}
-
-func testUsrITConnect(t *testing.T) {
- dataDBIn, err := NewMigratorDataDB(usrCfgIn.DataDbCfg().Type,
- usrCfgIn.DataDbCfg().Host, usrCfgIn.DataDbCfg().Port,
- usrCfgIn.DataDbCfg().Name, usrCfgIn.DataDbCfg().User,
- usrCfgIn.DataDbCfg().Password, usrCfgIn.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), usrCfgIn.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- dataDBOut, err := NewMigratorDataDB(usrCfgOut.DataDbCfg().Type,
- usrCfgOut.DataDbCfg().Host, usrCfgOut.DataDbCfg().Port,
- usrCfgOut.DataDbCfg().Name, usrCfgOut.DataDbCfg().User,
- usrCfgOut.DataDbCfg().Password, usrCfgOut.GeneralCfg().DBDataEncoding,
- config.CgrConfig().CacheCfg(), usrCfgOut.DataDbCfg().Opts)
- if err != nil {
- log.Fatal(err)
- }
- usrMigrator, err = NewMigrator(dataDBIn, dataDBOut,
- nil, nil, false, false, false, false)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func testUsrITFlush(t *testing.T) {
- usrMigrator.dmOut.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(usrMigrator.dmOut.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
- usrMigrator.dmIN.DataManager().DataDB().Flush("")
- if err := engine.SetDBVersions(usrMigrator.dmIN.DataManager().DataDB()); err != nil {
- t.Error("Error ", err.Error())
- }
-}
-
-func testUsrITMigrateAndMove(t *testing.T) {
- user := &v1UserProfile{
- Tenant: "cgrates.com",
- UserName: "1001",
- Masked: false,
- Profile: map[string]string{
- "Account": "1002",
- "ReqType": "*prepaid",
- "msisdn": "123423534646752",
- },
- Weight: 10,
- }
- attrProf := &engine.AttributeProfile{
- Tenant: defaultTenant,
- ID: "1001",
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{"*string:~Account:1002"},
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.RequestType,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*prepaid", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "msisdn",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("123423534646752", utils.InfieldSep),
- },
- {
- Path: utils.MetaTenant,
- Type: utils.MetaConstant,
- Value: config.NewRSRParsersMustCompile("cgrates.com", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- }
- attrProf.Compile()
-
- err := usrMigrator.dmIN.setV1User(user)
- if err != nil {
- t.Error("Error when setting v1 User ", err.Error())
- }
- currentVersion := engine.Versions{utils.User: 1}
- err = usrMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
- if err != nil {
- t.Error("Error when setting version for User ", err.Error())
- }
- //check if version was set correctly
- if vrs, err := usrMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.User] != 1 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.User])
- }
- //migrate user
- err, _ = usrMigrator.Migrate([]string{utils.MetaUsers})
- if err != nil {
- t.Error("Error when migrating User ", err.Error())
- }
- //check if version was updated
- if vrs, err := usrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil {
- t.Error(err)
- } else if vrs[utils.User] != 0 {
- t.Errorf("Unexpected version returned: %d", vrs[utils.User])
- }
- //check if user was migrate correctly
- result, err := usrMigrator.dmOut.DataManager().DataDB().GetAttributeProfileDrv(defaultTenant, user.UserName)
- if err != nil {
- t.Fatalf("Error when getting Attributes %v", err.Error())
- }
- result.Compile()
- sort.Slice(result.Attributes, func(i, j int) bool {
- return result.Attributes[i].Path < result.Attributes[j].Path
- }) // only for test; map returns random keys
- if !reflect.DeepEqual(*attrProf, *result) {
- t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result))
- }
- //check if old account was deleted
- if _, err = usrMigrator.dmIN.getV1User(); err != utils.ErrNoMoreData {
- t.Error("Error should be not found : ", err)
- }
-
- expUsrIdx := map[string]utils.StringSet{
- "*string:Account:1002": {
- "1001": struct{}{},
- },
- }
- if usridx, err := usrMigrator.dmOut.DataManager().GetIndexes(
- utils.CacheAttributeFilterIndexes,
- utils.ConcatenatedKey("cgrates.org", utils.MetaAny),
- "", true, true); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual(expUsrIdx, usridx) {
- t.Errorf("Expected %v, received: %v", utils.ToJSON(expUsrIdx), utils.ToJSON(usridx))
- }
-}
diff --git a/migrator/user_test.go b/migrator/user_test.go
deleted file mode 100644
index 358cf5f29..000000000
--- a/migrator/user_test.go
+++ /dev/null
@@ -1,215 +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 (
- "reflect"
- "sort"
- "testing"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestUserProfile2attributeProfile(t *testing.T) {
- usrCfgIn := config.CgrConfig()
- usrCfgIn.MigratorCgrCfg().UsersFilters = []string{"Account"}
- config.SetCgrConfig(usrCfgIn)
- usrTenant := "cgrates.com"
- users := map[int]*v1UserProfile{
- 0: {
- Tenant: defaultTenant,
- UserName: "1001",
- Masked: true,
- Profile: map[string]string{},
- Weight: 10,
- },
- 1: {
- Tenant: usrTenant,
- UserName: "1001",
- Masked: true,
- Profile: map[string]string{
- "Account": "1002",
- "Subject": "call_1001",
- },
- Weight: 10,
- },
- 2: {
- Tenant: defaultTenant,
- UserName: "1001",
- Masked: false,
- Profile: map[string]string{
- "Account": "1002",
- "ReqType": "*prepaid",
- "msisdn": "123423534646752",
- },
- Weight: 10,
- },
- 3: {
- Tenant: usrTenant,
- UserName: "1001",
- Masked: false,
- Profile: map[string]string{
- "Account": "1002",
- "ReqType": "*prepaid",
- },
- Weight: 10,
- },
- 4: {
- Tenant: usrTenant,
- UserName: "acstmusername",
- Profile: map[string]string{
- "Account": "acnt63",
- "Subject": "acnt63",
- "ReqType": "*prepaid",
- "msisdn": "12345",
- "imsi": "12345",
- },
- Weight: 10,
- },
- }
- expected := map[int]*engine.AttributeProfile{
- 0: {
- Tenant: defaultTenant,
- ID: "1001",
- Contexts: []string{utils.MetaAny},
- FilterIDs: make([]string, 0),
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{},
- Blocker: false,
- Weight: 10,
- },
- 1: {
- Tenant: defaultTenant,
- ID: "1001",
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{"*string:~Account:1002"},
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + "Subject",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("call_1001", utils.InfieldSep),
- },
- {
- Path: utils.MetaTenant,
- Type: utils.MetaConstant,
- Value: config.NewRSRParsersMustCompile(usrTenant, utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- 2: {
- Tenant: defaultTenant,
- ID: "1001",
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~Account:1002",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.RequestType,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*prepaid", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "msisdn",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("123423534646752", utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- 3: {
- Tenant: defaultTenant,
- ID: "1001",
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{"*string:~Account:1002"},
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.RequestType,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*prepaid", utils.InfieldSep),
- },
- {
- Path: utils.MetaTenant,
- Type: utils.MetaConstant,
- Value: config.NewRSRParsersMustCompile(usrTenant, utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- 4: {
- Tenant: defaultTenant,
- ID: "acstmusername",
- Contexts: []string{utils.MetaAny},
- FilterIDs: []string{
- "*string:~Account:acnt63",
- },
- ActivationInterval: nil,
- Attributes: []*engine.Attribute{
- {
- Path: utils.MetaReq + utils.NestingSep + utils.RequestType,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("*prepaid", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + utils.Subject,
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("acnt63", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "imsi",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("12345", utils.InfieldSep),
- },
- {
- Path: utils.MetaReq + utils.NestingSep + "msisdn",
- Type: utils.MetaVariable,
- Value: config.NewRSRParsersMustCompile("12345", utils.InfieldSep),
- },
- {
- Path: utils.MetaTenant,
- Type: utils.MetaConstant,
- Value: config.NewRSRParsersMustCompile(usrTenant, utils.InfieldSep),
- },
- },
- Blocker: false,
- Weight: 10,
- },
- }
- for i := range expected {
- rply := userProfile2attributeProfile(users[i])
- sort.Slice(rply.Attributes, func(i, j int) bool {
- if rply.Attributes[i].Path == rply.Attributes[j].Path {
- return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0]
- }
- return rply.Attributes[i].Path < rply.Attributes[j].Path
- }) // only for test; map returns random keys
- if !reflect.DeepEqual(expected[i], rply) {
- t.Errorf("For %v expected: %s ,\nreceived: %s ", i, utils.ToJSON(expected[i]), utils.ToJSON(rply))
- }
- }
-}
diff --git a/services/datadb.go b/services/datadb.go
index 922ef7800..4d2b8a3b9 100644
--- a/services/datadb.go
+++ b/services/datadb.go
@@ -137,7 +137,7 @@ func (db *DataDBService) ShouldRun() bool {
// mandatoryDB returns if the current configuration needs the DB
func (db *DataDBService) mandatoryDB() bool {
- return db.cfg.RalsCfg().Enabled || db.cfg.SchedulerCfg().Enabled || db.cfg.ChargerSCfg().Enabled ||
+ return db.cfg.RalsCfg().Enabled || db.cfg.ChargerSCfg().Enabled ||
db.cfg.AttributeSCfg().Enabled || db.cfg.ResourceSCfg().Enabled || db.cfg.StatSCfg().Enabled ||
db.cfg.ThresholdSCfg().Enabled || db.cfg.RouteSCfg().Enabled || db.cfg.DispatcherSCfg().Enabled ||
db.cfg.LoaderCfg().Enabled() || db.cfg.ApierCfg().Enabled || db.cfg.RateSCfg().Enabled ||
diff --git a/services/dispatchers.go b/services/dispatchers.go
index ede861874..4a3707e89 100644
--- a/services/dispatchers.go
+++ b/services/dispatchers.go
@@ -115,18 +115,12 @@ func (dspS *DispatcherService) Start() (err error) {
dspS.server.RpcRegisterName(utils.ChargerSv1,
v1.NewDispatcherChargerSv1(dspS.dspS))
- dspS.server.RpcRegisterName(utils.Responder,
- v1.NewDispatcherResponder(dspS.dspS))
-
dspS.server.RpcRegisterName(utils.CacheSv1,
v1.NewDispatcherCacheSv1(dspS.dspS))
dspS.server.RpcRegisterName(utils.GuardianSv1,
v1.NewDispatcherGuardianSv1(dspS.dspS))
- dspS.server.RpcRegisterName(utils.SchedulerSv1,
- v1.NewDispatcherSchedulerSv1(dspS.dspS))
-
dspS.server.RpcRegisterName(utils.CDRsV1,
v1.NewDispatcherSCDRsV1(dspS.dspS))
@@ -136,9 +130,6 @@ func (dspS *DispatcherService) Start() (err error) {
dspS.server.RpcRegisterName(utils.CoreSv1,
v1.NewDispatcherCoreSv1(dspS.dspS))
- dspS.server.RpcRegisterName(utils.RALsV1,
- v1.NewDispatcherRALsV1(dspS.dspS))
-
dspS.server.RpcRegisterName(utils.ReplicatorSv1,
v1.NewDispatcherReplicatorSv1(dspS.dspS))
diff --git a/services/globalvars.go b/services/globalvars.go
index c8eca06e9..875397179 100644
--- a/services/globalvars.go
+++ b/services/globalvars.go
@@ -47,7 +47,6 @@ type GlobalVarS struct {
// Start should handle the sercive start
func (gv *GlobalVarS) Start() (err error) {
- engine.SetRoundingDecimals(gv.cfg.GeneralCfg().RoundingDecimals)
engine.SetFailedPostCacheTTL(gv.cfg.GeneralCfg().FailedPostsTTL)
return gv.initHTTPTransport()
}
diff --git a/services/responders.go b/services/responders.go
deleted file mode 100644
index 700307d7c..000000000
--- a/services/responders.go
+++ /dev/null
@@ -1,161 +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 (
- "sync"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/cores"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
- "github.com/cgrates/rpcclient"
-)
-
-// NewResponderService returns the Resonder Service
-func NewResponderService(cfg *config.CGRConfig, server *cores.Server,
- internalRALsChan chan rpcclient.ClientConnector,
- shdChan *utils.SyncedChan, anz *AnalyzerService,
- srvDep map[string]*sync.WaitGroup) *ResponderService {
- return &ResponderService{
- connChan: internalRALsChan,
- cfg: cfg,
- server: server,
- shdChan: shdChan,
- anz: anz,
- srvDep: srvDep,
- syncChans: make(map[string]chan *engine.Responder),
- }
-}
-
-// ResponderService implements Service interface
-// this service is manged by the RALs as a component
-type ResponderService struct {
- sync.RWMutex
- cfg *config.CGRConfig
- server *cores.Server
- shdChan *utils.SyncedChan
-
- resp *engine.Responder
- connChan chan rpcclient.ClientConnector
- anz *AnalyzerService
- srvDep map[string]*sync.WaitGroup
- syncChans map[string]chan *engine.Responder
-}
-
-// Start should handle the sercive start
-// For this service the start should be called from RAL Service
-func (resp *ResponderService) Start() (err error) {
- if resp.IsRunning() {
- return utils.ErrServiceAlreadyRunning
- }
-
- resp.Lock()
- defer resp.Unlock()
- resp.resp = &engine.Responder{
- ShdChan: resp.shdChan,
- MaxComputedUsage: resp.cfg.RalsCfg().MaxComputedUsage,
- }
-
- if !resp.cfg.DispatcherSCfg().Enabled {
- resp.server.RpcRegister(resp.resp)
- }
-
- resp.connChan <- resp.anz.GetInternalCodec(resp.resp, utils.ResponderS) // Rater done
- resp.sync()
- return
-}
-
-// Reload handles the change of config
-func (resp *ResponderService) Reload() (err error) {
- resp.Lock()
- resp.resp.SetMaxComputedUsage(resp.cfg.RalsCfg().MaxComputedUsage)
- resp.Unlock()
- return
-}
-
-// Shutdown stops the service
-func (resp *ResponderService) Shutdown() (err error) {
- resp.Lock()
- resp.resp = nil
- <-resp.connChan
- for _, c := range resp.syncChans {
- c <- nil // just tell the services that responder is nil
- }
- resp.Unlock()
- return
-}
-
-// IsRunning returns if the service is running
-func (resp *ResponderService) IsRunning() bool {
- resp.RLock()
- defer resp.RUnlock()
- return resp.isRunning()
-}
-
-func (resp *ResponderService) isRunning() bool {
- return resp != nil && resp.resp != nil
-}
-
-// ServiceName returns the service name
-func (resp *ResponderService) ServiceName() string {
- return utils.ResponderS
-}
-
-// GetResponder returns the responder created
-func (resp *ResponderService) GetResponder() *engine.Responder {
- resp.RLock()
- defer resp.RUnlock()
- return resp.resp
-}
-
-// ShouldRun returns if the service should be running
-func (resp *ResponderService) ShouldRun() bool {
- return resp.cfg.RalsCfg().Enabled
-}
-
-// RegisterSyncChan used by dependent subsystems to register a channel to reload only the responder(thread safe)
-func (resp *ResponderService) RegisterSyncChan(srv string, c chan *engine.Responder) {
- resp.Lock()
- resp.syncChans[srv] = c
- if resp.isRunning() {
- c <- resp.resp
- }
- resp.Unlock()
-}
-
-// UnregisterSyncChan used by dependent subsystems to unregister a channel
-func (resp *ResponderService) UnregisterSyncChan(srv string) {
- resp.Lock()
- c, has := resp.syncChans[srv]
- if has {
- close(c)
- delete(resp.syncChans, srv)
- }
- resp.Unlock()
-}
-
-// sync sends the responder over syncChansv (not thread safe)
-func (resp *ResponderService) sync() {
- if resp.isRunning() {
- for _, c := range resp.syncChans {
- c <- resp.resp
- }
- }
-}
diff --git a/services/responders_it_test.go b/services/responders_it_test.go
deleted file mode 100644
index be959ceac..000000000
--- a/services/responders_it_test.go
+++ /dev/null
@@ -1,144 +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 (
- "sync"
- "testing"
-
- "github.com/cgrates/rpcclient"
-
- "github.com/cgrates/cgrates/config"
- "github.com/cgrates/cgrates/cores"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
-)
-
-func TestResponderSReload(t *testing.T) {
- // utils.Logger.SetLogLevel(7)
- cfg := config.NewDefaultCGRConfig()
-
- utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID)
- utils.Logger.SetLogLevel(7)
- cfg.ThresholdSCfg().Enabled = true
- filterSChan := make(chan *engine.FilterS, 1)
- filterSChan <- nil
- shdChan := utils.NewSyncedChan()
- server := cores.NewServer(nil)
- srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)}
- anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep)
- internalChan := make(chan rpcclient.ClientConnector, 1)
- srv := NewResponderService(cfg, server, internalChan,
- shdChan, anz, srvDep)
-
- srvName := srv.ServiceName()
- if srvName != utils.ResponderS {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ResponderS, srvName)
- }
-
- if srv.IsRunning() {
- t.Errorf("Expected service to be down")
- }
-
- err := srv.Start()
- if err != nil {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err)
- }
-
- if !srv.IsRunning() {
- t.Errorf("Expected service to be running")
- }
-
- err = srv.Start()
- if err != utils.ErrServiceAlreadyRunning {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrServiceAlreadyRunning, err)
- }
-
- err = srv.Reload()
- if err != nil {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err)
- }
- srv.syncChans = map[string]chan *engine.Responder{
- "srv": make(chan *engine.Responder, 1),
- }
- err = srv.Shutdown()
- if err != nil {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err)
- }
-
- if srv.IsRunning() {
- t.Errorf("Expected service to be down")
- }
-
-}
-func TestResponderSReload2(t *testing.T) {
- // utils.Logger.SetLogLevel(7)
- cfg := config.NewDefaultCGRConfig()
-
- utils.Logger, _ = utils.Newlogger(utils.MetaSysLog, cfg.GeneralCfg().NodeID)
- utils.Logger.SetLogLevel(7)
- cfg.ThresholdSCfg().Enabled = true
- filterSChan := make(chan *engine.FilterS, 1)
- filterSChan <- nil
- shdChan := utils.NewSyncedChan()
- server := cores.NewServer(nil)
- srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)}
- anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep)
- internalChan := make(chan rpcclient.ClientConnector, 1)
- srv := NewResponderService(cfg, server, internalChan,
- shdChan, anz, srvDep)
-
- srvName := srv.ServiceName()
- if srvName != utils.ResponderS {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ResponderS, srvName)
- }
-
- if srv.IsRunning() {
- t.Errorf("Expected service to be down")
- }
-
- err := srv.Start()
- if err != nil {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err)
- }
-
- if !srv.IsRunning() {
- t.Errorf("Expected service to be running")
- }
-
- err = srv.Start()
- if err != utils.ErrServiceAlreadyRunning {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrServiceAlreadyRunning, err)
- }
-
- srv.syncChans = map[string]chan *engine.Responder{
- "srv": make(chan *engine.Responder, 1),
- }
- srv.resp = &engine.Responder{
- ShdChan: shdChan,
- Timeout: 1,
- Timezone: "",
- MaxComputedUsage: nil,
- }
- srv.sync()
- srv.RegisterSyncChan("srv", make(chan *engine.Responder, 1))
- srv.resp = nil
-
-}
diff --git a/services/responders_test.go b/services/responders_test.go
deleted file mode 100644
index a376bd8c1..000000000
--- a/services/responders_test.go
+++ /dev/null
@@ -1,71 +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/config"
- "github.com/cgrates/cgrates/cores"
- "github.com/cgrates/cgrates/engine"
- "github.com/cgrates/cgrates/utils"
- "github.com/cgrates/rpcclient"
-)
-
-//TestResponderCoverage for cover testing
-func TestResponderCoverage(t *testing.T) {
- cfg := config.NewDefaultCGRConfig()
- server := cores.NewServer(nil)
- internalChan := make(chan rpcclient.ClientConnector, 1)
- shdChan := utils.NewSyncedChan()
- filterSChan := make(chan *engine.FilterS, 1)
- filterSChan <- nil
- srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)}
- anz := NewAnalyzerService(cfg, server, filterSChan,
- shdChan, make(chan rpcclient.ClientConnector, 1), srvDep)
- srv := NewResponderService(cfg, server, internalChan,
- shdChan, anz, srvDep)
- if srv == nil {
- t.Errorf("\nExpecting ,\n Received <%+v>", utils.ToJSON(srv))
- }
- if srv.IsRunning() {
- t.Errorf("Expected service to be down")
- }
- srv.resp = &engine.Responder{}
- if !srv.IsRunning() {
- t.Errorf("Expected service to be running")
- }
- err := srv.Start()
- if err != utils.ErrServiceAlreadyRunning {
- t.Errorf("\nExpected <%+v>, \nReceived <%+v>", utils.ErrServiceAlreadyRunning, err)
- }
- serviceName := srv.ServiceName()
- if !reflect.DeepEqual(serviceName, utils.ResponderS) {
- t.Errorf("\nExpecting <%+v>,\n Received <%+v>", utils.ResponderS, serviceName)
- }
- getResponder := srv.GetResponder()
- if !reflect.DeepEqual(getResponder, srv.resp) {
- t.Errorf("\nExpecting <%+v>,\n Received <%+v>", srv.resp, getResponder)
- }
- shouldRun := srv.ShouldRun()
- if !reflect.DeepEqual(shouldRun, false) {
- t.Errorf("\nExpecting <%+v>,\n Received <%+v>", false, shouldRun)
- }
-}
diff --git a/servmanager/servmanager.go b/servmanager/servmanager.go
index 3a33e1782..b25ba5771 100644
--- a/servmanager/servmanager.go
+++ b/servmanager/servmanager.go
@@ -19,7 +19,6 @@ along with this program. If not, see
package servmanager
import (
- "errors"
"fmt"
"reflect"
"strings"
@@ -81,68 +80,6 @@ func (srvMngr *ServiceManager) Call(serviceMethod string, args interface{}, repl
return err
}
-// ArgStartService are passed to Start/StopService/Status RPC methods
-type ArgStartService struct {
- ServiceID string
-}
-
-// V1StartService starts a service with ID
-func (srvMngr *ServiceManager) V1StartService(args ArgStartService, reply *string) (err error) {
- switch args.ServiceID {
- case utils.MetaScheduler:
- // stop the service using the config
- srvMngr.Lock()
- srvMngr.cfg.ActionSCfg().Enabled = true
- srvMngr.Unlock()
- srvMngr.cfg.GetReloadChan(config.ActionSJson) <- struct{}{}
- default:
- err = errors.New(utils.UnsupportedServiceIDCaps)
- }
- if err != nil {
- return err
- }
- *reply = utils.OK
- return
-}
-
-// V1StopService shuts-down a service with ID
-func (srvMngr *ServiceManager) V1StopService(args ArgStartService, reply *string) (err error) {
- switch args.ServiceID {
- case utils.MetaScheduler:
- // stop the service using the config
- srvMngr.Lock()
- srvMngr.cfg.ActionSCfg().Enabled = false
- srvMngr.Unlock()
- srvMngr.cfg.GetReloadChan(config.ActionSJson) <- struct{}{}
- default:
- err = errors.New(utils.UnsupportedServiceIDCaps)
- }
- if err != nil {
- return err
- }
- *reply = utils.OK
- return
-}
-
-// V1ServiceStatus returns the service status
-func (srvMngr *ServiceManager) V1ServiceStatus(args ArgStartService, reply *string) error {
- srvMngr.RLock()
- defer srvMngr.RUnlock()
- var running bool
- switch args.ServiceID {
- case utils.MetaScheduler:
- running = srvMngr.subsystems[utils.SchedulerS].IsRunning()
- default:
- return errors.New(utils.UnsupportedServiceIDCaps)
- }
- if running {
- *reply = utils.RunningCaps
- } else {
- *reply = utils.StoppedCaps
- }
- return nil
-}
-
// GetConfig returns the Configuration
func (srvMngr *ServiceManager) GetConfig() *config.CGRConfig {
srvMngr.RLock()
diff --git a/sessions/session.go b/sessions/session.go
index dc81a8217..37134d1bc 100644
--- a/sessions/session.go
+++ b/sessions/session.go
@@ -160,13 +160,6 @@ func (s *Session) AsExternalSessions(tmz, nodeID string) (aSs []*ExternalSession
if sr.NextAutoDebit != nil {
aSs[i].NextAutoDebit = *sr.NextAutoDebit
}
- if sr.CD != nil {
- aSs[i].LoopIndex = sr.CD.LoopIndex
- aSs[i].DurationIndex = sr.CD.DurationIndex
- aSs[i].MaxRate = sr.CD.MaxRate
- aSs[i].MaxRateUnit = sr.CD.MaxRateUnit
- aSs[i].MaxCostSoFar = sr.CD.MaxCostSoFar
- }
}
s.RUnlock()
return
@@ -197,13 +190,7 @@ func (s *Session) AsExternalSession(sr *SRun, tmz, nodeID string) (aS *ExternalS
if sr.NextAutoDebit != nil {
aS.NextAutoDebit = *sr.NextAutoDebit
}
- if sr.CD != nil {
- aS.LoopIndex = sr.CD.LoopIndex
- aS.DurationIndex = sr.CD.DurationIndex
- aS.MaxRate = sr.CD.MaxRate
- aS.MaxRateUnit = sr.CD.MaxRateUnit
- aS.MaxCostSoFar = sr.CD.MaxCostSoFar
- }
+
return
}
@@ -256,9 +243,7 @@ func (s *Session) stopDebitLoops() {
// SRun is one billing run for the Session
type SRun struct {
- Event engine.MapEvent // Event received from ChargerS
- CD *engine.CallDescriptor // initial CD used for debits, updated on each debit
- EventCost *engine.EventCost
+ Event engine.MapEvent // Event received from ChargerS
ExtraDuration time.Duration // keeps the current duration debited on top of what has been asked
LastUsage time.Duration // last requested Duration
@@ -274,12 +259,6 @@ func (sr *SRun) Clone() (clsr *SRun) {
LastUsage: sr.LastUsage,
TotalUsage: sr.TotalUsage,
}
- if sr.CD != nil {
- clsr.CD = sr.CD.Clone()
- }
- if sr.EventCost != nil {
- clsr.EventCost = sr.EventCost.Clone()
- }
if sr.NextAutoDebit != nil {
clsr.NextAutoDebit = utils.TimePointer(*sr.NextAutoDebit)
}
diff --git a/sessions/sessions.go b/sessions/sessions.go
index 6e807ae0c..7cc18954a 100644
--- a/sessions/sessions.go
+++ b/sessions/sessions.go
@@ -427,108 +427,11 @@ func (sS *SessionS) forceSTerminate(s *Session, extraUsage time.Duration, tUsage
// debitSession performs debit for a session run
func (sS *SessionS) debitSession(s *Session, sRunIdx int, dur time.Duration,
lastUsed *time.Duration) (maxDur time.Duration, err error) {
- if sRunIdx >= len(s.SRuns) {
- err = errors.New("sRunIdx out of range")
- return
- }
- sr := s.SRuns[sRunIdx]
- if !s.chargeable {
- sS.pause(sr, dur)
- sr.TotalUsage += sr.LastUsage
- return dur, nil
- }
- rDur := sr.debitReserve(dur, lastUsed) // debit out of reserve, rDur is still to be debited
- if rDur == time.Duration(0) {
- return dur, nil // complete debit out of reserve
- }
- dbtRsrv := dur - rDur // the amount debited from reserve
- if sr.CD.LoopIndex > 0 {
- sr.CD.TimeStart = sr.CD.TimeEnd
- }
- sr.CD.TimeEnd = sr.CD.TimeStart.Add(rDur)
- sr.CD.DurationIndex += rDur
- cd := sr.CD.Clone()
- cc := new(engine.CallCost)
- err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderMaxDebit,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: s.OptsStart,
- }, cc)
- if err != nil {
- // verify in case of *dynaprepaid RequestType
- if err.Error() == utils.ErrAccountNotFound.Error() &&
- sr.Event.GetStringIgnoreErrors(utils.RequestType) == utils.MetaDynaprepaid {
- var reply string
- // execute the actionPlan configured in RalS
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().SchedulerConns, nil,
- utils.SchedulerSv1ExecuteActionPlans, &utils.AttrsExecuteActionPlans{
- ActionPlanIDs: sS.cgrCfg.RalsCfg().DynaprepaidActionPlans,
- Tenant: cd.Tenant, AccountID: cd.Account},
- &reply); err != nil {
- return
- }
- // execute again the MaxDebit operation
- err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderMaxDebit,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: s.OptsStart,
- }, cc)
- }
- if err != nil {
- sr.ExtraDuration += dbtRsrv
- return 0, err
- }
- }
- sr.CD.TimeEnd = cc.GetEndTime() // set debited timeEnd
- ccDuration := cc.GetDuration()
- if ccDuration > rDur {
- sr.ExtraDuration = ccDuration - rDur
- }
- if ccDuration >= rDur {
- sr.LastUsage = dur
- } else {
- sr.LastUsage = ccDuration + dbtRsrv
- }
- sr.CD.DurationIndex -= rDur
- sr.CD.DurationIndex += ccDuration
- sr.CD.MaxCostSoFar += cc.Cost
- sr.CD.LoopIndex++
- sr.TotalUsage += sr.LastUsage
- ec := engine.NewEventCostFromCallCost(cc, s.CGRID,
- sr.Event.GetStringIgnoreErrors(utils.RunID))
- if sr.EventCost == nil {
- if ccDuration != time.Duration(0) {
- sr.EventCost = ec
- }
- } else {
- ec.SyncKeys(sr.EventCost)
- sr.EventCost.Merge(ec)
- }
- maxDur = sr.LastUsage
+
return
}
func (sS *SessionS) pause(sr *SRun, dur time.Duration) {
- if sr.CD.LoopIndex > 0 {
- sr.CD.TimeStart = sr.CD.TimeEnd
- }
- sr.CD.TimeEnd = sr.CD.TimeStart.Add(dur)
- sr.CD.DurationIndex += dur
- ec := engine.NewFreeEventCost(sr.CD.CgrID, sr.CD.RunID, sr.CD.Account, sr.CD.TimeStart, dur)
- sr.LastUsage = dur
- sr.CD.LoopIndex++
- if sr.EventCost == nil { // is the first increment
- // when we start the call with debit interval 0
- // but later we update this value with one greater than 0
- sr.EventCost = ec
- } else { // we already debited something
- // copy the old AccountSummary as in Merge the old one is overwriten by the new one
- ec.AccountSummary = sr.EventCost.AccountSummary
- // similar to the debit merge the event costs
- sr.EventCost.Merge(ec)
- }
}
// debitLoopSession will periodically debit sessions, ie: automatic prepaid
@@ -621,118 +524,13 @@ func (sS *SessionS) debitLoopSession(s *Session, sRunIdx int,
// not thread-safe so the locks need to be done in a layer above
// rUsage represents the amount of usage to be refunded
func (sS *SessionS) refundSession(s *Session, sRunIdx int, rUsage time.Duration) (err error) {
- if sRunIdx >= len(s.SRuns) {
- return errors.New("sRunIdx out of range")
- }
- sr := s.SRuns[sRunIdx]
- if sr.EventCost == nil {
- return errors.New("no event cost")
- }
- srplsEC, err := sr.EventCost.Trim(sr.EventCost.GetUsage() - rUsage)
- if err != nil {
- return err
- } else if srplsEC == nil {
- return
- }
- sCC := srplsEC.AsCallCost(sr.CD.ToR)
- var incrmts engine.Increments
- for _, tmspn := range sCC.Timespans {
- for _, incr := range tmspn.Increments {
- if incr.BalanceInfo == nil ||
- (incr.BalanceInfo.Unit == nil &&
- incr.BalanceInfo.Monetary == nil) {
- continue // not enough information for refunds, most probably free units uncounted
- }
- for i := 0; i < tmspn.CompressFactor; i++ {
- incrmts = append(incrmts, incr)
- }
- }
- }
- cd := &engine.CallDescriptor{
- CgrID: s.CGRID,
- RunID: sr.Event.GetStringIgnoreErrors(utils.RunID),
- Category: sr.CD.Category,
- Tenant: sr.CD.Tenant,
- Subject: sr.CD.Subject,
- Account: sr.CD.Account,
- Destination: sr.CD.Destination,
- ToR: utils.FirstNonEmpty(sr.CD.ToR, utils.MetaVoice),
- Increments: incrmts,
- }
- var acnt engine.Account
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil, utils.ResponderRefundIncrements,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: s.OptsStart,
- }, &acnt); err != nil {
- return
- }
- if acnt.ID != "" { // Account info updated, update also cached AccountSummary
- acntSummary := acnt.AsAccountSummary()
- acntSummary.UpdateInitialValue(sr.EventCost.AccountSummary)
- sr.EventCost.AccountSummary = acntSummary
- }
return
}
// storeSCost will post the session cost to CDRs
// not thread safe, need to be handled in a layer above
func (sS *SessionS) storeSCost(s *Session, sRunIdx int) (err error) {
- sr := s.SRuns[sRunIdx]
- smCost := &engine.SMCost{
- CGRID: s.CGRID,
- CostSource: utils.MetaSessionS,
- RunID: sr.Event.GetStringIgnoreErrors(utils.RunID),
- OriginHost: s.EventStart.GetStringIgnoreErrors(utils.OriginHost),
- OriginID: s.EventStart.GetStringIgnoreErrors(utils.OriginID),
- Usage: sr.TotalUsage,
- CostDetails: sr.EventCost,
- }
- argSmCost := &engine.AttrCDRSStoreSMCost{
- Cost: smCost,
- CheckDuplicate: true,
- APIOpts: s.OptsStart,
- Tenant: s.Tenant,
- }
- var reply string
- // use the v1 because it doesn't do rounding refund
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().CDRsConns, nil, utils.CDRsV1StoreSessionCost,
- argSmCost, &reply); err != nil && err == utils.ErrExists {
- utils.Logger.Warning(
- fmt.Sprintf("<%s> refunding session: <%s> error: <%s>",
- utils.SessionS, s.CGRID, err.Error()))
- if err = sS.refundSession(s, sRunIdx, sr.CD.GetDuration()); err != nil { // refund entire duration
- utils.Logger.Warning(
- fmt.Sprintf(
- "<%s> failed refunding session: <%s>, srIdx: <%d>, error: <%s>",
- utils.SessionS, s.CGRID, sRunIdx, err.Error()))
- }
- }
- return
-}
-// roundCost will round the EventCost and will refund the extra debited increments
-// should be called only at the endSession
-// not thread safe, need to be handled in a layer above
-func (sS *SessionS) roundCost(s *Session, sRunIdx int) (err error) {
- sr := s.SRuns[sRunIdx]
- runID := sr.Event.GetStringIgnoreErrors(utils.RunID)
- cc := sr.EventCost.AsCallCost(utils.EmptyString)
- cc.Round()
- if roundIncrements := cc.GetRoundIncrements(); len(roundIncrements) != 0 {
- cd := cc.CreateCallDescriptor()
- cd.CgrID = s.CGRID
- cd.RunID = runID
- cd.Increments = roundIncrements
- var response float64
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderRefundRounding,
- &engine.CallDescriptorWithAPIOpts{CallDescriptor: cd},
- &response); err != nil {
- return
- }
- }
- sr.EventCost = engine.NewEventCostFromCallCost(cc, s.CGRID, runID)
return
}
@@ -890,7 +688,7 @@ func (sS *SessionS) indexSession(s *Session, pSessions bool) {
if _, hasCGRID := ssIndx[fieldName][fieldVal][s.CGRID]; !hasCGRID {
ssIndx[fieldName][fieldVal][s.CGRID] = make(utils.StringSet)
}
- ssIndx[fieldName][fieldVal][s.CGRID].Add(sr.CD.RunID)
+ // ssIndx[fieldName][fieldVal][s.CGRID].Add(sr.CD.RunID)
// reverse index
if _, hasIt := ssRIdx[s.CGRID]; !hasIt {
@@ -1043,7 +841,7 @@ func (sS *SessionS) filterSessions(sf *utils.SessionFilter, psv bool) (aSs []*Ex
}
tenant := utils.FirstNonEmpty(sf.Tenant, sS.cgrCfg.GeneralCfg().DefaultTenant)
indx, unindx := sS.getIndexedFilters(tenant, sf.Filters)
- cgrIDs, matchingSRuns := sS.getSessionIDsMatchingIndexes(indx, psv)
+ cgrIDs, _ /*matchingSRuns*/ := sS.getSessionIDsMatchingIndexes(indx, psv)
if len(indx) != 0 && len(cgrIDs) == 0 { // no sessions matched the indexed filters
return
}
@@ -1067,11 +865,11 @@ func (sS *SessionS) filterSessions(sf *utils.SessionFilter, psv bool) (aSs []*Ex
}
for _, s := range ss {
s.RLock()
- runIDs := matchingSRuns[s.CGRID]
+ // runIDs := matchingSRuns[s.CGRID]
for _, sr := range s.SRuns {
- if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
- continue
- }
+ // if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
+ // continue
+ // }
if pass(unindx, sr.Event) {
aSs = append(aSs,
s.AsExternalSession(sr, sS.cgrCfg.GeneralCfg().DefaultTimezone,
@@ -1099,7 +897,7 @@ func (sS *SessionS) filterSessionsCount(sf *utils.SessionFilter, psv bool) (coun
}
tenant := utils.FirstNonEmpty(sf.Tenant, sS.cgrCfg.GeneralCfg().DefaultTenant)
indx, unindx := sS.getIndexedFilters(tenant, sf.Filters)
- cgrIDs, matchingSRuns := sS.getSessionIDsMatchingIndexes(indx, psv)
+ cgrIDs, _ /* matchingSRuns*/ := sS.getSessionIDsMatchingIndexes(indx, psv)
if len(indx) != 0 && len(cgrIDs) == 0 { // no sessions matched the indexed filters
return
}
@@ -1122,11 +920,11 @@ func (sS *SessionS) filterSessionsCount(sf *utils.SessionFilter, psv bool) (coun
}
for _, s := range ss {
s.RLock()
- runIDs := matchingSRuns[s.CGRID]
+ // runIDs := matchingSRuns[s.CGRID]
for _, sr := range s.SRuns {
- if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
- continue
- }
+ // if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
+ // continue
+ // }
if pass(unindx, sr.Event) {
count++
}
@@ -1187,20 +985,6 @@ func (sS *SessionS) newSession(cgrEv *utils.CGREvent, resID, clntConnID string,
}
s.SRuns[i] = &SRun{
Event: me,
- CD: &engine.CallDescriptor{
- CgrID: s.CGRID,
- RunID: me.GetStringIgnoreErrors(utils.RunID),
- ToR: me.GetStringIgnoreErrors(utils.ToR),
- Tenant: s.Tenant,
- Category: category,
- Subject: subject,
- Account: me.GetStringIgnoreErrors(utils.AccountField),
- Destination: me.GetStringIgnoreErrors(utils.Destination),
- TimeStart: startTime,
- TimeEnd: startTime.Add(s.EventStart.GetDurationIgnoreErrors(utils.Usage)),
- ExtraFields: me.AsMapString(utils.MainCDRFields),
- ForceDuration: forceDuration,
- },
}
}
return
@@ -1439,19 +1223,19 @@ func (sS *SessionS) authEvent(cgrEv *utils.CGREvent, forceDuration bool) (usage
if !authReqs.HasField(
sr.Event.GetStringIgnoreErrors(utils.RequestType)) {
rplyMaxUsage = eventUsage
- } else if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderGetMaxSessionTime,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: sr.CD,
- APIOpts: s.OptsStart,
- }, &rplyMaxUsage); err != nil {
- err = utils.NewErrRALs(err)
- return
+ // } else if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
+ // utils.ResponderGetMaxSessionTime,
+ // &engine.CallDescriptorWithAPIOpts{
+ // CallDescriptor: sr.CD,
+ // APIOpts: s.OptsStart,
+ // }, &rplyMaxUsage); err != nil {
+ // err = utils.NewErrRALs(err)
+ // return
}
if rplyMaxUsage > eventUsage {
rplyMaxUsage = eventUsage
}
- usage[sr.CD.RunID] = rplyMaxUsage
+ // usage[sr.CD.RunID] = rplyMaxUsage
}
return
}
@@ -1505,19 +1289,19 @@ func (sS *SessionS) updateSession(s *Session, updtEv, opts engine.MapEvent, isMs
updtEv[utils.Usage] = reqMaxUsage
}
maxUsage = make(map[string]time.Duration)
- for i, sr := range s.SRuns {
+ for _, sr := range s.SRuns {
reqType := sr.Event.GetStringIgnoreErrors(utils.RequestType)
if reqType == utils.MetaNone {
continue
}
- var rplyMaxUsage time.Duration
- if reqType != utils.MetaPrepaid || s.debitStop != nil {
- rplyMaxUsage = reqMaxUsage
- } else if rplyMaxUsage, err = sS.debitSession(s, i, reqMaxUsage,
- updtEv.GetDurationPtrIgnoreErrors(utils.LastUsed)); err != nil {
- return
- }
- maxUsage[sr.CD.RunID] = rplyMaxUsage
+ // var rplyMaxUsage time.Duration
+ // if reqType != utils.MetaPrepaid || s.debitStop != nil {
+ // rplyMaxUsage = reqMaxUsage
+ // } else if rplyMaxUsage, err = sS.debitSession(s, i, reqMaxUsage,
+ // updtEv.GetDurationPtrIgnoreErrors(utils.LastUsed)); err != nil {
+ // return
+ // }
+ // maxUsage[sr.CD.RunID] = rplyMaxUsage
}
return
}
@@ -1544,68 +1328,68 @@ func (sS *SessionS) endSession(s *Session, tUsage, lastUsage *time.Duration,
s.stopDebitLoops()
}
for sRunIdx, sr := range s.SRuns {
- sUsage := sr.TotalUsage
- if tUsage != nil {
- sUsage = *tUsage
- sr.TotalUsage = *tUsage
- } else if lastUsage != nil &&
- sr.LastUsage != *lastUsage {
- sr.TotalUsage -= sr.LastUsage
- sr.TotalUsage += *lastUsage
- sUsage = sr.TotalUsage
- }
- if sr.EventCost != nil {
- if !isMsg { // in case of one time charge there is no need of corrections
- if notCharged := sUsage - sr.EventCost.GetUsage(); notCharged > 0 { // we did not charge enough, make a manual debit here
- if !s.chargeable {
- sS.pause(sr, notCharged)
- } else {
- if sr.CD.LoopIndex > 0 {
- sr.CD.TimeStart = sr.CD.TimeEnd
- }
- sr.CD.TimeEnd = sr.CD.TimeStart.Add(notCharged)
- sr.CD.DurationIndex += notCharged
- cc := new(engine.CallCost)
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil, utils.ResponderDebit,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: sr.CD,
- APIOpts: s.OptsStart,
- }, cc); err == nil {
- sr.EventCost.Merge(
- engine.NewEventCostFromCallCost(cc, s.CGRID,
- sr.Event.GetStringIgnoreErrors(utils.RunID)))
- }
- }
- } else if notCharged < 0 { // charged too much, try refund
- if err = sS.refundSession(s, sRunIdx, -notCharged); err != nil {
- utils.Logger.Warning(
- fmt.Sprintf(
- "<%s> failed refunding session: <%s>, srIdx: <%d>, error: <%s>",
- utils.SessionS, s.CGRID, sRunIdx, err.Error()))
- }
- }
- if err := sS.roundCost(s, sRunIdx); err != nil { // will round the cost and refund the extra increment
- utils.Logger.Warning(
- fmt.Sprintf("<%s> failed rounding session cost for <%s>, srIdx: <%d>, error: <%s>",
- utils.SessionS, s.CGRID, sRunIdx, err.Error()))
- }
- }
- // compute the event cost before saving the SessionCost
- // add here to be applied for messages also
- sr.EventCost.Compute()
- if sS.cgrCfg.SessionSCfg().StoreSCosts {
- if err := sS.storeSCost(s, sRunIdx); err != nil {
- utils.Logger.Warning(
- fmt.Sprintf("<%s> failed storing session cost for <%s>, srIdx: <%d>, error: <%s>",
- utils.SessionS, s.CGRID, sRunIdx, err.Error()))
- }
- }
+ // sUsage := sr.TotalUsage
+ // if tUsage != nil {
+ // sUsage = *tUsage
+ // sr.TotalUsage = *tUsage
+ // } else if lastUsage != nil &&
+ // sr.LastUsage != *lastUsage {
+ // sr.TotalUsage -= sr.LastUsage
+ // sr.TotalUsage += *lastUsage
+ // sUsage = sr.TotalUsage
+ // }
+ // if sr.EventCost != nil {
+ // if !isMsg { // in case of one time charge there is no need of corrections
+ // if notCharged := sUsage - sr.EventCost.GetUsage(); notCharged > 0 { // we did not charge enough, make a manual debit here
+ // if !s.chargeable {
+ // sS.pause(sr, notCharged)
+ // } else {
+ // if sr.CD.LoopIndex > 0 {
+ // sr.CD.TimeStart = sr.CD.TimeEnd
+ // }
+ // sr.CD.TimeEnd = sr.CD.TimeStart.Add(notCharged)
+ // sr.CD.DurationIndex += notCharged
+ // cc := new(engine.CallCost)
+ // if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil, utils.ResponderDebit,
+ // &engine.CallDescriptorWithAPIOpts{
+ // CallDescriptor: sr.CD,
+ // APIOpts: s.OptsStart,
+ // }, cc); err == nil {
+ // sr.EventCost.Merge(
+ // engine.NewEventCostFromCallCost(cc, s.CGRID,
+ // sr.Event.GetStringIgnoreErrors(utils.RunID)))
+ // }
+ // }
+ // } else if notCharged < 0 { // charged too much, try refund
+ // if err = sS.refundSession(s, sRunIdx, -notCharged); err != nil {
+ // utils.Logger.Warning(
+ // fmt.Sprintf(
+ // "<%s> failed refunding session: <%s>, srIdx: <%d>, error: <%s>",
+ // utils.SessionS, s.CGRID, sRunIdx, err.Error()))
+ // }
+ // }
+ // if err := sS.roundCost(s, sRunIdx); err != nil { // will round the cost and refund the extra increment
+ // utils.Logger.Warning(
+ // fmt.Sprintf("<%s> failed rounding session cost for <%s>, srIdx: <%d>, error: <%s>",
+ // utils.SessionS, s.CGRID, sRunIdx, err.Error()))
+ // }
+ // }
+ // // compute the event cost before saving the SessionCost
+ // // add here to be applied for messages also
+ // sr.EventCost.Compute()
+ // if sS.cgrCfg.SessionSCfg().StoreSCosts {
+ // if err := sS.storeSCost(s, sRunIdx); err != nil {
+ // utils.Logger.Warning(
+ // fmt.Sprintf("<%s> failed storing session cost for <%s>, srIdx: <%d>, error: <%s>",
+ // utils.SessionS, s.CGRID, sRunIdx, err.Error()))
+ // }
+ // }
- // set cost fields
- sr.Event[utils.Cost] = sr.EventCost.GetCost()
- sr.Event[utils.CostDetails] = utils.ToJSON(sr.EventCost) // avoid map[string]interface{} when decoding
- sr.Event[utils.CostSource] = utils.MetaSessionS
- }
+ // // set cost fields
+ // sr.Event[utils.Cost] = sr.EventCost.GetCost()
+ // sr.Event[utils.CostDetails] = utils.ToJSON(sr.EventCost) // avoid map[string]interface{} when decoding
+ // sr.Event[utils.CostSource] = utils.MetaSessionS
+ // }
// Set Usage field
if sRunIdx == 0 {
s.EventStart[utils.Usage] = sr.TotalUsage
@@ -3338,144 +3122,144 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
}
// check what we need to do for RALs (*authorize/*initiate/*update/*terminate)
- dbtItvl := sS.cgrCfg.SessionSCfg().DebitInterval
- if argsFlagsWithParams.GetBool(utils.MetaRALs) {
- if ralsOpts := argsFlagsWithParams[utils.MetaRALs]; len(ralsOpts) != 0 {
- //check for subflags and convert them into utils.FlagsWithParams
- // check for *cost
- if ralsOpts.Has(utils.MetaCost) {
- rply.Cost = make(map[string]float64)
- for runID, cgrEv := range getDerivedEvents(events, ralsOpts.Has(utils.MetaDerivedReply)) {
- ev := engine.MapEvent(cgrEv.Event)
- //compose the CallDescriptor with Args
- startTime := ev.GetTimeIgnoreErrors(utils.AnswerTime,
- sS.cgrCfg.GeneralCfg().DefaultTimezone)
- if startTime.IsZero() { // AnswerTime not parsable, try SetupTime
- startTime = ev.GetTimeIgnoreErrors(utils.SetupTime,
- sS.cgrCfg.GeneralCfg().DefaultTimezone)
- }
- category := ev.GetStringIgnoreErrors(utils.Category)
- if len(category) == 0 {
- category = sS.cgrCfg.GeneralCfg().DefaultCategory
- }
- subject := ev.GetStringIgnoreErrors(utils.Subject)
- if len(subject) == 0 {
- subject = ev.GetStringIgnoreErrors(utils.AccountField)
- }
+ // dbtItvl := sS.cgrCfg.SessionSCfg().DebitInterval
+ // if argsFlagsWithParams.GetBool(utils.MetaRALs) {
+ // if ralsOpts := argsFlagsWithParams[utils.MetaRALs]; len(ralsOpts) != 0 {
+ // //check for subflags and convert them into utils.FlagsWithParams
+ // // check for *cost
+ // if ralsOpts.Has(utils.MetaCost) {
+ // rply.Cost = make(map[string]float64)
+ // for runID, cgrEv := range getDerivedEvents(events, ralsOpts.Has(utils.MetaDerivedReply)) {
+ // ev := engine.MapEvent(cgrEv.Event)
+ // //compose the CallDescriptor with Args
+ // startTime := ev.GetTimeIgnoreErrors(utils.AnswerTime,
+ // sS.cgrCfg.GeneralCfg().DefaultTimezone)
+ // if startTime.IsZero() { // AnswerTime not parsable, try SetupTime
+ // startTime = ev.GetTimeIgnoreErrors(utils.SetupTime,
+ // sS.cgrCfg.GeneralCfg().DefaultTimezone)
+ // }
+ // category := ev.GetStringIgnoreErrors(utils.Category)
+ // if len(category) == 0 {
+ // category = sS.cgrCfg.GeneralCfg().DefaultCategory
+ // }
+ // subject := ev.GetStringIgnoreErrors(utils.Subject)
+ // if len(subject) == 0 {
+ // subject = ev.GetStringIgnoreErrors(utils.AccountField)
+ // }
- cd := &engine.CallDescriptor{
- CgrID: cgrEv.ID,
- RunID: ev.GetStringIgnoreErrors(utils.RunID),
- ToR: ev.GetStringIgnoreErrors(utils.ToR),
- Tenant: cgrEv.Tenant,
- Category: category,
- Subject: subject,
- Account: ev.GetStringIgnoreErrors(utils.AccountField),
- Destination: ev.GetStringIgnoreErrors(utils.Destination),
- TimeStart: startTime,
- TimeEnd: startTime.Add(ev.GetDurationIgnoreErrors(utils.Usage)),
- ForceDuration: ralsOpts.Has(utils.MetaFD),
- }
- var cc engine.CallCost
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderGetCost,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: cgrEv.APIOpts,
- }, &cc); err != nil {
- return err
- }
- rply.Cost[runID] = cc.Cost
- }
- }
- opts := engine.MapEvent(args.APIOpts)
- ev := engine.MapEvent(args.CGREvent.Event)
- originID := ev.GetStringIgnoreErrors(utils.OriginID)
- switch {
- //check for auth session
- case ralsOpts.Has(utils.MetaAuthorize):
- var sRunsMaxUsage map[string]time.Duration
- if sRunsMaxUsage, err = sS.authEvent(args.CGREvent, ralsOpts.Has(utils.MetaFD)); err != nil {
- return err
- }
- rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
- // check for init session
- case ralsOpts.Has(utils.MetaInitiate):
- if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
- if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
- return utils.NewErrRALs(err)
- }
- }
- s, err := sS.initSession(args.CGREvent, sS.biJClntID(clnt), originID, dbtItvl, false,
- ralsOpts.Has(utils.MetaFD))
- if err != nil {
- return err
- }
- sRunsMaxUsage := make(map[string]time.Duration)
- s.RLock()
- isPrepaid := s.debitStop != nil
- s.RUnlock()
- if isPrepaid { //active debit
- for _, sr := range s.SRuns {
- sRunsMaxUsage[sr.CD.RunID] = sS.cgrCfg.SessionSCfg().GetDefaultUsage(ev.GetStringIgnoreErrors(utils.ToR))
- }
- } else if sRunsMaxUsage, err = sS.updateSession(s, nil, args.APIOpts, false); err != nil {
- return utils.NewErrRALs(err)
- }
- rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
- //check for update session
- case ralsOpts.Has(utils.MetaUpdate):
- if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
- if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
- return utils.NewErrRALs(err)
- }
- }
- s := sS.getRelocateSession(GetSetCGRID(ev),
- ev.GetStringIgnoreErrors(utils.InitialOriginID),
- ev.GetStringIgnoreErrors(utils.OriginID),
- ev.GetStringIgnoreErrors(utils.OriginHost))
- if s == nil {
- if s, err = sS.initSession(args.CGREvent, sS.biJClntID(clnt), ev.GetStringIgnoreErrors(utils.OriginID),
- dbtItvl, false, ralsOpts.Has(utils.MetaFD)); err != nil {
- return err
- }
- }
- var sRunsMaxUsage map[string]time.Duration
- if sRunsMaxUsage, err = sS.updateSession(s, ev, args.APIOpts, false); err != nil {
- return utils.NewErrRALs(err)
- }
- rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
- // check for terminate session
- case ralsOpts.Has(utils.MetaTerminate):
- if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
- if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
- return utils.NewErrRALs(err)
- }
- }
- s := sS.getRelocateSession(GetSetCGRID(ev),
- ev.GetStringIgnoreErrors(utils.InitialOriginID),
- ev.GetStringIgnoreErrors(utils.OriginID),
- ev.GetStringIgnoreErrors(utils.OriginHost))
- if s == nil {
- if s, err = sS.initSession(args.CGREvent, sS.biJClntID(clnt), ev.GetStringIgnoreErrors(utils.OriginID),
- dbtItvl, false, ralsOpts.Has(utils.MetaFD)); err != nil {
- return err
- }
- } else {
- s.Lock()
- s.chargeable = opts.GetBoolOrDefault(utils.OptsChargeable, true)
- s.Unlock()
- }
- if err = sS.terminateSession(s,
- ev.GetDurationPtrIgnoreErrors(utils.Usage),
- ev.GetDurationPtrIgnoreErrors(utils.LastUsed),
- ev.GetTimePtrIgnoreErrors(utils.AnswerTime, utils.EmptyString),
- false); err != nil {
- return utils.NewErrRALs(err)
- }
- }
- }
- }
+ // cd := &engine.CallDescriptor{
+ // CgrID: cgrEv.ID,
+ // RunID: ev.GetStringIgnoreErrors(utils.RunID),
+ // ToR: ev.GetStringIgnoreErrors(utils.ToR),
+ // Tenant: cgrEv.Tenant,
+ // Category: category,
+ // Subject: subject,
+ // Account: ev.GetStringIgnoreErrors(utils.AccountField),
+ // Destination: ev.GetStringIgnoreErrors(utils.Destination),
+ // TimeStart: startTime,
+ // TimeEnd: startTime.Add(ev.GetDurationIgnoreErrors(utils.Usage)),
+ // ForceDuration: ralsOpts.Has(utils.MetaFD),
+ // }
+ // var cc engine.CallCost
+ // if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
+ // utils.ResponderGetCost,
+ // &engine.CallDescriptorWithAPIOpts{
+ // CallDescriptor: cd,
+ // APIOpts: cgrEv.APIOpts,
+ // }, &cc); err != nil {
+ // return err
+ // }
+ // rply.Cost[runID] = cc.Cost
+ // }
+ // }
+ // opts := engine.MapEvent(args.APIOpts)
+ // ev := engine.MapEvent(args.CGREvent.Event)
+ // originID := ev.GetStringIgnoreErrors(utils.OriginID)
+ // switch {
+ // //check for auth session
+ // case ralsOpts.Has(utils.MetaAuthorize):
+ // var sRunsMaxUsage map[string]time.Duration
+ // if sRunsMaxUsage, err = sS.authEvent(args.CGREvent, ralsOpts.Has(utils.MetaFD)); err != nil {
+ // return err
+ // }
+ // rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
+ // // check for init session
+ // case ralsOpts.Has(utils.MetaInitiate):
+ // if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
+ // if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // }
+ // s, err := sS.initSession(args.CGREvent, sS.biJClntID(clnt), originID, dbtItvl, false,
+ // ralsOpts.Has(utils.MetaFD))
+ // if err != nil {
+ // return err
+ // }
+ // sRunsMaxUsage := make(map[string]time.Duration)
+ // s.RLock()
+ // isPrepaid := s.debitStop != nil
+ // s.RUnlock()
+ // if isPrepaid { //active debit
+ // for _, sr := range s.SRuns {
+ // sRunsMaxUsage[sr.CD.RunID] = sS.cgrCfg.SessionSCfg().GetDefaultUsage(ev.GetStringIgnoreErrors(utils.ToR))
+ // }
+ // } else if sRunsMaxUsage, err = sS.updateSession(s, nil, args.APIOpts, false); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
+ // //check for update session
+ // case ralsOpts.Has(utils.MetaUpdate):
+ // if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
+ // if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // }
+ // s := sS.getRelocateSession(GetSetCGRID(ev),
+ // ev.GetStringIgnoreErrors(utils.InitialOriginID),
+ // ev.GetStringIgnoreErrors(utils.OriginID),
+ // ev.GetStringIgnoreErrors(utils.OriginHost))
+ // if s == nil {
+ // if s, err = sS.initSession(args.CGREvent, sS.biJClntID(clnt), ev.GetStringIgnoreErrors(utils.OriginID),
+ // dbtItvl, false, ralsOpts.Has(utils.MetaFD)); err != nil {
+ // return err
+ // }
+ // }
+ // var sRunsMaxUsage map[string]time.Duration
+ // if sRunsMaxUsage, err = sS.updateSession(s, ev, args.APIOpts, false); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // rply.MaxUsage = getDerivedMaxUsage(sRunsMaxUsage, ralsOpts.Has(utils.MetaDerivedReply))
+ // // check for terminate session
+ // case ralsOpts.Has(utils.MetaTerminate):
+ // if opts.HasField(utils.OptsDebitInterval) { // dynamic DebitInterval via CGRDebitInterval
+ // if dbtItvl, err = opts.GetDuration(utils.OptsDebitInterval); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // }
+ // s := sS.getRelocateSession(GetSetCGRID(ev),
+ // ev.GetStringIgnoreErrors(utils.InitialOriginID),
+ // ev.GetStringIgnoreErrors(utils.OriginID),
+ // ev.GetStringIgnoreErrors(utils.OriginHost))
+ // if s == nil {
+ // if s, err = sS.initSession(args.CGREvent, sS.biJClntID(clnt), ev.GetStringIgnoreErrors(utils.OriginID),
+ // dbtItvl, false, ralsOpts.Has(utils.MetaFD)); err != nil {
+ // return err
+ // }
+ // } else {
+ // s.Lock()
+ // s.chargeable = opts.GetBoolOrDefault(utils.OptsChargeable, true)
+ // s.Unlock()
+ // }
+ // if err = sS.terminateSession(s,
+ // ev.GetDurationPtrIgnoreErrors(utils.Usage),
+ // ev.GetDurationPtrIgnoreErrors(utils.LastUsed),
+ // ev.GetTimePtrIgnoreErrors(utils.AnswerTime, utils.EmptyString),
+ // false); err != nil {
+ // return utils.NewErrRALs(err)
+ // }
+ // }
+ // }
+ // }
if argsFlagsWithParams.GetBool(utils.MetaCDRs) {
if len(sS.cgrCfg.SessionSCfg().CDRsConns) == 0 {
@@ -3501,102 +3285,6 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
return
}
-// V1GetCostReply is the reply for the GetCost API
-type V1GetCostReply struct {
- Attributes *engine.AttrSProcessEventReply
- EventCost *engine.EventCost
-}
-
-// BiRPCv1GetCost processes one event with the right subsystems based on arguments received
-func (sS *SessionS) BiRPCv1GetCost(clnt rpcclient.ClientConnector,
- args *V1ProcessEventArgs, rply *V1GetCostReply) (err error) {
- if args.CGREvent == nil {
- return utils.NewErrMandatoryIeMissing(utils.CGREventString)
- }
- if args.CGREvent.ID == "" {
- args.CGREvent.ID = utils.GenUUID()
- }
- if args.CGREvent.Tenant == "" {
- args.CGREvent.Tenant = sS.cgrCfg.GeneralCfg().DefaultTenant
- }
-
- // RPC caching
- if sS.cgrCfg.CacheCfg().Partitions[utils.CacheRPCResponses].Limit != 0 {
- cacheKey := utils.ConcatenatedKey(utils.SessionSv1GetCost, args.CGREvent.ID)
- refID := guardian.Guardian.GuardIDs("",
- sS.cgrCfg.GeneralCfg().LockingTimeout, cacheKey) // RPC caching needs to be atomic
- defer guardian.Guardian.UnguardIDs(refID)
-
- if itm, has := engine.Cache.Get(utils.CacheRPCResponses, cacheKey); has {
- cachedResp := itm.(*utils.CachedRPCResponse)
- if cachedResp.Error == nil {
- *rply = *cachedResp.Result.(*V1GetCostReply)
- }
- return cachedResp.Error
- }
- defer engine.Cache.Set(utils.CacheRPCResponses, cacheKey,
- &utils.CachedRPCResponse{Result: rply, Error: err},
- nil, true, utils.NonTransactional)
- }
- // end of RPC caching
-
- //convert from Flags []string to utils.FlagsWithParams
- argsFlagsWithParams := utils.FlagsWithParamsFromSlice(args.Flags)
- // check for *attribute
- if argsFlagsWithParams.Has(utils.MetaAttributes) {
- rplyAttr, err := sS.processAttributes(args.CGREvent,
- argsFlagsWithParams.ParamsSlice(utils.MetaAttributes, utils.MetaIDs), false)
- if err == nil {
- args.CGREvent = rplyAttr.CGREvent
- rply.Attributes = &rplyAttr
- } else if err.Error() != utils.ErrNotFound.Error() {
- return utils.NewErrAttributeS(err)
- }
- }
- //compose the CallDescriptor with Args
- me := engine.MapEvent(args.CGREvent.Event)
- startTime := me.GetTimeIgnoreErrors(utils.AnswerTime,
- sS.cgrCfg.GeneralCfg().DefaultTimezone)
- if startTime.IsZero() { // AnswerTime not parsable, try SetupTime
- startTime = me.GetTimeIgnoreErrors(utils.SetupTime,
- sS.cgrCfg.GeneralCfg().DefaultTimezone)
- }
- category := me.GetStringIgnoreErrors(utils.Category)
- if len(category) == 0 {
- category = sS.cgrCfg.GeneralCfg().DefaultCategory
- }
- subject := me.GetStringIgnoreErrors(utils.Subject)
- if len(subject) == 0 {
- subject = me.GetStringIgnoreErrors(utils.AccountField)
- }
-
- cd := &engine.CallDescriptor{
- CgrID: args.CGREvent.ID,
- RunID: me.GetStringIgnoreErrors(utils.RunID),
- ToR: me.GetStringIgnoreErrors(utils.ToR),
- Tenant: args.CGREvent.Tenant,
- Category: category,
- Subject: subject,
- Account: me.GetStringIgnoreErrors(utils.AccountField),
- Destination: me.GetStringIgnoreErrors(utils.Destination),
- TimeStart: startTime,
- TimeEnd: startTime.Add(me.GetDurationIgnoreErrors(utils.Usage)),
- }
- var cc engine.CallCost
- if err = sS.connMgr.Call(sS.cgrCfg.SessionSCfg().RALsConns, nil,
- utils.ResponderGetCost,
- &engine.CallDescriptorWithAPIOpts{
- CallDescriptor: cd,
- APIOpts: args.APIOpts,
- }, &cc); err != nil {
- return
- }
- ec := engine.NewEventCostFromCallCost(&cc, args.CGREvent.ID, me.GetStringIgnoreErrors(utils.RunID))
- ec.Compute()
- rply.EventCost = ec
- return
-}
-
// BiRPCv1SyncSessions will sync sessions on demand
func (sS *SessionS) BiRPCv1SyncSessions(clnt rpcclient.ClientConnector,
ignParam *utils.TenantWithAPIOpts, reply *string) error {
@@ -4108,9 +3796,6 @@ func (sS *SessionS) Handlers() map[string]interface{} {
utils.SessionSv1ProcessEvent: func(clnt *rpc2.Client, args *V1ProcessEventArgs, rply *V1ProcessEventReply) (err error) {
return sS.BiRPCv1ProcessEvent(clnt, args, rply)
},
- utils.SessionSv1GetCost: func(clnt *rpc2.Client, args *V1ProcessEventArgs, rply *V1GetCostReply) (err error) {
- return sS.BiRPCv1GetCost(clnt, args, rply)
- },
utils.SessionSv1GetActiveSessions: func(clnt *rpc2.Client, args *utils.SessionFilter, rply *[]*ExternalSession) (err error) {
return sS.BiRPCv1GetActiveSessions(clnt, args, rply)
},
diff --git a/utils/apitpdata.go b/utils/apitpdata.go
index 3ed5e7e7c..ee1f162a9 100755
--- a/utils/apitpdata.go
+++ b/utils/apitpdata.go
@@ -146,32 +146,6 @@ type AttrSetDestination struct {
Overwrite bool
}
-type TPActions struct {
- TPid string // Tariff plan id
- ID string // Actions id
- Actions []*TPAction // Set of actions this Actions profile will perform
-}
-
-type TPAction struct {
- Identifier string // Identifier mapped in the code
- BalanceId string // Balance identification string (account scope)
- BalanceUuid string // Balance identification string (global scope)
- BalanceType string // Type of balance the action will operate on
- Units string // Number of units to add/deduct
- ExpiryTime string // Time when the units will expire
- Filter string // The condition on balances that is checked before the action
- TimingTags string // Timing when balance is active
- DestinationIds string // Destination profile id
- RatingSubject string // Reference a rate subject defined in RatingProfiles
- Categories string // category filter for balances
- SharedGroups string // Reference to a shared group
- BalanceWeight string // Balance weight
- ExtraParameters string
- BalanceBlocker string
- BalanceDisabled string
- Weight float64 // Action's weight
-}
-
type AttrGetAccountsCount struct {
Tenant string
}
@@ -540,62 +514,11 @@ func (fltr *RPCCDRsFilter) AsCDRsFilter(timezone string) (cdrFltr *CDRsFilter, e
return
}
-type AttrSetActions struct {
- ActionsId string // Actions id
- Overwrite bool // If previously defined, will be overwritten
- Actions []*TPAction // Set of actions this Actions profile will perform
-}
-
-type AttrExecuteAction struct {
- Tenant string
- Account string
- ActionsId string
-}
-
-type AttrSetAccount struct {
- Tenant string
- Account string
- ActionPlanID string
- ActionTriggersID string
- ExtraOptions map[string]bool
- ReloadScheduler bool
-}
-
-type AttrRemoveAccount struct {
- Tenant string
- Account string
- ReloadScheduler bool
-}
-
type AttrGetCallCost struct {
CgrId string // Unique id of the CDR
RunId string // Run Id
}
-type AttrSetBalance struct {
- Tenant string
- Account string
- BalanceType string
- Value float64
- Balance map[string]interface{}
- ActionExtraData *map[string]interface{}
- Cdrlog bool
-}
-
-type AttrSetBalances struct {
- Tenant string
- Account string
- Balances []*AttrBalance
-}
-
-type AttrBalance struct {
- BalanceType string
- Value float64
- Balance map[string]interface{}
- ActionExtraData *map[string]interface{}
- Cdrlog bool
-}
-
// TPResourceProfile is used in APIs to manage remotely offline ResourceProfile
type TPResourceProfile struct {
TPid string
@@ -1024,13 +947,6 @@ func NewAttrReloadCacheWithOpts() *AttrReloadCacheWithAPIOpts {
ArgsCache: map[string][]string{
DestinationIDs: nil,
ReverseDestinationIDs: nil,
- RatingPlanIDs: nil,
- RatingProfileIDs: nil,
- ActionIDs: nil,
- ActionPlanIDs: nil,
- AccountActionPlanIDs: nil,
- ActionTriggerIDs: nil,
- SharedGroupIDs: nil,
ResourceProfileIDs: nil,
ResourceIDs: nil,
StatsQueueIDs: nil,
diff --git a/utils/consts.go b/utils/consts.go
index bce04377d..f8e7c084b 100755
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -47,8 +47,7 @@ var (
CacheCDRIDs, CacheRPCConnections, CacheUCH, CacheSTIR, CacheEventCharges, MetaAPIBan,
CacheCapsEvents, CacheVersions, CacheReplicationHosts})
- dataDBPartition = NewStringSet([]string{CacheDestinations, CacheReverseDestinations,
- CacheActions, CacheTimings,
+ dataDBPartition = NewStringSet([]string{CacheDestinations, CacheReverseDestinations, CacheTimings,
CacheResourceProfiles, CacheResources, CacheEventResources, CacheStatQueueProfiles, CacheStatQueues,
CacheThresholdProfiles, CacheThresholds, CacheFilters, CacheRouteProfiles, CacheAttributeProfiles,
CacheChargerProfiles, CacheActionProfiles, CacheDispatcherProfiles, CacheDispatcherHosts,
@@ -58,7 +57,7 @@ var (
CacheActionProfilesFilterIndexes, CacheAccountProfilesFilterIndexes, CacheReverseFilterIndexes,
CacheAccountProfiles})
- storDBPartition = NewStringSet([]string{CacheTBLTPTimings, CacheTBLTPDestinations, CacheTBLTPActions,
+ storDBPartition = NewStringSet([]string{CacheTBLTPTimings, CacheTBLTPDestinations,
CacheTBLTPResources, CacheTBLTPStats, CacheTBLTPThresholds, CacheTBLTPFilters, CacheSessionCostsTBL, CacheCDRsTBL,
CacheTBLTPRoutes, CacheTBLTPAttributes, CacheTBLTPChargers, CacheTBLTPDispatchers,
CacheTBLTPDispatcherHosts, CacheTBLTPRateProfiles, CacheTBLTPActionProfiles, CacheTBLTPAccountProfiles})
@@ -69,7 +68,6 @@ var (
CacheInstanceToPrefix = map[string]string{
CacheDestinations: DestinationPrefix,
CacheReverseDestinations: ReverseDestinationPrefix,
- CacheActions: ActionPrefix,
CacheResourceProfiles: ResourceProfilesPrefix,
CacheResources: ResourcesPrefix,
CacheTimings: TimingsPrefix,
@@ -141,7 +139,6 @@ var (
CacheStorDBPartitions = map[string]string{
TBLTPTimings: CacheTBLTPTimings,
TBLTPDestinations: CacheTBLTPDestinations,
- TBLTPActions: CacheTBLTPActions,
TBLTPResources: CacheTBLTPResources,
TBLTPStats: CacheTBLTPStats,
TBLTPThresholds: CacheTBLTPThresholds,
@@ -162,7 +159,6 @@ var (
ArgCacheToPrefix = map[string]string{
DestinationIDs: DestinationPrefix,
ReverseDestinationIDs: ReverseDestinationPrefix,
- ActionIDs: ActionPrefix,
ResourceProfileIDs: ResourceProfilesPrefix,
ResourceIDs: ResourcesPrefix,
StatsQueueIDs: StatQueuePrefix,
@@ -196,7 +192,6 @@ var (
ArgCacheToInstance = map[string]string{
DestinationIDs: CacheDestinations,
ReverseDestinationIDs: CacheReverseDestinations,
- ActionIDs: CacheActions,
ResourceProfileIDs: CacheResourceProfiles,
ResourceIDs: CacheResources,
StatsQueueIDs: CacheStatQueues,
@@ -348,8 +343,6 @@ const (
MetaVoice = "*voice"
ACD = "ACD"
- TasksKey = "tasks"
- ActionPrefix = "act_"
DestinationPrefix = "dst_"
ReverseDestinationPrefix = "rds_"
ResourcesPrefix = "res_"
@@ -457,8 +450,6 @@ const (
RunningCaps = "RUNNING"
StoppedCaps = "STOPPED"
SchedulerNotRunningCaps = "SCHEDULLER_NOT_RUNNING"
- MetaScheduler = "*scheduler"
- MetaSessionsCosts = "*sessions_costs"
MetaRALs = "*rals"
MetaReplicator = "*replicator"
MetaRerate = "*rerate"
@@ -600,9 +591,7 @@ const (
RatingProfile = "RatingProfile"
MetaRatingPlans = "*rating_plans"
MetaRatingProfiles = "*rating_profiles"
- MetaUsers = "*users"
MetaSubscribers = "*subscribers"
- MetaDerivedChargersV = "*derivedchargers"
MetaStorDB = "*stordb"
MetaDataDB = "*datadb"
MetaWeight = "*weight"
@@ -948,8 +937,6 @@ const (
MetaAccounts = "*accounts"
MetaAccountActionPlans = "*account_action_plans"
MetaReverseDestinations = "*reverse_destinations"
- MetaActionPlans = "*action_plans"
- MetaActionTriggers = "*action_triggers"
MetaActions = "*actions"
MetaResourceProfile = "*resource_profiles"
MetaStatQueueProfiles = "*statqueue_profiles"
@@ -962,7 +949,6 @@ const (
MetaRateProfiles = "*rate_profiles"
MetaRateProfileRates = "*rate_profile_rates"
MetaChargerProfiles = "*charger_profiles"
- MetaSharedGroups = "*shared_groups"
MetaThresholds = "*thresholds"
MetaRoutes = "*routes"
MetaAttributes = "*attributes"
@@ -1080,22 +1066,13 @@ const (
const (
MetaSetVersions = "*set_versions"
MetaEnsureIndexes = "*ensure_indexes"
- MetaTpRatingPlans = "*tp_rating_plans"
MetaTpFilters = "*tp_filters"
- MetaTpDestinationRates = "*tp_destination_rates"
- MetaTpActionTriggers = "*tp_action_triggers"
- MetaTpAccountActions = "*tp_account_actions"
- MetaTpActionPlans = "*tp_action_plans"
- MetaTpActions = "*tp_actions"
MetaTpThresholds = "*tp_thresholds"
MetaTpRoutes = "*tp_Routes"
MetaTpStats = "*tp_stats"
- MetaTpSharedGroups = "*tp_shared_groups"
- MetaTpRatingProfiles = "*tp_rating_profiles"
MetaTpActionProfiles = "*tp_action_profiles"
MetaTpRateProfiles = "*tp_rate_profiles"
MetaTpResources = "*tp_resources"
- MetaTpRates = "*tp_rates"
MetaTpTimings = "*tp_timings"
MetaTpDestinations = "*tp_destinations"
MetaTpChargers = "*tp_chargers"
@@ -1594,21 +1571,6 @@ const (
SessionSv1Sleep = "SessionSv1.Sleep"
)
-// Responder APIs
-const (
- Responder = "Responder"
- ResponderDebit = "Responder.Debit"
- ResponderRefundIncrements = "Responder.RefundIncrements"
- ResponderGetMaxSessionTime = "Responder.GetMaxSessionTime"
- ResponderMaxDebit = "Responder.MaxDebit"
- ResponderRefundRounding = "Responder.RefundRounding"
- ResponderGetCost = "Responder.GetCost"
- ResponderGetCostOnRatingPlans = "Responder.GetCostOnRatingPlans"
- ResponderGetMaxSessionTimeOnAccounts = "Responder.GetMaxSessionTimeOnAccounts"
- ResponderShutdown = "Responder.Shutdown"
- ResponderPing = "Responder.Ping"
-)
-
// DispatcherS APIs
const (
DispatcherSv1 = "DispatcherSv1"
@@ -1736,14 +1698,6 @@ const (
TimingsCsv = "Timings.csv"
DestinationsCsv = "Destinations.csv"
RatesCsv = "Rates.csv"
- DestinationRatesCsv = "DestinationRates.csv"
- RatingPlansCsv = "RatingPlans.csv"
- RatingProfilesCsv = "RatingProfiles.csv"
- SharedGroupsCsv = "SharedGroups.csv"
- ActionsCsv = "Actions.csv"
- ActionPlansCsv = "ActionPlans.csv"
- ActionTriggersCsv = "ActionTriggers.csv"
- AccountActionsCsv = "AccountActions.csv"
ResourcesCsv = "Resources.csv"
StatsCsv = "Stats.csv"
ThresholdsCsv = "Thresholds.csv"
@@ -1762,7 +1716,6 @@ const (
const (
TBLTPTimings = "tp_timings"
TBLTPDestinations = "tp_destinations"
- TBLTPActions = "tp_actions"
TBLTPResources = "tp_resources"
TBLTPStats = "tp_stats"
TBLTPThresholds = "tp_thresholds"
@@ -1785,7 +1738,6 @@ const (
const (
CacheDestinations = "*destinations"
CacheReverseDestinations = "*reverse_destinations"
- CacheActions = "*actions"
CacheResources = "*resources"
CacheResourceProfiles = "*resource_profiles"
CacheTimings = "*timings"
@@ -1836,7 +1788,6 @@ const (
// storDB
CacheTBLTPTimings = "*tp_timings"
CacheTBLTPDestinations = "*tp_destinations"
- CacheTBLTPActions = "*tp_actions"
CacheTBLTPResources = "*tp_resources"
CacheTBLTPStats = "*tp_stats"
CacheTBLTPThresholds = "*tp_thresholds"
@@ -2278,7 +2229,7 @@ const (
DataPathCfg = "data_path"
DisableReverseCfg = "disable_reverse"
CachesConnsCfg = "caches_conns"
- SchedulerConnsCfg = "scheduler_conns"
+ ActionSConnsCfg = "actions_conns"
GapiCredentialsCfg = "gapi_credentials"
GapiTokenCfg = "gapi_token"
)
@@ -2477,13 +2428,6 @@ const (
const (
DestinationIDs = "DestinationIDs"
ReverseDestinationIDs = "ReverseDestinationIDs"
- RatingPlanIDs = "RatingPlanIDs"
- RatingProfileIDs = "RatingProfileIDs"
- ActionIDs = "ActionIDs"
- ActionPlanIDs = "ActionPlanIDs"
- AccountActionPlanIDs = "AccountActionPlanIDs"
- ActionTriggerIDs = "ActionTriggerIDs"
- SharedGroupIDs = "SharedGroupIDs"
ResourceProfileIDs = "ResourceProfileIDs"
ResourceIDs = "ResourceIDs"
StatsQueueIDs = "StatsQueueIDs"