Dashboard Alert Extractor: Create service for dashboard extractor and remove bus (#45518)

* Create DashAlertService service

* Remove no used dashboard service from plugin's manager that generates dependency cycle in Enterprise

* Remove bus for dashboard permissions

* Remove bus from dashboard extractor service

* Add missing argument

* Fix wire

* Fix lint

* More goimports

* Use datasource service instead sql calls

* Fix integration test
This commit is contained in:
Selene
2022-02-28 09:54:56 +01:00
committed by GitHub
parent 1df040eb23
commit 2c90dcf3c0
29 changed files with 294 additions and 232 deletions
@@ -19,14 +19,16 @@ import (
)
type DashboardServiceImpl struct {
dashboardStore m.Store
log log.Logger
dashboardStore m.Store
dashAlertExtractor alerting.DashAlertExtractor
log log.Logger
}
func ProvideDashboardService(store m.Store) *DashboardServiceImpl {
func ProvideDashboardService(store m.Store, dashAlertExtractor alerting.DashAlertExtractor) *DashboardServiceImpl {
return &DashboardServiceImpl{
dashboardStore: store,
log: log.New("dashboard-service"),
dashboardStore: store,
dashAlertExtractor: dashAlertExtractor,
log: log.New("dashboard-service"),
}
}
@@ -74,7 +76,8 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
}
if shouldValidateAlerts {
if err := validateAlerts(ctx, dash, dto.User); err != nil {
dashAlertInfo := alerting.DashAlertInfo{Dash: dash, User: dto.User, OrgID: dash.OrgId}
if err := dr.dashAlertExtractor.ValidateAlerts(ctx, dashAlertInfo); err != nil {
return nil, err
}
}
@@ -139,11 +142,6 @@ func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.
return dr.dashboardStore.DeleteOrphanedProvisionedDashboards(ctx, cmd)
}
var validateAlerts = func(ctx context.Context, dash *models.Dashboard, user *models.SignedInUser) error {
extractor := alerting.NewDashAlertExtractor(dash, dash.OrgId, user)
return extractor.ValidateAlerts(ctx)
}
func validateDashboardRefreshInterval(dash *models.Dashboard) error {
if setting.MinRefreshInterval == "" {
return nil
@@ -171,19 +169,6 @@ func validateDashboardRefreshInterval(dash *models.Dashboard) error {
return nil
}
// UpdateAlerting updates alerting.
//
// Stubbable by tests.
var UpdateAlerting = func(ctx context.Context, store m.Store, orgID int64, dashboard *models.Dashboard, user *models.SignedInUser) error {
extractor := alerting.NewDashAlertExtractor(dashboard, orgID, user)
alerts, err := extractor.GetAlerts(ctx)
if err != nil {
return err
}
return store.SaveAlerts(ctx, dashboard.Id, alerts)
}
func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dto *m.SaveDashboardDTO,
provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil {
@@ -210,7 +195,19 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
}
// alerts
if err := UpdateAlerting(ctx, dr.dashboardStore, dto.OrgId, dash, dto.User); err != nil {
dashAlertInfo := alerting.DashAlertInfo{
User: dto.User,
Dash: dash,
OrgID: dto.OrgId,
}
alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo)
if err != nil {
return nil, err
}
err = dr.dashboardStore.SaveAlerts(ctx, dash.Id, alerts)
if err != nil {
return nil, err
}
@@ -232,7 +229,19 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
return nil, err
}
if err := UpdateAlerting(ctx, dr.dashboardStore, dto.OrgId, dash, dto.User); err != nil {
dashAlertInfo := alerting.DashAlertInfo{
User: dto.User,
Dash: dash,
OrgID: dto.OrgId,
}
alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo)
if err != nil {
return nil, err
}
err = dr.dashboardStore.SaveAlerts(ctx, dash.Id, alerts)
if err != nil {
return nil, err
}
@@ -258,7 +267,19 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *m.SaveDa
return nil, fmt.Errorf("saving dashboard failed: %w", err)
}
if err := UpdateAlerting(ctx, dr.dashboardStore, dto.OrgId, dash, dto.User); err != nil {
dashAlertInfo := alerting.DashAlertInfo{
User: dto.User,
Dash: dash,
OrgID: dto.OrgId,
}
alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo)
if err != nil {
return nil, err
}
err = dr.dashboardStore.SaveAlerts(ctx, dash.Id, alerts)
if err != nil {
return nil, err
}
@@ -5,6 +5,7 @@ package service
import (
"context"
"github.com/grafana/grafana/pkg/services/alerting"
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
@@ -21,14 +22,6 @@ const testOrgID int64 = 1
func TestIntegratedDashboardService(t *testing.T) {
t.Run("Given saved folders and dashboards in organization A", func(t *testing.T) {
origUpdateAlerting := UpdateAlerting
t.Cleanup(func() {
UpdateAlerting = origUpdateAlerting
})
UpdateAlerting = func(ctx context.Context, store dashbboardservice.Store, orgID int64, dashboard *models.Dashboard, user *models.SignedInUser) error {
return nil
}
// Basic validation tests
permissionScenario(t, "When saving a dashboard with non-existing id", true,
@@ -861,7 +854,7 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
dto := toSaveDashboardDto(cmd)
dashboardStore := database.ProvideDashboardStore(sqlStore)
res, err := ProvideDashboardService(dashboardStore).SaveDashboard(context.Background(), &dto, false)
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
return res
@@ -870,7 +863,7 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLStore) error {
dto := toSaveDashboardDto(cmd)
dashboardStore := database.ProvideDashboardStore(sqlStore)
_, err := ProvideDashboardService(dashboardStore).SaveDashboard(context.Background(), &dto, false)
_, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
return err
}
@@ -897,7 +890,7 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
}
dashboardStore := database.ProvideDashboardStore(sqlStore)
res, err := ProvideDashboardService(dashboardStore).SaveDashboard(context.Background(), &dto, false)
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
return res
@@ -925,7 +918,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
}
dashboardStore := database.ProvideDashboardStore(sqlStore)
res, err := ProvideDashboardService(dashboardStore).SaveDashboard(context.Background(), &dto, false)
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
require.NoError(t, err)
return res
@@ -942,3 +935,14 @@ func toSaveDashboardDto(cmd models.SaveDashboardCommand) dashbboardservice.SaveD
Overwrite: cmd.Overwrite,
}
}
type dummyDashAlertExtractor struct {
}
func (d *dummyDashAlertExtractor) GetAlerts(ctx context.Context, dashAlertInfo alerting.DashAlertInfo) ([]*models.Alert, error) {
return nil, nil
}
func (d *dummyDashAlertExtractor) ValidateAlerts(ctx context.Context, dashAlertInfo alerting.DashAlertInfo) error {
return nil
}
@@ -27,8 +27,9 @@ func TestDashboardService(t *testing.T) {
fakeStore := database.FakeDashboardStore{}
defer fakeStore.AssertExpectations(t)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: &fakeStore,
log: log.New("test.logger"),
dashboardStore: &fakeStore,
dashAlertExtractor: &dummyDashAlertExtractor{},
}
origNewDashboardGuardian := guardian.New
@@ -25,7 +25,7 @@ func TestFolderService(t *testing.T) {
store := &database.FakeDashboardStore{}
defer store.AssertExpectations(t)
service := ProvideFolderService(
&dashboards.FakeDashboardService{DashboardService: ProvideDashboardService(store)},
&dashboards.FakeDashboardService{DashboardService: ProvideDashboardService(store, nil)},
store,
nil,
)