mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
using extrenal lib for next date
This commit is contained in:
@@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/gorhill/cronexpr"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -46,6 +47,29 @@ type ActionTiming struct {
|
||||
type ActionPlan []*ActionTiming
|
||||
|
||||
func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
|
||||
if !at.stCache.IsZero() {
|
||||
return at.stCache
|
||||
}
|
||||
i := at.Timing
|
||||
if i == nil || i.Timing == nil {
|
||||
return
|
||||
}
|
||||
// Normalize
|
||||
if i.Timing.StartTime == "" {
|
||||
i.Timing.StartTime = "00:00:00"
|
||||
}
|
||||
if len(i.Timing.Years) > 0 && len(i.Timing.Months) == 0 {
|
||||
i.Timing.Months = append(i.Timing.Months, 1)
|
||||
}
|
||||
if len(i.Timing.Months) > 0 && len(i.Timing.MonthDays) == 0 {
|
||||
i.Timing.MonthDays = append(i.Timing.MonthDays, 1)
|
||||
}
|
||||
at.stCache = cronexpr.MustParse(i.Timing.CronString()).Next(now)
|
||||
return at.stCache
|
||||
}
|
||||
|
||||
// To be deleted after the above solution proves reliable
|
||||
func (at *ActionTiming) GetNextStartTimeOld(now time.Time) (t time.Time) {
|
||||
if !at.stCache.IsZero() {
|
||||
return at.stCache
|
||||
}
|
||||
|
||||
@@ -69,9 +69,9 @@ func TestActionTimingOnlyHour(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionTimingHourYear(t *testing.T) {
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2012}, StartTime: "10:01:00"}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2022}, StartTime: "10:01:00"}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(2012, 1, 1, 10, 1, 0, 0, time.Local)
|
||||
expected := time.Date(2022, 1, 1, 10, 1, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
@@ -245,9 +245,9 @@ func TestActionTimingOnlyYears(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestActionTimingPast(t *testing.T) {
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2013}}}}
|
||||
at := &ActionTiming{Timing: &RateInterval{Timing: &RITiming{Years: utils.Years{2023}}}}
|
||||
st := at.GetNextStartTime(referenceDate)
|
||||
expected := time.Date(2013, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
expected := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
if !st.Equal(expected) {
|
||||
t.Errorf("Expected %v was %v", expected, st)
|
||||
}
|
||||
@@ -411,7 +411,7 @@ func TestActionTimingLogFunction(t *testing.T) {
|
||||
func TestActionTimingPriotityListSortByWeight(t *testing.T) {
|
||||
at1 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2100},
|
||||
Years: utils.Years{2020},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
StartTime: "00:00:00",
|
||||
@@ -420,7 +420,7 @@ func TestActionTimingPriotityListSortByWeight(t *testing.T) {
|
||||
}}
|
||||
at2 := &ActionTiming{Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: utils.Years{2100},
|
||||
Years: utils.Years{2020},
|
||||
Months: utils.Months{time.January, time.February, time.March, time.April, time.May, time.June, time.July, time.August, time.September, time.October, time.November, time.December},
|
||||
MonthDays: utils.MonthDays{2},
|
||||
StartTime: "00:00:00",
|
||||
|
||||
@@ -532,28 +532,28 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
expected := &RatingPlan{
|
||||
Id: "STANDARD",
|
||||
Timings: map[string]*RITiming{
|
||||
"14ae6e41": &RITiming{
|
||||
"4c954a4f": &RITiming{
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
"9a6f8e32": &RITiming{
|
||||
"4d593287": &RITiming{
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{1, 2, 3, 4, 5},
|
||||
StartTime: "18:00:00",
|
||||
},
|
||||
"7181e535": &RITiming{
|
||||
"a60bfb13": &RITiming{
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
WeekDays: utils.WeekDays{time.Saturday, time.Sunday},
|
||||
StartTime: "00:00:00",
|
||||
},
|
||||
"96c78ff5": &RITiming{
|
||||
"30eab300": &RITiming{
|
||||
Years: utils.Years{},
|
||||
Months: utils.Months{},
|
||||
MonthDays: utils.MonthDays{},
|
||||
@@ -618,48 +618,48 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
DestinationRates: map[string]RPRateList{
|
||||
"GERMANY": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Timing: "4c954a4f",
|
||||
Rating: "822a5aef",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "9a6f8e32",
|
||||
Timing: "4d593287",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "7181e535",
|
||||
Timing: "a60bfb13",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_O2": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Timing: "4c954a4f",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "9a6f8e32",
|
||||
Timing: "4d593287",
|
||||
Rating: "b05c5f6b",
|
||||
Weight: 10,
|
||||
},
|
||||
&RPRate{
|
||||
Timing: "7181e535",
|
||||
Timing: "a60bfb13",
|
||||
Rating: "b05c5f6b",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"GERMANY_PREMIUM": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "14ae6e41",
|
||||
Timing: "4c954a4f",
|
||||
Rating: "4a25c533",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
"URG": []*RPRate{
|
||||
&RPRate{
|
||||
Timing: "96c78ff5",
|
||||
Timing: "30eab300",
|
||||
Rating: "9f49ef8e",
|
||||
Weight: 20,
|
||||
},
|
||||
@@ -667,7 +667,7 @@ func TestLoadRatingPlans(t *testing.T) {
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(rplan, expected) {
|
||||
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["URG"][0])
|
||||
t.Errorf("Error loading destination rate timing: %+v", rplan.DestinationRates["GERMANY_O2"][0])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,74 @@ type RITiming struct {
|
||||
MonthDays utils.MonthDays
|
||||
WeekDays utils.WeekDays
|
||||
StartTime, EndTime string // ##:##:## format
|
||||
cronString string
|
||||
}
|
||||
|
||||
func (rit *RITiming) CronString() string {
|
||||
if rit.cronString != "" {
|
||||
return rit.cronString
|
||||
}
|
||||
var sec, min, hour, monthday, month, weekday, year string
|
||||
if len(rit.StartTime) == 0 {
|
||||
hour, min, sec = "*", "*", "*"
|
||||
} else {
|
||||
hms := strings.Split(rit.StartTime, ":")
|
||||
if len(hms) != 3 {
|
||||
hour, min, sec = "*", "*", "*"
|
||||
}
|
||||
hour, min, sec = hms[0], hms[1], hms[2]
|
||||
if strings.HasPrefix(hour, "0") {
|
||||
hour = hour[1:]
|
||||
}
|
||||
if strings.HasPrefix(min, "0") {
|
||||
min = min[1:]
|
||||
}
|
||||
if strings.HasPrefix(sec, "0") {
|
||||
sec = sec[1:]
|
||||
}
|
||||
}
|
||||
if len(rit.MonthDays) == 0 {
|
||||
monthday = "*"
|
||||
} else {
|
||||
for i, md := range rit.MonthDays {
|
||||
if i > 0 {
|
||||
monthday += ","
|
||||
}
|
||||
monthday += strconv.Itoa(md)
|
||||
}
|
||||
}
|
||||
if len(rit.Months) == 0 {
|
||||
month = "*"
|
||||
} else {
|
||||
for i, md := range rit.Months {
|
||||
if i > 0 {
|
||||
month += ","
|
||||
}
|
||||
month += strconv.Itoa(int(md))
|
||||
}
|
||||
}
|
||||
if len(rit.WeekDays) == 0 {
|
||||
weekday = "*"
|
||||
} else {
|
||||
for i, md := range rit.WeekDays {
|
||||
if i > 0 {
|
||||
weekday += ","
|
||||
}
|
||||
weekday += strconv.Itoa(int(md))
|
||||
}
|
||||
}
|
||||
if len(rit.Years) == 0 {
|
||||
year = "*"
|
||||
} else {
|
||||
for i, md := range rit.Years {
|
||||
if i > 0 {
|
||||
year += ","
|
||||
}
|
||||
year += strconv.Itoa(int(md))
|
||||
}
|
||||
}
|
||||
rit.cronString = fmt.Sprintf("%s %s %s %s %s %s %s", sec, min, hour, monthday, month, weekday, year)
|
||||
return rit.cronString
|
||||
}
|
||||
|
||||
func (rit *RITiming) Stringify() string {
|
||||
|
||||
@@ -19,9 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func TestRateIntervalSimpleContains(t *testing.T) {
|
||||
@@ -283,6 +284,59 @@ func TestRateStrigyfy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalCronAll(t *testing.T) {
|
||||
rit := &RITiming{
|
||||
Years: utils.Years{2012},
|
||||
Months: utils.Months{time.February},
|
||||
MonthDays: utils.MonthDays{1},
|
||||
WeekDays: []time.Weekday{time.Sunday},
|
||||
StartTime: "14:30:00",
|
||||
}
|
||||
expected := "0 30 14 1 2 0 2012"
|
||||
cron := rit.CronString()
|
||||
if cron != expected {
|
||||
t.Errorf("Expected %s was %s", expected, cron)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalCronMultiple(t *testing.T) {
|
||||
rit := &RITiming{
|
||||
Years: utils.Years{2012, 2014},
|
||||
Months: utils.Months{time.February, time.January},
|
||||
MonthDays: utils.MonthDays{15, 16},
|
||||
WeekDays: []time.Weekday{time.Sunday, time.Monday},
|
||||
StartTime: "14:30:00",
|
||||
}
|
||||
expected := "0 30 14 15,16 2,1 0,1 2012,2014"
|
||||
cron := rit.CronString()
|
||||
|
||||
if cron != expected {
|
||||
t.Errorf("Expected %s was %s", expected, cron)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalCronStar(t *testing.T) {
|
||||
rit := &RITiming{
|
||||
StartTime: "*:30:00",
|
||||
}
|
||||
expected := "0 30 * * * * *"
|
||||
cron := rit.CronString()
|
||||
|
||||
if cron != expected {
|
||||
t.Errorf("Expected %s was %s", expected, cron)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalCronEmpty(t *testing.T) {
|
||||
rit := &RITiming{}
|
||||
expected := "* * * * * * *"
|
||||
cron := rit.CronString()
|
||||
|
||||
if cron != expected {
|
||||
t.Errorf("Expected %s was %s", expected, cron)
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************Benchmarks**************************************/
|
||||
|
||||
func BenchmarkRateIntervalContainsDate(b *testing.B) {
|
||||
|
||||
@@ -14,6 +14,7 @@ libs = ('code.google.com/p/goconf/conf',
|
||||
'github.com/hoisie/redis'
|
||||
'github.com/howeyc/fsnotify',
|
||||
'github.com/jinzhu/gorm',
|
||||
'github.com/gorhill/cronexpr',
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -11,3 +11,4 @@ go get -u -v github.com/howeyc/fsnotify
|
||||
go get -u -v github.com/cgrates/liner
|
||||
go get -u -v github.com/cgrates/rpcclient
|
||||
go get -u -v github.com/jinzhu/gorm
|
||||
go get -u -v github.com/gorhill/cronexpr
|
||||
|
||||
Reference in New Issue
Block a user