Skip to content

Commit fac37eb

Browse files
authored
Merge pull request #3601 from ActiveState/DX-3161
Add Date Recognition To Messages
2 parents 0a5c961 + 1412ea3 commit fac37eb

6 files changed

Lines changed: 960 additions & 201 deletions

File tree

cmd/state-svc/internal/messages/messages.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func New(cfg *config.Instance, auth *auth.Auth) (*Messages, error) {
4444
return nil, errs.Wrap(err, "Could not parse state version")
4545
}
4646

47-
poll := poller.New(1*time.Hour, func() (interface{}, error) {
47+
poll := poller.New(10*time.Minute, func() (interface{}, error) {
4848
defer func() {
4949
panics.LogAndPanic(recover(), debug.Stack())
5050
}()
@@ -112,11 +112,36 @@ func (m *Messages) Check(command string, flags []string) ([]*graph.MessageInfo,
112112
return msgs, nil
113113
}
114114

115+
func messageInDateRange(message *graph.MessageInfo, baseTime time.Time) (bool, error) {
116+
if message.StartDate != "" {
117+
startDate, err := time.Parse(time.RFC3339, message.StartDate)
118+
if err != nil {
119+
return false, errs.Wrap(err, "Could not parse start date for message %s", message.ID)
120+
}
121+
if baseTime.Before(startDate) {
122+
return false, nil
123+
}
124+
}
125+
126+
if message.EndDate != "" {
127+
endDate, err := time.Parse(time.RFC3339, message.EndDate)
128+
if err != nil {
129+
return false, errs.Wrap(err, "Could not parse end date for message %s", message.ID)
130+
}
131+
if baseTime.After(endDate) {
132+
return false, nil
133+
}
134+
}
135+
136+
return true, nil
137+
}
138+
115139
func check(params *ConditionParams, messages []*graph.MessageInfo, lastReportMap map[string]interface{}, baseTime time.Time) ([]*graph.MessageInfo, error) {
116140
funcMap := conditionFuncMap()
117141
filteredMessages := []*graph.MessageInfo{}
118142
for _, message := range messages {
119143
logging.Debug("Checking message %s", message.ID)
144+
120145
// Ensure we don't show the same message too often
121146
if lastReport, ok := lastReportMap[message.ID]; ok {
122147
lr, ok := lastReport.(string)
@@ -140,11 +165,23 @@ func check(params *ConditionParams, messages []*graph.MessageInfo, lastReportMap
140165
}
141166
}
142167

168+
// Check if message is within date range
169+
inRange, err := messageInDateRange(message, baseTime)
170+
if err != nil {
171+
logging.Warning("Could not check if message %s is in date range: %v", message.ID, err)
172+
continue
173+
}
174+
if !inRange {
175+
logging.Debug("Skipping message %s as it is outside of its date range", message.ID)
176+
continue
177+
}
178+
143179
// Validate the conditional
144180
if message.Condition != "" {
145181
result, err := strutils.ParseTemplate(fmt.Sprintf(`{{%s}}`, message.Condition), params, funcMap)
146182
if err != nil {
147-
return nil, errs.Wrap(err, "Could not parse condition template for message %s", message.ID)
183+
logging.Warning("Could not parse condition template for message %s: %v", message.ID, err)
184+
continue
148185
}
149186
if result == "true" {
150187
logging.Debug("Including message %s as condition %s evaluated to %s", message.ID, message.Condition, result)

cmd/state-svc/internal/messages/messages_test.go

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
)
1212

1313
func Test_check(t *testing.T) {
14+
baseTime := time.Now()
1415
type args struct {
1516
params *ConditionParams
1617
messages []*graph.MessageInfo
@@ -31,7 +32,7 @@ func Test_check(t *testing.T) {
3132
{ID: "A"}, {ID: "B"}, {ID: "C"},
3233
},
3334
lastReportMap: map[string]interface{}{},
34-
baseTime: time.Now(),
35+
baseTime: baseTime,
3536
},
3637
[]string{"A", "B", "C"},
3738
false,
@@ -48,7 +49,7 @@ func Test_check(t *testing.T) {
4849
{ID: "C", Condition: `eq .Command "foobar"`},
4950
},
5051
lastReportMap: map[string]interface{}{},
51-
baseTime: time.Now(),
52+
baseTime: baseTime,
5253
},
5354
[]string{"B"},
5455
false,
@@ -64,7 +65,7 @@ func Test_check(t *testing.T) {
6465
{ID: "B", Condition: `contains .UserEmail "fred"`},
6566
},
6667
lastReportMap: map[string]interface{}{},
67-
baseTime: time.Now(),
68+
baseTime: baseTime,
6869
},
6970
[]string{"A"},
7071
false,
@@ -80,7 +81,7 @@ func Test_check(t *testing.T) {
8081
{ID: "B", Condition: `hasPrefix .UserEmail "org"`},
8182
},
8283
lastReportMap: map[string]interface{}{},
83-
baseTime: time.Now(),
84+
baseTime: baseTime,
8485
},
8586
[]string{"A"},
8687
false,
@@ -96,7 +97,7 @@ func Test_check(t *testing.T) {
9697
{ID: "B", Condition: `hasSuffix .UserEmail "org"`},
9798
},
9899
lastReportMap: map[string]interface{}{},
99-
baseTime: time.Now(),
100+
baseTime: baseTime,
100101
},
101102
[]string{"B"},
102103
false,
@@ -112,7 +113,7 @@ func Test_check(t *testing.T) {
112113
{ID: "B", Condition: `regexMatch .UserEmail "^doe.org$"`},
113114
},
114115
lastReportMap: map[string]interface{}{},
115-
baseTime: time.Now(),
116+
baseTime: baseTime,
116117
},
117118
[]string{"A"},
118119
false,
@@ -128,7 +129,7 @@ func Test_check(t *testing.T) {
128129
{ID: "B", Condition: `regexMatch .UserEmail ".*("`},
129130
},
130131
lastReportMap: map[string]interface{}{},
131-
baseTime: time.Now(),
132+
baseTime: baseTime,
132133
},
133134
[]string{"A"},
134135
false,
@@ -150,7 +151,7 @@ func Test_check(t *testing.T) {
150151
{ID: "H", Condition: `eq .StateVersion.Build "foo"`},
151152
},
152153
lastReportMap: map[string]interface{}{},
153-
baseTime: time.Now(),
154+
baseTime: baseTime,
154155
},
155156
[]string{"A", "B", "C", "D"},
156157
false,
@@ -165,10 +166,10 @@ func Test_check(t *testing.T) {
165166
{ID: "C", Repeat: graph.MessageRepeatTypeDisabled},
166167
},
167168
lastReportMap: map[string]interface{}{
168-
"A": time.Now(),
169-
"C": time.Now(),
169+
"A": baseTime.Format(time.RFC3339),
170+
"C": baseTime.Format(time.RFC3339),
170171
},
171-
baseTime: time.Now(),
172+
baseTime: baseTime,
172173
},
173174
[]string{"B"},
174175
false,
@@ -183,10 +184,10 @@ func Test_check(t *testing.T) {
183184
{ID: "C", Repeat: graph.MessageRepeatTypeConstantly},
184185
},
185186
lastReportMap: map[string]interface{}{
186-
"A": time.Now(),
187-
"C": time.Now().Add(-time.Hour * 24 * 30),
187+
"A": baseTime.Format(time.RFC3339),
188+
"C": baseTime.Add(-time.Hour * 24 * 30).Format(time.RFC3339),
188189
},
189-
baseTime: time.Now(),
190+
baseTime: baseTime,
190191
},
191192
[]string{"A", "B", "C"},
192193
false,
@@ -201,11 +202,11 @@ func Test_check(t *testing.T) {
201202
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
202203
},
203204
lastReportMap: map[string]interface{}{
204-
"A": time.Now(),
205-
"B": time.Now().Add(-time.Hour),
206-
"C": time.Now(),
205+
"A": baseTime.Format(time.RFC3339),
206+
"B": baseTime.Add(-time.Hour).Format(time.RFC3339),
207+
"C": baseTime.Format(time.RFC3339),
207208
},
208-
baseTime: time.Now(),
209+
baseTime: baseTime,
209210
},
210211
[]string{"B"},
211212
false,
@@ -220,11 +221,11 @@ func Test_check(t *testing.T) {
220221
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
221222
},
222223
lastReportMap: map[string]interface{}{
223-
"A": time.Now(),
224-
"B": time.Now().Add(-time.Hour * 24),
225-
"C": time.Now(),
224+
"A": baseTime.Format(time.RFC3339),
225+
"B": baseTime.Add(-time.Hour * 24).Format(time.RFC3339),
226+
"C": baseTime.Format(time.RFC3339),
226227
},
227-
baseTime: time.Now(),
228+
baseTime: baseTime,
228229
},
229230
[]string{"B"},
230231
false,
@@ -239,11 +240,11 @@ func Test_check(t *testing.T) {
239240
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
240241
},
241242
lastReportMap: map[string]interface{}{
242-
"A": time.Now(),
243-
"B": time.Now().Add(-time.Hour * 24 * 7),
244-
"C": time.Now(),
243+
"A": baseTime.Format(time.RFC3339),
244+
"B": baseTime.Add(-time.Hour * 24 * 7).Format(time.RFC3339),
245+
"C": baseTime.Format(time.RFC3339),
245246
},
246-
baseTime: time.Now(),
247+
baseTime: baseTime,
247248
},
248249
[]string{"B"},
249250
false,
@@ -258,15 +259,86 @@ func Test_check(t *testing.T) {
258259
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
259260
},
260261
lastReportMap: map[string]interface{}{
261-
"A": time.Now(),
262-
"B": time.Now().Add(-time.Hour * 24 * 7 * 30),
263-
"C": time.Now(),
262+
"A": baseTime.Format(time.RFC3339),
263+
"B": baseTime.Add(-time.Hour * 24 * 7 * 30).Format(time.RFC3339),
264+
"C": baseTime.Format(time.RFC3339),
264265
},
265-
baseTime: time.Now(),
266+
baseTime: baseTime,
266267
},
267268
[]string{"B"},
268269
false,
269270
},
271+
{
272+
"Date Range - Within Range",
273+
args{
274+
params: &ConditionParams{},
275+
messages: []*graph.MessageInfo{
276+
{ID: "A", StartDate: baseTime.Add(-24 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(24 * time.Hour).Format(time.RFC3339)},
277+
{ID: "B", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
278+
{ID: "C", StartDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(24 * time.Hour).Format(time.RFC3339)},
279+
},
280+
lastReportMap: map[string]interface{}{},
281+
baseTime: baseTime,
282+
},
283+
[]string{"A", "B"},
284+
false,
285+
},
286+
{
287+
"Date Range - No Dates Specified",
288+
args{
289+
params: &ConditionParams{},
290+
messages: []*graph.MessageInfo{
291+
{ID: "A"},
292+
{ID: "B", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
293+
{ID: "C", EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
294+
},
295+
lastReportMap: map[string]interface{}{},
296+
baseTime: baseTime,
297+
},
298+
[]string{"A", "B", "C"},
299+
false,
300+
},
301+
{
302+
"Date Range - Invalid Date Format",
303+
args{
304+
params: &ConditionParams{},
305+
messages: []*graph.MessageInfo{
306+
{ID: "A", StartDate: "invalid-date"},
307+
},
308+
lastReportMap: map[string]interface{}{},
309+
baseTime: baseTime,
310+
},
311+
[]string{},
312+
true,
313+
},
314+
{
315+
"Date Range - Only Start Date",
316+
args{
317+
params: &ConditionParams{},
318+
messages: []*graph.MessageInfo{
319+
{ID: "A", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
320+
{ID: "B", StartDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
321+
},
322+
lastReportMap: map[string]interface{}{},
323+
baseTime: baseTime,
324+
},
325+
[]string{"A"},
326+
false,
327+
},
328+
{
329+
"Date Range - Only End Date",
330+
args{
331+
params: &ConditionParams{},
332+
messages: []*graph.MessageInfo{
333+
{ID: "A", EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
334+
{ID: "B", EndDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
335+
},
336+
lastReportMap: map[string]interface{}{},
337+
baseTime: baseTime,
338+
},
339+
[]string{"A"},
340+
false,
341+
},
270342
}
271343
for _, tt := range tests {
272344
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)