added remove rating profile api + console

This commit is contained in:
Radu Ioan Fericean
2015-08-18 19:19:56 +03:00
parent 3d4626de5a
commit 891f407b54
11 changed files with 180 additions and 20 deletions

View File

@@ -34,7 +34,7 @@ import (
)
const (
OK = "OK"
OK = utils.OK
)
type ApierV1 struct {
@@ -925,7 +925,7 @@ func (self *ApierV1) ReloadCache(attrs utils.ApiReloadCache, reply *string) erro
}); err != nil {
return err
}
*reply = "OK"
*reply = utils.OK
return nil
}
@@ -1122,6 +1122,49 @@ func (self *ApierV1) LoadTariffPlanFromFolder(attrs utils.AttrLoadTpFromFolder,
return err
}
}
*reply = "OK"
*reply = utils.OK
return nil
}
type AttrRemoveRatingProfile struct {
Direction string
Tennat string
Category string
Subject string
}
func (arrp *AttrRemoveRatingProfile) GetId() (result string) {
if arrp.Direction != "" && arrp.Direction != utils.ANY {
result += arrp.Direction
result += utils.CONCATENATED_KEY_SEP
} else {
return
}
if arrp.Tennat != "" && arrp.Tennat != utils.ANY {
result += arrp.Tennat
result += utils.CONCATENATED_KEY_SEP
} else {
return
}
if arrp.Category != "" && arrp.Category != utils.ANY {
result += arrp.Category
result += utils.CONCATENATED_KEY_SEP
} else {
return
}
if arrp.Subject != "" && arrp.Subject != utils.ANY {
result += arrp.Subject
}
return
}
func (self *ApierV1) RemoveRatingProfile(attr AttrRemoveRatingProfile, reply *string) error {
err := self.RatingDb.RemoveRatingProfile(attr.GetId())
if err != nil {
*reply = err.Error()
return err
}
*reply = utils.OK
return nil
}

View File

@@ -0,0 +1,66 @@
/*
Rating system designed to be used in VoIP Carriers World
Copyright (C) 2012-2015 ITsysCOM
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 console
import (
"github.com/cgrates/cgrates/apier/v1"
"github.com/cgrates/cgrates/utils"
)
func init() {
c := &CmdRemRatingProfile{
name: "ratingprofile_rem",
rpcMethod: "ApierV1.RemoveRatingProfile",
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
}
// Commander implementation
type CmdRemRatingProfile struct {
name string
rpcMethod string
rpcParams *v1.AttrRemoveRatingProfile
rpcResult string
*CommandExecuter
}
func (self *CmdRemRatingProfile) Name() string {
return self.name
}
func (self *CmdRemRatingProfile) RpcMethod() string {
return self.rpcMethod
}
func (self *CmdRemRatingProfile) RpcParams(reset bool) interface{} {
if reset || self.rpcParams == nil {
self.rpcParams = &v1.AttrRemoveRatingProfile{Direction: utils.OUT}
}
return self.rpcParams
}
func (self *CmdRemRatingProfile) PostprocessRpcParams() error {
return nil
}
func (self *CmdRemRatingProfile) RpcResult() interface{} {
var s string
return &s
}

View File

@@ -199,12 +199,13 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
}
// history record method
func (rpf *RatingProfile) GetHistoryRecord() history.Record {
func (rpf *RatingProfile) GetHistoryRecord(deleted bool) history.Record {
js, _ := json.Marshal(rpf)
return history.Record{
Id: rpf.Id,
Filename: history.RATING_PROFILES_FN,
Payload: js,
Deleted: deleted,
}
}

View File

@@ -46,6 +46,7 @@ type RatingStorage interface {
SetRatingPlan(*RatingPlan) error
GetRatingProfile(string, bool) (*RatingProfile, error)
SetRatingProfile(*RatingProfile) error
RemoveRatingProfile(string) error
GetDestination(string) (*Destination, error)
SetDestination(*Destination) error
GetLCR(string, bool) (*LCR, error)

View File

@@ -312,7 +312,22 @@ func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
ms.dict[utils.RATING_PROFILE_PREFIX+rpf.Id] = result
response := 0
if historyScribe != nil {
go historyScribe.Record(rpf.GetHistoryRecord(), &response)
go historyScribe.Record(rpf.GetHistoryRecord(false), &response)
}
return
}
func (ms *MapStorage) RemoveRatingProfile(key string) (err error) {
for k := range ms.dict {
if strings.HasPrefix(k, key) {
delete(ms.dict, key)
cache2go.RemKey(k)
response := 0
rpf := &RatingProfile{Id: key}
if historyScribe != nil {
go historyScribe.Record(rpf.GetHistoryRecord(true), &response)
}
}
}
return
}

View File

@@ -156,7 +156,7 @@ func (ms *MongoStorage) GetRatingProfile(key string) (rp *RatingProfile, err err
func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile) error {
if historyScribe != nil {
response := 0
historyScribe.Record(rp.GetHistoryRecord(), &response)
historyScribe.Record(rp.GetHistoryRecord(false), &response)
}
return ms.db.C("ratingprofiles").Insert(rp)
}

View File

@@ -399,11 +399,31 @@ func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
err = rs.db.Set(utils.RATING_PROFILE_PREFIX+rpf.Id, result)
if err == nil && historyScribe != nil {
response := 0
go historyScribe.Record(rpf.GetHistoryRecord(), &response)
go historyScribe.Record(rpf.GetHistoryRecord(false), &response)
}
return
}
func (rs *RedisStorage) RemoveRatingProfile(key string) error {
keys, err := rs.db.Keys(utils.RATING_PROFILE_PREFIX + key + "*")
if err != nil {
return err
}
for _, key := range keys {
_, err = rs.db.Del(key)
if err != nil {
return err
}
cache2go.RemKey(key)
rpf := &RatingProfile{Id: key}
if err == nil && historyScribe != nil {
response := 0
go historyScribe.Record(rpf.GetHistoryRecord(true), &response)
}
}
return nil
}
func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) {
key = utils.LCR_PREFIX + key
if !skipCache {

View File

@@ -63,7 +63,7 @@ func NewFileScribe(fileRoot string, saveInterval time.Duration) (*FileScribe, er
func (s *FileScribe) Record(rec Record, out *int) error {
s.mu.Lock()
fileToSave := rec.Filename
recordsMap[fileToSave] = recordsMap[fileToSave].SetOrAdd(&rec)
recordsMap[fileToSave] = recordsMap[fileToSave].Modify(&rec)
// flood protection for save method (do not save on every loop iteration)
if s.waitingFile == fileToSave {

View File

@@ -40,7 +40,7 @@ func NewMockScribe() (*MockScribe, error) {
func (s *MockScribe) Record(rec Record, out *int) error {
s.mu.Lock()
fn := rec.Filename
recordsMap[fn] = recordsMap[fn].SetOrAdd(&rec)
recordsMap[fn] = recordsMap[fn].Modify(&rec)
s.mu.Unlock()
s.save(fn)
return nil

View File

@@ -38,6 +38,7 @@ type Record struct {
Id string
Filename string
Payload []byte
Deleted bool
}
type records []*Record
@@ -63,12 +64,17 @@ func (rs records) Sort() {
sort.Sort(rs)
}
func (rs records) SetOrAdd(rec *Record) records {
func (rs records) Modify(rec *Record) records {
//rs.Sort()
n := len(rs)
i := sort.Search(n, func(i int) bool { return rs[i].Id >= rec.Id })
if i < n && rs[i].Id == rec.Id {
rs[i] = rec
if rec.Deleted {
// delete
rs = append(rs[:i], rs[i+1:]...)
} else {
rs[i] = rec
}
} else {
// i is the index where it would be inserted.
rs = append(rs, nil)

View File

@@ -26,7 +26,7 @@ import (
func TestHistorySet(t *testing.T) {
rs := records{&Record{Id: "first"}}
second := &Record{Id: "first"}
rs.SetOrAdd(second)
rs.Modify(second)
if len(rs) != 1 || rs[0] != second {
t.Error("error setting new value: ", rs[0])
}
@@ -35,18 +35,26 @@ func TestHistorySet(t *testing.T) {
func TestHistoryAdd(t *testing.T) {
rs := records{&Record{Id: "first"}}
second := &Record{Id: "second"}
rs = rs.SetOrAdd(second)
rs = rs.Modify(second)
if len(rs) != 2 || rs[1] != second {
t.Error("error setting new value: ", rs)
}
}
func BenchmarkSetOrAdd(b *testing.B) {
var rs records
for i := 0; i < 1000; i++ {
rs = rs.SetOrAdd(&Record{Id: strconv.Itoa(i)})
}
for i := 0; i < b.N; i++ {
rs.SetOrAdd(&Record{Id: "400"})
func TestHistoryRemove(t *testing.T) {
rs := records{&Record{Id: "first"}, &Record{Id: "second"}}
rs = rs.Modify(&Record{Id: "first", Deleted: true})
if len(rs) != 1 || rs[0].Id != "second" {
t.Error("error deleting record: ", rs)
}
}
func BenchmarkModify(b *testing.B) {
var rs records
for i := 0; i < 1000; i++ {
rs = rs.Modify(&Record{Id: strconv.Itoa(i)})
}
for i := 0; i < b.N; i++ {
rs.Modify(&Record{Id: "400"})
}
}