blob: cb0f51e37f6a2f55c46553518a34a6791da049d3 [file] [log] [blame]
package notify
import (
"context"
"go.skia.org/infra/go/skerr"
"go.skia.org/infra/go/sklog"
ag "go.skia.org/infra/perf/go/anomalygroup/proto/v1"
"go.skia.org/infra/perf/go/config"
"go.skia.org/infra/perf/go/culprit/formatter"
pb "go.skia.org/infra/perf/go/culprit/proto/v1"
"go.skia.org/infra/perf/go/culprit/transport"
sub_pb "go.skia.org/infra/perf/go/subscription/proto/v1"
"go.skia.org/infra/perf/go/types"
)
// TODO(wenbinzhang): considering using specific type for issue ID instead of 'string'.
type CulpritNotifier interface {
// Sends out notification to users about the detected culprit.
NotifyCulpritFound(ctx context.Context, culprit *pb.Culprit, subscription *sub_pb.Subscription) (string, error)
// Sends out notification to users about the detected anomalies.
NotifyAnomaliesFound(ctx context.Context, anomalyGroup *ag.AnomalyGroup, subscription *sub_pb.Subscription, anomalyList []*pb.Anomaly) (string, error)
}
// DefaultCulpritNotifier sends notifications.
type DefaultCulpritNotifier struct {
formatter formatter.Formatter
transport transport.Transport
}
// newNotifier returns a newNotifier Notifier.
func GetDefaultNotifier(ctx context.Context, cfg *config.InstanceConfig, commitURLTemplate string) (CulpritNotifier, error) {
switch cfg.IssueTrackerConfig.NotificationType {
case types.NoneNotify:
return &DefaultCulpritNotifier{
formatter: formatter.NewNoopFormatter(),
transport: transport.NewNoopTransport(),
}, nil
case types.IssueNotify:
transport, err := transport.NewIssueTrackerTransport(ctx, &cfg.IssueTrackerConfig)
if err != nil {
return nil, skerr.Wrap(err)
}
formatter, err := formatter.NewMarkdownFormatter(commitURLTemplate, cfg)
if err != nil {
return nil, skerr.Wrap(err)
}
return &DefaultCulpritNotifier{
formatter: formatter,
transport: transport,
}, nil
default:
return nil, skerr.Fmt("Unsupported Notifier type: %s", cfg.IssueTrackerConfig.NotificationType)
}
}
// Creates a bug in Buganizer about the detected culprit.
func (n *DefaultCulpritNotifier) NotifyCulpritFound(ctx context.Context, culprit *pb.Culprit, subscription *sub_pb.Subscription) (string, error) {
if subscription == nil || culprit == nil {
sklog.Debugf("No subscription or no culprit.")
return "nil", skerr.Fmt("No subscription or no culprit when calling NotifyCulpritFound")
}
sklog.Debugf("Culprit found for [%s]: %s", subscription.Name, culprit.Commit.Revision)
subject, body, err := n.formatter.GetCulpritSubjectAndBody(ctx, culprit, subscription)
if err != nil {
return "", err
}
bugId, err := n.transport.SendNewNotification(ctx, subscription, subject, body)
if err != nil {
return "", skerr.Wrapf(err, "sending new culprit message")
}
return bugId, nil
}
// Creates a bug in Buganizer about the detected anomalies.
func (n *DefaultCulpritNotifier) NotifyAnomaliesFound(ctx context.Context, anomalyGroup *ag.AnomalyGroup, subscription *sub_pb.Subscription, anomalyList []*pb.Anomaly) (string, error) {
if subscription == nil || anomalyGroup == nil {
return "nil", skerr.Fmt("No subscription or no anomalyGroup when calling NotifyAnomaliesFound")
}
sklog.Debugf("Anomalies found for [%s]: %s", subscription.Name, anomalyGroup.AnomalyIds)
subject, body, err := n.formatter.GetReportSubjectAndBody(ctx, anomalyGroup, subscription, anomalyList)
if err != nil {
return "", err
}
bugId, err := n.transport.SendNewNotification(ctx, subscription, subject, body)
if err != nil {
return "", skerr.Wrapf(err, "sending new anomaly group message")
}
return bugId, nil
}