refactor: make handlers able to send multiple notifications at once

This commit is contained in:
Bastien Riviere 2023-09-03 16:37:02 +02:00
parent 1b48840c8b
commit ea22fa5569
Signed by: babariviere
GPG key ID: 4E5F0839249F162E
2 changed files with 20 additions and 19 deletions

View file

@ -4,7 +4,6 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors" "errors"
"io"
"log/slog" "log/slog"
"net/http" "net/http"
"strconv" "strconv"
@ -16,7 +15,7 @@ var (
) )
type Handler interface { type Handler interface {
FormatNotification(r io.Reader) (Notification, error) ProduceNotifications(r *http.Request) ([]Notification, error)
} }
type NotificationError struct { type NotificationError struct {
@ -132,8 +131,7 @@ func (b Bridge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
not, err := b.h.FormatNotification(r.Body) nots, err := b.h.ProduceNotifications(r)
defer r.Body.Close()
if errors.Is(err, errSkipNotification) { if errors.Is(err, errSkipNotification) {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
@ -146,6 +144,7 @@ func (b Bridge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
for _, not := range nots {
not.topic = b.topic not.topic = b.topic
not.auth = b.auth not.auth = b.auth
if err = not.Send(b.baseURL); err != nil { if err = not.Send(b.baseURL); err != nil {
@ -153,8 +152,9 @@ func (b Bridge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
}
slog.Debug("notification sent with success") slog.Debug("notifications sent with success", "sent", len(nots))
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
} }

View file

@ -3,8 +3,8 @@ package bridge
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log/slog" "log/slog"
"net/http"
"strings" "strings"
"time" "time"
) )
@ -48,21 +48,22 @@ func NewFluxHandler() FluxHandler {
} }
} }
func (f FluxHandler) FormatNotification(r io.Reader) (Notification, error) { func (f FluxHandler) ProduceNotifications(r *http.Request) ([]Notification, error) {
l := slog.With(slog.String("handler", "flux")) l := slog.With(slog.String("handler", "flux"))
dec := json.NewDecoder(r) dec := json.NewDecoder(r.Body)
defer r.Body.Close()
var not FluxNotification var not FluxNotification
if err := dec.Decode(&not); err != nil { if err := dec.Decode(&not); err != nil {
l.Error("invalid message format in flux", "error", err) l.Error("invalid message format", "error", err)
return Notification{}, err return nil, err
} }
obj := not.InvolvedObject.String() obj := not.InvolvedObject.String()
if not.Reason == "ReconciliationSucceeded" { if not.Reason == "ReconciliationSucceeded" {
if ok := f.reconciliations[obj]; !ok { if ok := f.reconciliations[obj]; !ok {
// Filter out spammy ReconciliationSucceeded notification // Filter out spammy ReconciliationSucceeded notification
return Notification{}, errSkipNotification return nil, errSkipNotification
} }
// we will print the object so skip it next time it spam // we will print the object so skip it next time it spam
@ -78,9 +79,9 @@ func (f FluxHandler) FormatNotification(r io.Reader) (Notification, error) {
l.Debug("flux notification", slog.Group("notification", l.Debug("flux notification", slog.Group("notification",
slog.String("title", title), slog.String("title", title),
slog.String("body", body))) slog.String("body", body)))
return Notification{ return []Notification{{
Title: title, Title: title,
Body: body, Body: body,
IsMarkdown: true, IsMarkdown: true,
}, nil }}, nil
} }