diff --git a/pkg/api/common_test.go b/pkg/api/common_test.go index b2ada961523..c9f30dd7a66 100644 --- a/pkg/api/common_test.go +++ b/pkg/api/common_test.go @@ -353,7 +353,7 @@ func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessCo license := &licensing.OSSLicensingService{} routeRegister := routing.NewRouteRegister() - dashboardsStore := dashboardsstore.ProvideDashboardStore(db) + dashboardsStore := dashboardsstore.ProvideDashboardStore(db, featuremgmt.WithFeatures()) var acmock *accesscontrolmock.Mock var ac accesscontrol.AccessControl diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index c7f3b285895..53107d39795 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -28,7 +28,6 @@ import ( "github.com/grafana/grafana/pkg/services/guardian" pref "github.com/grafana/grafana/pkg/services/preference" "github.com/grafana/grafana/pkg/services/star" - "github.com/grafana/grafana/pkg/services/store" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -318,15 +317,6 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response { return response.Error(500, "Failed to delete dashboard", err) } - if hs.entityEventsService != nil { - if err := hs.entityEventsService.SaveEvent(c.Req.Context(), store.SaveEventCmd{ - EntityId: store.CreateDatabaseEntityId(dash.Uid, dash.OrgId, store.EntityTypeDashboard), - EventType: store.EntityEventTypeDelete, - }); err != nil { - hs.log.Warn("failed to save dashboard entity event", "uid", dash.Uid, "error", err) - } - } - if hs.Live != nil { err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.OrgId, c.ToUserDisplayDTO(), dash.Uid) if err != nil { @@ -449,15 +439,6 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa dashboard, err := hs.DashboardService.SaveDashboard(alerting.WithUAEnabled(ctx, hs.Cfg.UnifiedAlerting.IsEnabled()), dashItem, allowUiUpdate) - if dashboard != nil && hs.entityEventsService != nil { - if err := hs.entityEventsService.SaveEvent(ctx, store.SaveEventCmd{ - EntityId: store.CreateDatabaseEntityId(dashboard.Uid, dashboard.OrgId, store.EntityTypeDashboard), - EventType: store.EntityEventTypeUpdate, - }); err != nil { - hs.log.Warn("failed to save dashboard entity event", "uid", dashboard.Uid, "error", err) - } - } - if hs.Live != nil { // Tell everyone listening that the dashboard changed if dashboard == nil { diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index 28e04b1e315..261cfc185b9 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -927,7 +927,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr if dashboardStore == nil { sql := sqlstore.InitTestDB(t) - dashboardStore = database.ProvideDashboardStore(sql) + dashboardStore = database.ProvideDashboardStore(sql, featuremgmt.WithFeatures()) } libraryPanelsService := mockLibraryPanelService{} diff --git a/pkg/api/folder.go b/pkg/api/folder.go index 5ba54de4fe0..59ce684066a 100644 --- a/pkg/api/folder.go +++ b/pkg/api/folder.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/libraryelements" - "github.com/grafana/grafana/pkg/services/store" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -123,14 +122,6 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response { if err != nil { return apierrors.ToFolderErrorResponse(err) } - if hs.entityEventsService != nil { - if err := hs.entityEventsService.SaveEvent(c.Req.Context(), store.SaveEventCmd{ - EntityId: store.CreateDatabaseEntityId(folder.Uid, c.OrgId, store.EntityTypeFolder), - EventType: store.EntityEventTypeCreate, - }); err != nil { - hs.log.Warn("failed to save folder entity event", "uid", folder.Uid, "error", err) - } - } g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser) return response.JSON(http.StatusOK, hs.toFolderDto(c, g, folder)) @@ -157,15 +148,6 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response { if err != nil { return apierrors.ToFolderErrorResponse(err) } - if hs.entityEventsService != nil { - if err := hs.entityEventsService.SaveEvent(c.Req.Context(), store.SaveEventCmd{ - EntityId: store.CreateDatabaseEntityId(cmd.Uid, c.OrgId, store.EntityTypeFolder), - EventType: store.EntityEventTypeUpdate, - }); err != nil { - hs.log.Warn("failed to save folder entity event", "uid", cmd.Uid, "error", err) - } - } - g := guardian.New(c.Req.Context(), cmd.Result.Id, c.OrgId, c.SignedInUser) return response.JSON(http.StatusOK, hs.toFolderDto(c, g, cmd.Result)) } @@ -197,14 +179,6 @@ func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // if err != nil { return apierrors.ToFolderErrorResponse(err) } - if hs.entityEventsService != nil { - if err := hs.entityEventsService.SaveEvent(c.Req.Context(), store.SaveEventCmd{ - EntityId: store.CreateDatabaseEntityId(uid, c.OrgId, store.EntityTypeFolder), - EventType: store.EntityEventTypeDelete, - }); err != nil { - hs.log.Warn("failed to save folder entity event", "uid", uid, "error", err) - } - } return response.JSON(http.StatusOK, util.DynMap{ "title": f.Title, diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 1fef87eec81..04ae711c5c9 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -165,7 +165,6 @@ type HTTPServer struct { AvatarCacheServer *avatar.AvatarCacheServer preferenceService pref.Service Csrf csrf.Service - entityEventsService store.EntityEventsService folderPermissionsService accesscontrol.FolderPermissionsService dashboardPermissionsService accesscontrol.DashboardPermissionsService dashboardVersionService dashver.Service @@ -207,7 +206,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi dashboardProvisioningService dashboards.DashboardProvisioningService, folderService dashboards.FolderService, datasourcePermissionsService permissions.DatasourcePermissionsService, alertNotificationService *alerting.AlertNotificationService, dashboardsnapshotsService dashboardsnapshots.Service, commentsService *comments.Service, pluginSettings *pluginSettings.Service, - avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service, entityEventsService store.EntityEventsService, + avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service, teamsPermissionsService accesscontrol.TeamPermissionsService, folderPermissionsService accesscontrol.FolderPermissionsService, dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service, starService star.Service, csrfService csrf.Service, coremodelRegistry *registry.Generic, coremodelStaticRegistry *registry.Static, @@ -289,7 +288,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi AvatarCacheServer: avatarCacheServer, preferenceService: preferenceService, Csrf: csrfService, - entityEventsService: entityEventsService, folderPermissionsService: folderPermissionsService, dashboardPermissionsService: dashboardPermissionsService, dashboardVersionService: dashboardVersionService, diff --git a/pkg/services/dashboards/database/acl_test.go b/pkg/services/dashboards/database/acl_test.go index e66b25ecfb4..31a861d3845 100644 --- a/pkg/services/dashboards/database/acl_test.go +++ b/pkg/services/dashboards/database/acl_test.go @@ -21,7 +21,7 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) { setup := func(t *testing.T) { sqlStore = sqlstore.InitTestDB(t) - dashboardStore = ProvideDashboardStore(sqlStore) + dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles) currentUser = createUser(t, sqlStore, "viewer", "Viewer", false) savedFolder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp") childDash = insertTestDashboard(t, dashboardStore, "2 test dash", 1, savedFolder.Id, false, "prod", "webapp") diff --git a/pkg/services/dashboards/database/database.go b/pkg/services/dashboards/database/database.go index 2e8b2e984ec..135875428e8 100644 --- a/pkg/services/dashboards/database/database.go +++ b/pkg/services/dashboards/database/database.go @@ -14,10 +14,12 @@ import ( ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/permissions" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" + "github.com/grafana/grafana/pkg/services/store" "github.com/grafana/grafana/pkg/util" ) @@ -25,13 +27,18 @@ type DashboardStore struct { sqlStore *sqlstore.SQLStore log log.Logger dialect migrator.Dialect + features featuremgmt.FeatureToggles } // DashboardStore implements the Store interface var _ dashboards.Store = (*DashboardStore)(nil) -func ProvideDashboardStore(sqlStore *sqlstore.SQLStore) *DashboardStore { - return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect} +func ProvideDashboardStore(sqlStore *sqlstore.SQLStore, features featuremgmt.FeatureToggles) *DashboardStore { + return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect, features: features} +} + +func (d *DashboardStore) emitEntityEvent() bool { + return d.features != nil && d.features.IsEnabled(featuremgmt.FlagPanelTitleSearch) } func (d *DashboardStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) { @@ -171,7 +178,7 @@ func (d *DashboardStore) GetProvisionedDashboardData(name string) ([]*models.Das func (d *DashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) { err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error { - if err := saveDashboard(sess, &cmd); err != nil { + if err := saveDashboard(sess, &cmd, d.emitEntityEvent()); err != nil { return err } @@ -187,7 +194,7 @@ func (d *DashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardComman func (d *DashboardStore) SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error) { err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error { - return saveDashboard(sess, &cmd) + return saveDashboard(sess, &cmd, d.emitEntityEvent()) }) return cmd.Result, err } @@ -396,7 +403,7 @@ func getExistingDashboardByTitleAndFolder(sess *sqlstore.DBSession, dash *models return isParentFolderChanged, nil } -func saveDashboard(sess *sqlstore.DBSession, cmd *models.SaveDashboardCommand) error { +func saveDashboard(sess *sqlstore.DBSession, cmd *models.SaveDashboardCommand, emitEntityEvent bool) error { dash := cmd.GetDashboardModel() userId := cmd.UserId @@ -507,6 +514,12 @@ func saveDashboard(sess *sqlstore.DBSession, cmd *models.SaveDashboardCommand) e cmd.Result = dash + if emitEntityEvent { + _, err := sess.Insert(createEntityEvent(dash, store.EntityEventTypeUpdate)) + if err != nil { + return err + } + } return nil } @@ -698,11 +711,11 @@ func (d *DashboardStore) GetDashboardsByPluginID(ctx context.Context, query *mod func (d *DashboardStore) DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error { return d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { - return d.deleteDashboard(cmd, sess) + return d.deleteDashboard(cmd, sess, d.emitEntityEvent()) }) } -func (d *DashboardStore) deleteDashboard(cmd *models.DeleteDashboardCommand, sess *sqlstore.DBSession) error { +func (d *DashboardStore) deleteDashboard(cmd *models.DeleteDashboardCommand, sess *sqlstore.DBSession, emitEntityEvent bool) error { dashboard := models.Dashboard{Id: cmd.Id, OrgId: cmd.OrgId} has, err := sess.Get(&dashboard) if err != nil { @@ -812,9 +825,33 @@ func (d *DashboardStore) deleteDashboard(cmd *models.DeleteDashboardCommand, ses } } + if emitEntityEvent { + _, err := sess.Insert(createEntityEvent(&dashboard, store.EntityEventTypeDelete)) + if err != nil { + return err + } + } return nil } +func createEntityEvent(dashboard *models.Dashboard, eventType store.EntityEventType) *store.EntityEvent { + var entityEvent *store.EntityEvent + if dashboard.IsFolder { + entityEvent = &store.EntityEvent{ + EventType: eventType, + EntityId: store.CreateDatabaseEntityId(dashboard.Uid, dashboard.OrgId, store.EntityTypeFolder), + Created: time.Now().Unix(), + } + } else { + entityEvent = &store.EntityEvent{ + EventType: eventType, + EntityId: store.CreateDatabaseEntityId(dashboard.Uid, dashboard.OrgId, store.EntityTypeDashboard), + Created: time.Now().Unix(), + } + } + return entityEvent +} + func (d *DashboardStore) deleteAlertDefinition(dashboardId int64, sess *sqlstore.DBSession) error { alerts := make([]*models.Alert, 0) if err := sess.Where("dashboard_id = ?", dashboardId).Find(&alerts); err != nil { diff --git a/pkg/services/dashboards/database/database_folder_test.go b/pkg/services/dashboards/database/database_folder_test.go index 664fffeecf0..15e6ff2d7ee 100644 --- a/pkg/services/dashboards/database/database_folder_test.go +++ b/pkg/services/dashboards/database/database_folder_test.go @@ -9,10 +9,13 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" ) +var testFeatureToggles = featuremgmt.WithFeatures(featuremgmt.FlagPanelTitleSearch) + func TestIntegrationDashboardFolderDataAccess(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") @@ -26,7 +29,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t) sqlStore.Cfg.RBACEnabled = false - dashboardStore = ProvideDashboardStore(sqlStore) + dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles) folder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp") dashInRoot = insertTestDashboard(t, dashboardStore, "test dash 67", 1, 0, false, "prod", "webapp") childDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, folder.Id, false, "prod", "webapp") @@ -179,7 +182,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { setup2 := func() { sqlStore = sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folder1 = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod") folder2 = insertTestDashboard(t, dashboardStore, "2 test dash folder", 1, 0, true, "prod") dashInRoot = insertTestDashboard(t, dashboardStore, "test dash 67", 1, 0, false, "prod") @@ -284,7 +287,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { setup3 := func() { sqlStore = sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folder1 = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod") folder2 = insertTestDashboard(t, dashboardStore, "2 test dash folder", 1, 0, true, "prod") insertTestDashboard(t, dashboardStore, "folder in another org", 2, 0, true, "prod") @@ -466,7 +469,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { var sqlStore *sqlstore.SQLStore var folder1, folder2 *models.Dashboard sqlStore = sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folder2 = insertTestDashboard(t, dashboardStore, "TEST", orgId, 0, true, "prod") _ = insertTestDashboard(t, dashboardStore, title, orgId, folder2.Id, false, "prod") folder1 = insertTestDashboard(t, dashboardStore, title, orgId, 0, true, "prod") @@ -481,7 +484,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("GetFolderByUID", func(t *testing.T) { var orgId int64 = 1 sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folder := insertTestDashboard(t, dashboardStore, "TEST", orgId, 0, true, "prod") dash := insertTestDashboard(t, dashboardStore, "Very Unique Name", orgId, folder.Id, false, "prod") @@ -505,7 +508,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) { t.Run("GetFolderByID", func(t *testing.T) { var orgId int64 = 1 sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folder := insertTestDashboard(t, dashboardStore, "TEST", orgId, 0, true, "prod") dash := insertTestDashboard(t, dashboardStore, "Very Unique Name", orgId, folder.Id, false, "prod") diff --git a/pkg/services/dashboards/database/database_provisioning_test.go b/pkg/services/dashboards/database/database_provisioning_test.go index f882ca64cc3..fdd71876782 100644 --- a/pkg/services/dashboards/database/database_provisioning_test.go +++ b/pkg/services/dashboards/database/database_provisioning_test.go @@ -18,7 +18,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) { t.Skip("skipping integration test") } sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) folderCmd := models.SaveDashboardCommand{ OrgId: 1, diff --git a/pkg/services/dashboards/database/database_test.go b/pkg/services/dashboards/database/database_test.go index 98bfd184ce0..f9fecec199d 100644 --- a/pkg/services/dashboards/database/database_test.go +++ b/pkg/services/dashboards/database/database_test.go @@ -33,7 +33,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t) starService = starimpl.ProvideService(sqlStore) - dashboardStore = ProvideDashboardStore(sqlStore) + dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles) savedFolder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp") savedDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") insertTestDashboard(t, dashboardStore, "test dash 45", 1, savedFolder.Id, false, "prod") @@ -484,7 +484,7 @@ func TestIntegrationDashboardDataAccessGivenPluginWithImportedDashboards(t *test t.Skip("skipping integration test") } sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) pluginId := "test-app" appFolder := insertTestDashboardForPlugin(t, dashboardStore, "app-test", 1, 0, true, pluginId) @@ -506,7 +506,7 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) { t.Skip("skipping integration test") } sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false) dashA := insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false) @@ -555,7 +555,7 @@ func TestIntegrationDashboard_Filter(t *testing.T) { t.Skip("skipping integration test") } sqlStore := sqlstore.InitTestDB(t) - dashboardStore := ProvideDashboardStore(sqlStore) + dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles) insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false) dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false) qNoFilter := &models.FindPersistedDashboardsQuery{ diff --git a/pkg/services/dashboards/service/dashboard_service_integration_test.go b/pkg/services/dashboards/service/dashboard_service_integration_test.go index dad3576988e..0e7e3a6fc01 100644 --- a/pkg/services/dashboards/service/dashboard_service_integration_test.go +++ b/pkg/services/dashboards/service/dashboard_service_integration_test.go @@ -814,7 +814,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc t.Run(desc, func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) service := ProvideDashboardService( &setting.Cfg{}, dashboardStore, &dummyDashAlertExtractor{}, featuremgmt.WithFeatures(), @@ -868,7 +868,7 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore t.Helper() dto := toSaveDashboardDto(cmd) - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled service := ProvideDashboardService( @@ -886,7 +886,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) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled service := ProvideDashboardService( @@ -922,7 +922,7 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto }, } - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled service := ProvideDashboardService( @@ -959,7 +959,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore. }, } - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled service := ProvideDashboardService( diff --git a/pkg/services/guardian/accesscontrol_guardian_test.go b/pkg/services/guardian/accesscontrol_guardian_test.go index 3e3520634b6..72b610d2074 100644 --- a/pkg/services/guardian/accesscontrol_guardian_test.go +++ b/pkg/services/guardian/accesscontrol_guardian_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -587,7 +589,7 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce toSave.SetUid(uid) // seed dashboard - dashStore := dashdb.ProvideDashboardStore(store) + dashStore := dashdb.ProvideDashboardStore(store, featuremgmt.WithFeatures()) dash, err := dashStore.SaveDashboard(models.SaveDashboardCommand{ Dashboard: toSave.Data, UserId: 1, diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index 71bc9e04c40..a2b2ac1464d 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -269,7 +269,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign Overwrite: false, } - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) dashAlertExtractor := alerting.ProvideDashAlertExtractorService(nil, nil, nil) features := featuremgmt.WithFeatures() cfg := setting.NewCfg() @@ -297,7 +297,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string ac := acmock.New() folderPermissions := acmock.NewMockedPermissionsService() dashboardPermissions := acmock.NewMockedPermissionsService() - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) d := dashboardservice.ProvideDashboardService( cfg, dashboardStore, nil, @@ -401,7 +401,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo orgID := int64(1) role := models.ROLE_ADMIN sqlStore := sqlstore.InitTestDB(t) - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) features := featuremgmt.WithFeatures() cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = features.IsEnabled diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index 6ae0f70de21..50a699107c5 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -1374,7 +1374,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig Overwrite: false, } - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) dashAlertService := alerting.ProvideDashAlertExtractorService(nil, nil, nil) cfg := setting.NewCfg() cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled @@ -1399,7 +1399,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string features := featuremgmt.WithFeatures() folderPermissions := acmock.NewMockedPermissionsService() dashboardPermissions := acmock.NewMockedPermissionsService() - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac) s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, folderPermissions, ac, busmock.New()) @@ -1491,7 +1491,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo orgID := int64(1) role := models.ROLE_ADMIN sqlStore := sqlstore.InitTestDB(t) - dashboardStore := database.ProvideDashboardStore(sqlStore) + dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) features := featuremgmt.WithFeatures() ac := acmock.New() diff --git a/pkg/services/ngalert/tests/util.go b/pkg/services/ngalert/tests/util.go index 6dfb322973f..bcd92a8a281 100644 --- a/pkg/services/ngalert/tests/util.go +++ b/pkg/services/ngalert/tests/util.go @@ -44,7 +44,7 @@ func SetupTestEnv(t *testing.T, baseInterval time.Duration) (*ngalert.AlertNG, * m := metrics.NewNGAlert(prometheus.NewRegistry()) sqlStore := sqlstore.InitTestDB(t) secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore)) - dashboardStore := databasestore.ProvideDashboardStore(sqlStore) + dashboardStore := databasestore.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) ac := acmock.New() features := featuremgmt.WithFeatures() diff --git a/pkg/services/publicdashboards/api/api_test.go b/pkg/services/publicdashboards/api/api_test.go index 4eb0ea1ad4e..bc2af0cc0ae 100644 --- a/pkg/services/publicdashboards/api/api_test.go +++ b/pkg/services/publicdashboards/api/api_test.go @@ -531,7 +531,7 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T) } // create dashboard - dashboardStore := dashboardStore.ProvideDashboardStore(db) + dashboardStore := dashboardStore.ProvideDashboardStore(db, featuremgmt.WithFeatures()) dashboard, err := dashboardStore.SaveDashboard(saveDashboardCmd) require.NoError(t, err) diff --git a/pkg/services/publicdashboards/database/database_test.go b/pkg/services/publicdashboards/database/database_test.go index 49cc2f370df..092e3226dde 100644 --- a/pkg/services/publicdashboards/database/database_test.go +++ b/pkg/services/publicdashboards/database/database_test.go @@ -32,7 +32,7 @@ func TestIntegrationGetDashboard(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t) - dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore = ProvideStore(sqlStore) savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true) } @@ -56,7 +56,7 @@ func TestIntegrationGetPublicDashboard(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t) - dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore = ProvideStore(sqlStore) savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true) } @@ -173,7 +173,7 @@ func TestIntegrationGetPublicDashboardConfig(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t) - dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore = ProvideStore(sqlStore) savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true) } @@ -227,7 +227,7 @@ func TestIntegrationSavePublicDashboardConfig(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}}) - dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore = ProvideStore(sqlStore) savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true) savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, true) @@ -276,7 +276,7 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) { setup := func() { sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}}) - dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore = ProvideStore(sqlStore) savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true) anotherSavedDashboard = insertTestDashboard(t, dashboardStore, "test another Dashie", 1, 0, true) diff --git a/pkg/services/publicdashboards/service/service_test.go b/pkg/services/publicdashboards/service/service_test.go index 519c5cdce84..9d7f8b70792 100644 --- a/pkg/services/publicdashboards/service/service_test.go +++ b/pkg/services/publicdashboards/service/service_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -118,7 +120,7 @@ func TestGetPublicDashboard(t *testing.T) { func TestSavePublicDashboard(t *testing.T) { t.Run("Saving public dashboard", func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) @@ -162,7 +164,7 @@ func TestSavePublicDashboard(t *testing.T) { t.Run("Validate pubdash has default time setting value", func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) @@ -192,7 +194,7 @@ func TestSavePublicDashboard(t *testing.T) { t.Run("Validate pubdash whose dashboard has template variables returns error", func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) templateVars := make([]map[string]interface{}, 1) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, templateVars) @@ -221,7 +223,7 @@ func TestSavePublicDashboard(t *testing.T) { func TestUpdatePublicDashboard(t *testing.T) { t.Run("Updating public dashboard", func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) @@ -288,7 +290,7 @@ func TestUpdatePublicDashboard(t *testing.T) { t.Run("Updating set empty time settings", func(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) @@ -347,7 +349,7 @@ func TestUpdatePublicDashboard(t *testing.T) { func TestBuildAnonymousUser(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) publicdashboardStore := database.ProvideStore(sqlStore) service := &PublicDashboardServiceImpl{ @@ -368,7 +370,7 @@ func TestBuildAnonymousUser(t *testing.T) { func TestBuildPublicDashboardMetricRequest(t *testing.T) { sqlStore := sqlstore.InitTestDB(t) - dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore) + dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures()) publicdashboardStore := database.ProvideStore(sqlStore) publicDashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{}) diff --git a/pkg/services/searchV2/index.go b/pkg/services/searchV2/index.go index 7911195b117..8560aa54df1 100644 --- a/pkg/services/searchV2/index.go +++ b/pkg/services/searchV2/index.go @@ -33,7 +33,6 @@ type dashboardLoader interface { } type eventStore interface { - OnEvent(handler store.EventHandler) GetLastEvent(ctx context.Context) (*store.EntityEvent, error) GetAllEventsAfter(ctx context.Context, id int64) ([]*store.EntityEvent, error) } diff --git a/pkg/services/sqlstore/annotation_test.go b/pkg/services/sqlstore/annotation_test.go index d6c1c50b6c1..c0d44e19652 100644 --- a/pkg/services/sqlstore/annotation_test.go +++ b/pkg/services/sqlstore/annotation_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -47,7 +49,7 @@ func TestIntegrationAnnotations(t *testing.T) { assert.NoError(t, err) }) - dashboardStore := dashboardstore.ProvideDashboardStore(sql) + dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures()) testDashboard1 := models.SaveDashboardCommand{ UserId: 1, @@ -388,7 +390,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) { } sql := sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{}) repo := sqlstore.NewSQLAnnotationRepo(sql) - dashboardStore := dashboardstore.ProvideDashboardStore(sql) + dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures()) testDashboard1 := models.SaveDashboardCommand{ UserId: 1, diff --git a/pkg/services/store/entity_events.go b/pkg/services/store/entity_events.go index 1c4055908d4..185857e9979 100644 --- a/pkg/services/store/entity_events.go +++ b/pkg/services/store/entity_events.go @@ -62,10 +62,8 @@ type EventHandler func(ctx context.Context, e *EntityEvent) error type EntityEventsService interface { registry.BackgroundService registry.CanBeDisabled - SaveEvent(ctx context.Context, cmd SaveEventCmd) error GetLastEvent(ctx context.Context) (*EntityEvent, error) GetAllEventsAfter(ctx context.Context, id int64) ([]*EntityEvent, error) - OnEvent(handler EventHandler) deleteEventsOlderThan(ctx context.Context, duration time.Duration) error } @@ -90,36 +88,6 @@ type entityEventService struct { eventHandlers []EventHandler } -func (e *entityEventService) SaveEvent(ctx context.Context, cmd SaveEventCmd) error { - entityEvent := &EntityEvent{ - EventType: cmd.EventType, - EntityId: cmd.EntityId, - Created: time.Now().Unix(), - } - err := e.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - _, err := sess.Insert(entityEvent) - return err - }) - if err != nil { - return err - } - return e.broadcastEvent(ctx, entityEvent) -} - -func (e *entityEventService) broadcastEvent(ctx context.Context, event *EntityEvent) error { - for _, h := range e.eventHandlers { - err := h(ctx, event) - if err != nil { - return err - } - } - return nil -} - -func (e *entityEventService) OnEvent(handler EventHandler) { - e.eventHandlers = append(e.eventHandlers, handler) -} - func (e *entityEventService) GetLastEvent(ctx context.Context) (*EntityEvent, error) { var entityEvent *EntityEvent err := e.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { @@ -187,13 +155,6 @@ func (d dummyEntityEventsService) IsDisabled() bool { return false } -func (d dummyEntityEventsService) SaveEvent(ctx context.Context, cmd SaveEventCmd) error { - return nil -} - -func (d dummyEntityEventsService) OnEvent(handler EventHandler) { -} - func (d dummyEntityEventsService) GetLastEvent(ctx context.Context) (*EntityEvent, error) { return nil, nil } diff --git a/pkg/services/store/entity_events_test.go b/pkg/services/store/entity_events_test.go index ba81b8832b5..cd274661cd0 100644 --- a/pkg/services/store/entity_events_test.go +++ b/pkg/services/store/entity_events_test.go @@ -10,25 +10,34 @@ import ( "github.com/stretchr/testify/require" ) +func saveEvent(ctx context.Context, sql *sqlstore.SQLStore, cmd SaveEventCmd) error { + entityEvent := &EntityEvent{ + EventType: cmd.EventType, + EntityId: cmd.EntityId, + Created: time.Now().Unix(), + } + return sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { + _, err := sess.Insert(entityEvent) + return err + }) +} + func TestIntegrationEntityEventsService(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") } - var ctx context.Context - var service EntityEventsService + ctx := context.Background() - setup := func() { - service = &entityEventService{ + setup := func() *entityEventService { + return &entityEventService{ sql: sqlstore.InitTestDB(t), log: log.New("entity-event-test"), } - ctx = context.Background() } t.Run("Should insert an entity event", func(t *testing.T) { - setup() - - err := service.SaveEvent(ctx, SaveEventCmd{ + service := setup() + err := saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/1", EventType: EntityEventTypeCreate, }) @@ -36,28 +45,27 @@ func TestIntegrationEntityEventsService(t *testing.T) { }) t.Run("Should retrieve nil entity if database is empty", func(t *testing.T) { - setup() - + service := setup() ev, err := service.GetLastEvent(ctx) require.NoError(t, err) require.Nil(t, ev) }) t.Run("Should retrieve last entity event", func(t *testing.T) { - setup() + service := setup() lastEventEntityId := "database/dash/1" - err := service.SaveEvent(ctx, SaveEventCmd{ + err := saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/3", EventType: EntityEventTypeCreate, }) require.NoError(t, err) - err = service.SaveEvent(ctx, SaveEventCmd{ + err = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/2", EventType: EntityEventTypeCreate, }) require.NoError(t, err) - err = service.SaveEvent(ctx, SaveEventCmd{ + err = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: lastEventEntityId, EventType: EntityEventTypeCreate, }) @@ -69,10 +77,10 @@ func TestIntegrationEntityEventsService(t *testing.T) { }) t.Run("Should retrieve sorted events after an id", func(t *testing.T) { - setup() + service := setup() lastEventEntityId := "database/dash/1" - err := service.SaveEvent(ctx, SaveEventCmd{ + err := saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/3", EventType: EntityEventTypeCreate, }) @@ -81,12 +89,12 @@ func TestIntegrationEntityEventsService(t *testing.T) { require.NoError(t, err) firstEvId := firstEv.Id - err = service.SaveEvent(ctx, SaveEventCmd{ + err = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/2", EventType: EntityEventTypeCreate, }) require.NoError(t, err) - err = service.SaveEvent(ctx, SaveEventCmd{ + err = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: lastEventEntityId, EventType: EntityEventTypeCreate, }) @@ -100,16 +108,16 @@ func TestIntegrationEntityEventsService(t *testing.T) { }) t.Run("Should delete old events", func(t *testing.T) { - setup() - _ = service.SaveEvent(ctx, SaveEventCmd{ + service := setup() + _ = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/3", EventType: EntityEventTypeCreate, }) - _ = service.SaveEvent(ctx, SaveEventCmd{ + _ = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/2", EventType: EntityEventTypeCreate, }) - _ = service.SaveEvent(ctx, SaveEventCmd{ + _ = saveEvent(ctx, service.sql, SaveEventCmd{ EntityId: "database/dash/1", EventType: EntityEventTypeCreate, })