Added Action and Action plan migration methods and tests

This commit is contained in:
Edwardro22
2017-02-24 19:45:47 +02:00
parent 61aef1a154
commit 34a4e0b4bc
9 changed files with 341 additions and 137 deletions

View File

@@ -56,6 +56,12 @@ type v1Balance struct {
TimingIDs string
Disabled bool
}
type v1UnitsCounter struct {
Direction string
BalanceType string
// Units float64
Balances v1BalanceChain // first balance is the general one (no destination)
}
func (b *v1Balance) IsDefault() bool {
return (b.DestinationIds == "" || b.DestinationIds == utils.ANY) &&
@@ -67,13 +73,6 @@ func (b *v1Balance) IsDefault() bool {
b.Disabled == false
}
type v1UnitsCounter struct {
Direction string
BalanceType string
// Units float64
Balances v1BalanceChain // first balance is the general one (no destination)
}
func (v1Acc v1Account) AsAccount() (ac engine.Account, err error) {
// transfer data into new structurse
ac = engine.Account{

View File

@@ -26,24 +26,17 @@ import (
)
func TestV1AccountAsAccount(t *testing.T) {
v1b1 := &v1Balance{Value: 10, Weight: 10, DestinationIds: "NAT"}
v1Acc := &v1Account{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]v1BalanceChain{utils.VOICE: v1BalanceChain{v1b1}, utils.MONETARY: v1BalanceChain{&v1Balance{Value: 21}}}}
v1b := &v1Balance{Value: 10, Weight: 10, DestinationIds: "NAT"}
v1Acc := &v1Account{Id: "OUT:CUSTOMER_1:rif", BalanceMap: map[string]v1BalanceChain{utils.VOICE: v1BalanceChain{v1b}, utils.MONETARY: v1BalanceChain{&v1Balance{Value: 21}}}}
v2 := &engine.Balance{Uuid: "", ID: "", Value: 10, Directions: utils.StringMap{"*OUT": true}, Weight: 10, DestinationIDs: utils.StringMap{"NAT": true}, RatingSubject: "", Categories: utils.NewStringMap(""), SharedGroups: utils.NewStringMap(""), TimingIDs: utils.NewStringMap("")}
m2 := &engine.Balance{Uuid: "", ID: "", Value: 21, Directions: utils.StringMap{"*OUT": true}, DestinationIDs: utils.NewStringMap(""), RatingSubject: "", Categories: utils.NewStringMap(""), SharedGroups: utils.NewStringMap(""), TimingIDs: utils.NewStringMap("")}
testAccount := &engine.Account{ID: "CUSTOMER_1:rif", BalanceMap: map[string]engine.Balances{utils.VOICE: engine.Balances{v2}, utils.MONETARY: engine.Balances{m2}}, UnitCounters: engine.UnitCounters{}, ActionTriggers: engine.ActionTriggers{}}
def := v1b1.IsDefault()
if def != false {
if def := v1b.IsDefault(); def != false {
t.Errorf("Expecting: false, received: true")
}
newAcc, err := v1Acc.AsAccount()
if err != nil {
if newAcc, err := v1Acc.AsAccount(); err != nil {
t.Error(err)
}
if !reflect.DeepEqual(*testAccount, newAcc) {
} else if !reflect.DeepEqual(*testAccount, newAcc) {
t.Errorf("Expecting: %+v, received: %+v", *testAccount, newAcc)
t.Errorf(" \n")
}
}

86
migrator/action.go Normal file
View File

@@ -0,0 +1,86 @@
/*
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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"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 (v1Act v1Action) AsAction() (act engine.Action, err error) {
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
}

75
migrator/action_plan.go Normal file
View File

@@ -0,0 +1,75 @@
/*
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 <http://www.gnu.org/licenses/>
*/
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.ASAP
}
func (v1AP v1ActionPlan) AsActionPlan() (ap engine.ActionPlan, err error) {
for idx, actionId := range v1AP.AccountIds {
idElements := strings.Split(actionId, utils.CONCATENATED_KEY_SEP)
if len(idElements) != 3 {
continue
}
v1AP.AccountIds[idx] = fmt.Sprintf("%s:%s", idElements[1], idElements[2])
}
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
}

View File

@@ -0,0 +1,40 @@
/*
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 <http://www.gnu.org/licenses/>
*/
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)}}}}
if newap, err := v1ap.AsActionPlan(); err != nil {
t.Error(err)
} else 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)
}
}

35
migrator/action_test.go Normal file
View File

@@ -0,0 +1,35 @@
/*
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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"reflect"
"testing"
"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{}}
if newact, err := v1act.AsAction(); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(*act, newact) {
t.Errorf("Expecting: %+v, received: %+v", *act, newact)
}
}

View File

@@ -0,0 +1,88 @@
package migrator
import (
"strings"
"time"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
type v1ActionTrigger struct {
Id string
ThresholdType string
ThresholdValue float64
Recurrent bool
MinSleep time.Duration
BalanceId string
BalanceType string
BalanceDirection string
BalanceDestinationIds string
BalanceWeight float64
BalanceExpirationDate time.Time
BalanceTimingTags string
BalanceRatingSubject string
BalanceCategory string
BalanceSharedGroup string
BalanceDisabled bool
Weight float64
ActionsId string
MinQueuedItems int
Executed bool
}
type v1ActionTriggers []*v1ActionTrigger
func (v1Act v1ActionTrigger) AsActionTrigger() (at engine.ActionTrigger, err error) {
at = engine.ActionTrigger{
UniqueID: 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.BalanceDirection != "" {
bf.Directions = utils.StringMapPointer(utils.ParseStringMap(v1Act.BalanceDirection))
}
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.BalanceDisabled != false {
bf.Disabled = utils.BoolPointer(v1Act.BalanceDisabled)
}
if !v1Act.BalanceExpirationDate.IsZero() {
bf.ExpirationDate = utils.TimePointer(v1Act.BalanceExpirationDate)
}
at.Balance = bf
if at.ThresholdType == "*min_counter" ||
at.ThresholdType == "*max_counter" {
at.ThresholdType = strings.Replace(at.ThresholdType, "_", "_event_", 1)
}
return
}

View File

@@ -26,10 +26,10 @@ import (
"github.com/cgrates/cgrates/utils"
)
var v1ActionTriggers1 = `[{"BalanceType": "*monetary","BalanceDirection": "*out","ThresholdType":"*max_balance", "ThresholdValue" :2, "ActionsId": "TEST_ACTIONS", "Executed": true}]`
var v1ActionTriggers1 = `{"BalanceType": "*monetary","BalanceDirection": "*out","ThresholdType":"*max_balance", "ThresholdValue" :2, "ActionsId": "TEST_ACTIONS", "Executed": true}`
func TestV1ActionTriggersAsActionTriggers(t *testing.T) {
atrs := engine.ActionTriggers{&engine.ActionTrigger{
atrs := &engine.ActionTrigger{
Balance: &engine.BalanceFilter{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
@@ -38,15 +38,14 @@ func TestV1ActionTriggersAsActionTriggers(t *testing.T) {
ThresholdValue: 2,
ActionsID: "TEST_ACTIONS",
Executed: true,
},
}
var v1actstrgrs v1ActionTriggers
var v1actstrgrs v1ActionTrigger
if err := json.Unmarshal([]byte(v1ActionTriggers1), &v1actstrgrs); err != nil {
t.Error(err)
}
if newatrs, err := v1actstrgrs.AsActionTriggers(); err != nil {
if newatrs, err := v1actstrgrs.AsActionTrigger(); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(atrs, newatrs) {
t.Errorf("Expecting: %+v, received: %+v", atrs, newatrs)
} else if !reflect.DeepEqual(*atrs, newatrs) {
t.Errorf("Expecting: %+v, received: %+v", *atrs, newatrs)
}
}

View File

@@ -1,111 +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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"strings"
"time"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
type v1ActionTriggers []*v1ActionTrigger
type v1ActionTrigger struct {
Id string
ThresholdType string
ThresholdValue float64
Recurrent bool
MinSleep time.Duration
BalanceId string
BalanceType string
BalanceDirection string
BalanceDestinationIds string
BalanceWeight float64
BalanceExpirationDate time.Time
BalanceTimingTags string
BalanceRatingSubject string
BalanceCategory string
BalanceSharedGroup string
BalanceDisabled bool
Weight float64
ActionsId string
MinQueuedItems int
Executed bool
}
func (v1Act v1ActionTriggers) AsActionTriggers() (at engine.ActionTriggers, err error) {
at = make(engine.ActionTriggers, len(v1Act))
for index, oldAct := range v1Act {
atr := &engine.ActionTrigger{
UniqueID: oldAct.Id,
ThresholdType: oldAct.ThresholdType,
ThresholdValue: oldAct.ThresholdValue,
Recurrent: oldAct.Recurrent,
MinSleep: oldAct.MinSleep,
Weight: oldAct.Weight,
ActionsID: oldAct.ActionsId,
MinQueuedItems: oldAct.MinQueuedItems,
Executed: oldAct.Executed,
}
bf := &engine.BalanceFilter{}
if oldAct.BalanceId != "" {
bf.ID = utils.StringPointer(oldAct.BalanceId)
}
if oldAct.BalanceType != "" {
bf.Type = utils.StringPointer(oldAct.BalanceType)
}
if oldAct.BalanceRatingSubject != "" {
bf.RatingSubject = utils.StringPointer(oldAct.BalanceRatingSubject)
}
if oldAct.BalanceDirection != "" {
bf.Directions = utils.StringMapPointer(utils.ParseStringMap(oldAct.BalanceDirection))
}
if oldAct.BalanceDestinationIds != "" {
bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(oldAct.BalanceDestinationIds))
}
if oldAct.BalanceTimingTags != "" {
bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(oldAct.BalanceTimingTags))
}
if oldAct.BalanceCategory != "" {
bf.Categories = utils.StringMapPointer(utils.ParseStringMap(oldAct.BalanceCategory))
}
if oldAct.BalanceSharedGroup != "" {
bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(oldAct.BalanceSharedGroup))
}
if oldAct.BalanceWeight != 0 {
bf.Weight = utils.Float64Pointer(oldAct.BalanceWeight)
}
if oldAct.BalanceDisabled != false {
bf.Disabled = utils.BoolPointer(oldAct.BalanceDisabled)
}
if !oldAct.BalanceExpirationDate.IsZero() {
bf.ExpirationDate = utils.TimePointer(oldAct.BalanceExpirationDate)
}
atr.Balance = bf
at[index] = atr
if at[index].ThresholdType == "*min_counter" ||
at[index].ThresholdType == "*max_counter" {
at[index].ThresholdType = strings.Replace(at[index].ThresholdType, "_", "_event_", 1)
}
}
return at, nil
}