Create APIerSV1GetAccountCost

This commit is contained in:
arberkatellari
2023-11-08 11:35:56 -05:00
committed by Dan Christian Bogos
parent 681cd3c58a
commit 054c584775
6 changed files with 117 additions and 43 deletions

View File

@@ -115,3 +115,23 @@ func (apierSv1 *APIerSv1) GetDataCost(ctx *context.Context, attrs *AttrGetDataCo
}
return nil
}
// GetAccountCost returns a simulated cost of an account without debiting from it (dryrun)
func (apierSv1 *APIerSv1) GetAccountCost(ctx *context.Context, args *utils.CGREvent, ec *engine.EventCost) (err error) {
cd, err := engine.NewCallDescriptorFromCGREvent(args, apierSv1.Config.GeneralCfg().DefaultTimezone)
if err != nil {
return
}
args.APIOpts[utils.MetaRALsDryRun] = true
var cc engine.CallCost
if err := apierSv1.Responder.Debit(context.Background(),
&engine.CallDescriptorWithAPIOpts{
CallDescriptor: cd,
APIOpts: args.APIOpts,
}, &cc); err != nil {
return utils.NewErrServerError(err)
}
*ec = *engine.NewEventCostFromCallCost(&cc, cd.CgrID, cd.RunID)
ec.Compute()
return nil
}

View File

@@ -2329,19 +2329,21 @@ func TestERSConfig(t *testing.T) {
SessionSConns: []string{"*internal:*sessions"},
Readers: []*EventReaderCfg{
{
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
Fields: nil,
CacheDumpFields: make([]*FCTemplate, 0),
PartialCommitFields: make([]*FCTemplate, 0),
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
Fields: nil,
CacheDumpFields: make([]*FCTemplate, 0),
PartialCommitFields: make([]*FCTemplate, 0),
Reconnects: -1,
MaxReconnectInterval: 300000000000,
Opts: &EventReaderOpts{
CSV: &CSVROpts{
FieldSeparator: utils.StringPointer(utils.FieldsSep),
@@ -5356,16 +5358,18 @@ func TestCgrCdfEventReader(t *testing.T) {
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
Readers: []*EventReaderCfg{
{
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
Reconnects: -1,
MaxReconnectInterval: 300000000000,
Fields: []*FCTemplate{
{Tag: utils.ToR, Path: utils.MetaCgreq + utils.NestingSep + utils.ToR, Type: utils.MetaVariable,
Value: NewRSRParsersMustCompile("~*req.2", utils.InfieldSep), Mandatory: true, Layout: time.RFC3339},
@@ -5467,16 +5471,18 @@ func TestCgrCdfEventExporter(t *testing.T) {
func TestCgrCfgEventReaderDefault(t *testing.T) {
eCfg := &EventReaderCfg{
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
ID: utils.MetaDefault,
Type: utils.MetaNone,
RunDelay: 0,
ConcurrentReqs: 1024,
SourcePath: "/var/spool/cgrates/ers/in",
ProcessedPath: "/var/spool/cgrates/ers/out",
Tenant: nil,
Timezone: utils.EmptyString,
Filters: []string{},
Flags: utils.FlagsWithParams{},
Reconnects: -1,
MaxReconnectInterval: 300000000000,
Fields: []*FCTemplate{
{Tag: utils.ToR, Path: utils.MetaCgreq + utils.NestingSep + utils.ToR, Type: utils.MetaVariable,
Value: NewRSRParsersMustCompile("~*req.2", utils.InfieldSep), Mandatory: true, Layout: time.RFC3339},

View File

@@ -26,12 +26,15 @@ import (
"testing"
"time"
"github.com/cgrates/birpc"
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func TestCDRsProcessEventDryrun(t *testing.T) {
var aSummaryBefore *engine.AccountSummary
func TestGetAccountCost(t *testing.T) {
cfgPath := path.Join(*dataDir, "conf", "samples", "rerate_cdrs_mysql")
tpPath := path.Join(*dataDir, "tariffplans", "reratecdrs")
client, _, shutdown, err := setupTest(t, "TestRerateCDRs", cfgPath, tpPath, utils.EmptyString, nil)
@@ -42,8 +45,6 @@ func TestCDRsProcessEventDryrun(t *testing.T) {
CGRID := utils.GenUUID()
var aSummaryBefore *engine.AccountSummary
t.Run("SetBalance", func(t *testing.T) {
var reply string
if err := client.Call(context.Background(), utils.APIerSv1SetBalances,
@@ -129,6 +130,48 @@ func TestCDRsProcessEventDryrun(t *testing.T) {
})
t.Run("GetAccountCost", func(t *testing.T) {
var reply engine.EventCost
err := client.Call(context.Background(), utils.APIerSV1GetAccountCost,
&engine.ArgV1ProcessEvent{
Flags: []string{utils.MetaRALs},
CGREvent: utils.CGREvent{
Tenant: "cgrates.org",
ID: "event1",
Event: map[string]any{
utils.RunID: "run_1",
utils.CGRID: CGRID,
utils.Tenant: "cgrates.org",
utils.Category: "call",
utils.ToR: utils.MetaVoice,
utils.OriginID: "processCDR1",
utils.OriginHost: "OriginHost1",
utils.RequestType: utils.MetaPostpaid,
utils.AccountField: "1001",
utils.Destination: "1002",
utils.SetupTime: time.Date(2021, time.February, 2, 16, 14, 50, 0, time.UTC),
utils.AnswerTime: time.Date(2021, time.February, 2, 16, 15, 0, 0, time.UTC),
utils.Usage: 4 * time.Minute,
},
APIOpts: map[string]any{
utils.MetaRALsDryRun: true,
},
},
}, &reply)
if err != nil {
t.Fatal(err)
}
if *reply.Cost != 2.4 {
t.Errorf("expected cost to be <%+v>, received <%+v>", 2.4, *reply.Cost)
}
if *reply.Usage != 4*time.Minute {
t.Errorf("expected cost to be <%+v>, received <%+v>", 4*time.Minute, *reply.Usage)
}
})
t.Run("CheckAccountBalancesAfterGetAccountCost", checkAccountBalances(client))
t.Run("ProcessFirstCDR", func(t *testing.T) {
var reply []*utils.EventWithFlags
err := client.Call(context.Background(), utils.CDRsV2ProcessEvent,
@@ -176,7 +219,13 @@ func TestCDRsProcessEventDryrun(t *testing.T) {
}
})
t.Run("CheckAccountBalancesAfterFirstProcessCDR", func(t *testing.T) {
t.Run("CheckAccountBalancesAfterProcessCDR", checkAccountBalances(client))
}
func checkAccountBalances(client *birpc.Client) func(t *testing.T) {
return func(t *testing.T) {
expAcnt := engine.Account{
ID: "cgrates.org:1001",
BalanceMap: map[string]engine.Balances{
@@ -210,7 +259,5 @@ func TestCDRsProcessEventDryrun(t *testing.T) {
if !reflect.DeepEqual(aSummaryBefore, aSummaryAfter) {
t.Errorf("expected <%+v>, \nreceived <%+v>", utils.ToJSON(aSummaryBefore), utils.ToJSON(aSummaryAfter))
}
})
}
}

2
go.mod
View File

@@ -23,7 +23,7 @@ require (
github.com/cgrates/fsock v0.0.0-20230123160954-12cae14030cc
github.com/cgrates/kamevapi v0.0.0-20220525160402-5b8036487a6c
github.com/cgrates/ltcache v0.0.0-20210405185848-da943e80c1ab
github.com/cgrates/radigo v0.0.0-20231010181109-b0e5b086459e
github.com/cgrates/radigo v0.0.0-20231107162145-dac6e5c377ea
github.com/cgrates/rpcclient v0.0.0-20230605090759-8bb5188b73e5
github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e
github.com/cgrates/ugocodec v0.0.0-20201023092048-df93d0123f60

4
go.sum
View File

@@ -57,8 +57,8 @@ github.com/cgrates/kamevapi v0.0.0-20220525160402-5b8036487a6c h1:ILTMiCcBw80hSe
github.com/cgrates/kamevapi v0.0.0-20220525160402-5b8036487a6c/go.mod h1:R1iZadqJTrjkwWxhK8gVPcYhcWoE4d0A6HZ+y6ZHzys=
github.com/cgrates/ltcache v0.0.0-20210405185848-da943e80c1ab h1:dKdAUwrij6vYwewe1WV1+pDSagqGI5JLqjTZZyN2ANo=
github.com/cgrates/ltcache v0.0.0-20210405185848-da943e80c1ab/go.mod h1:9oSG/6gUoab/vKm/eQ3QcX6KeTR0wRw88N33iCnC/k4=
github.com/cgrates/radigo v0.0.0-20231010181109-b0e5b086459e h1:ZlZUnZwtho03GuD0pnr1yodrfCo7JfwTNEjtWcjv7tw=
github.com/cgrates/radigo v0.0.0-20231010181109-b0e5b086459e/go.mod h1:PizDxlLTjVQpyPU0ksWYfmM9UbYGu7q6at0nzuiZprI=
github.com/cgrates/radigo v0.0.0-20231107162145-dac6e5c377ea h1:P5yYTIwL3MXE70+bJECW720DMEOEK1RwK6eSxZNo0BY=
github.com/cgrates/radigo v0.0.0-20231107162145-dac6e5c377ea/go.mod h1:PizDxlLTjVQpyPU0ksWYfmM9UbYGu7q6at0nzuiZprI=
github.com/cgrates/rpcclient v0.0.0-20230605090759-8bb5188b73e5 h1:GhA5qBUK7o0j+7fi1GACKnT454pv/LfCjoI52vFIz3E=
github.com/cgrates/rpcclient v0.0.0-20230605090759-8bb5188b73e5/go.mod h1:tDqS6BieViKYpz696//gxseUN1b92hPHqk+w0CzY8AE=
github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e h1:izFjZB83/XRXInc+gMIssUxdbleGsGIuGCPj2u7RQo0=

View File

@@ -1455,6 +1455,7 @@ const (
APIerSv1GetTiming = "APIerSv1.GetTiming"
APIerSv1SetTiming = "APIerSv1.SetTiming"
APIerSv1RemoveTiming = "APIerSv1.RemoveTiming"
APIerSV1GetAccountCost = "APIerSv1.GetAccountCost"
)
// APIerSv1 TP APIs