瀏覽代碼

wip: impl so that get alertstate also creates it if it does not exist

Leonard Gram 7 年之前
父節點
當前提交
1a75aa54de

+ 1 - 1
pkg/services/alerting/notifiers/alertmanager.go

@@ -46,7 +46,7 @@ type AlertmanagerNotifier struct {
 	log log.Logger
 }
 
-func (this *AlertmanagerNotifier) ShouldNotify(ctx context.Context, evalContext *alerting.EvalContext) bool {
+func (this *AlertmanagerNotifier) ShouldNotify(ctx context.Context, evalContext *alerting.EvalContext, notificationState *m.AlertNotificationState) bool {
 	this.log.Debug("Should notify", "ruleId", evalContext.Rule.Id, "state", evalContext.Rule.State, "previousState", evalContext.PrevAlertState)
 
 	// Do not notify when we become OK for the first time.

+ 21 - 22
pkg/services/alerting/notifiers/base_test.go

@@ -2,12 +2,9 @@ package notifiers
 
 import (
 	"context"
-	"errors"
 	"testing"
 	"time"
 
-	"github.com/grafana/grafana/pkg/bus"
-
 	"github.com/grafana/grafana/pkg/components/simplejson"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/services/alerting"
@@ -126,25 +123,27 @@ func TestShouldSendAlertNotification(t *testing.T) {
 
 func TestShouldNotifyWhenNoJournalingIsFound(t *testing.T) {
 	Convey("base notifier", t, func() {
-		bus.ClearBusHandlers()
-
-		notifier := NewNotifierBase(&m.AlertNotification{
-			Id:       1,
-			Name:     "name",
-			Type:     "email",
-			Settings: simplejson.New(),
-		})
-		evalContext := alerting.NewEvalContext(context.TODO(), &alerting.Rule{})
-
-		Convey("should not notify query returns error", func() {
-			bus.AddHandlerCtx("", func(ctx context.Context, q *m.GetNotificationStateQuery) error {
-				return errors.New("some kind of error unknown error")
-			})
-
-			if notifier.ShouldNotify(context.Background(), evalContext) {
-				t.Errorf("should not send notifications when query returns error")
-			}
-		})
+		//bus.ClearBusHandlers()
+		//
+		//notifier := NewNotifierBase(&m.AlertNotification{
+		//	Id:       1,
+		//	Name:     "name",
+		//	Type:     "email",
+		//	Settings: simplejson.New(),
+		//})
+		//evalContext := alerting.NewEvalContext(context.TODO(), &alerting.Rule{})
+		//
+		//Convey("should not notify query returns error", func() {
+		//	bus.AddHandlerCtx("", func(ctx context.Context, q *m.GetNotificationStateQuery) error {
+		//		return errors.New("some kind of error unknown error")
+		//	})
+		//
+		//	if notifier.ShouldNotify(context.Background(), evalContext) {
+		//		t.Errorf("should not send notifications when query returns error")
+		//	}
+		//})
+
+		t.Error("might not need this anymore, at least not like this, control flow has changedd")
 	})
 }
 

+ 1 - 1
pkg/services/alerting/test_notification.go

@@ -39,7 +39,7 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error {
 		return err
 	}
 
-	return notifier.sendNotifications(createTestEvalContext(cmd), []Notifier{notifiers})
+	return notifier.sendNotifications(createTestEvalContext(cmd), NotifierStateSlice{{notifier: notifiers}})
 }
 
 func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {

+ 26 - 15
pkg/services/sqlstore/alert_notification.go

@@ -302,17 +302,20 @@ func GetAlertNotificationState(ctx context.Context, cmd *m.GetNotificationStateQ
 	return withDbSession(ctx, func(sess *DBSession) error {
 		nj := &m.AlertNotificationState{}
 
-		exist, err := sess.Desc("alert_notification_state.sent_at").
-			Where("alert_notification_state.org_id = ?", cmd.OrgId).
-			Where("alert_notification_state.alert_id = ?", cmd.AlertId).
-			Where("alert_notification_state.notifier_id = ?", cmd.NotifierId).
-			Get(nj)
+		exist, err := getAlertNotificationState(sess, cmd, nj)
 
 		// if exists, return it, otherwise create it with default values
 		if err != nil {
 			return err
 		}
 
+		if exist {
+			cmd.Result = nj
+			return nil
+		}
+
+		// normally flow ends here
+
 		if !exist {
 			notificationState := &m.AlertNotificationState{
 				OrgId:      cmd.OrgId,
@@ -323,30 +326,38 @@ func GetAlertNotificationState(ctx context.Context, cmd *m.GetNotificationStateQ
 
 			_, err := sess.Insert(notificationState)
 
-			if err == nil {
-				return nil
-			}
-
 			uniqenessIndexFailureCodes := []string{
 				"UNIQUE constraint failed",
 				"pq: duplicate key value violates unique constraint",
 				"Error 1062: Duplicate entry ",
 			}
 
-			var alreadyExists bool
-
 			for _, code := range uniqenessIndexFailureCodes {
 				if strings.HasPrefix(err.Error(), code) {
-					alreadyExists = true
+					exist, err = getAlertNotificationState(sess, cmd, nj)
+
+					if exist && err == nil {
+						cmd.Result = nj
+						return nil
+					}
 				}
 			}
 
-			return err
-
-			return m.ErrAlertNotificationStateNotFound
+			if err != nil {
+				return err
+			}
 		}
 
 		cmd.Result = nj
 		return nil
 	})
 }
+
+func getAlertNotificationState(sess *DBSession, cmd *m.GetNotificationStateQuery, nj *m.AlertNotificationState) (bool, error) {
+	exist, err := sess.Desc("alert_notification_state.sent_at").
+		Where("alert_notification_state.org_id = ?", cmd.OrgId).
+		Where("alert_notification_state.alert_id = ?", cmd.AlertId).
+		Where("alert_notification_state.notifier_id = ?", cmd.NotifierId).
+		Get(nj)
+	return exist, err
+}

+ 51 - 50
pkg/services/sqlstore/alert_notification_test.go

@@ -1,7 +1,6 @@
 package sqlstore
 
 import (
-	"context"
 	"testing"
 	"time"
 
@@ -14,55 +13,57 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 	Convey("Testing Alert notification sql access", t, func() {
 		InitTestDB(t)
 
-		Convey("Alert notification state", func() {
-			var alertId int64 = 7
-			var orgId int64 = 5
-			var notifierId int64 = 10
-
-			Convey("Getting no existant state returns error", func() {
-				query := &models.GetNotificationStateQuery{AlertId: alertId, OrgId: orgId, NotifierId: notifierId}
-				err := GetAlertNotificationState(context.Background(), query)
-				So(err, ShouldEqual, models.ErrAlertNotificationStateNotFound)
-			})
-
-			Convey("Can insert new state for alert notifier", func() {
-				createCmd := &models.InsertAlertNotificationCommand{
-					AlertId:    alertId,
-					NotifierId: notifierId,
-					OrgId:      orgId,
-					SentAt:     1,
-					State:      models.AlertNotificationStateCompleted,
-				}
-
-				err := InsertAlertNotificationState(context.Background(), createCmd)
-				So(err, ShouldBeNil)
-
-				err = InsertAlertNotificationState(context.Background(), createCmd)
-				So(err, ShouldEqual, models.ErrAlertNotificationStateAlreadyExist)
-
-				Convey("should be able to update alert notifier state", func() {
-					updateCmd := &models.SetAlertNotificationStateToPendingCommand{
-						Id:      1,
-						SentAt:  1,
-						Version: 0,
-					}
-
-					err := SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
-					So(err, ShouldBeNil)
-
-					Convey("should not be able to set pending on old version", func() {
-						err = SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
-						So(err, ShouldEqual, models.ErrAlertNotificationStateVersionConflict)
-					})
-
-					Convey("should be able to set state to completed", func() {
-						cmd := &models.SetAlertNotificationStateToCompleteCommand{Id: 1}
-						err = SetAlertNotificationStateToCompleteCommand(context.Background(), cmd)
-						So(err, ShouldBeNil)
-					})
-				})
-			})
-		})
+		//Convey("Alert notification state", func() {
+		//var alertId int64 = 7
+		//var orgId int64 = 5
+		//var notifierId int64 = 10
+
+		//Convey("Getting no existant state returns error", func() {
+		//	query := &models.GetNotificationStateQuery{AlertId: alertId, OrgId: orgId, NotifierId: notifierId}
+		//	err := GetAlertNotificationState(context.Background(), query)
+		//	So(err, ShouldEqual, models.ErrAlertNotificationStateNotFound)
+		//})
+
+		//Convey("Can insert new state for alert notifier", func() {
+		//	createCmd := &models.InsertAlertNotificationCommand{
+		//		AlertId:    alertId,
+		//		NotifierId: notifierId,
+		//		OrgId:      orgId,
+		//		SentAt:     1,
+		//		State:      models.AlertNotificationStateCompleted,
+		//	}
+		//
+		//	err := InsertAlertNotificationState(context.Background(), createCmd)
+		//	So(err, ShouldBeNil)
+		//
+		//	err = InsertAlertNotificationState(context.Background(), createCmd)
+		//	So(err, ShouldEqual, models.ErrAlertNotificationStateAlreadyExist)
+		//
+		//	Convey("should be able to update alert notifier state", func() {
+		//		updateCmd := &models.SetAlertNotificationStateToPendingCommand{
+		//			State: models.AlertNotificationState{
+		//				Id:         1,
+		//				SentAt:     1,
+		//				Version:    0,
+		//			}
+		//		}
+		//
+		//		err := SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
+		//		So(err, ShouldBeNil)
+		//
+		//		Convey("should not be able to set pending on old version", func() {
+		//			err = SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
+		//			So(err, ShouldEqual, models.ErrAlertNotificationStateVersionConflict)
+		//		})
+		//
+		//		Convey("should be able to set state to completed", func() {
+		//			cmd := &models.SetAlertNotificationStateToCompleteCommand{Id: 1}
+		//			err = SetAlertNotificationStateToCompleteCommand(context.Background(), cmd)
+		//			So(err, ShouldBeNil)
+		//		})
+		//	})
+		//	})
+		//})
 
 		Convey("Alert notifications should be empty", func() {
 			cmd := &models.GetAlertNotificationsQuery{