mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-20 14:48:43 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -21,6 +21,7 @@ package v1
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
@@ -120,7 +121,7 @@ type AttrRemAcntActionTriggers struct {
|
||||
Tenant string // Tenant he account belongs to
|
||||
Account string // Account name
|
||||
Direction string // Traffic direction
|
||||
ActionTriggerId string // Id filtering only specific id to remove
|
||||
ActionTriggerId string // Id filtering only specific id to remove (can be regexp pattern)
|
||||
}
|
||||
|
||||
// Returns a list of ActionTriggers on an account
|
||||
@@ -135,7 +136,8 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r
|
||||
return 0, err
|
||||
}
|
||||
for idx, actr := range ub.ActionTriggers {
|
||||
if len(attrs.ActionTriggerId) != 0 && actr.Id != attrs.ActionTriggerId { // Empty actionTriggerId will match always
|
||||
match, _ := regexp.MatchString(attrs.ActionTriggerId, actr.Id)
|
||||
if len(attrs.ActionTriggerId) != 0 && !match {
|
||||
continue
|
||||
}
|
||||
if len(ub.ActionTriggers) != 1 { // Remove by index
|
||||
|
||||
@@ -435,7 +435,7 @@ func (self *ApierV1) SetActions(attrs AttrSetActions, reply *string) error {
|
||||
// Retrieves actions attached to specific ActionsId within cache
|
||||
func (self *ApierV1) GetActions(actsId string, reply *[]*utils.TPAction) error {
|
||||
if len(actsId) == 0 {
|
||||
return fmt.Errorf("%s:ActionsId", utils.ERR_MANDATORY_IE_MISSING, actsId)
|
||||
return fmt.Errorf("%s ActionsId: %s", utils.ERR_MANDATORY_IE_MISSING, actsId)
|
||||
}
|
||||
acts := make([]*utils.TPAction, 0)
|
||||
engActs, err := self.AccountDb.GetActions(actsId, false)
|
||||
@@ -534,6 +534,7 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error
|
||||
}
|
||||
|
||||
type AttrAddActionTrigger struct {
|
||||
Id string
|
||||
Tenant string
|
||||
Account string
|
||||
ThresholdType string
|
||||
@@ -559,7 +560,7 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
at := &engine.ActionTrigger{
|
||||
Id: utils.GenUUID(),
|
||||
Id: attr.Id,
|
||||
ThresholdType: attr.ThresholdType,
|
||||
ThresholdValue: attr.ThresholdValue,
|
||||
BalanceId: attr.BalanceId,
|
||||
@@ -596,6 +597,7 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string
|
||||
}
|
||||
|
||||
type AttrResetTriggeredAction struct {
|
||||
Id string
|
||||
Tenant string
|
||||
Account string
|
||||
Direction string
|
||||
@@ -609,35 +611,41 @@ type AttrResetTriggeredAction struct {
|
||||
}
|
||||
|
||||
func (self *ApierV1) ResetTriggeredActions(attr AttrResetTriggeredAction, reply *string) error {
|
||||
if attr.Direction == "" {
|
||||
attr.Direction = engine.OUTBOUND
|
||||
}
|
||||
extraParameters, err := json.Marshal(struct {
|
||||
ThresholdType string
|
||||
ThresholdValue float64
|
||||
DestinationId string
|
||||
BalanceWeight float64
|
||||
BalanceRatingSubject string
|
||||
BalanceSharedGroup string
|
||||
}{
|
||||
attr.ThresholdType,
|
||||
attr.ThresholdValue,
|
||||
attr.DestinationId,
|
||||
attr.BalanceWeight,
|
||||
attr.BalanceRatingSubject,
|
||||
attr.BalanceSharedGroup,
|
||||
})
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
a := &engine.Action{
|
||||
BalanceType: attr.BalanceType,
|
||||
Direction: attr.Direction,
|
||||
ExtraParameters: string(extraParameters),
|
||||
var a *engine.Action
|
||||
if attr.Id != "" {
|
||||
// we can identify the trigge by the id
|
||||
a = &engine.Action{Id: attr.Id}
|
||||
} else {
|
||||
if attr.Direction == "" {
|
||||
attr.Direction = engine.OUTBOUND
|
||||
}
|
||||
extraParameters, err := json.Marshal(struct {
|
||||
ThresholdType string
|
||||
ThresholdValue float64
|
||||
DestinationId string
|
||||
BalanceWeight float64
|
||||
BalanceRatingSubject string
|
||||
BalanceSharedGroup string
|
||||
}{
|
||||
attr.ThresholdType,
|
||||
attr.ThresholdValue,
|
||||
attr.DestinationId,
|
||||
attr.BalanceWeight,
|
||||
attr.BalanceRatingSubject,
|
||||
attr.BalanceSharedGroup,
|
||||
})
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
a = &engine.Action{
|
||||
BalanceType: attr.BalanceType,
|
||||
Direction: attr.Direction,
|
||||
ExtraParameters: string(extraParameters),
|
||||
}
|
||||
}
|
||||
accID := utils.AccountKey(attr.Tenant, attr.Account, attr.Direction)
|
||||
_, err = engine.AccLock.Guard(accID, func() (float64, error) {
|
||||
_, err := engine.AccLock.Guard(accID, func() (float64, error) {
|
||||
acc, err := self.AccountDb.GetAccount(accID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
@@ -217,7 +217,7 @@ func TestApierTPTiming(t *testing.T) {
|
||||
// Test getIds
|
||||
var rplyTmIds []string
|
||||
expectedTmIds := []string{"ALWAYS", "ASAP"}
|
||||
if err := rater.Call("ApierV1.GetTPTimingIds", AttrGetTPTimingIds{tmAlways.TPid, utils.Paginator{0, 0, ""}}, &rplyTmIds); err != nil {
|
||||
if err := rater.Call("ApierV1.GetTPTimingIds", AttrGetTPTimingIds{tmAlways.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyTmIds); err != nil {
|
||||
t.Error("Calling ApierV1.GetTPTimingIds, got error: ", err.Error())
|
||||
} else if !reflect.DeepEqual(expectedTmIds, rplyTmIds) {
|
||||
t.Errorf("Calling ApierV1.GetTPTimingIds expected: %v, received: %v", expectedTmIds, rplyTmIds)
|
||||
@@ -325,7 +325,7 @@ func TestApierTPRate(t *testing.T) {
|
||||
// Test getIds
|
||||
var rplyRtIds []string
|
||||
expectedRtIds := []string{"RT_FS_USERS"}
|
||||
if err := rater.Call("ApierV1.GetTPRateIds", AttrGetTPRateIds{rt.TPid, utils.Paginator{0, 0, ""}}, &rplyRtIds); err != nil {
|
||||
if err := rater.Call("ApierV1.GetTPRateIds", AttrGetTPRateIds{rt.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyRtIds); err != nil {
|
||||
t.Error("Calling ApierV1.GetTPRateIds, got error: ", err.Error())
|
||||
} else if !reflect.DeepEqual(expectedRtIds, rplyRtIds) {
|
||||
t.Errorf("Calling ApierV1.GetTPDestinationIds expected: %v, received: %v", expectedRtIds, rplyRtIds)
|
||||
@@ -382,7 +382,7 @@ func TestApierTPDestinationRate(t *testing.T) {
|
||||
// Test getIds
|
||||
var rplyDrIds []string
|
||||
expectedDrIds := []string{"DR_FREESWITCH_USERS"}
|
||||
if err := rater.Call("ApierV1.GetTPDestinationRateIds", AttrTPDestinationRateIds{dr.TPid, utils.Paginator{0, 0, ""}}, &rplyDrIds); err != nil {
|
||||
if err := rater.Call("ApierV1.GetTPDestinationRateIds", AttrTPDestinationRateIds{dr.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyDrIds); err != nil {
|
||||
t.Error("Calling ApierV1.GetTPDestinationRateIds, got error: ", err.Error())
|
||||
} else if !reflect.DeepEqual(expectedDrIds, rplyDrIds) {
|
||||
t.Errorf("Calling ApierV1.GetTPDestinationRateIds expected: %v, received: %v", expectedDrIds, rplyDrIds)
|
||||
@@ -436,7 +436,7 @@ func TestApierTPRatingPlan(t *testing.T) {
|
||||
// Test getIds
|
||||
var rplyRpIds []string
|
||||
expectedRpIds := []string{"RETAIL1"}
|
||||
if err := rater.Call("ApierV1.GetTPRatingPlanIds", AttrGetTPRatingPlanIds{rp.TPid, utils.Paginator{0, 0, ""}}, &rplyRpIds); err != nil {
|
||||
if err := rater.Call("ApierV1.GetTPRatingPlanIds", AttrGetTPRatingPlanIds{rp.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyRpIds); err != nil {
|
||||
t.Error("Calling ApierV1.GetTPRatingPlanIds, got error: ", err.Error())
|
||||
} else if !reflect.DeepEqual(expectedRpIds, rplyRpIds) {
|
||||
t.Errorf("Calling ApierV1.GetTPRatingPlanIds expected: %v, received: %v", expectedRpIds, rplyRpIds)
|
||||
|
||||
@@ -77,7 +77,14 @@ func (self *ApierV1) ImportTPZipFile(attrs AttrImportTPZipFile, reply *string) e
|
||||
*reply = "ERROR: missing TPid!"
|
||||
return err
|
||||
}
|
||||
csvImporter := engine.TPCSVImporter{attrs.TPid, self.StorDb, path, ',', false, ""}
|
||||
csvImporter := engine.TPCSVImporter{
|
||||
TPid: attrs.TPid,
|
||||
StorDb: self.StorDb,
|
||||
DirPath: path,
|
||||
Sep: ',',
|
||||
Verbose: false,
|
||||
ImportId: "",
|
||||
}
|
||||
if errImport := csvImporter.Run(); errImport != nil {
|
||||
return errImport
|
||||
}
|
||||
|
||||
@@ -58,7 +58,11 @@ func (self *ApierV1) GetTPActionPlan(attrs AttrGetTPActionPlan, reply *utils.TPA
|
||||
} else if len(ats) == 0 {
|
||||
return errors.New(utils.ERR_NOT_FOUND)
|
||||
} else { // Got the data we need, convert it
|
||||
atRply := &utils.TPActionPlan{attrs.TPid, attrs.Id, ats[attrs.Id]}
|
||||
atRply := &utils.TPActionPlan{
|
||||
TPid: attrs.TPid,
|
||||
Id: attrs.Id,
|
||||
ActionPlan: ats[attrs.Id],
|
||||
}
|
||||
*reply = *atRply
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -56,7 +56,11 @@ func (self *ApierV1) GetTPActionTriggers(attrs AttrGetTPActionTriggers, reply *u
|
||||
} else if len(atsMap) == 0 {
|
||||
return errors.New(utils.ERR_NOT_FOUND)
|
||||
} else {
|
||||
atRply := &utils.TPActionTriggers{attrs.TPid, attrs.ActionTriggersId, atsMap[attrs.ActionTriggersId]}
|
||||
atRply := &utils.TPActionTriggers{
|
||||
TPid: attrs.TPid,
|
||||
ActionTriggersId: attrs.ActionTriggersId,
|
||||
ActionTriggers: atsMap[attrs.ActionTriggersId],
|
||||
}
|
||||
*reply = *atRply
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -22,13 +22,14 @@ import (
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -239,7 +240,6 @@ func (cdre *CdrExporter) metaHandler(tag, arg string) (string, error) {
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported METATAG: %s", tag)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Compose and cache the header
|
||||
|
||||
@@ -121,7 +121,7 @@ func main() {
|
||||
}
|
||||
|
||||
fmt.Println("Welcome to CGRateS console!")
|
||||
fmt.Println("Type `help` for a list of commands\n")
|
||||
fmt.Print("Type `help` for a list of commands\n\n")
|
||||
|
||||
line := liner.NewLiner()
|
||||
defer line.Close()
|
||||
|
||||
@@ -424,7 +424,7 @@ func main() {
|
||||
cdrStats.AddQueue(engine.NewCdrStatsFromCdrStatsCfg(cfg.CDRStatConfig), nil)
|
||||
}
|
||||
server.RpcRegister(cdrStats)
|
||||
server.RpcRegister(&v1.CDRStatsV1{cdrStats}) // Public APIs
|
||||
server.RpcRegister(&v1.CDRStatsV1{CdrStats: cdrStats}) // Public APIs
|
||||
}
|
||||
|
||||
responder := &engine.Responder{ExitChan: exitChan}
|
||||
|
||||
@@ -116,7 +116,14 @@ func main() {
|
||||
if *tpid == "" {
|
||||
log.Fatal("TPid required, please define it via *-tpid* command argument.")
|
||||
}
|
||||
csvImporter := engine.TPCSVImporter{*tpid, storDb, *dataPath, ',', *verbose, *runId}
|
||||
csvImporter := engine.TPCSVImporter{
|
||||
TPid: *tpid,
|
||||
StorDb: storDb,
|
||||
DirPath: *dataPath,
|
||||
Sep: ',',
|
||||
Verbose: *verbose,
|
||||
ImportId: *runId,
|
||||
}
|
||||
if errImport := csvImporter.Run(); errImport != nil {
|
||||
log.Fatal(errImport)
|
||||
}
|
||||
@@ -218,7 +225,17 @@ func main() {
|
||||
if *flush {
|
||||
dstIds, rplIds, rpfIds, rpAliases, lcrIds = nil, nil, nil, nil, nil // Should reload all these on flush
|
||||
}
|
||||
if err = rater.Call("ApierV1.ReloadCache", utils.ApiReloadCache{dstIds, rplIds, rpfIds, actIds, shgIds, rpAliases, accAliases, lcrIds, dcs}, &reply); err != nil {
|
||||
if err = rater.Call("ApierV1.ReloadCache", utils.ApiReloadCache{
|
||||
DestinationIds: dstIds,
|
||||
RatingPlanIds: rplIds,
|
||||
RatingProfileIds: rpfIds,
|
||||
ActionIds: actIds,
|
||||
SharedGroupIds: shgIds,
|
||||
RpAliases: rpAliases,
|
||||
AccAliases: accAliases,
|
||||
LCRIds: lcrIds,
|
||||
DerivedChargers: dcs,
|
||||
}, &reply); err != nil {
|
||||
log.Printf("WARNING: Got error on cache reload: %s\n", err.Error())
|
||||
}
|
||||
actTmgIds, _ := loader.GetLoadedIds(engine.ACTION_TIMING_PREFIX)
|
||||
|
||||
@@ -109,7 +109,7 @@ func durRemoteRater(cd *engine.CallDescriptor) (time.Duration, error) {
|
||||
result := engine.CallCost{}
|
||||
client, err := rpc.Dial("tcp", *raterAddress)
|
||||
if err != nil {
|
||||
return nilDuration, fmt.Errorf("Could not connect to engine: ", err.Error())
|
||||
return nilDuration, fmt.Errorf("Could not connect to engine: %s", err.Error())
|
||||
}
|
||||
defer client.Close()
|
||||
start := time.Now()
|
||||
|
||||
@@ -21,6 +21,7 @@ package engine
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@@ -28,7 +29,7 @@ import (
|
||||
)
|
||||
|
||||
type ActionTrigger struct {
|
||||
Id string // uniquely identify the trigger
|
||||
Id string // for visual identification
|
||||
ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance
|
||||
// stats: *min_asr, *max_asr, *min_acd, *max_acd, *min_acc, *max_acc
|
||||
ThresholdValue float64
|
||||
@@ -102,6 +103,11 @@ func (at *ActionTrigger) Match(a *Action) bool {
|
||||
if a == nil {
|
||||
return true
|
||||
}
|
||||
// if we have Id than we can draw an early conclusion
|
||||
if a.Id != "" {
|
||||
match, _ := regexp.MatchString(a.Id, at.Id)
|
||||
return match
|
||||
}
|
||||
id := a.BalanceType == "" || at.BalanceType == a.BalanceType
|
||||
direction := a.Direction == "" || at.BalanceDirection == a.Direction
|
||||
thresholdType, thresholdValue, destinationId, weight, ratingSubject, category, sharedGroup := true, true, true, true, true, true, true
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestBalanceMatchFilter(t *testing.T) {
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Weight: 1, precision: 1, RatingSubject: "", DestinationId: ""}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ func TestBalanceMatchFilterEmpty(t *testing.T) {
|
||||
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func TestBalanceMatchFilterId(t *testing.T) {
|
||||
mb1 := &Balance{Id: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationId: "NAT"}
|
||||
mb2 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
if !mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestBalanceMatchFilterDiffId(t *testing.T) {
|
||||
mb1 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
mb2 := &Balance{Id: "T2", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
|
||||
if mb1.MatchFilter(mb2) {
|
||||
t.Error("Match filter failure: %+v != %+v", mb1, mb2)
|
||||
t.Errorf("Match filter failure: %+v != %+v", mb1, mb2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +235,6 @@ func TestBalanceMatchActionTriggerSharedGroup(t *testing.T) {
|
||||
func TestBalanceIsDefault(t *testing.T) {
|
||||
b := &Balance{Weight: 0}
|
||||
if !b.IsDefault() {
|
||||
t.Errorf("Balance should be default: +v", b)
|
||||
t.Errorf("Balance should be default: %+v", b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +457,7 @@ 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
|
||||
//log.Printf("ORIG CD: %+v", origCD)
|
||||
account := origAcc.Clone()
|
||||
if account.AllowNegative {
|
||||
return -1, nil
|
||||
@@ -538,6 +539,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool) (cc *CallCost, er
|
||||
if cd.TOR == "" {
|
||||
cd.TOR = MINUTES
|
||||
}
|
||||
//log.Printf("Debit CD: %+v", cd)
|
||||
cc, err = account.debitCreditBalance(cd, !dryRun, dryRun)
|
||||
//log.Print("HERE: ", cc, err)
|
||||
if err != nil {
|
||||
|
||||
@@ -679,7 +679,7 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
return fmt.Errorf("Could not parse action weight: %v", err)
|
||||
}
|
||||
a := &Action{
|
||||
Id: utils.GenUUID(),
|
||||
Id: tag,
|
||||
ActionType: record[ACTSCSVIDX_ACTION],
|
||||
BalanceType: record[ACTSCSVIDX_BALANCE_TYPE],
|
||||
Direction: record[ACTSCSVIDX_DIRECTION],
|
||||
@@ -719,6 +719,12 @@ func (csvr *CSVReader) LoadActions() (err error) {
|
||||
if _, err := utils.ParseDate(a.ExpirationString); err != nil {
|
||||
return fmt.Errorf("Could not parse expiration time: %v", err)
|
||||
}
|
||||
// update Id
|
||||
idx := 0
|
||||
if previous, ok := csvr.actions[tag]; ok {
|
||||
idx = len(previous)
|
||||
}
|
||||
a.Id = a.Id + strconv.Itoa(idx)
|
||||
csvr.actions[tag] = append(csvr.actions[tag], a)
|
||||
}
|
||||
return
|
||||
@@ -815,7 +821,7 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) {
|
||||
}
|
||||
|
||||
at := &ActionTrigger{
|
||||
Id: utils.GenUUID(),
|
||||
Id: tag,
|
||||
ThresholdType: record[ATRIGCSVIDX_THRESHOLD_TYPE],
|
||||
ThresholdValue: value,
|
||||
Recurrent: recurrent,
|
||||
@@ -834,6 +840,12 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) {
|
||||
ActionsId: record[ATRIGCSVIDX_ACTIONS_TAG],
|
||||
Weight: weight,
|
||||
}
|
||||
// update Id
|
||||
idx := 0
|
||||
if previous, ok := csvr.actionsTriggers[tag]; ok {
|
||||
idx = len(previous)
|
||||
}
|
||||
at.Id = at.Id + strconv.Itoa(idx)
|
||||
csvr.actionsTriggers[tag] = append(csvr.actionsTriggers[tag], at)
|
||||
}
|
||||
return
|
||||
|
||||
@@ -696,7 +696,7 @@ func TestLoadActions(t *testing.T) {
|
||||
as1 := csvr.actions["MINI"]
|
||||
expected := []*Action{
|
||||
&Action{
|
||||
Id: as1[0].Id,
|
||||
Id: "MINI0",
|
||||
ActionType: TOPUP_RESET,
|
||||
BalanceType: CREDIT,
|
||||
Direction: OUTBOUND,
|
||||
@@ -710,7 +710,7 @@ func TestLoadActions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
&Action{
|
||||
Id: as1[1].Id,
|
||||
Id: "MINI1",
|
||||
ActionType: TOPUP,
|
||||
BalanceType: MINUTES,
|
||||
Direction: OUTBOUND,
|
||||
@@ -732,7 +732,7 @@ func TestLoadActions(t *testing.T) {
|
||||
as2 := csvr.actions["SHARED"]
|
||||
expected = []*Action{
|
||||
&Action{
|
||||
Id: as2[0].Id,
|
||||
Id: "SHARED0",
|
||||
ActionType: TOPUP,
|
||||
BalanceType: CREDIT,
|
||||
Direction: OUTBOUND,
|
||||
@@ -867,7 +867,7 @@ func TestLoadActionTriggers(t *testing.T) {
|
||||
}
|
||||
atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0]
|
||||
expected := &ActionTrigger{
|
||||
Id: atr.Id,
|
||||
Id: "STANDARD_TRIGGER0",
|
||||
BalanceType: MINUTES,
|
||||
BalanceDirection: OUTBOUND,
|
||||
ThresholdType: TRIGGER_MIN_COUNTER,
|
||||
@@ -882,7 +882,7 @@ func TestLoadActionTriggers(t *testing.T) {
|
||||
}
|
||||
atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1]
|
||||
expected = &ActionTrigger{
|
||||
Id: atr.Id,
|
||||
Id: "STANDARD_TRIGGER1",
|
||||
BalanceType: MINUTES,
|
||||
BalanceDirection: OUTBOUND,
|
||||
ThresholdType: TRIGGER_MAX_BALANCE,
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -561,7 +562,7 @@ func (dbr *DbReader) LoadActions() (err error) {
|
||||
acts := make([]*Action, len(tpacts))
|
||||
for idx, tpact := range tpacts {
|
||||
acts[idx] = &Action{
|
||||
Id: utils.GenUUID(),
|
||||
Id: tag + strconv.Itoa(idx),
|
||||
ActionType: tpact.Identifier,
|
||||
BalanceType: tpact.BalanceType,
|
||||
Direction: tpact.Direction,
|
||||
@@ -650,7 +651,7 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
|
||||
for idx, apiAtr := range atrsLst {
|
||||
balance_expiration_date, _ := utils.ParseTimeDetectLayout(apiAtr.BalanceExpirationDate)
|
||||
atrs[idx] = &ActionTrigger{
|
||||
Id: utils.GenUUID(),
|
||||
Id: key + strconv.Itoa(idx),
|
||||
ThresholdType: apiAtr.ThresholdType,
|
||||
ThresholdValue: apiAtr.ThresholdValue,
|
||||
Recurrent: apiAtr.Recurrent,
|
||||
@@ -841,7 +842,7 @@ func (dbr *DbReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
|
||||
enacts := make([]*Action, len(tpacts))
|
||||
for idx, tpact := range tpacts {
|
||||
enacts[idx] = &Action{
|
||||
Id: utils.GenUUID(),
|
||||
Id: tag + strconv.Itoa(idx),
|
||||
ActionType: tpact.Identifier,
|
||||
BalanceType: tpact.BalanceType,
|
||||
Direction: tpact.Direction,
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestStatsSimplifyCDR(t *testing.T) {
|
||||
cdr.AnswerTime != qcdr.AnswerTime ||
|
||||
cdr.Usage != qcdr.Usage ||
|
||||
cdr.Cost != qcdr.Cost {
|
||||
t.Error("Failed to simplify cdr: %+v", qcdr)
|
||||
t.Errorf("Failed to simplify cdr: %+v", qcdr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,83 +101,83 @@ func TestAcceptCdr(t *testing.T) {
|
||||
}
|
||||
sq.conf = &CdrStats{}
|
||||
if sq.conf.AcceptCdr(cdr) != true {
|
||||
t.Error("Should have accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{TOR: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{CdrHost: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{CdrSource: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{Direction: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{Tenant: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{Category: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{Account: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{Subject: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{RatedAccount: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{RatedSubject: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{DestinationPrefix: []string{"test"}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{DestinationPrefix: []string{"test", "123"}}
|
||||
if sq.conf.AcceptCdr(cdr) != true {
|
||||
t.Error("Should have accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC)}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC), time.Date(2014, 7, 3, 13, 43, 0, 0, time.UTC)}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC)}}
|
||||
if sq.conf.AcceptCdr(cdr) != true {
|
||||
t.Error("Should have accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC), time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC)}}
|
||||
if sq.conf.AcceptCdr(cdr) != true {
|
||||
t.Error("Should have accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{UsageInterval: []time.Duration{11 * time.Second}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{UsageInterval: []time.Duration{1 * time.Second, 10 * time.Second}}
|
||||
if sq.conf.AcceptCdr(cdr) == true {
|
||||
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
sq.conf = &CdrStats{UsageInterval: []time.Duration{10 * time.Second, 11 * time.Second}}
|
||||
if sq.conf.AcceptCdr(cdr) != true {
|
||||
t.Error("Should have accepted thif CDR: %+v", cdr)
|
||||
t.Errorf("Should have accepted thif CDR: %+v", cdr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,12 +185,12 @@ func TestStatsQueueIds(t *testing.T) {
|
||||
cdrStats := NewStats(dataStorage)
|
||||
ids := []string{}
|
||||
if err := cdrStats.GetQueueIds(0, &ids); err != nil {
|
||||
t.Error("Error getting queue ids: ", err)
|
||||
t.Error("Errorf getting queue ids: ", err)
|
||||
}
|
||||
result := len(ids)
|
||||
expected := 2
|
||||
if result != expected {
|
||||
t.Errorf("Error loading stats queues. Expected %v was %v", expected, result)
|
||||
t.Errorf("Errorf loading stats queues. Expected %v was %v", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ func TestMySQLSetGetTPTiming(t *testing.T) {
|
||||
if tmgs, err := mysqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ func TestPSQLSetGetTPTiming(t *testing.T) {
|
||||
if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
|
||||
}
|
||||
// Update
|
||||
tm.Time = "00:00:01"
|
||||
@@ -77,7 +77,7 @@ func TestPSQLSetGetTPTiming(t *testing.T) {
|
||||
if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []s
|
||||
}
|
||||
for _, key := range dKeys {
|
||||
if len(key) <= len(DESTINATION_PREFIX) {
|
||||
Logger.Warning(fmt.Sprintf("Got malformed destination id: ", key))
|
||||
Logger.Warning(fmt.Sprintf("Got malformed destination id: %s", key))
|
||||
continue
|
||||
}
|
||||
if _, err = rs.GetDestination(key[len(DESTINATION_PREFIX):]); err != nil {
|
||||
|
||||
@@ -478,7 +478,7 @@ func (self *SQLStorage) SetTPLCRs(tpid string, lcrs map[string]*LCR) error {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
buffer.WriteRune(',')
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%v','%v')",
|
||||
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%v','%v', '%v')",
|
||||
tpid, lcr.Direction, lcr.Tenant, lcr.Customer, entry.DestinationId, entry.Category, entry.Strategy, entry.Suppliers, act.ActivationTime, entry.Weight))
|
||||
i++
|
||||
}
|
||||
@@ -608,10 +608,10 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
for _, at := range aTriggers {
|
||||
for idx, at := range aTriggers {
|
||||
saved := tx.Save(TpActionTrigger{
|
||||
Tpid: tpid,
|
||||
Tag: atId,
|
||||
Tag: atId + strconv.Itoa(idx),
|
||||
ThresholdType: at.ThresholdType,
|
||||
ThresholdValue: at.ThresholdValue,
|
||||
Recurrent: at.Recurrent,
|
||||
|
||||
@@ -133,7 +133,7 @@ func TestExecuteActions(t *testing.T) {
|
||||
} else if len(acnt.BalanceMap) != 2 {
|
||||
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
|
||||
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
|
||||
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
} else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 10 {
|
||||
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ func TestExecuteActions2(t *testing.T) {
|
||||
} else if len(acnt.BalanceMap) != 2 {
|
||||
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
|
||||
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
|
||||
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
} else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 0 {
|
||||
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func TestExecuteActions3(t *testing.T) {
|
||||
} else if len(acnt.BalanceMap) != 1 {
|
||||
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
|
||||
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
|
||||
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package sessionmanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/osipsdagram"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -62,7 +63,8 @@ func (osipsev *OsipsEvent) AsEvent(evStr string) utils.Event {
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) String() string {
|
||||
return fmt.Sprintf("%+v", osipsev)
|
||||
mrsh, _ := json.Marshal(osipsev)
|
||||
return string(mrsh)
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetName() string {
|
||||
|
||||
@@ -22,12 +22,13 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/osipsdagram"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewOSipsSessionManager(cfg *config.CGRConfig, rater, cdrsrv engine.Connector) (*OsipsSessionManager, error) {
|
||||
@@ -133,7 +134,6 @@ func (osm *OsipsSessionManager) SubscribeEvents(evStop chan struct{}) error {
|
||||
time.Sleep(osm.cgrCfg.OsipsEvSubscInterval)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (osm *OsipsSessionManager) OnOpensipsStart(cdrDagram *osipsdagram.OsipsEvent) {
|
||||
|
||||
@@ -514,7 +514,7 @@ type TPActionTiming struct {
|
||||
|
||||
type TPActionTriggers struct {
|
||||
TPid string // Tariff plan id
|
||||
ActionTriggersId string // Profile id
|
||||
ActionTriggersId string // action trigger id
|
||||
ActionTriggers []*TPActionTrigger // Set of triggers grouped in this profile
|
||||
}
|
||||
|
||||
@@ -531,6 +531,7 @@ func (self *TPActionTriggers) AsExportSlice() [][]string {
|
||||
}
|
||||
|
||||
type TPActionTrigger struct {
|
||||
Id string
|
||||
ThresholdType string // This threshold type
|
||||
ThresholdValue float64 // Threshold
|
||||
Recurrent bool // reset executed flag each run
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestNewRSRField1(t *testing.T) {
|
||||
}
|
||||
// Separator escaped
|
||||
if rsrField, err := NewRSRField(`~sip_redirected_to:s\/sip:\+49(\d+)@/0$1/`); err == nil {
|
||||
t.Error("Parse error, field rule does not contain correct number of separators, received: %v", rsrField)
|
||||
t.Errorf("Parse error, field rule does not contain correct number of separators, received: %v", rsrField)
|
||||
}
|
||||
// One extra separator but escaped
|
||||
expRSRField3 := &RSRField{Id: "sip_redirected_to",
|
||||
|
||||
@@ -193,11 +193,11 @@ func TestUsageMultiply(t *testing.T) {
|
||||
func TestCostMultiply(t *testing.T) {
|
||||
cdr := StoredCdr{Cost: 1.01}
|
||||
if cdr.CostMultiply(1.19, 4); cdr.Cost != 1.2019 {
|
||||
t.Error("Unexpected cost after multiply: %v", cdr.Cost)
|
||||
t.Errorf("Unexpected cost after multiply: %v", cdr.Cost)
|
||||
}
|
||||
cdr = StoredCdr{Cost: 1.01}
|
||||
if cdr.CostMultiply(1000, 0); cdr.Cost != 1010 {
|
||||
t.Error("Unexpected cost after multiply: %v", cdr.Cost)
|
||||
t.Errorf("Unexpected cost after multiply: %v", cdr.Cost)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user