diff --git a/engine/action.go b/engine/action.go index f40e092e7..ac1d1fe38 100644 --- a/engine/action.go +++ b/engine/action.go @@ -69,6 +69,7 @@ const ( MAIL_ASYNC = "*mail_async" UNLIMITED = "*unlimited" CDRLOG = "*cdrlog" + SET_DDESTINATIONS = "*set_ddestinations" ) func (a *Action) Clone() *Action { @@ -125,6 +126,8 @@ func getActionFunc(typ string) (actionTypeFunc, bool) { return callUrlAsync, true case MAIL_ASYNC: return mailAsync, true + case SET_DDESTINATIONS: + return setddestinations, true } return nil, false } @@ -485,6 +488,44 @@ func mailAsync(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) err return nil } +func setddestinations(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error { + var ddcDestId string + for _, bchain := range ub.BalanceMap { + for _, b := range bchain { + for destId := range b.DestinationIds { + if strings.HasPrefix(destId, "*ddc") { + ddcDestId = destId + break + } + } + if ddcDestId != "" { + break + } + } + if ddcDestId != "" { + break + } + } + if ddcDestId != "" { + // make slice from prefixes + prefixes := make([]string, len(sq.Metrics)) + i := 0 + for p := range sq.Metrics { + prefixes[i] = p + i++ + } + // update destid in storage + ratingStorage.SetDestination(&Destination{Id: ddcDestId, Prefixes: prefixes}) + // remove existing from cache + CleanStalePrefixes([]string{ddcDestId}) + // update new values from redis + ratingStorage.CacheRatingPrefixValues(map[string][]string{utils.DESTINATION_PREFIX: []string{utils.DESTINATION_PREFIX + ddcDestId}}) + } else { + return utils.ErrNotFound + } + return nil +} + // Structure to store actions according to weight type Actions []*Action diff --git a/engine/actions_test.go b/engine/actions_test.go index eb4de9d71..53886b664 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -25,6 +25,7 @@ import ( "testing" "time" + "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/utils" ) @@ -1231,7 +1232,47 @@ func TestActionCdrLogParamsWithOverload(t *testing.T) { } } -/********************************** Benchmarks ********************************/ +func TestActionSetDDestination(t *testing.T) { + acc := &Account{BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{DestinationIds: utils.NewStringMap("*ddc_test")}}}} + origD := &Destination{Id: "*ddc_test", Prefixes: []string{"111", "222"}} + ratingStorage.SetDestination(origD) + ratingStorage.CacheRatingPrefixValues(map[string][]string{utils.DESTINATION_PREFIX: []string{utils.DESTINATION_PREFIX + "*ddc_test"}}) + // check redis and cache + if d, err := ratingStorage.GetDestination("*ddc_test"); err != nil || !reflect.DeepEqual(d, origD) { + t.Error("Error storing destination: ", d, err) + } + x1, err := cache2go.Get(utils.DESTINATION_PREFIX + "111") + if _, ok := x1.(map[interface{}]struct{})["*ddc_test"]; err != nil || !ok { + t.Error("Error cacheing destination: ", x1) + } + x1, err = cache2go.Get(utils.DESTINATION_PREFIX + "222") + if _, ok := x1.(map[interface{}]struct{})["*ddc_test"]; err != nil || !ok { + t.Error("Error cacheing destination: ", x1) + } + setddestinations(acc, &StatsQueueTriggered{Metrics: map[string]float64{"333": 1, "444": 1}}, nil, nil) + alteredDest := &Destination{Id: "*ddc_test", Prefixes: []string{"333", "444"}} + if d, err := ratingStorage.GetDestination("*ddc_test"); err != nil || !reflect.DeepEqual(d, alteredDest) { + t.Error("Error storing destination: ", d, err) + } + x1, err = cache2go.Get(utils.DESTINATION_PREFIX + "111") + if err == nil { + t.Error("Error cacheing destination: ", x1) + } + x1, err = cache2go.Get(utils.DESTINATION_PREFIX + "222") + if err == nil { + t.Error("Error cacheing destination: ", x1) + } + x1, err = cache2go.Get(utils.DESTINATION_PREFIX + "333") + if _, ok := x1.(map[interface{}]struct{})["*ddc_test"]; err != nil || !ok { + t.Error("Error cacheing destination: ", x1) + } + x1, err = cache2go.Get(utils.DESTINATION_PREFIX + "444") + if _, ok := x1.(map[interface{}]struct{})["*ddc_test"]; err != nil || !ok { + t.Error("Error cacheing destination: ", x1) + } +} + +/**************** Benchmarks ********************************/ func BenchmarkUUID(b *testing.B) { m := make(map[string]int, 1000) diff --git a/engine/balances.go b/engine/balances.go index 4f9d055f1..1468e1a6b 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -133,7 +133,8 @@ func (b *Balance) IsDefault() bool { } func (b *Balance) IsExpired() bool { - return !b.ExpirationDate.IsZero() && b.ExpirationDate.Before(time.Now()) + // check if it expires in the next second + return !b.ExpirationDate.IsZero() && b.ExpirationDate.Before(time.Now().Add(1*time.Second)) } func (b *Balance) IsActive() bool {