diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index cc7d81452ba..fa085e9485e 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -45,7 +45,6 @@ import ( "github.com/grafana/grafana/pkg/services/comments" "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/correlations" - dashboardThumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboardsnapshots" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" @@ -193,7 +192,7 @@ type HTTPServer struct { userService user.Service tempUserService tempUser.Service - dashboardThumbsService dashboardThumbs.Service + dashboardThumbsService thumbs.DashboardThumbService loginAttemptService loginAttempt.Service orgService org.Service teamService team.Service @@ -240,7 +239,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi secretsPluginMigrator spm.SecretMigrationProvider, secretsStore secretsKV.SecretsKVStore, publicDashboardsApi *publicdashboardsApi.Api, userService user.Service, tempUserService tempUser.Service, loginAttemptService loginAttempt.Service, orgService org.Service, teamService team.Service, - accesscontrolService accesscontrol.Service, dashboardThumbsService dashboardThumbs.Service, navTreeService navtree.Service, + accesscontrolService accesscontrol.Service, dashboardThumbsService thumbs.DashboardThumbService, navTreeService navtree.Service, annotationRepo annotations.Repository, tagService tag.Service, searchv2HTTPService searchV2.SearchHTTPService, userAuthService userauth.Service, ) (*HTTPServer, error) { diff --git a/pkg/server/wire.go b/pkg/server/wire.go index 8a56e474611..36b61905181 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -54,7 +54,6 @@ import ( "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/contexthandler/authproxy" "github.com/grafana/grafana/pkg/services/correlations" - "github.com/grafana/grafana/pkg/services/dashboard_thumbs/dashboardthumbsimpl" "github.com/grafana/grafana/pkg/services/dashboardimport" dashboardimportservice "github.com/grafana/grafana/pkg/services/dashboardimport/service" "github.com/grafana/grafana/pkg/services/dashboards" @@ -132,6 +131,7 @@ import ( tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/temp_user/tempuserimpl" "github.com/grafana/grafana/pkg/services/thumbs" + "github.com/grafana/grafana/pkg/services/thumbs/dashboardthumbsimpl" "github.com/grafana/grafana/pkg/services/updatechecker" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/services/userauth/userauthimpl" @@ -177,6 +177,7 @@ var wireBasicSet = wire.NewSet( hooks.ProvideService, kvstore.ProvideService, localcache.ProvideService, + dashboardthumbsimpl.ProvideService, updatechecker.ProvideGrafanaService, updatechecker.ProvidePluginsService, uss.ProvideService, @@ -345,7 +346,6 @@ var wireBasicSet = wire.NewSet( grpcserver.ProvideHealthService, teamimpl.ProvideService, tempuserimpl.ProvideService, - dashboardthumbsimpl.ProvideService, loginattemptimpl.ProvideService, userauthimpl.ProvideService, secretsMigrations.ProvideDataSourceMigrationService, diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go deleted file mode 100644 index a71116b2136..00000000000 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go +++ /dev/null @@ -1,45 +0,0 @@ -package dashboardthumbsimpl - -import ( - "context" - - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" - "github.com/grafana/grafana/pkg/services/sqlstore/db" -) - -type Service struct { - store store -} - -func ProvideService( - db db.DB, -) dashboardthumbs.Service { - return &Service{ - store: &xormStore{db: db}, - } -} - -func (s *Service) GetThumbnail(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { - dt, err := s.store.Get(ctx, query) - return dt, err -} - -func (s *Service) SaveThumbnail(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { - dt, err := s.store.Save(ctx, cmd) - return dt, err -} - -func (s *Service) UpdateThumbnailState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error { - err := s.store.UpdateState(ctx, cmd) - return err -} - -func (s *Service) FindThumbnailCount(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) { - n, err := s.store.Count(ctx, cmd) - return n, err -} - -func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { - thumbs, err := s.store.FindDashboardsWithStaleThumbnails(ctx, cmd) - return thumbs, err -} diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go deleted file mode 100644 index 23ea9cc2221..00000000000 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go +++ /dev/null @@ -1,15 +0,0 @@ -package dashboardthumbsimpl - -import ( - "context" - - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" -) - -type store interface { - Get(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) - Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) - UpdateState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error - Count(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) - FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) -} diff --git a/pkg/services/dashboard_thumbs/model.go b/pkg/services/dashboard_thumbs/model.go deleted file mode 100644 index 3ee310880ba..00000000000 --- a/pkg/services/dashboard_thumbs/model.go +++ /dev/null @@ -1,148 +0,0 @@ -package dashboardthumbs - -import ( - "encoding/json" - "errors" - "fmt" - "time" - - "github.com/grafana/grafana/pkg/models" -) - -type ThumbnailKind string -type ThumbnailState string -type CrawlerMode string - -const ( - // ThumbnailKindDefault is a small 320x240 preview - ThumbnailKindDefault ThumbnailKind = "thumb" - - // unsupported for now - // - ThumbnailKindLarge ThumbnailKind = "large" - // - ThumbnailKindTall ThumbnailKind = "tall" -) - -const ( - // ThumbnailStateDefault is the initial state for all thumbnails. Thumbnails in the "default" state will be considered stale, - // and thus refreshed by the crawler, if the dashboard version from the time of taking the thumbnail is different from the current dashboard version - ThumbnailStateDefault ThumbnailState = "default" - - // ThumbnailStateStale is a manually assigned state. Thumbnails in the "stale" state will be refreshed on the next crawler run - ThumbnailStateStale ThumbnailState = "stale" - - // ThumbnailStateLocked is a manually assigned state. Thumbnails in the "locked" state will not be refreshed by the crawler as long as they remain in the "locked" state. - ThumbnailStateLocked ThumbnailState = "locked" -) - -func (s ThumbnailState) IsValid() bool { - return s == ThumbnailStateDefault || s == ThumbnailStateStale || s == ThumbnailStateLocked -} - -func (s *ThumbnailState) UnmarshalJSON(data []byte) error { - var str string - err := json.Unmarshal(data, &str) - if err != nil { - return err - } - - *s = ThumbnailState(str) - - if !s.IsValid() { - if (*s) != "" { - return fmt.Errorf("JSON validation error: invalid thumbnail state value: %s", *s) - } - - *s = ThumbnailStateDefault - } - - return nil -} - -// IsKnownThumbnailKind checks if the value is supported -func (p ThumbnailKind) IsKnownThumbnailKind() bool { - switch p { - case - ThumbnailKindDefault: - return true - } - return false -} - -func ParseThumbnailKind(str string) (ThumbnailKind, error) { - switch str { - case string(ThumbnailKindDefault): - return ThumbnailKindDefault, nil - } - return ThumbnailKindDefault, errors.New("unknown thumbnail kind " + str) -} - -// A DashboardThumbnail includes all metadata for a dashboard thumbnail -type DashboardThumbnail struct { - Id int64 `json:"id"` - DashboardId int64 `json:"dashboardId"` - DashboardVersion int `json:"dashboardVersion"` - State ThumbnailState `json:"state"` - PanelId int64 `json:"panelId,omitempty"` - Kind ThumbnailKind `json:"kind"` - Theme models.Theme `json:"theme"` - Image []byte `json:"image"` - MimeType string `json:"mimeType"` - Updated time.Time `json:"updated"` - DsUIDs string `json:"-" xorm:"ds_uids"` -} - -// -// Commands -// - -// DashboardThumbnailMeta uniquely identifies a thumbnail; a natural key -type DashboardThumbnailMeta struct { - DashboardUID string - OrgId int64 - PanelID int64 - Kind ThumbnailKind - Theme models.Theme -} - -type GetDashboardThumbnailCommand struct { - DashboardThumbnailMeta - - Result *DashboardThumbnail -} - -const DashboardVersionForManualThumbnailUpload = -1 - -type DashboardWithStaleThumbnail struct { - Id int64 - OrgId int64 - Uid string - Version int - Slug string -} - -type FindDashboardThumbnailCountCommand struct { - Result int64 -} - -type FindDashboardsWithStaleThumbnailsCommand struct { - IncludeManuallyUploadedThumbnails bool - IncludeThumbnailsWithEmptyDsUIDs bool - Theme models.Theme - Kind ThumbnailKind - Result []*DashboardWithStaleThumbnail -} - -type SaveDashboardThumbnailCommand struct { - DashboardThumbnailMeta - DashboardVersion int - Image []byte - MimeType string - DatasourceUIDs []string - - Result *DashboardThumbnail -} - -type UpdateThumbnailStateCommand struct { - State ThumbnailState - DashboardThumbnailMeta -} diff --git a/pkg/services/thumbs/crawler.go b/pkg/services/thumbs/crawler.go index e941dc96ce9..8612acc2c37 100644 --- a/pkg/services/thumbs/crawler.go +++ b/pkg/services/thumbs/crawler.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/live" "github.com/grafana/grafana/pkg/services/rendering" ) @@ -29,12 +28,12 @@ type simpleCrawler struct { glive *live.GrafanaLive thumbnailRepo thumbnailRepo mode CrawlerMode - thumbnailKind dashboardthumbs.ThumbnailKind + thumbnailKind ThumbnailKind auth CrawlerAuth opts rendering.Opts status crawlStatus statusMutex sync.RWMutex - queue []*dashboardthumbs.DashboardWithStaleThumbnail + queue []*DashboardWithStaleThumbnail queueMutex sync.Mutex log log.Logger renderingSessionByOrgId map[int64]rendering.Session @@ -65,7 +64,7 @@ func newSimpleCrawler(renderService rendering.Service, gl *live.GrafanaLive, rep return c } -func (r *simpleCrawler) next(ctx context.Context) (*dashboardthumbs.DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) { +func (r *simpleCrawler) next(ctx context.Context) (*DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) { r.queueMutex.Lock() defer r.queueMutex.Unlock() @@ -117,13 +116,13 @@ func (r *simpleCrawler) broadcastStatus() { } } -type byOrgId []*dashboardthumbs.DashboardWithStaleThumbnail +type byOrgId []*DashboardWithStaleThumbnail func (d byOrgId) Len() int { return len(d) } func (d byOrgId) Less(i, j int) bool { return d[i].OrgId > d[j].OrgId } func (d byOrgId) Swap(i, j int) { d[i], d[j] = d[j], d[i] } -func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind dashboardthumbs.ThumbnailKind) error { +func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind ThumbnailKind) error { res, err := r.renderService.HasCapability(ctx, rendering.ScalingDownImages) if err != nil { return err @@ -326,7 +325,7 @@ func (r *simpleCrawler) walk(ctx context.Context, id int) { } }() - thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, dashboardthumbs.DashboardThumbnailMeta{ + thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, DashboardThumbnailMeta{ DashboardUID: item.Uid, OrgId: item.OrgId, Theme: r.opts.Theme, diff --git a/pkg/services/dashboard_thumbs/dashboard_thumbs.go b/pkg/services/thumbs/dashboard_thumbs.go similarity index 91% rename from pkg/services/dashboard_thumbs/dashboard_thumbs.go rename to pkg/services/thumbs/dashboard_thumbs.go index 2561f0c3e6a..2c30915724b 100644 --- a/pkg/services/dashboard_thumbs/dashboard_thumbs.go +++ b/pkg/services/thumbs/dashboard_thumbs.go @@ -1,10 +1,10 @@ -package dashboardthumbs +package thumbs import ( "context" ) -type Service interface { +type DashboardThumbService interface { GetThumbnail(ctx context.Context, query *GetDashboardThumbnailCommand) (*DashboardThumbnail, error) SaveThumbnail(ctx context.Context, cmd *SaveDashboardThumbnailCommand) (*DashboardThumbnail, error) UpdateThumbnailState(ctx context.Context, cmd *UpdateThumbnailStateCommand) error diff --git a/pkg/services/thumbs/dashboardthumbsimpl/dashboard_thumbs.go b/pkg/services/thumbs/dashboardthumbsimpl/dashboard_thumbs.go new file mode 100644 index 00000000000..f2a5e3d0ba1 --- /dev/null +++ b/pkg/services/thumbs/dashboardthumbsimpl/dashboard_thumbs.go @@ -0,0 +1,43 @@ +package dashboardthumbsimpl + +import ( + "context" + + "github.com/grafana/grafana/pkg/services/sqlstore/db" + "github.com/grafana/grafana/pkg/services/thumbs" +) + +type Service struct { + store store +} + +func ProvideService(db db.DB) thumbs.DashboardThumbService { + return &Service{ + store: &xormStore{db: db}, + } +} + +func (s *Service) GetThumbnail(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) { + dt, err := s.store.Get(ctx, query) + return dt, err +} + +func (s *Service) SaveThumbnail(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) { + dt, err := s.store.Save(ctx, cmd) + return dt, err +} + +func (s *Service) UpdateThumbnailState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error { + err := s.store.UpdateState(ctx, cmd) + return err +} + +func (s *Service) FindThumbnailCount(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error) { + n, err := s.store.Count(ctx, cmd) + return n, err +} + +func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error) { + thumbs, err := s.store.FindDashboardsWithStaleThumbnails(ctx, cmd) + return thumbs, err +} diff --git a/pkg/services/thumbs/dashboardthumbsimpl/store.go b/pkg/services/thumbs/dashboardthumbsimpl/store.go new file mode 100644 index 00000000000..49284504690 --- /dev/null +++ b/pkg/services/thumbs/dashboardthumbsimpl/store.go @@ -0,0 +1,15 @@ +package dashboardthumbsimpl + +import ( + "context" + + "github.com/grafana/grafana/pkg/services/thumbs" +) + +type store interface { + Get(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) + Save(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) + UpdateState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error + Count(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error) + FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error) +} diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go b/pkg/services/thumbs/dashboardthumbsimpl/store_test.go similarity index 85% rename from pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go rename to pkg/services/thumbs/dashboardthumbsimpl/store_test.go index d7890b6b4e8..7564d431a58 100644 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go +++ b/pkg/services/thumbs/dashboardthumbsimpl/store_test.go @@ -7,16 +7,16 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/thumbs" "github.com/grafana/grafana/pkg/util" "github.com/stretchr/testify/require" ) var theme = models.ThemeDark -var kind = dashboardthumbs.ThumbnailKindDefault +var kind = thumbs.ThumbnailKindDefault func TestIntegrationSqlStorage(t *testing.T) { if testing.Short() { @@ -39,7 +39,7 @@ func TestIntegrationSqlStorage(t *testing.T) { thumb := getThumbnail(t, store, dash.Uid, dash.OrgId) require.Positive(t, thumb.Id) - require.Equal(t, dashboardthumbs.ThumbnailStateDefault, thumb.State) + require.Equal(t, thumbs.ThumbnailStateDefault, thumb.State) require.Equal(t, dash.Version, thumb.DashboardVersion) }) @@ -63,7 +63,7 @@ func TestIntegrationSqlStorage(t *testing.T) { upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -78,7 +78,7 @@ func TestIntegrationSqlStorage(t *testing.T) { upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, IncludeThumbnailsWithEmptyDsUIDs: true, Theme: theme, @@ -93,9 +93,9 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateStale) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -109,10 +109,10 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateStale) upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -125,7 +125,7 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -144,7 +144,7 @@ func TestIntegrationSqlStorage(t *testing.T) { "tags": "different-tag", }) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -158,13 +158,13 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateLocked) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateLocked) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -176,13 +176,13 @@ func TestIntegrationSqlStorage(t *testing.T) { t.Run("Should not return dashboards with manually uploaded thumbnails by default", func(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload) + upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, thumbs.DashboardVersionForManualThumbnailUpload) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -194,13 +194,13 @@ func TestIntegrationSqlStorage(t *testing.T) { t.Run("Should return dashboards with manually uploaded thumbnails if requested", func(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload) + upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, thumbs.DashboardVersionForManualThumbnailUpload) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ + cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, IncludeManuallyUploadedThumbnails: true, @@ -222,17 +222,17 @@ func TestIntegrationSqlStorage(t *testing.T) { "tags": "different-tag", }) - cmd := dashboardthumbs.FindDashboardThumbnailCountCommand{} + cmd := thumbs.FindDashboardThumbnailCountCommand{} res, err := store.Count(context.Background(), &cmd) require.NoError(t, err) require.Equal(t, res, int64(2)) }) } -func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *dashboardthumbs.DashboardThumbnail { +func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *thumbs.DashboardThumbnail { t.Helper() - cmd := dashboardthumbs.GetDashboardThumbnailCommand{ - DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ + cmd := thumbs.GetDashboardThumbnailCommand{ + DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, @@ -246,10 +246,10 @@ func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) * return thumb } -func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *dashboardthumbs.DashboardThumbnail { +func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *thumbs.DashboardThumbnail { t.Helper() - cmd := dashboardthumbs.SaveDashboardThumbnailCommand{ - DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ + cmd := thumbs.SaveDashboardThumbnailCommand{ + DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, @@ -267,10 +267,10 @@ func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string return dash } -func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state dashboardthumbs.ThumbnailState) { +func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state thumbs.ThumbnailState) { t.Helper() - cmd := dashboardthumbs.UpdateThumbnailStateCommand{ - DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ + cmd := thumbs.UpdateThumbnailStateCommand{ + DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go b/pkg/services/thumbs/dashboardthumbsimpl/xorm_store.go similarity index 75% rename from pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go rename to pkg/services/thumbs/dashboardthumbsimpl/xorm_store.go index ae1bdd901ee..d9ce5083f0d 100644 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go +++ b/pkg/services/thumbs/dashboardthumbsimpl/xorm_store.go @@ -6,17 +6,17 @@ import ( "errors" "time" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/db" + "github.com/grafana/grafana/pkg/services/thumbs" ) type xormStore struct { db db.DB } -func (ss *xormStore) Get(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { +func (ss *xormStore) Get(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) { err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { result, err := findThumbnailByMeta(sess, query.DashboardThumbnailMeta) if err != nil { @@ -41,7 +41,7 @@ func marshalDatasourceUids(dsUids []string) (string, error) { return string(b), nil } -func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { +func (ss *xormStore) Save(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) { err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) @@ -60,13 +60,13 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar existing.Updated = time.Now() existing.DashboardVersion = cmd.DashboardVersion existing.DsUIDs = dsUids - existing.State = dashboardthumbs.ThumbnailStateDefault + existing.State = thumbs.ThumbnailStateDefault _, err = sess.ID(existing.Id).Update(existing) cmd.Result = existing return err } - thumb := &dashboardthumbs.DashboardThumbnail{} + thumb := &thumbs.DashboardThumbnail{} dash, err := findDashboardIdByThumbMeta(sess, cmd.DashboardThumbnailMeta) @@ -82,7 +82,7 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar thumb.MimeType = cmd.MimeType thumb.DashboardId = dash.Id thumb.DashboardVersion = cmd.DashboardVersion - thumb.State = dashboardthumbs.ThumbnailStateDefault + thumb.State = thumbs.ThumbnailStateDefault thumb.PanelId = cmd.PanelID _, err = sess.Insert(thumb) cmd.Result = thumb @@ -92,7 +92,7 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar return cmd.Result, err } -func (ss *xormStore) UpdateState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error { +func (ss *xormStore) UpdateState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error { err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) @@ -108,9 +108,9 @@ func (ss *xormStore) UpdateState(ctx context.Context, cmd *dashboardthumbs.Updat return err } -func (ss *xormStore) Count(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) { +func (ss *xormStore) Count(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error) { err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - count, err := sess.Count(&dashboardthumbs.DashboardThumbnail{}) + count, err := sess.Count(&thumbs.DashboardThumbnail{}) if err != nil { return err } @@ -122,7 +122,7 @@ func (ss *xormStore) Count(ctx context.Context, cmd *dashboardthumbs.FindDashboa return cmd.Result, err } -func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { +func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error) { err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { sess.Table("dashboard") sess.Join("LEFT", "dashboard_thumbnail", "dashboard.id = dashboard_thumbnail.dashboard_id AND dashboard_thumbnail.theme = ? AND dashboard_thumbnail.kind = ?", cmd.Theme, cmd.Kind) @@ -131,7 +131,7 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd query := "(dashboard.version != dashboard_thumbnail.dashboard_version " + "OR dashboard_thumbnail.state = ? " + "OR dashboard_thumbnail.id IS NULL" - args := []interface{}{dashboardthumbs.ThumbnailStateStale} + args := []interface{}{thumbs.ThumbnailStateStale} if cmd.IncludeThumbnailsWithEmptyDsUIDs { query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL" @@ -142,10 +142,10 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd if !cmd.IncludeManuallyUploadedThumbnails { sess.Where("(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) "+ "OR dashboard_thumbnail.id is null "+ - "OR dashboard_thumbnail.state = ?", dashboardthumbs.DashboardVersionForManualThumbnailUpload, dashboardthumbs.ThumbnailStateStale) + "OR dashboard_thumbnail.state = ?", thumbs.DashboardVersionForManualThumbnailUpload, thumbs.ThumbnailStateStale) } - sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", dashboardthumbs.ThumbnailStateLocked) + sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", thumbs.ThumbnailStateLocked) sess.Cols("dashboard.id", "dashboard.uid", @@ -153,7 +153,7 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd "dashboard.version", "dashboard.slug") - var result = make([]*dashboardthumbs.DashboardWithStaleThumbnail, 0) + var result = make([]*thumbs.DashboardWithStaleThumbnail, 0) err := sess.Find(&result) if err != nil { @@ -166,8 +166,8 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd return cmd.Result, err } -func findThumbnailByMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) { - result := &dashboardthumbs.DashboardThumbnail{} +func findThumbnailByMeta(sess *sqlstore.DBSession, meta thumbs.DashboardThumbnailMeta) (*thumbs.DashboardThumbnail, error) { + result := &thumbs.DashboardThumbnail{} sess.Table("dashboard_thumbnail") sess.Join("INNER", "dashboard", "dashboard.id = dashboard_thumbnail.dashboard_id") @@ -200,7 +200,7 @@ type dash struct { Id int64 } -func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dash, error) { +func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta thumbs.DashboardThumbnailMeta) (*dash, error) { result := &dash{} sess.Table("dashboard").Where("dashboard.uid = ? AND dashboard.org_id = ?", meta.DashboardUID, meta.OrgId).Cols("id") diff --git a/pkg/services/thumbs/models.go b/pkg/services/thumbs/models.go index d8df1fe8ef8..dfc6fc7d887 100644 --- a/pkg/services/thumbs/models.go +++ b/pkg/services/thumbs/models.go @@ -2,10 +2,12 @@ package thumbs import ( "context" + "encoding/json" + "errors" + "fmt" "time" "github.com/grafana/grafana/pkg/models" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" ) type CrawlerMode string @@ -32,10 +34,10 @@ const ( ) type previewRequest struct { - OrgID int64 `json:"orgId"` - UID string `json:"uid"` - Kind dashboardthumbs.ThumbnailKind `json:"kind"` - Theme models.Theme `json:"theme"` + OrgID int64 `json:"orgId"` + UID string `json:"uid"` + Kind ThumbnailKind `json:"kind"` + Theme models.Theme `json:"theme"` } type crawlCmd struct { @@ -63,10 +65,147 @@ type dashboardPreviewsSetupConfig struct { ThumbnailsExist bool `json:"thumbnailsExist"` } +type ThumbnailKind string +type ThumbnailState string + +const ( + // ThumbnailKindDefault is a small 320x240 preview + ThumbnailKindDefault ThumbnailKind = "thumb" + + // unsupported for now + // - ThumbnailKindLarge ThumbnailKind = "large" + // - ThumbnailKindTall ThumbnailKind = "tall" +) + +const ( + // ThumbnailStateDefault is the initial state for all thumbnails. Thumbnails in the "default" state will be considered stale, + // and thus refreshed by the crawler, if the dashboard version from the time of taking the thumbnail is different from the current dashboard version + ThumbnailStateDefault ThumbnailState = "default" + + // ThumbnailStateStale is a manually assigned state. Thumbnails in the "stale" state will be refreshed on the next crawler run + ThumbnailStateStale ThumbnailState = "stale" + + // ThumbnailStateLocked is a manually assigned state. Thumbnails in the "locked" state will not be refreshed by the crawler as long as they remain in the "locked" state. + ThumbnailStateLocked ThumbnailState = "locked" +) + +func (s ThumbnailState) IsValid() bool { + return s == ThumbnailStateDefault || s == ThumbnailStateStale || s == ThumbnailStateLocked +} + +func (s *ThumbnailState) UnmarshalJSON(data []byte) error { + var str string + err := json.Unmarshal(data, &str) + if err != nil { + return err + } + + *s = ThumbnailState(str) + + if !s.IsValid() { + if (*s) != "" { + return fmt.Errorf("JSON validation error: invalid thumbnail state value: %s", *s) + } + + *s = ThumbnailStateDefault + } + + return nil +} + +// IsKnownThumbnailKind checks if the value is supported +func (p ThumbnailKind) IsKnownThumbnailKind() bool { + switch p { + case + ThumbnailKindDefault: + return true + } + return false +} + +func ParseThumbnailKind(str string) (ThumbnailKind, error) { + switch str { + case string(ThumbnailKindDefault): + return ThumbnailKindDefault, nil + } + return ThumbnailKindDefault, errors.New("unknown thumbnail kind " + str) +} + +// A DashboardThumbnail includes all metadata for a dashboard thumbnail +type DashboardThumbnail struct { + Id int64 `json:"id"` + DashboardId int64 `json:"dashboardId"` + DashboardVersion int `json:"dashboardVersion"` + State ThumbnailState `json:"state"` + PanelId int64 `json:"panelId,omitempty"` + Kind ThumbnailKind `json:"kind"` + Theme models.Theme `json:"theme"` + Image []byte `json:"image"` + MimeType string `json:"mimeType"` + Updated time.Time `json:"updated"` + DsUIDs string `json:"-" xorm:"ds_uids"` +} + +// +// Commands +// + +// DashboardThumbnailMeta uniquely identifies a thumbnail; a natural key +type DashboardThumbnailMeta struct { + DashboardUID string + OrgId int64 + PanelID int64 + Kind ThumbnailKind + Theme models.Theme +} + +type GetDashboardThumbnailCommand struct { + DashboardThumbnailMeta + + Result *DashboardThumbnail +} + +const DashboardVersionForManualThumbnailUpload = -1 + +type DashboardWithStaleThumbnail struct { + Id int64 + OrgId int64 + Uid string + Version int + Slug string +} + +type FindDashboardThumbnailCountCommand struct { + Result int64 +} + +type FindDashboardsWithStaleThumbnailsCommand struct { + IncludeManuallyUploadedThumbnails bool + IncludeThumbnailsWithEmptyDsUIDs bool + Theme models.Theme + Kind ThumbnailKind + Result []*DashboardWithStaleThumbnail +} + +type SaveDashboardThumbnailCommand struct { + DashboardThumbnailMeta + DashboardVersion int + Image []byte + MimeType string + DatasourceUIDs []string + + Result *DashboardThumbnail +} + +type UpdateThumbnailStateCommand struct { + State ThumbnailState + DashboardThumbnailMeta +} + type dashRenderer interface { // Run Assumes you have already authenticated as admin. - Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind dashboardthumbs.ThumbnailKind) error + Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind ThumbnailKind) error // Assumes you have already authenticated as admin. Stop() (crawlStatus, error) @@ -78,10 +217,10 @@ type dashRenderer interface { } type thumbnailRepo interface { - updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error + updateThumbnailState(ctx context.Context, state ThumbnailState, meta DashboardThumbnailMeta) error doThumbnailsExist(ctx context.Context) (bool, error) - saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) - saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) - getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) - findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) + saveFromFile(ctx context.Context, filePath string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) + saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) + getThumbnail(ctx context.Context, meta DashboardThumbnailMeta) (*DashboardThumbnail, error) + findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind ThumbnailKind) ([]*DashboardWithStaleThumbnail, error) } diff --git a/pkg/services/thumbs/repo.go b/pkg/services/thumbs/repo.go index 4d0f6f94697..f69e04db8e9 100644 --- a/pkg/services/thumbs/repo.go +++ b/pkg/services/thumbs/repo.go @@ -9,11 +9,10 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/searchV2" ) -func newThumbnailRepo(thumbsService dashboardthumbs.Service, search searchV2.SearchService) thumbnailRepo { +func newThumbnailRepo(thumbsService DashboardThumbService, search searchV2.SearchService) thumbnailRepo { repo := &sqlThumbnailRepository{ store: thumbsService, search: search, @@ -23,12 +22,12 @@ func newThumbnailRepo(thumbsService dashboardthumbs.Service, search searchV2.Sea } type sqlThumbnailRepository struct { - store dashboardthumbs.Service + store DashboardThumbService search searchV2.SearchService log log.Logger } -func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { +func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { // the filePath variable is never set by the user. it refers to a temporary file created either in // 1. thumbs/service.go, when user uploads a thumbnail // 2. the rendering service, when image-renderer returns a screenshot @@ -56,8 +55,8 @@ func getMimeType(filePath string) string { return "image/png" } -func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { - cmd := &dashboardthumbs.SaveDashboardThumbnailCommand{ +func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { + cmd := &SaveDashboardThumbnailCommand{ DashboardThumbnailMeta: meta, Image: content, MimeType: mimeType, @@ -74,22 +73,22 @@ func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []by return cmd.Result.Id, nil } -func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error { - return r.store.UpdateThumbnailState(ctx, &dashboardthumbs.UpdateThumbnailStateCommand{ +func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state ThumbnailState, meta DashboardThumbnailMeta) error { + return r.store.UpdateThumbnailState(ctx, &UpdateThumbnailStateCommand{ State: state, DashboardThumbnailMeta: meta, }) } -func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) { - query := &dashboardthumbs.GetDashboardThumbnailCommand{ +func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta DashboardThumbnailMeta) (*DashboardThumbnail, error) { + query := &GetDashboardThumbnailCommand{ DashboardThumbnailMeta: meta, } return r.store.GetThumbnail(ctx, query) } -func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { - return r.store.FindDashboardsWithStaleThumbnails(ctx, &dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ +func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind ThumbnailKind) ([]*DashboardWithStaleThumbnail, error) { + return r.store.FindDashboardsWithStaleThumbnails(ctx, &FindDashboardsWithStaleThumbnailsCommand{ IncludeManuallyUploadedThumbnails: false, IncludeThumbnailsWithEmptyDsUIDs: !r.search.IsDisabled(), Theme: theme, @@ -98,7 +97,7 @@ func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.C } func (r *sqlThumbnailRepository) doThumbnailsExist(ctx context.Context) (bool, error) { - cmd := &dashboardthumbs.FindDashboardThumbnailCountCommand{} + cmd := &FindDashboardThumbnailCountCommand{} count, err := r.store.FindThumbnailCount(ctx, cmd) if err != nil { r.log.Error("Error finding thumbnails", "err", err) diff --git a/pkg/services/thumbs/service.go b/pkg/services/thumbs/service.go index 8d520e81513..6b186ff237c 100644 --- a/pkg/services/thumbs/service.go +++ b/pkg/services/thumbs/service.go @@ -8,7 +8,6 @@ import ( "net/http" "time" - dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/datasources/permissions" "github.com/grafana/grafana/pkg/services/searchV2" "github.com/segmentio/encoding/json" @@ -69,7 +68,7 @@ type crawlerScheduleOptions struct { tickerInterval time.Duration maxCrawlDuration time.Duration crawlerMode CrawlerMode - thumbnailKind dashboardthumbs.ThumbnailKind + thumbnailKind ThumbnailKind themes []models.Theme auth CrawlerAuth } @@ -77,7 +76,7 @@ type crawlerScheduleOptions struct { func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockService *serverlock.ServerLockService, renderService rendering.Service, gl *live.GrafanaLive, store *sqlstore.SQLStore, authSetupService CrawlerAuthSetupService, - dashboardService dashboards.DashboardService, dashboardThumbsService dashboardthumbs.Service, searchService searchV2.SearchService, + dashboardService dashboards.DashboardService, dashboardThumbsService DashboardThumbService, searchService searchV2.SearchService, dsPermissionsService permissions.DatasourcePermissionsService, licensing models.Licensing) Service { if !features.IsEnabled(featuremgmt.FlagDashboardPreviews) { return &dummyService{} @@ -124,7 +123,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, crawlInterval: cfg.DashboardPreviews.SchedulerInterval, maxCrawlDuration: cfg.DashboardPreviews.MaxCrawlDuration, crawlerMode: CrawlerModeThumbs, - thumbnailKind: dashboardthumbs.ThumbnailKindDefault, + thumbnailKind: ThumbnailKindDefault, themes: []models.Theme{models.ThemeDark, models.ThemeLight}, auth: crawlerAuth, }, @@ -157,7 +156,7 @@ func (hs *thumbService) Enabled() bool { func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *previewRequest { params := web.Params(c.Req) - kind, err := dashboardthumbs.ParseThumbnailKind(params[":kind"]) + kind, err := ParseThumbnailKind(params[":kind"]) if err != nil { c.JSON(400, map[string]string{"error": "invalid size"}) return nil @@ -191,7 +190,7 @@ func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *pre } type updateThumbnailStateRequest struct { - State dashboardthumbs.ThumbnailState `json:"state" binding:"Required"` + State ThumbnailState `json:"state" binding:"Required"` } func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) { @@ -209,11 +208,11 @@ func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) { return } - err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, dashboardthumbs.DashboardThumbnailMeta{ + err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, - Kind: dashboardthumbs.ThumbnailKindDefault, + Kind: ThumbnailKindDefault, }) if err != nil { @@ -232,11 +231,11 @@ func (hs *thumbService) GetImage(c *models.ReqContext) { return // already returned value } - res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), dashboardthumbs.DashboardThumbnailMeta{ + res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, - Kind: dashboardthumbs.ThumbnailKindDefault, + Kind: ThumbnailKindDefault, }) if errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) { @@ -269,7 +268,7 @@ func (hs *thumbService) GetImage(c *models.ReqContext) { } } -func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *dashboardthumbs.DashboardThumbnail, req *previewRequest) bool { +func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *DashboardThumbnail, req *previewRequest) bool { if !hs.licensing.FeatureEnabled("accesscontrol.enforcement") { return true } @@ -402,12 +401,12 @@ func (hs *thumbService) SetImage(c *models.ReqContext) { return } - _, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), dashboardthumbs.DashboardThumbnailMeta{ + _, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, Kind: req.Kind, - }, dashboardthumbs.DashboardVersionForManualThumbnailUpload, dsUids) + }, DashboardVersionForManualThumbnailUpload, dsUids) if err != nil { c.JSON(400, map[string]string{"error": "error saving thumbnail file"}) @@ -432,7 +431,7 @@ func (hs *thumbService) StartCrawler(c *models.ReqContext) response.Response { cmd.Mode = CrawlerModeThumbs } - go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, dashboardthumbs.ThumbnailKindDefault, rendering.AuthOpts{ + go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, ThumbnailKindDefault, rendering.AuthOpts{ OrgID: c.OrgID, UserID: c.UserID, OrgRole: c.OrgRole, @@ -494,7 +493,7 @@ func (hs *thumbService) getDashboardId(c *models.ReqContext, uid string) (int64, return query.Result.Id, nil } -func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind dashboardthumbs.ThumbnailKind, authOpts rendering.AuthOpts) { +func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind ThumbnailKind, authOpts rendering.AuthOpts) { if !hs.canRunCrawler { return }