Skip to content

Commit

Permalink
Add date recognition to messages
Browse files Browse the repository at this point in the history
  • Loading branch information
MDrakos committed Nov 19, 2024
1 parent 7d88e59 commit 84b42c2
Show file tree
Hide file tree
Showing 6 changed files with 963 additions and 201 deletions.
44 changes: 42 additions & 2 deletions cmd/state-svc/internal/messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func New(cfg *config.Instance, auth *auth.Auth) (*Messages, error) {
return nil, errs.Wrap(err, "Could not parse state version")
}

poll := poller.New(1*time.Hour, func() (interface{}, error) {
poll := poller.New(10*time.Minute, func() (interface{}, error) {
defer func() {
panics.LogAndPanic(recover(), debug.Stack())
}()
Expand Down Expand Up @@ -112,11 +112,39 @@ func (m *Messages) Check(command string, flags []string) ([]*graph.MessageInfo,
return msgs, nil
}

func messageInDateRange(message *graph.MessageInfo, baseTime time.Time) (bool, error) {
logging.Debug("Checking message %s in date range with base time %s", message.ID, baseTime.Format(time.RFC3339))
if message.StartDate != "" {
startDate, err := time.Parse(time.RFC3339, message.StartDate)
if err != nil {
return false, errs.Wrap(err, "Could not parse start date for message %s", message.ID)
}
if baseTime.Before(startDate) {
logging.Debug("Skipping message %s as it is before start date %s", message.ID, startDate.Format(time.RFC3339))
return false, nil
}
}

if message.EndDate != "" {
endDate, err := time.Parse(time.RFC3339, message.EndDate)
if err != nil {
return false, errs.Wrap(err, "Could not parse end date for message %s", message.ID)
}
if baseTime.After(endDate) {
logging.Debug("Skipping message %s as it is after end date %s", message.ID, endDate.Format(time.RFC3339))
return false, nil
}
}

return true, nil
}

func check(params *ConditionParams, messages []*graph.MessageInfo, lastReportMap map[string]interface{}, baseTime time.Time) ([]*graph.MessageInfo, error) {
funcMap := conditionFuncMap()
filteredMessages := []*graph.MessageInfo{}
for _, message := range messages {
logging.Debug("Checking message %s", message.ID)

// Ensure we don't show the same message too often
if lastReport, ok := lastReportMap[message.ID]; ok {
lr, ok := lastReport.(string)
Expand All @@ -140,11 +168,23 @@ func check(params *ConditionParams, messages []*graph.MessageInfo, lastReportMap
}
}

// Check if message is within date range
inRange, err := messageInDateRange(message, baseTime)
if err != nil {
logging.Warning("Could not check if message %s is in date range: %v", message.ID, err)
continue
}
if !inRange {
logging.Debug("Skipping message %s as it is outside of its date range", message.ID)
continue
}

// Validate the conditional
if message.Condition != "" {
result, err := strutils.ParseTemplate(fmt.Sprintf(`{{%s}}`, message.Condition), params, funcMap)
if err != nil {
return nil, errs.Wrap(err, "Could not parse condition template for message %s", message.ID)
logging.Warning("Could not parse condition template for message %s: %v", message.ID, err)
continue
}
if result == "true" {
logging.Debug("Including message %s as condition %s evaluated to %s", message.ID, message.Condition, result)
Expand Down
132 changes: 102 additions & 30 deletions cmd/state-svc/internal/messages/messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
)

func Test_check(t *testing.T) {
baseTime := time.Now()
type args struct {
params *ConditionParams
messages []*graph.MessageInfo
Expand All @@ -31,7 +32,7 @@ func Test_check(t *testing.T) {
{ID: "A"}, {ID: "B"}, {ID: "C"},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A", "B", "C"},
false,
Expand All @@ -48,7 +49,7 @@ func Test_check(t *testing.T) {
{ID: "C", Condition: `eq .Command "foobar"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -64,7 +65,7 @@ func Test_check(t *testing.T) {
{ID: "B", Condition: `contains .UserEmail "fred"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A"},
false,
Expand All @@ -80,7 +81,7 @@ func Test_check(t *testing.T) {
{ID: "B", Condition: `hasPrefix .UserEmail "org"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A"},
false,
Expand All @@ -96,7 +97,7 @@ func Test_check(t *testing.T) {
{ID: "B", Condition: `hasSuffix .UserEmail "org"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -112,7 +113,7 @@ func Test_check(t *testing.T) {
{ID: "B", Condition: `regexMatch .UserEmail "^doe.org$"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A"},
false,
Expand All @@ -128,7 +129,7 @@ func Test_check(t *testing.T) {
{ID: "B", Condition: `regexMatch .UserEmail ".*("`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A"},
false,
Expand All @@ -150,7 +151,7 @@ func Test_check(t *testing.T) {
{ID: "H", Condition: `eq .StateVersion.Build "foo"`},
},
lastReportMap: map[string]interface{}{},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A", "B", "C", "D"},
false,
Expand All @@ -165,10 +166,10 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeDisabled},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"C": time.Now(),
"A": baseTime.Format(time.RFC3339),
"C": baseTime.Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -183,10 +184,10 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeConstantly},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"C": time.Now().Add(-time.Hour * 24 * 30),
"A": baseTime.Format(time.RFC3339),
"C": baseTime.Add(-time.Hour * 24 * 30).Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"A", "B", "C"},
false,
Expand All @@ -201,11 +202,11 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"B": time.Now().Add(-time.Hour),
"C": time.Now(),
"A": baseTime.Format(time.RFC3339),
"B": baseTime.Add(-time.Hour).Format(time.RFC3339),
"C": baseTime.Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -220,11 +221,11 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"B": time.Now().Add(-time.Hour * 24),
"C": time.Now(),
"A": baseTime.Format(time.RFC3339),
"B": baseTime.Add(-time.Hour * 24).Format(time.RFC3339),
"C": baseTime.Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -239,11 +240,11 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"B": time.Now().Add(-time.Hour * 24 * 7),
"C": time.Now(),
"A": baseTime.Format(time.RFC3339),
"B": baseTime.Add(-time.Hour * 24 * 7).Format(time.RFC3339),
"C": baseTime.Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
Expand All @@ -258,15 +259,86 @@ func Test_check(t *testing.T) {
{ID: "C", Repeat: graph.MessageRepeatTypeHourly},
},
lastReportMap: map[string]interface{}{
"A": time.Now(),
"B": time.Now().Add(-time.Hour * 24 * 7 * 30),
"C": time.Now(),
"A": baseTime.Format(time.RFC3339),
"B": baseTime.Add(-time.Hour * 24 * 7 * 30).Format(time.RFC3339),
"C": baseTime.Format(time.RFC3339),
},
baseTime: time.Now(),
baseTime: baseTime,
},
[]string{"B"},
false,
},
{
"Date Range - Within Range",
args{
params: &ConditionParams{},
messages: []*graph.MessageInfo{
{ID: "A", StartDate: baseTime.Add(-24 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(24 * time.Hour).Format(time.RFC3339)},
{ID: "B", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
{ID: "C", StartDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339), EndDate: baseTime.Add(24 * time.Hour).Format(time.RFC3339)},
},
lastReportMap: map[string]interface{}{},
baseTime: baseTime,
},
[]string{"A", "B"},
false,
},
{
"Date Range - No Dates Specified",
args{
params: &ConditionParams{},
messages: []*graph.MessageInfo{
{ID: "A"},
{ID: "B", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
{ID: "C", EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
},
lastReportMap: map[string]interface{}{},
baseTime: baseTime,
},
[]string{"A", "B", "C"},
false,
},
{
"Date Range - Invalid Date Format",
args{
params: &ConditionParams{},
messages: []*graph.MessageInfo{
{ID: "A", StartDate: "invalid-date"},
},
lastReportMap: map[string]interface{}{},
baseTime: baseTime,
},
[]string{},
true,
},
{
"Date Range - Only Start Date",
args{
params: &ConditionParams{},
messages: []*graph.MessageInfo{
{ID: "A", StartDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
{ID: "B", StartDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
},
lastReportMap: map[string]interface{}{},
baseTime: baseTime,
},
[]string{"A"},
false,
},
{
"Date Range - Only End Date",
args{
params: &ConditionParams{},
messages: []*graph.MessageInfo{
{ID: "A", EndDate: baseTime.Add(1 * time.Hour).Format(time.RFC3339)},
{ID: "B", EndDate: baseTime.Add(-1 * time.Hour).Format(time.RFC3339)},
},
lastReportMap: map[string]interface{}{},
baseTime: baseTime,
},
[]string{"A"},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Loading

0 comments on commit 84b42c2

Please sign in to comment.