Пример #1
0
func TestSmOsipsJsonCfg(t *testing.T) {
	eCfg := &SmOsipsJsonCfg{
		Enabled:    utils.BoolPointer(false),
		Listen_udp: utils.StringPointer("127.0.0.1:2020"),
		Ha_rater: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Server:  utils.StringPointer("internal"),
				Timeout: utils.StringPointer("100ms"),
			}},
		Ha_cdrs: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Server:  utils.StringPointer("internal"),
				Timeout: utils.StringPointer("100ms"),
			}},
		Create_cdr:                utils.BoolPointer(false),
		Debit_interval:            utils.StringPointer("10s"),
		Min_call_duration:         utils.StringPointer("0s"),
		Max_call_duration:         utils.StringPointer("3h"),
		Events_subscribe_interval: utils.StringPointer("60s"),
		Mi_addr:                   utils.StringPointer("127.0.0.1:8020"),
	}
	if cfg, err := dfCgrJsonCfg.SmOsipsJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #2
0
func TestApierV2itSetAccountActionTriggers(t *testing.T) {
	attrs := AttrSetAccountActionTriggers{
		Tenant:         "cgrates.org",
		Account:        "dan",
		GroupID:        utils.StringPointer("MONITOR_MAX_BALANCE"),
		ThresholdType:  utils.StringPointer(utils.TRIGGER_MAX_BALANCE),
		ThresholdValue: utils.Float64Pointer(50),
		BalanceType:    utils.StringPointer(utils.MONETARY),
		ActionsID:      utils.StringPointer("DISABLE_ACCOUNT"),
	}
	var reply string
	if err := apierRPC.Call("ApierV2.SetAccountActionTriggers", attrs, &reply); err != nil {
		t.Error(err)
	}
	var ats engine.ActionTriggers
	if err := apierRPC.Call("ApierV2.GetAccountActionTriggers", v1.AttrAcntAction{Tenant: "cgrates.org", Account: "dan"}, &ats); err != nil {
		t.Error(err)
	} else if len(ats) != 1 || ats[0].ID != *attrs.GroupID || ats[0].ThresholdValue != 50.0 {
		t.Errorf("Received: %+v", ats)
	}
	attrs.ThresholdValue = utils.Float64Pointer(55) // Change the threshold
	if err := apierRPC.Call("ApierV2.SetAccountActionTriggers", attrs, &reply); err != nil {
		t.Error(err)
	}
	if err := apierRPC.Call("ApierV2.GetAccountActionTriggers", v1.AttrAcntAction{Tenant: "cgrates.org", Account: "dan"}, &ats); err != nil {
		t.Error(err)
	} else if len(ats) != 1 || ats[0].ID != *attrs.GroupID || ats[0].ThresholdValue != 55.0 {
		t.Errorf("Received: %+v", ats)
	}
}
Пример #3
0
func TesSmFsConfigLoadFromJsonCfg(t *testing.T) {
	smFsJsnCfg := &SmFsJsonCfg{
		Enabled:        utils.BoolPointer(true),
		Create_cdr:     utils.BoolPointer(true),
		Subscribe_park: utils.BoolPointer(true),
		Connections: &[]*FsConnJsonCfg{
			&FsConnJsonCfg{
				Server:     utils.StringPointer("1.2.3.4:8021"),
				Password:   utils.StringPointer("ClueCon"),
				Reconnects: utils.IntPointer(5),
			},
			&FsConnJsonCfg{
				Server:     utils.StringPointer("2.3.4.5:8021"),
				Password:   utils.StringPointer("ClueCon"),
				Reconnects: utils.IntPointer(5),
			},
		},
	}
	eSmFsConfig := &SmFsConfig{Enabled: true,
		CreateCdr:     true,
		SubscribePark: true,
		Connections: []*FsConnConfig{
			&FsConnConfig{Server: "1.2.3.4:8021", Password: "******", Reconnects: 5},
			&FsConnConfig{Server: "1.2.3.4:8021", Password: "******", Reconnects: 5},
		},
	}
	smFsCfg := new(SmFsConfig)
	if err := smFsCfg.loadFromJsonCfg(smFsJsnCfg); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eSmFsConfig, smFsCfg) {
		t.Error("Received: ", smFsCfg)
	}
}
Пример #4
0
// Deprecated in rc8, replaced by AddAccountActionTriggers
func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	at := &engine.ActionTrigger{
		ID:             attr.ActionTriggersId,
		ThresholdType:  attr.ThresholdType,
		ThresholdValue: attr.ThresholdValue,
		Balance:        new(engine.BalanceFilter),
		Weight:         attr.Weight,
		ActionsID:      attr.ActionsId,
	}
	if attr.BalanceId != "" {
		at.Balance.ID = utils.StringPointer(attr.BalanceId)
	}
	if attr.BalanceType != "" {
		at.Balance.Type = utils.StringPointer(attr.BalanceType)
	}
	if attr.BalanceDirection != "" {
		at.Balance.Directions = &utils.StringMap{attr.BalanceDirection: true}
	}
	if attr.BalanceDestinationIds != "" {
		dstIDsMp := utils.StringMapFromSlice(strings.Split(attr.BalanceDestinationIds, utils.INFIELD_SEP))
		at.Balance.DestinationIDs = &dstIDsMp
	}
	if attr.BalanceRatingSubject != "" {
		at.Balance.RatingSubject = utils.StringPointer(attr.BalanceRatingSubject)
	}
	if attr.BalanceWeight != 0.0 {
		at.Balance.Weight = utils.Float64Pointer(attr.BalanceWeight)
	}
	if balExpiryTime, err := utils.ParseTimeDetectLayout(attr.BalanceExpiryTime, self.Config.DefaultTimezone); err != nil {
		return utils.NewErrServerError(err)
	} else {
		at.Balance.ExpirationDate = &balExpiryTime
	}
	if attr.BalanceSharedGroup != "" {
		at.Balance.SharedGroups = &utils.StringMap{attr.BalanceSharedGroup: true}
	}
	acntID := utils.AccountKey(attr.Tenant, attr.Account)
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		acnt, err := self.AccountDb.GetAccount(acntID)
		if err != nil {
			return 0, err
		}
		acnt.ActionTriggers = append(acnt.ActionTriggers, at)

		if err = self.AccountDb.SetAccount(acnt); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, acntID)
	if err != nil {
		return err
	}
	*reply = OK
	return nil
}
Пример #5
0
func TestDfRaterJsonCfg(t *testing.T) {
	eCfg := &RaterJsonCfg{Enabled: utils.BoolPointer(false), Balancer: utils.StringPointer(""), Cdrstats: utils.StringPointer(""),
		Historys: utils.StringPointer(""), Pubsubs: utils.StringPointer(""), Users: utils.StringPointer(""), Aliases: utils.StringPointer("")}
	if cfg, err := dfCgrJsonCfg.RaterJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Received: %+v", cfg)
	}
}
Пример #6
0
func TestDfListenJsonCfg(t *testing.T) {
	eCfg := &ListenJsonCfg{
		Rpc_json: utils.StringPointer("127.0.0.1:2012"),
		Rpc_gob:  utils.StringPointer("127.0.0.1:2013"),
		Http:     utils.StringPointer("127.0.0.1:2080")}
	if cfg, err := dfCgrJsonCfg.ListenJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #7
0
func testOnStorITCacheActions(t *testing.T) {
	acts := Actions{
		&Action{
			Id:               "MINI",
			ActionType:       TOPUP_RESET,
			ExpirationString: UNLIMITED,
			Weight:           10,
			Balance: &BalanceFilter{
				Type:       utils.StringPointer(utils.MONETARY),
				Uuid:       utils.StringPointer(utils.GenUUID()),
				Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
				Value: &utils.ValueFormula{Static: 10,
					Params: make(map[string]interface{})},
				Weight:   utils.Float64Pointer(10),
				Disabled: utils.BoolPointer(false),
				Timings:  make([]*RITiming, 0),
				Blocker:  utils.BoolPointer(false),
			},
		},
		&Action{
			Id:               "MINI",
			ActionType:       TOPUP,
			ExpirationString: UNLIMITED,
			Weight:           10,
			Balance: &BalanceFilter{
				Type:       utils.StringPointer(utils.VOICE),
				Uuid:       utils.StringPointer(utils.GenUUID()),
				Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
				Value: &utils.ValueFormula{Static: 100,
					Params: make(map[string]interface{})},
				Weight:         utils.Float64Pointer(10),
				RatingSubject:  utils.StringPointer("test"),
				DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")),
				Disabled:       utils.BoolPointer(false),
				Timings:        make([]*RITiming, 0),
				Blocker:        utils.BoolPointer(false),
			},
		},
	}
	if err := onStor.SetActions(acts[0].Id, acts, utils.NonTransactional); err != nil {
		t.Error(err)
	}
	if _, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); hasIt {
		t.Error("Already in cache")
	}
	if err := onStor.CacheDataFromDB(utils.ACTION_PREFIX, []string{acts[0].Id}, false); err != nil {
		t.Error(err)
	}
	if itm, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); !hasIt {
		t.Error("Did not cache")
	} else if rcv := itm.(Actions); !reflect.DeepEqual(acts, rcv) {
		t.Errorf("Expecting: %+v, received: %+v", acts, rcv)
	}
}
Пример #8
0
func TestDfHistServJsonCfg(t *testing.T) {
	eCfg := &HistServJsonCfg{
		Enabled:       utils.BoolPointer(false),
		History_dir:   utils.StringPointer("/var/lib/cgrates/history"),
		Save_interval: utils.StringPointer("1s"),
	}
	if cfg, err := dfCgrJsonCfg.HistServJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #9
0
func (self *ApierV1) SetActions(attrs V1AttrSetActions, reply *string) (err error) {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, action := range attrs.Actions {
		requiredFields := []string{"Identifier", "Weight"}
		if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions
			requiredFields = append(requiredFields, "Direction", "Units")
		}
		if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), action.Identifier, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, attrs.ActionsId); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			return utils.ErrExists
		}
	}
	storeActions := make(engine.Actions, len(attrs.Actions))
	for idx, apiAct := range attrs.Actions {
		a := &engine.Action{
			Id:               attrs.ActionsId,
			ActionType:       apiAct.Identifier,
			Weight:           apiAct.Weight,
			ExpirationString: apiAct.ExpiryTime,
			ExtraParameters:  apiAct.ExtraParameters,
			Filter:           apiAct.Filter,
			Balance: &engine.BalanceFilter{ // TODO: update this part
				Uuid:           utils.StringPointer(apiAct.BalanceUuid),
				ID:             utils.StringPointer(apiAct.BalanceId),
				Type:           utils.StringPointer(apiAct.BalanceType),
				Value:          &utils.ValueFormula{Static: apiAct.Units},
				Weight:         apiAct.BalanceWeight,
				Directions:     utils.StringMapPointer(utils.ParseStringMap(apiAct.Directions)),
				DestinationIDs: utils.StringMapPointer(utils.ParseStringMap(apiAct.DestinationIds)),
				RatingSubject:  utils.StringPointer(apiAct.RatingSubject),
				SharedGroups:   utils.StringMapPointer(utils.ParseStringMap(apiAct.SharedGroups)),
			},
		}
		storeActions[idx] = a
	}
	if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions, utils.NonTransactional); err != nil {
		return utils.NewErrServerError(err)
	}
	if err = self.RatingDb.CacheDataFromDB(utils.ACTION_PREFIX, []string{attrs.ActionsId}, true); err != nil {
		utils.NewErrServerError(err)
	}
	*reply = OK
	return nil
}
Пример #10
0
func TestDfResourceLimiterSJsonCfg(t *testing.T) {
	eCfg := &ResourceLimiterServJsonCfg{
		Enabled:             utils.BoolPointer(false),
		Cdrstats_conns:      &[]*HaPoolJsonCfg{},
		Cache_dump_interval: utils.StringPointer("0s"),
		Usage_ttl:           utils.StringPointer("3h"),
	}
	if cfg, err := dfCgrJsonCfg.ResourceLimiterJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #11
0
func TestDfMailerJsonCfg(t *testing.T) {
	eCfg := &MailerJsonCfg{
		Server:        utils.StringPointer("localhost"),
		Auth_user:     utils.StringPointer("cgrates"),
		Auth_password: utils.StringPointer("CGRateS.org"),
		From_address:  utils.StringPointer("*****@*****.**"),
	}
	if cfg, err := dfCgrJsonCfg.MailerJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #12
0
func TestLoadAccountActions(t *testing.T) {
	if len(csvr.accountActions) != 17 {
		t.Error("Failed to load account actions: ", len(csvr.accountActions))
	}
	aa := csvr.accountActions["vdf:minitsboy"]
	expected := &Account{
		ID: "vdf:minitsboy",
		UnitCounters: UnitCounters{
			utils.VOICE: []*UnitCounter{
				&UnitCounter{
					CounterType: "*event",
					Counters: CounterFilters{
						&CounterFilter{
							Value: 0,
							Filter: &BalanceFilter{
								ID:             utils.StringPointer("st0"),
								Type:           utils.StringPointer(utils.VOICE),
								Directions:     utils.StringMapPointer(utils.NewStringMap("*out")),
								DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")),
								SharedGroups:   nil,
								Categories:     nil,
								TimingIDs:      nil,
							},
						},
					},
				},
			},
		},
		ActionTriggers: csvr.actionsTriggers["STANDARD_TRIGGER"],
	}
	// set propper uuid
	for i, atr := range aa.ActionTriggers {
		csvr.actionsTriggers["STANDARD_TRIGGER"][i].ID = atr.ID
	}
	for i, b := range aa.UnitCounters[utils.VOICE][0].Counters {
		expected.UnitCounters[utils.VOICE][0].Counters[i].Filter.ID = b.Filter.ID
	}
	if !reflect.DeepEqual(aa.UnitCounters[utils.VOICE][0].Counters[0], expected.UnitCounters[utils.VOICE][0].Counters[0]) {
		t.Errorf("Error loading account action: %+v", utils.ToIJSON(aa.UnitCounters[utils.VOICE][0].Counters[0].Filter))
	}
	// test that it does not overwrite balances
	existing, err := accountingStorage.GetAccount(aa.ID)
	if err != nil || len(existing.BalanceMap) != 2 {
		t.Errorf("The account was not set before load: %+v", existing)
	}
	accountingStorage.SetAccount(aa)
	existing, err = accountingStorage.GetAccount(aa.ID)
	if err != nil || len(existing.BalanceMap) != 2 {
		t.Errorf("The set account altered the balances: %+v", existing)
	}
}
Пример #13
0
func TestLoadActionTriggers(t *testing.T) {
	if len(csvr.actionsTriggers) != 7 {
		t.Error("Failed to load action triggers: ", len(csvr.actionsTriggers))
	}
	atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0]
	expected := &ActionTrigger{
		ID:             "STANDARD_TRIGGER",
		UniqueID:       "st0",
		ThresholdType:  utils.TRIGGER_MIN_EVENT_COUNTER,
		ThresholdValue: 10,
		Balance: &BalanceFilter{
			ID:             nil,
			Type:           utils.StringPointer(utils.VOICE),
			Directions:     utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
			DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")),
			Categories:     nil,
			TimingIDs:      nil,
			SharedGroups:   nil,
			Disabled:       nil,
			Blocker:        nil,
		},
		Weight:    10,
		ActionsID: "SOME_1",
		Executed:  false,
	}
	if !reflect.DeepEqual(atr, expected) {
		t.Errorf("Error loading action trigger: %+v", utils.ToIJSON(atr.Balance))
	}
	atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1]
	expected = &ActionTrigger{
		ID:             "STANDARD_TRIGGER",
		UniqueID:       "st1",
		ThresholdType:  utils.TRIGGER_MAX_BALANCE,
		ThresholdValue: 200,
		Balance: &BalanceFilter{
			Type:           utils.StringPointer(utils.VOICE),
			Directions:     utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
			DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY")),
			Categories:     nil,
			TimingIDs:      nil,
			SharedGroups:   nil,
		},
		Weight:    10,
		ActionsID: "SOME_2",
		Executed:  false,
	}
	if !reflect.DeepEqual(atr, expected) {
		t.Errorf("Error loading action trigger: %+v", atr)
	}
}
Пример #14
0
func TestSmKamJsonCfg(t *testing.T) {
	eCfg := &SmKamJsonCfg{
		Enabled: utils.BoolPointer(false),
		Ha_rater: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Server:  utils.StringPointer("internal"),
				Timeout: utils.StringPointer("100ms"),
			}},
		Ha_cdrs: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Server:  utils.StringPointer("internal"),
				Timeout: utils.StringPointer("100ms"),
			}},
		Create_cdr:        utils.BoolPointer(false),
		Debit_interval:    utils.StringPointer("10s"),
		Min_call_duration: utils.StringPointer("0s"),
		Max_call_duration: utils.StringPointer("3h"),
		Connections: &[]*KamConnJsonCfg{
			&KamConnJsonCfg{
				Evapi_addr: utils.StringPointer("127.0.0.1:8448"),
				Reconnects: utils.IntPointer(5),
			},
		},
	}
	if cfg, err := dfCgrJsonCfg.SmKamJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #15
0
func TestSmAsteriskJsonCfg(t *testing.T) {
	eCfg := &SMAsteriskJsonCfg{
		Enabled: utils.BoolPointer(false),
		Sm_generic_conns: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Address: utils.StringPointer(utils.MetaInternal),
			}},
		Session_terminate_subscriber: &HaPoolJsonCfg{Address: utils.StringPointer(utils.MetaInternal)},
		Debit_interval:               utils.StringPointer("10s"),
		Min_call_duration:            utils.StringPointer("0s"),
		Max_call_duration:            utils.StringPointer("3h"),
		Asterisk_conns: &[]*AstConnJsonCfg{
			&AstConnJsonCfg{
				Address:          utils.StringPointer("127.0.0.1:8088"),
				User:             utils.StringPointer("cgrates"),
				Password:         utils.StringPointer("CGRateS.org"),
				Connect_attempts: utils.IntPointer(3),
				Reconnects:       utils.IntPointer(5),
			},
		},
	}
	if cfg, err := dfCgrJsonCfg.SmAsteriskJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #16
0
func GetUB() *Account {
	uc := &UnitCounter{
		Counters: CounterFilters{&CounterFilter{Value: 1}, &CounterFilter{Filter: &BalanceFilter{Weight: utils.Float64Pointer(20), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}, &CounterFilter{Filter: &BalanceFilter{Weight: utils.Float64Pointer(10), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("RET"))}}},
	}
	at := &ActionTrigger{
		ID:             "some_uuid",
		ThresholdValue: 100.0,
		Balance: &BalanceFilter{
			Type:           utils.StringPointer(utils.MONETARY),
			Directions:     utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
			DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")),
		},
		Weight:    10.0,
		ActionsID: "Commando",
	}
	var zeroTime time.Time
	zeroTime = zeroTime.UTC() // for deep equal to find location
	ub := &Account{
		ID:             "rif",
		AllowNegative:  true,
		BalanceMap:     map[string]Balances{utils.SMS: Balances{&Balance{Value: 14, ExpirationDate: zeroTime}}, utils.DATA: Balances{&Balance{Value: 1024, ExpirationDate: zeroTime}}, utils.VOICE: Balances{&Balance{Weight: 20, DestinationIDs: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}},
		UnitCounters:   UnitCounters{utils.SMS: []*UnitCounter{uc, uc}},
		ActionTriggers: ActionTriggers{at, at, at},
	}
	return ub
}
Пример #17
0
func TestTpActionTriggers(t *testing.T) {
	var atrs engine.ActionTriggers
	if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil {
		t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
	} else if len(atrs) != 9 {
		t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
	}
	var reply string
	if err := tpRPC.Call("ApierV1.SetActionTrigger", v1.AttrSetActionTrigger{
		GroupID:   "TestATR",
		UniqueID:  "Unique atr id",
		BalanceID: utils.StringPointer("BID1"),
	}, &reply); err != nil {
		t.Error("Got error on ApierV1.SetActionTrigger: ", err.Error())
	} else if reply != utils.OK {
		t.Errorf("Calling v1.SetActionTrigger got: %v", reply)
	}

	if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil {
		t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
	} else if len(atrs) != 10 {
		t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
	}
	if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{"TestATR"}}, &atrs); err != nil {
		t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error())
	} else if len(atrs) != 1 {
		t.Errorf("Calling v1.GetActionTriggers got: %v", atrs)
	}
	if atrs[0].ID != "TestATR" ||
		atrs[0].UniqueID != "Unique atr id" ||
		*atrs[0].Balance.ID != "BID1" {
		t.Error("Wrong action trigger set: ", utils.ToIJSON(atrs[0]))
	}
}
Пример #18
0
func TestBalanceMatchFilterId(t *testing.T) {
	mb1 := &Balance{ID: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationIDs: utils.NewStringMap("NAT")}
	mb2 := &BalanceFilter{ID: utils.StringPointer("T1"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIDs: nil}
	if !mb1.MatchFilter(mb2, false) {
		t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
	}
}
Пример #19
0
func TestBalanceMatchFilterDiffId(t *testing.T) {
	mb1 := &Balance{ID: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationIDs: utils.StringMap{}}
	mb2 := &BalanceFilter{ID: utils.StringPointer("T2"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIDs: nil}
	if mb1.MatchFilter(mb2, false) {
		t.Errorf("Match filter failure: %+v != %+v", mb1, mb2)
	}
}
Пример #20
0
func (self *ApierV1) RemoveBalances(attr *utils.AttrSetBalance, reply *string) error {
	if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	var expTime *time.Time
	if attr.ExpiryTime != nil {
		expTimeVal, err := utils.ParseTimeDetectLayout(*attr.ExpiryTime, self.Config.DefaultTimezone)
		if err != nil {
			*reply = err.Error()
			return err
		}
		expTime = &expTimeVal
	}
	accID := utils.AccountKey(attr.Tenant, attr.Account)
	if _, err := self.AccountDb.GetAccount(accID); err != nil {
		return utils.ErrNotFound
	}

	at := &engine.ActionTiming{}
	at.SetAccountIDs(utils.StringMap{accID: true})
	a := &engine.Action{
		ActionType: engine.REMOVE_BALANCE,
		Balance: &engine.BalanceFilter{
			Uuid:           attr.BalanceUUID,
			ID:             attr.BalanceID,
			Type:           utils.StringPointer(attr.BalanceType),
			ExpirationDate: expTime,
			RatingSubject:  attr.RatingSubject,
			Weight:         attr.Weight,
			Blocker:        attr.Blocker,
			Disabled:       attr.Disabled,
		},
	}
	if attr.Value != nil {
		a.Balance.Value = &utils.ValueFormula{Static: *attr.Value}
	}
	if attr.Directions != nil {
		a.Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(*attr.Directions))
	}
	if attr.DestinationIds != nil {
		a.Balance.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.DestinationIds))
	}
	if attr.Categories != nil {
		a.Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(*attr.Categories))
	}
	if attr.SharedGroups != nil {
		a.Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(*attr.SharedGroups))
	}
	if attr.TimingIds != nil {
		a.Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.TimingIds))
	}
	at.SetActions(engine.Actions{a})
	if err := at.Execute(); err != nil {
		*reply = err.Error()
		return err
	}
	*reply = OK
	return nil
}
Пример #21
0
func TestSmGenericJsonCfg(t *testing.T) {
	eCfg := &SmGenericJsonCfg{
		Enabled:       utils.BoolPointer(false),
		Listen_bijson: utils.StringPointer("127.0.0.1:2014"),
		Rals_conns: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Address: utils.StringPointer(utils.MetaInternal),
			}},
		Cdrs_conns: &[]*HaPoolJsonCfg{
			&HaPoolJsonCfg{
				Address: utils.StringPointer(utils.MetaInternal),
			}},
		Smg_replication_conns: &[]*HaPoolJsonCfg{},
		Debit_interval:        utils.StringPointer("0s"),
		Min_call_duration:     utils.StringPointer("0s"),
		Max_call_duration:     utils.StringPointer("3h"),
		Session_ttl:           utils.StringPointer("0s"),
		Session_indexes:       utils.StringSlicePointer([]string{}),
	}
	if cfg, err := dfCgrJsonCfg.SmGenericJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #22
0
func TestDfCdrsJsonCfg(t *testing.T) {
	eCfg := &CdrsJsonCfg{
		Enabled:         utils.BoolPointer(false),
		Extra_fields:    utils.StringSlicePointer([]string{}),
		Store_cdrs:      utils.BoolPointer(true),
		Rater:           utils.StringPointer("internal"),
		Pubsubs:         utils.StringPointer(""),
		Users:           utils.StringPointer(""),
		Aliases:         utils.StringPointer(""),
		Cdrstats:        utils.StringPointer(""),
		Cdr_replication: &[]*CdrReplicationJsonCfg{},
	}
	if cfg, err := dfCgrJsonCfg.CdrsJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Received: %+v", *cfg)
	}
}
Пример #23
0
func TestDfRalsJsonCfg(t *testing.T) {
	eCfg := &RalsJsonCfg{Enabled: utils.BoolPointer(false), Balancer: utils.StringPointer(""), Cdrstats_conns: &[]*HaPoolJsonCfg{},
		Historys_conns: &[]*HaPoolJsonCfg{}, Pubsubs_conns: &[]*HaPoolJsonCfg{}, Users_conns: &[]*HaPoolJsonCfg{}, Aliases_conns: &[]*HaPoolJsonCfg{},
		Rp_subject_prefix_matching: utils.BoolPointer(false), Lcr_subject_prefix_matching: utils.BoolPointer(false)}
	if cfg, err := dfCgrJsonCfg.RalsJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Errorf("Received: %+v", cfg)
	}
}
Пример #24
0
func TestDfCdrStatsJsonCfg(t *testing.T) {
	eCfg := &CdrStatsJsonCfg{
		Enabled:       utils.BoolPointer(false),
		Save_Interval: utils.StringPointer("1m"),
	}
	if cfg, err := dfCgrJsonCfg.CdrStatsJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", *cfg)
	}
}
Пример #25
0
func TestSmAsteriskJsonCfg(t *testing.T) {
	eCfg := &SMAsteriskJsonCfg{
		Enabled:    utils.BoolPointer(false),
		Create_cdr: utils.BoolPointer(false),
		Asterisk_conns: &[]*AstConnJsonCfg{
			&AstConnJsonCfg{
				Address:          utils.StringPointer("127.0.0.1:8088"),
				User:             utils.StringPointer("cgrates"),
				Password:         utils.StringPointer("CGRateS.org"),
				Connect_attempts: utils.IntPointer(3),
				Reconnects:       utils.IntPointer(5),
			},
		},
	}
	if cfg, err := dfCgrJsonCfg.SmAsteriskJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, cfg) {
		t.Error("Received: ", cfg)
	}
}
Пример #26
0
func TestDfGeneralJsonCfg(t *testing.T) {
	eCfg := &GeneralJsonCfg{
		Http_skip_tls_verify: utils.BoolPointer(false),
		Rounding_decimals:    utils.IntPointer(10),
		Dbdata_encoding:      utils.StringPointer("msgpack"),
		Tpexport_dir:         utils.StringPointer("/var/log/cgrates/tpe"),
		Http_failed_dir:      utils.StringPointer("/var/log/cgrates/http_failed"),
		Default_reqtype:      utils.StringPointer(utils.META_RATED),
		Default_category:     utils.StringPointer("call"),
		Default_tenant:       utils.StringPointer("cgrates.org"),
		Default_subject:      utils.StringPointer("cgrates"),
		Default_timezone:     utils.StringPointer("Local"),
		Connect_attempts:     utils.IntPointer(3),
		Reconnects:           utils.IntPointer(-1),
		Response_cache_ttl:   utils.StringPointer("3s"),
		Internal_ttl:         utils.StringPointer("2m")}
	if gCfg, err := dfCgrJsonCfg.GeneralJsonCfg(); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eCfg, gCfg) {
		t.Error("Received: ", gCfg)
	}
}
Пример #27
0
// Create counters for all triggered actions
func (acc *Account) InitCounters() {
	oldUcs := acc.UnitCounters
	acc.UnitCounters = make(UnitCounters)
	ucTempMap := make(map[string]*UnitCounter)
	for _, at := range acc.ActionTriggers {
		//log.Print("AT: ", utils.ToJSON(at))
		if !strings.Contains(at.ThresholdType, "counter") {
			continue
		}
		ct := utils.COUNTER_EVENT //default
		if strings.Contains(at.ThresholdType, "balance") {
			ct = utils.COUNTER_BALANCE
		}
		uc, exists := ucTempMap[at.Balance.GetType()+ct]
		//log.Print("CT: ", at.Balance.GetType()+ct)
		if !exists {
			uc = &UnitCounter{
				CounterType: ct,
			}
			ucTempMap[at.Balance.GetType()+ct] = uc
			uc.Counters = make(CounterFilters, 0)
			acc.UnitCounters[at.Balance.GetType()] = append(acc.UnitCounters[at.Balance.GetType()], uc)
		}

		c := &CounterFilter{Filter: at.Balance.Clone()}
		if (c.Filter.ID == nil || *c.Filter.ID == "") && at.UniqueID != "" {
			c.Filter.ID = utils.StringPointer(at.UniqueID)
		}
		//log.Print("C: ", utils.ToJSON(c))
		if !uc.Counters.HasCounter(c) {
			uc.Counters = append(uc.Counters, c)
		}
	}
	// copy old counter values
	for key, counters := range acc.UnitCounters {
		oldCounters, found := oldUcs[key]
		if !found {
			continue
		}
		for _, uc := range counters {
			for _, oldUc := range oldCounters {
				if uc.CopyCounterValues(oldUc) {
					break
				}
			}
		}
	}
	if len(acc.UnitCounters) == 0 {
		acc.UnitCounters = nil // leave it nil if empty
	}
}
Пример #28
0
func TestBalanceMatchActionTriggerId(t *testing.T) {
	at := &ActionTrigger{Balance: &BalanceFilter{ID: utils.StringPointer("test")}}
	b := &Balance{ID: "test"}
	if !b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.ID = "test1"
	if b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.ID = ""
	if b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.ID = "test"
	at.Balance.ID = nil
	if !b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
}
Пример #29
0
func TestApierV2itAddBalance(t *testing.T) {
	attrs := &utils.AttrSetBalance{
		Tenant:      "cgrates.org",
		Account:     "dan",
		BalanceType: utils.MONETARY,
		BalanceID:   utils.StringPointer(utils.META_DEFAULT),
		Value:       utils.Float64Pointer(5.0),
		Weight:      utils.Float64Pointer(10.0),
	}
	var reply string
	if err := apierRPC.Call("ApierV2.SetBalance", attrs, &reply); err != nil {
		t.Fatal(err)
	}
	var acnt engine.Account
	if err := apierRPC.Call("ApierV2.GetAccount", &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "dan"}, &acnt); err != nil {
		t.Error(err)
	} else if acnt.BalanceMap[utils.MONETARY][0].Value != 5.0 {
		t.Errorf("Unexpected balance received: %+v", acnt.BalanceMap[utils.MONETARY][0])
	}
}
Пример #30
0
func TestBalanceMatchActionTriggerRatingSubject(t *testing.T) {
	at := &ActionTrigger{Balance: &BalanceFilter{RatingSubject: utils.StringPointer("test")}}
	b := &Balance{RatingSubject: "test"}
	if !b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.RatingSubject = "test1"
	if b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.RatingSubject = ""
	if b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
	b.RatingSubject = "test"
	at.Balance.RatingSubject = nil
	if !b.MatchActionTrigger(at) {
		t.Errorf("Error matching action trigger: %+v %+v", b, at)
	}
}