Add *month_end timingID in both TPReader and ApierSv1.SetActionPlan fixes #2255

This commit is contained in:
TeoV
2020-07-13 16:17:11 +03:00
committed by Dan Christian Bogos
parent a9a00e58ad
commit c6c1569554
6 changed files with 23 additions and 152 deletions

View File

@@ -809,6 +809,15 @@ func checkDefaultTiming(tStr string) (rTm *engine.RITiming, isDefault bool) {
StartTime: startTime,
EndTime: "",
}, true
case utils.MetaMonthEnd:
return &engine.RITiming{
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{-1},
WeekDays: utils.WeekDays{},
StartTime: startTime,
EndTime: "",
}, true
case utils.MetaYearly:
return &engine.RITiming{
Years: utils.Years{},

View File

@@ -131,157 +131,6 @@ func (at *ActionTiming) GetNextStartTime(now time.Time) (t time.Time) {
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
}
i := at.Timing
if i == 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)
}
y, m, d := now.Date()
z, _ := now.Zone()
if i.Timing.StartTime != utils.ASAP {
l := fmt.Sprintf("%d-%d-%d %s %s", y, m, d, i.Timing.StartTime, z)
var err error
t, err = time.Parse(FORMAT, l)
if err != nil {
utils.Logger.Err(fmt.Sprintf("Cannot parse action plan's StartTime %v", l))
at.stCache = t
return
}
if now.After(t) || now.Equal(t) { // Set it to next day this time
t = t.AddDate(0, 0, 1)
}
}
// weekdays
if i.Timing.WeekDays != nil && len(i.Timing.WeekDays) > 0 {
i.Timing.WeekDays.Sort()
if t.IsZero() {
t = time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, now.Location())
}
for j := 0; j < 8; j++ {
n := t.AddDate(0, 0, j)
for _, wd := range i.Timing.WeekDays {
if n.Weekday() == wd && (n.Equal(now) || n.After(now)) {
at.stCache = n
t = n
return
}
}
}
}
// monthdays
if i.Timing.MonthDays != nil && len(i.Timing.MonthDays) > 0 {
i.Timing.MonthDays.Sort()
year := t.Year()
month := t
x := sort.SearchInts(i.Timing.MonthDays, t.Day())
d = i.Timing.MonthDays[0]
if x < len(i.Timing.MonthDays) {
if i.Timing.MonthDays[x] == t.Day() {
if t.Equal(now) || t.After(now) {
goto MONTHS
}
if x+1 < len(i.Timing.MonthDays) { // today was found in the list, jump to the next grater day
d = i.Timing.MonthDays[x+1]
} else { // jump to next month
//not using now to make sure the next month has the the 1 date
//(if today is 31) next month may not have it
tmp := time.Date(year, month.Month(), 1, 0, 0, 0, 0, time.Local)
month = tmp.AddDate(0, 1, 0)
}
} else { // today was not found in the list, x is the first greater day
d = i.Timing.MonthDays[x]
}
}
h, m, s := t.Clock()
t = time.Date(month.Year(), month.Month(), d, h, m, s, 0, time.Local)
}
MONTHS:
if i.Timing.Months != nil && len(i.Timing.Months) > 0 {
i.Timing.Months.Sort()
year := t.Year()
x := sort.Search(len(i.Timing.Months), func(x int) bool { return i.Timing.Months[x] >= t.Month() })
m = i.Timing.Months[0]
if x < len(i.Timing.Months) {
if i.Timing.Months[x] == t.Month() {
if t.Equal(now) || t.After(now) {
goto YEARS
}
if x+1 < len(i.Timing.Months) { // this month was found in the list so jump to next available month
m = i.Timing.Months[x+1]
// reset the monthday
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
} else { // jump to next year
//not using now to make sure the next year has the the 1 date
//(if today is 31) next month may not have it
tmp := time.Date(year, 1, 1, 0, 0, 0, 0, time.Local)
year = tmp.AddDate(1, 0, 0).Year()
}
} else { // this month was not found in the list, x is the first greater month
m = i.Timing.Months[x]
// reset the monthday
t = time.Date(t.Year(), t.Month(), i.Timing.MonthDays[0], t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
}
h, min, s := t.Clock()
t = time.Date(year, m, t.Day(), h, min, s, 0, time.Local)
} else {
if now.After(t) {
t = t.AddDate(0, 1, 0)
}
}
YEARS:
if i.Timing.Years != nil && len(i.Timing.Years) > 0 {
i.Timing.Years.Sort()
x := sort.Search(len(i.Timing.Years), func(x int) bool { return i.Timing.Years[x] >= t.Year() })
y = i.Timing.Years[0]
if x < len(i.Timing.Years) {
if i.Timing.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)
at.stCache = t
return
}
if x+1 < len(i.Timing.Years) { // this year was found in the list so jump to next available year
y = i.Timing.Years[x+1]
// reset the month
if i.Timing.Months != nil {
t = time.Date(t.Year(), i.Timing.Months[0], t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
}
// reset the monthday
t = time.Date(t.Year(), t.Month(), i.Timing.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.Timing.Years[x]
// reset the month/monthday
t = time.Date(t.Year(), i.Timing.Months[0], i.Timing.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)
} else {
if now.After(t) {
t = t.AddDate(1, 0, 0)
}
}
at.stCache = t
return
}
func (at *ActionTiming) ResetStartTimeCache() {
at.stCache = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
}

View File

@@ -185,7 +185,7 @@ func TestLoadReverseDestinations(t *testing.T) {
}
func TestLoadTimimgs(t *testing.T) {
if len(csvr.timings) != 12 {
if len(csvr.timings) != 13 {
t.Error("Failed to load timings: ", csvr.timings)
}
timing := csvr.timings["WORKDAYS_00"]

View File

@@ -118,6 +118,9 @@ func (rit *RITiming) CronString() string {
year += strconv.Itoa(int(md))
}
}
if monthday == "-1" { // in case we receive -1 we send to cron special character L ( Last )
monthday = "L"
}
rit.cronString = fmt.Sprintf("%s %s %s %s %s %s %s", sec, min, hour, monthday, month, weekday, year)
return rit.cronString
}

View File

@@ -2613,6 +2613,15 @@ func (tpr *TpReader) addDefaultTimings() {
StartTime: startTime,
EndTime: "",
}
tpr.timings[utils.MetaMonthEnd] = &utils.TPTiming{
ID: utils.MetaMonthEnd,
Years: utils.Years{},
Months: utils.Months{},
MonthDays: utils.MonthDays{-1},
WeekDays: utils.WeekDays{},
StartTime: startTime,
EndTime: "",
}
tpr.timings[utils.MetaYearly] = &utils.TPTiming{
ID: utils.MetaYearly,
Years: utils.Years{},

View File

@@ -769,6 +769,7 @@ const (
MetaPartial = "*partial"
MetaBusy = "*busy"
MetaQueue = "*queue"
MetaMonthEnd = "*month_end"
)
// Migrator Action