mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
how does it work section in introduction and code formatting
This commit is contained in:
@@ -57,4 +57,4 @@ resetvolumediscountseconds
|
||||
addrecievedcallseconds
|
||||
:Example: curl "http://127.0.0.1:8000/addrecievedcallseconds?cstmid=vdf&subj=rif&dest=0257@amount=100"
|
||||
resetuserbudget
|
||||
:Example: curl "http://127.0.0.1:8000/resetuserbudget?cstmid=vdf&subj=rif&dest=0257"
|
||||
:Example: curl "http://127.0.0.1:8000/resetuserbudget?cstmid=vdf&subj=rif&dest=0257"
|
||||
|
||||
@@ -2,7 +2,7 @@ Introduction
|
||||
============
|
||||
CGRates is a very fast and easy scalable rating engine targeted especially for telecom providers.
|
||||
|
||||
It is written in go (http://golang.net) and accesible from any language via JSON RPC. The code is well documented (go doc compliant api docs) and heavily tested.
|
||||
It is written in go (http://golang.net) and accessible from any language via JSON RPC. The code is well documented (go doc compliant API docs) and heavily tested.
|
||||
|
||||
Supported databases: kyoto_ cabinet, redis_, mongodb_.
|
||||
|
||||
@@ -20,4 +20,28 @@ Features
|
||||
+ Fully/Easy configurable
|
||||
+ Very fast (5000+ req/sec)
|
||||
+ Good documentation
|
||||
+ Commercial support available
|
||||
+ Commercial support available
|
||||
|
||||
How does CGRates work?
|
||||
----------------------
|
||||
Let's start with the most important function: finding the cost of a certain call. The call information comes to CGRates as the following values: subject, destination, start time and end time. The engine will lookup in the database for the activation periods applicable to the received subject and destination. What are the activation periods?
|
||||
|
||||
The activation period is a structure describing different prices for a call on different intervals of time. This structure has an activation time, from this time on the activation period is in effect and one ore more (usually more than one) intervals with prices. An interval is looking like this:
|
||||
|
||||
::
|
||||
|
||||
type Interval struct {
|
||||
Month time.Month
|
||||
MonthDay int
|
||||
WeekDays []time.Weekday
|
||||
StartTime, EndTime string // ##:##:## format
|
||||
Ponder, ConnectFee, Price, BillingUnit float64
|
||||
}
|
||||
|
||||
It specifies the Month, the MonthDay, the WeekDays and the StartTime and the EndTime when the Interval's Price is in effect.
|
||||
|
||||
For example the interval {"Month": 1, "WeekDays":[1,2,3,4,5]. "StartTime":"18:00:00", "Price":0.1, "BillingUnit": 1} specifies that the Price for the first month of each year from Monday to Friday starting 18:00 is 0.1 cents per second. Most structure elements are optional and they can be combined in any way it makes sense. If an element is omitted it means it is zero ore any.
|
||||
|
||||
The ConnectFee specifies the connection price for the call if this interval is the first one from the call and the Ponder will establishes which interval will set the price for a call segment if more then one applies to it.
|
||||
|
||||
The other functions relay on a user budget structure to manage the postpaid and prepaid different quotas.
|
||||
|
||||
@@ -33,15 +33,15 @@ type Destination struct {
|
||||
Serializes the destination for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (d *Destination) store() (result string) {
|
||||
for _, p := range d.Prefixes {
|
||||
result += p + ","
|
||||
}
|
||||
result = strings.TrimRight(result, ",")
|
||||
return
|
||||
for _, p := range d.Prefixes {
|
||||
result += p + ","
|
||||
}
|
||||
result = strings.TrimRight(result, ",")
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Destination) restore(input string) {
|
||||
d.Prefixes = strings.Split(input, ",")
|
||||
d.Prefixes = strings.Split(input, ",")
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -18,9 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package timespans
|
||||
|
||||
import (
|
||||
// "log"
|
||||
"strings"
|
||||
// "log"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -41,56 +41,56 @@ type TariffPlan struct {
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (tp *TariffPlan) store() (result string) {
|
||||
result += strconv.FormatFloat(tp.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.ReceivedCallSecondsLimit, 'f', -1, 64) + ";"
|
||||
if tp.RecivedCallBonus == nil {
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
}
|
||||
result += tp.RecivedCallBonus.store() + ";"
|
||||
for i, mb := range tp.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
if tp.VolumeDiscountThresholds != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, vd := range tp.VolumeDiscountThresholds {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += strconv.FormatFloat(vd.Volume, 'f', -1, 64) + "|" + strconv.FormatFloat(vd.Discount, 'f', -1, 64)
|
||||
}
|
||||
result = strings.TrimRight(result, ";")
|
||||
return
|
||||
result += strconv.FormatFloat(tp.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.ReceivedCallSecondsLimit, 'f', -1, 64) + ";"
|
||||
if tp.RecivedCallBonus == nil {
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
}
|
||||
result += tp.RecivedCallBonus.store() + ";"
|
||||
for i, mb := range tp.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
if tp.VolumeDiscountThresholds != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, vd := range tp.VolumeDiscountThresholds {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += strconv.FormatFloat(vd.Volume, 'f', -1, 64) + "|" + strconv.FormatFloat(vd.Discount, 'f', -1, 64)
|
||||
}
|
||||
result = strings.TrimRight(result, ";")
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (tp *TariffPlan) restore(input string) {
|
||||
elements := strings.Split(input, ";")
|
||||
tp.SmsCredit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
tp.Traffic, _ = strconv.ParseFloat(elements[1], 64)
|
||||
tp.ReceivedCallSecondsLimit, _ = strconv.ParseFloat(elements[2], 64)
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
tp.RecivedCallBonus.restore(elements[3])
|
||||
for _, mbs := range strings.Split(elements[4], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
tp.MinuteBuckets = append(tp.MinuteBuckets, mb)
|
||||
}
|
||||
if len(elements) > 5 {
|
||||
for _, vdss := range strings.Split(elements[5], ",") {
|
||||
vd := &VolumeDiscount{}
|
||||
vds := strings.Split(vdss, "|")
|
||||
vd.Volume, _ = strconv.ParseFloat(vds[0], 64)
|
||||
vd.Discount, _ = strconv.ParseFloat(vds[1], 64)
|
||||
tp.VolumeDiscountThresholds = append(tp.VolumeDiscountThresholds, vd)
|
||||
}
|
||||
}
|
||||
elements := strings.Split(input, ";")
|
||||
tp.SmsCredit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
tp.Traffic, _ = strconv.ParseFloat(elements[1], 64)
|
||||
tp.ReceivedCallSecondsLimit, _ = strconv.ParseFloat(elements[2], 64)
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
tp.RecivedCallBonus.restore(elements[3])
|
||||
for _, mbs := range strings.Split(elements[4], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
tp.MinuteBuckets = append(tp.MinuteBuckets, mb)
|
||||
}
|
||||
if len(elements) > 5 {
|
||||
for _, vdss := range strings.Split(elements[5], ",") {
|
||||
vd := &VolumeDiscount{}
|
||||
vds := strings.Split(vdss, "|")
|
||||
vd.Volume, _ = strconv.ParseFloat(vds[0], 64)
|
||||
vd.Discount, _ = strconv.ParseFloat(vds[1], 64)
|
||||
tp.VolumeDiscountThresholds = append(tp.VolumeDiscountThresholds, vd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -115,26 +115,26 @@ type RecivedCallBonus struct {
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) store() (result string) {
|
||||
result += strconv.FormatFloat(rcb.Credit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.SmsCredit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.Traffic, 'f', -1, 64)
|
||||
if rcb.MinuteBucket != nil {
|
||||
result += ","
|
||||
result += rcb.MinuteBucket.store()
|
||||
}
|
||||
return
|
||||
result += strconv.FormatFloat(rcb.Credit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.SmsCredit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.Traffic, 'f', -1, 64)
|
||||
if rcb.MinuteBucket != nil {
|
||||
result += ","
|
||||
result += rcb.MinuteBucket.store()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) restore(input string) {
|
||||
elements := strings.Split(input, ",")
|
||||
rcb.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
rcb.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
rcb.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
if len(elements) > 3 {
|
||||
rcb.MinuteBucket = &MinuteBucket{}
|
||||
rcb.MinuteBucket.restore(elements[3])
|
||||
}
|
||||
elements := strings.Split(input, ",")
|
||||
rcb.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
rcb.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
rcb.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
if len(elements) > 3 {
|
||||
rcb.MinuteBucket = &MinuteBucket{}
|
||||
rcb.MinuteBucket.restore(elements[3])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func (ts *TimeSpan) Contains(t time.Time) bool {
|
||||
}
|
||||
|
||||
/*
|
||||
will set ne interval as spans's interval if new ponder is greater then span's interval ponder
|
||||
will set the interval as spans's interval if new ponder is greater then span's interval ponder
|
||||
or if the ponders are equal and new price is lower then spans's interval price
|
||||
*/
|
||||
func (ts *TimeSpan) SetInterval(i *Interval) {
|
||||
|
||||
@@ -20,9 +20,9 @@ package timespans
|
||||
import (
|
||||
// "log"
|
||||
"sort"
|
||||
"sync"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -74,44 +74,44 @@ func (bs bucketsorter) Less(j, i int) bool {
|
||||
Serializes the user budget for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ub *UserBudget) store() (result string) {
|
||||
result += strconv.FormatFloat(ub.Credit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.VolumeDiscountSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.ReceivedCallSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.Itoa(ub.ResetDayOfTheMonth) + ";"
|
||||
result += ub.TariffPlanId
|
||||
if ub.MinuteBuckets != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, mb := range ub.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
return
|
||||
result += strconv.FormatFloat(ub.Credit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.VolumeDiscountSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.ReceivedCallSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.Itoa(ub.ResetDayOfTheMonth) + ";"
|
||||
result += ub.TariffPlanId
|
||||
if ub.MinuteBuckets != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, mb := range ub.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the user budget for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ub *UserBudget) restore(input string) {
|
||||
elements := strings.Split(input, ";")
|
||||
ub.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
ub.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
ub.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
ub.VolumeDiscountSeconds, _ = strconv.ParseFloat(elements[3], 64)
|
||||
ub.ReceivedCallSeconds, _ = strconv.ParseFloat(elements[4], 64)
|
||||
ub.ResetDayOfTheMonth, _ = strconv.Atoi(elements[5])
|
||||
ub.TariffPlanId = elements[6]
|
||||
if len(elements) > 7 {
|
||||
for _, mbs := range strings.Split(elements[7], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
ub.MinuteBuckets = append(ub.MinuteBuckets, mb)
|
||||
}
|
||||
}
|
||||
elements := strings.Split(input, ";")
|
||||
ub.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
ub.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
ub.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
ub.VolumeDiscountSeconds, _ = strconv.ParseFloat(elements[3], 64)
|
||||
ub.ReceivedCallSeconds, _ = strconv.ParseFloat(elements[4], 64)
|
||||
ub.ResetDayOfTheMonth, _ = strconv.Atoi(elements[5])
|
||||
ub.TariffPlanId = elements[6]
|
||||
if len(elements) > 7 {
|
||||
for _, mbs := range strings.Split(elements[7], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
ub.MinuteBuckets = append(ub.MinuteBuckets, mb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user