mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
using years in get next activation time
This commit is contained in:
@@ -20,6 +20,7 @@ package main
|
||||
|
||||
import (
|
||||
"code.google.com/p/goconf/conf"
|
||||
"database/sql"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/cgrates/cgrates/balancer"
|
||||
@@ -156,6 +157,28 @@ func listenToHttpRequests() {
|
||||
http.ListenAndServe(stats_listen, nil)
|
||||
}
|
||||
|
||||
func startSessionManager(responder *timespans.Responder) {
|
||||
var connector sessionmanager.Connector
|
||||
if sm_rater == INTERNAL {
|
||||
connector = responder
|
||||
} else {
|
||||
var client *rpc.Client
|
||||
var err error
|
||||
if sm_json {
|
||||
client, err = jsonrpc.Dial("tcp", sm_rater)
|
||||
} else {
|
||||
client, err = rpc.Dial("tcp", sm_rater)
|
||||
}
|
||||
if err != nil {
|
||||
timespans.Logger.Crit(fmt.Sprintf("Could not connect to rater: %v", err))
|
||||
exitChan <- true
|
||||
}
|
||||
connector = &sessionmanager.RPCClientConnector{client}
|
||||
}
|
||||
sm := &sessionmanager.FSSessionManager{}
|
||||
sm.Connect(&sessionmanager.SessionDelegate{connector}, sm_freeswitch_server, sm_freeswitch_pass)
|
||||
}
|
||||
|
||||
func checkConfigSanity() {
|
||||
if sm_enabled && rater_enabled && rater_balancer != DISABLED {
|
||||
timespans.Logger.Crit("The session manager must not be enabled on a worker rater (change [rater]/balancer to disabled)!")
|
||||
@@ -213,30 +236,34 @@ func main() {
|
||||
}
|
||||
|
||||
if sm_enabled {
|
||||
go func() {
|
||||
var connector sessionmanager.Connector
|
||||
if sm_rater == INTERNAL {
|
||||
connector = responder
|
||||
} else {
|
||||
var client *rpc.Client
|
||||
if sm_json {
|
||||
client, err = jsonrpc.Dial("tcp", sm_rater)
|
||||
} else {
|
||||
client, err = rpc.Dial("tcp", sm_rater)
|
||||
}
|
||||
if err != nil {
|
||||
timespans.Logger.Crit(fmt.Sprintf("Could not connect to rater: %v", err))
|
||||
exitChan <- true
|
||||
}
|
||||
connector = &sessionmanager.RPCClientConnector{client}
|
||||
}
|
||||
sm := &sessionmanager.FSSessionManager{}
|
||||
sm.Connect(&sessionmanager.SessionDelegate{connector}, sm_freeswitch_server, sm_freeswitch_pass)
|
||||
}()
|
||||
go startSessionManager(responder)
|
||||
}
|
||||
|
||||
if mediator_enabled {
|
||||
go startMediator()
|
||||
db, err := sql.Open("postgres", fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=disable", mediator_host, mediator_port, mediator_db, mediator_user, mediator_password))
|
||||
//defer db.Close()
|
||||
if err != nil {
|
||||
timespans.Logger.Err(fmt.Sprintf("failed to open the database: %v", err))
|
||||
}
|
||||
var connector sessionmanager.Connector
|
||||
if sm_rater == INTERNAL {
|
||||
connector = responder
|
||||
} else {
|
||||
var client *rpc.Client
|
||||
var err error
|
||||
if sm_json {
|
||||
client, err = jsonrpc.Dial("tcp", sm_rater)
|
||||
} else {
|
||||
client, err = rpc.Dial("tcp", sm_rater)
|
||||
}
|
||||
if err != nil {
|
||||
timespans.Logger.Crit(fmt.Sprintf("Could not connect to rater: %v", err))
|
||||
exitChan <- true
|
||||
}
|
||||
connector = &sessionmanager.RPCClientConnector{client}
|
||||
}
|
||||
m := &Mediator{connector, db}
|
||||
_ = m
|
||||
}
|
||||
|
||||
<-exitChan
|
||||
|
||||
@@ -25,68 +25,61 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
_ "github.com/bmizerany/pq"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/timespans"
|
||||
"log"
|
||||
"net/rpc/jsonrpc"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func readDbRecord(db *sql.DB, searchedUUID string) (cc *timespans.CallCost, timespansText string, err error) {
|
||||
row := db.QueryRow(fmt.Sprintf("SELECT * FROM callcosts WHERE uuid='%s'", searchedUUID))
|
||||
type Mediator struct {
|
||||
Connector sessionmanager.Connector
|
||||
Db *sql.DB
|
||||
}
|
||||
|
||||
/*func readDbRecord(db *sql.DB, searchedUUID string) (cc *timespans.CallCost, timespansText string, err error) {
|
||||
|
||||
}*/
|
||||
|
||||
func (m *Mediator) parseCSV() {
|
||||
flag.Parse()
|
||||
file, err := os.Open(mediator_cdr_file)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
csvReader := csv.NewReader(bufio.NewReader(file))
|
||||
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
uuid := record[10]
|
||||
_ = uuid
|
||||
t, _ := time.Parse("2012-05-21 17:48:20", record[5])
|
||||
fmt.Println(t)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Mediator) GetCostsFromDB(searchedUUID string) (cc *timespans.CallCost, timespansText string, err error) {
|
||||
row := m.Db.QueryRow(fmt.Sprintf("SELECT * FROM callcosts WHERE uuid='%s'", searchedUUID))
|
||||
var uuid string
|
||||
cc = ×pans.CallCost{}
|
||||
err = row.Scan(&uuid, &cc.Direction, &cc.Tenant, &cc.TOR, &cc.Subject, &cc.Destination, &cc.Cost, &cc.ConnectFee, ×pansText)
|
||||
return
|
||||
}
|
||||
|
||||
func startMediator() {
|
||||
flag.Parse()
|
||||
useDB := true
|
||||
file, err := os.Open(mediator_cdr_file)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
db, err := sql.Open("postgres", fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=disable", mediator_host, mediator_port, mediator_db, mediator_user, mediator_password))
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
log.Printf("failed to open the database: %v", err)
|
||||
useDB = false
|
||||
}
|
||||
csvReader := csv.NewReader(bufio.NewReader(file))
|
||||
client, err := jsonrpc.Dial("tcp", "localhost:2001")
|
||||
useRPC := true
|
||||
if err != nil {
|
||||
log.Printf("Could not connect to rater server: %v!", err)
|
||||
useRPC = false
|
||||
}
|
||||
for record, err := csvReader.Read(); err == nil; record, err = csvReader.Read() {
|
||||
uuid := record[10]
|
||||
t, _ := time.Parse("2012-05-21 17:48:20", record[5])
|
||||
fmt.Println(t)
|
||||
if useDB {
|
||||
cc, timespansText, err := readDbRecord(db, uuid)
|
||||
if err != nil && useRPC {
|
||||
// try getting the price from the rater
|
||||
|
||||
tenant := record[0]
|
||||
subject := record[1]
|
||||
dest := record[2]
|
||||
t1, _ := time.Parse("2012-05-21 17:48:20", record[5])
|
||||
t2, _ := time.Parse("2012-05-21 17:48:20", record[6])
|
||||
cd := timespans.CallDescriptor{
|
||||
Direction: "OUT",
|
||||
Tenant: tenant,
|
||||
TOR: "0",
|
||||
Subject: subject,
|
||||
Destination: dest,
|
||||
TimeStart: t1,
|
||||
TimeEnd: t2}
|
||||
client.Call("Responder.GetCost", cd, cc)
|
||||
}
|
||||
_ = timespansText
|
||||
//log.Print(cc, timespansText)
|
||||
}
|
||||
}
|
||||
func (m *Mediator) GetCostsFromRater(record []string) (cc *timespans.CallCost, err error) {
|
||||
tenant := record[0]
|
||||
subject := record[1]
|
||||
dest := record[2]
|
||||
t1, _ := time.Parse("2012-05-21 17:48:20", record[5])
|
||||
t2, _ := time.Parse("2012-05-21 17:48:20", record[6])
|
||||
cd := timespans.CallDescriptor{
|
||||
Direction: "OUT",
|
||||
Tenant: tenant,
|
||||
TOR: "0",
|
||||
Subject: subject,
|
||||
Destination: dest,
|
||||
TimeStart: t1,
|
||||
TimeEnd: t2}
|
||||
err = m.Connector.GetCost(cd, cc)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ const (
|
||||
)
|
||||
|
||||
type Connector interface {
|
||||
GetCost(timespans.CallDescriptor, *timespans.CallCost) error
|
||||
Debit(timespans.CallDescriptor, *timespans.CallCost) error
|
||||
DebitCents(timespans.CallDescriptor, *float64) error
|
||||
DebitSeconds(timespans.CallDescriptor, *float64) error
|
||||
@@ -40,6 +41,10 @@ type RPCClientConnector struct {
|
||||
Client *rpc.Client
|
||||
}
|
||||
|
||||
func (rcc *RPCClientConnector) GetCost(cd timespans.CallDescriptor, cc *timespans.CallCost) error {
|
||||
return rcc.Client.Call("Responder.GetCost", cd, cc)
|
||||
}
|
||||
|
||||
func (rcc *RPCClientConnector) Debit(cd timespans.CallDescriptor, cc *timespans.CallCost) error {
|
||||
return rcc.Client.Call("Responder.Debit", cd, cc)
|
||||
}
|
||||
|
||||
@@ -112,16 +112,16 @@ MONTHS:
|
||||
if t.Equal(now) || t.After(now) {
|
||||
h, m, s := t.Clock()
|
||||
t = time.Date(now.Year(), now.Month(), t.Day(), h, m, s, 0, time.Local)
|
||||
return
|
||||
goto YEARS
|
||||
}
|
||||
if x+1 < len(i.Months) { // today was found in the list, jump to the next grater day
|
||||
if x+1 < len(i.Months) { // this month was found in the list so jump to next available month
|
||||
m = i.Months[x+1]
|
||||
// reset the monthday
|
||||
if i.MonthDays != nil {
|
||||
t = time.Date(t.Year(), t.Month(), i.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
|
||||
}
|
||||
}
|
||||
} else { // today was not found in the list, x is the first greater day
|
||||
} else { // this month was not found in the list, x is the first greater month
|
||||
m = i.Months[x]
|
||||
// reset the monthday
|
||||
if i.MonthDays != nil {
|
||||
@@ -132,6 +132,45 @@ MONTHS:
|
||||
h, min, s := t.Clock()
|
||||
t = time.Date(now.Year(), m, t.Day(), h, min, s, 0, time.Local)
|
||||
}
|
||||
YEARS:
|
||||
if i.Years != nil && len(i.Years) > 0 {
|
||||
i.Years.Sort()
|
||||
now := time.Now()
|
||||
x := sort.Search(len(i.Years), func(x int) bool { return i.Years[x] >= now.Year() })
|
||||
y = i.Years[0]
|
||||
if x < len(i.Years) {
|
||||
if i.Years[x] == now.Year() {
|
||||
if t.Equal(now) || t.After(now) {
|
||||
h, m, s := t.Clock()
|
||||
t = time.Date(now.Year(), t.Month(), t.Day(), h, m, s, 0, time.Local)
|
||||
return
|
||||
}
|
||||
if x+1 < len(i.Years) { // this year was found in the list so jump to next available year
|
||||
y = i.Years[x+1]
|
||||
// reset the month
|
||||
if i.Months != nil {
|
||||
t = time.Date(t.Year(), i.Months[0], t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
|
||||
}
|
||||
// reset the monthday
|
||||
if i.MonthDays != nil {
|
||||
t = time.Date(t.Year(), t.Month(), i.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
|
||||
}
|
||||
}
|
||||
} else { // this year was not found in the list, x is the first greater year
|
||||
y = i.Years[x]
|
||||
// reset the month
|
||||
if i.Months != nil {
|
||||
t = time.Date(t.Year(), i.Months[0], t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
|
||||
}
|
||||
// reset the monthday
|
||||
if i.MonthDays != nil {
|
||||
t = time.Date(t.Year(), t.Month(), i.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
|
||||
}
|
||||
}
|
||||
}
|
||||
h, min, s := t.Clock()
|
||||
t = time.Date(y, t.Month(), t.Day(), h, min, s, 0, time.Local)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ func TestActionTimingHourMonthdaysMonths(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingFisrtOfTheMonth(t *testing.T) {
|
||||
func TestActionTimingFirstOfTheMonth(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, _ := now.Date()
|
||||
nextMonth := time.Date(y, m+1, 1, 0, 0, 0, 0, time.Local)
|
||||
@@ -241,6 +241,118 @@ func TestActionTimingFisrtOfTheMonth(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingOnlyYears(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
nextYear := time.Date(y+1, m, d, 0, 0, 0, 0, time.Local)
|
||||
at := &ActionTiming{Timing: &Interval{Years: Years{now.Year(), nextYear.Year()}}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(nextYear.Year(), 1, 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingHourYears(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
|
||||
nextYear := time.Date(y+1, m, d, 0, 0, 0, 0, time.Local)
|
||||
year := now.Year()
|
||||
if now.After(testTime) {
|
||||
year = nextYear.Year()
|
||||
}
|
||||
at := &ActionTiming{Timing: &Interval{Years: Years{now.Year(), nextYear.Year()}, StartTime: "10:01:00"}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(year, m, d, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingHourMonthdaysYear(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
|
||||
nextYear := time.Date(y+1, m, d, 0, 0, 0, 0, time.Local)
|
||||
tomorrow := time.Date(y, m, d+1, 0, 0, 0, 0, time.Local)
|
||||
day := now.Day()
|
||||
if now.After(testTime) {
|
||||
day = tomorrow.Day()
|
||||
}
|
||||
nextDay := time.Date(y, m, day, 10, 1, 0, 0, time.Local)
|
||||
year := now.Year()
|
||||
if nextDay.Before(now) {
|
||||
if now.After(testTime) {
|
||||
year = nextYear.Year()
|
||||
}
|
||||
}
|
||||
at := &ActionTiming{Timing: &Interval{
|
||||
Years: Years{now.Year(), nextYear.Year()},
|
||||
MonthDays: MonthDays{now.Day(), tomorrow.Day()},
|
||||
StartTime: "10:01:00",
|
||||
}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(year, m, day, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingHourMonthdaysMonthYear(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, m, d := now.Date()
|
||||
testTime := time.Date(y, m, d, 10, 1, 0, 0, time.Local)
|
||||
nextYear := time.Date(y+1, m, d, 0, 0, 0, 0, time.Local)
|
||||
nextMonth := time.Date(y, m+1, d, 0, 0, 0, 0, time.Local)
|
||||
tomorrow := time.Date(y, m, d+1, 0, 0, 0, 0, time.Local)
|
||||
day := now.Day()
|
||||
if now.After(testTime) {
|
||||
day = tomorrow.Day()
|
||||
}
|
||||
nextDay := time.Date(y, m, day, 10, 1, 0, 0, time.Local)
|
||||
month := now.Month()
|
||||
if nextDay.Before(now) {
|
||||
if now.After(testTime) {
|
||||
month = nextMonth.Month()
|
||||
}
|
||||
}
|
||||
year := now.Year()
|
||||
if nextDay.Before(now) {
|
||||
if now.After(testTime) {
|
||||
year = nextYear.Year()
|
||||
}
|
||||
}
|
||||
at := &ActionTiming{Timing: &Interval{
|
||||
Years: Years{now.Year(), nextYear.Year()},
|
||||
Months: Months{now.Month(), nextMonth.Month()},
|
||||
MonthDays: MonthDays{now.Day(), tomorrow.Day()},
|
||||
StartTime: "10:01:00",
|
||||
}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := time.Date(year, month, day, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingFirstOfTheYear(t *testing.T) {
|
||||
now := time.Now()
|
||||
y, _, _ := now.Date()
|
||||
nextYear := time.Date(y+1, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
at := &ActionTiming{Timing: &Interval{
|
||||
Years: Years{nextYear.Year()},
|
||||
Months: Months{time.January},
|
||||
MonthDays: MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
}}
|
||||
st := at.GetNextStartTime()
|
||||
expected := nextYear
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTimingIsOneTimeRunNoInterval(t *testing.T) {
|
||||
at := &ActionTiming{Timing: &Interval{StartTime: ASAP}}
|
||||
if !at.CheckForASAP() {
|
||||
|
||||
Reference in New Issue
Block a user