Chore: StoreSplit tag service (#55453)

* move tag service outside

* fix dashboard

* fix test

* lint

* fix linter

* remove spew
This commit is contained in:
ying-jeanne 2022-09-21 14:04:01 +02:00 committed by GitHub
parent e3e954cbba
commit 7b4cea8151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 355 additions and 293 deletions

View File

@ -228,7 +228,7 @@ func (hs *HTTPServer) PostGraphiteAnnotation(c *models.ReqContext) response.Resp
Tags: tagsArray,
}
if err := hs.annotationsRepo.Save(context.Background(), &item); err != nil {
if err := hs.annotationsRepo.Save(c.Req.Context(), &item); err != nil {
return response.Error(500, "Failed to save Graphite annotation", err)
}

View File

@ -51,6 +51,7 @@ import (
"github.com/grafana/grafana/pkg/services/searchusers/filters"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
@ -371,7 +372,7 @@ func setupHTTPServerWithCfgDb(
license := &licensing.OSSLicensingService{}
routeRegister := routing.NewRouteRegister()
teamService := teamimpl.ProvideService(db)
dashboardsStore := dashboardsstore.ProvideDashboardStore(db, featuremgmt.WithFeatures())
dashboardsStore := dashboardsstore.ProvideDashboardStore(db, featuremgmt.WithFeatures(), tagimpl.ProvideService(db))
var acmock *accesscontrolmock.Mock
var ac accesscontrol.AccessControl

View File

@ -189,7 +189,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
meta.FolderUrl = query.Result.GetUrl()
}
provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(dash.Id)
provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(c.Req.Context(), dash.Id)
if err != nil {
return response.Error(500, "Error while checking if dashboard is provisioned", err)
}
@ -407,13 +407,13 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
var provisioningData *models.DashboardProvisioning
if dash.Id != 0 {
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(dash.Id)
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(c.Req.Context(), dash.Id)
if err != nil {
return response.Error(500, "Error while checking if dashboard is provisioned using ID", err)
}
provisioningData = data
} else if dash.Uid != "" {
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardUID(dash.OrgId, dash.Uid)
data, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardUID(c.Req.Context(), dash.OrgId, dash.Uid)
if err != nil && !errors.Is(err, dashboards.ErrProvisionedDashboardNotFound) && !errors.Is(err, dashboards.ErrDashboardNotFound) {
return response.Error(500, "Error while checking if dashboard is provisioned", err)
}

View File

@ -39,6 +39,7 @@ import (
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -935,7 +936,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
if dashboardStore == nil {
sql := sqlstore.InitTestDB(t)
dashboardStore = database.ProvideDashboardStore(sql, featuremgmt.WithFeatures())
dashboardStore = database.ProvideDashboardStore(sql, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql))
}
libraryPanelsService := mockLibraryPanelService{}
@ -1140,7 +1141,7 @@ type mockDashboardProvisioningService struct {
dashboards.DashboardProvisioningService
}
func (s mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(dashboardID int64) (
func (s mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (
*models.DashboardProvisioning, error) {
return nil, nil
}

View File

@ -84,6 +84,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/services/store"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/teamguardian"
tempUser "github.com/grafana/grafana/pkg/services/temp_user"
@ -193,6 +194,7 @@ type HTTPServer struct {
teamService team.Service
accesscontrolService accesscontrol.Service
annotationsRepo annotations.Repository
tagService tag.Service
}
type ServerOptions struct {
@ -232,7 +234,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, annotationRepo annotations.Repository,
accesscontrolService accesscontrol.Service, dashboardThumbsService dashboardThumbs.Service, annotationRepo annotations.Repository, tagService tag.Service,
) (*HTTPServer, error) {
web.Env = cfg.Env
m := web.New()
@ -330,6 +332,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
teamService: teamService,
accesscontrolService: accesscontrolService,
annotationsRepo: annotationRepo,
tagService: tagService,
}
if hs.Listener != nil {
hs.log.Debug("Using provided listener")

View File

@ -156,7 +156,7 @@ func TestOrgUsersAPIEndpoint_LegacyAccessControl_FolderAdmin(t *testing.T) {
"tags": "prod",
}),
}
folder, err := sc.dashboardsStore.SaveDashboard(cmd)
folder, err := sc.dashboardsStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.NotNil(t, folder)

View File

@ -116,6 +116,8 @@ import (
"github.com/grafana/grafana/pkg/services/star/starimpl"
"github.com/grafana/grafana/pkg/services/store"
"github.com/grafana/grafana/pkg/services/store/sanitizer"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/teamguardian"
teamguardianDatabase "github.com/grafana/grafana/pkg/services/teamguardian/database"
@ -336,6 +338,8 @@ var wireSet = wire.NewSet(
opentsdb.ProvideService,
acimpl.ProvideAccessControl,
wire.Bind(new(accesscontrol.AccessControl), new(*acimpl.AccessControl)),
tagimpl.ProvideService,
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
)
func Initialize(cfg *setting.Cfg) (Runner, error) {

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/user"
)
@ -115,15 +116,15 @@ func (a *Alert) ContainsUpdates(other *Alert) bool {
return result
}
func (a *Alert) GetTagsFromSettings() []*Tag {
tags := []*Tag{}
func (a *Alert) GetTagsFromSettings() []*tag.Tag {
tags := []*tag.Tag{}
if a.Settings != nil {
if data, ok := a.Settings.CheckGet("alertRuleTags"); ok {
for tagNameString, tagValue := range data.MustMap() {
// MustMap() already guarantees the return of a `map[string]interface{}`.
// Therefore we only need to verify that tagValue is a String.
tagValueString := simplejson.NewFromAny(tagValue).MustString()
tags = append(tags, &Tag{Key: tagNameString, Value: tagValueString})
tags = append(tags, &tag.Tag{Key: tagNameString, Value: tagValueString})
}
}
}

View File

@ -4,6 +4,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -51,7 +52,7 @@ func TestAlert_GetTagsFromSettings(t *testing.T) {
Message: "Message",
}
expectedTags := []*Tag{
expectedTags := []*tag.Tag{
{Id: 0, Key: "foo", Value: "bar"},
{Id: 0, Key: "waldo", Value: "fred"},
{Id: 0, Key: "tagMap", Value: ""},

View File

@ -123,6 +123,8 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/star/starimpl"
"github.com/grafana/grafana/pkg/services/store"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/teamguardian"
teamguardianDatabase "github.com/grafana/grafana/pkg/services/teamguardian/database"
@ -349,6 +351,8 @@ var wireBasicSet = wire.NewSet(
acimpl.ProvideAccessControl,
wire.Bind(new(accesscontrol.AccessControl), new(*acimpl.AccessControl)),
wire.Bind(new(notifications.TempUserStore), new(tempuser.Service)),
tagimpl.ProvideService,
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
)
var wireSet = wire.NewSet(

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require"
@ -83,7 +84,7 @@ func TestOpsGenieNotifier(t *testing.T) {
"apiKey": "abcdefgh0123456789"
}`
tagPairs := []*models.Tag{
tagPairs := []*tag.Tag{
{Key: "keyOnly"},
{Key: "aKey", Value: "aValue"},
}
@ -132,7 +133,7 @@ func TestOpsGenieNotifier(t *testing.T) {
"sendTagsAs": "details"
}`
tagPairs := []*models.Tag{
tagPairs := []*tag.Tag{
{Key: "keyOnly"},
{Key: "aKey", Value: "aValue"},
}
@ -181,7 +182,7 @@ func TestOpsGenieNotifier(t *testing.T) {
"sendTagsAs": "both"
}`
tagPairs := []*models.Tag{
tagPairs := []*tag.Tag{
{Key: "keyOnly"},
{Key: "aKey", Value: "aValue"},
}

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require"
@ -328,7 +329,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: []*models.Tag{
AlertRuleTags: []*tag.Tag{
{Key: "keyOnly"},
{Key: "group", Value: "aGroup"},
{Key: "class", Value: "aClass"},
@ -408,7 +409,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: []*models.Tag{
AlertRuleTags: []*tag.Tag{
{Key: "keyOnly"},
{Key: "group", Value: "aGroup"},
{Key: "class", Value: "aClass"},
@ -487,7 +488,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: []*models.Tag{
AlertRuleTags: []*tag.Tag{
{Key: "keyOnly"},
{Key: "group", Value: "aGroup"},
{Key: "class", Value: "aClass"},

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/require"
@ -90,7 +91,7 @@ func TestVictoropsNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: []*models.Tag{
AlertRuleTags: []*tag.Tag{
{Key: "keyOnly"},
{Key: "severity", Value: "warning"},
},
@ -138,7 +139,7 @@ func TestVictoropsNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateOK,
AlertRuleTags: []*models.Tag{
AlertRuleTags: []*tag.Tag{
{Key: "keyOnly"},
{Key: "severity", Value: "warning"},
},

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/tag"
)
var unitMultiplier = map[string]int{
@ -53,7 +54,7 @@ type Rule struct {
State models.AlertStateType
Conditions []Condition
Notifications []string
AlertRuleTags []*models.Tag
AlertRuleTags []*tag.Tag
StateChanges int64
}

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/setting"
)
@ -33,20 +34,22 @@ type AlertStore interface {
}
type sqlStore struct {
db db.DB
cache *localcache.CacheService
log *log.ConcreteLogger
cfg *setting.Cfg
db db.DB
cache *localcache.CacheService
log *log.ConcreteLogger
cfg *setting.Cfg
tagService tag.Service
}
func ProvideAlertStore(
db db.DB,
cacheService *localcache.CacheService, cfg *setting.Cfg) AlertStore {
cacheService *localcache.CacheService, cfg *setting.Cfg, tagService tag.Service) AlertStore {
return &sqlStore{
db: db,
cache: cacheService,
log: log.New("alerting.store"),
cfg: cfg,
db: db,
cache: cacheService,
log: log.New("alerting.store"),
cfg: cfg,
tagService: tagService,
}
}
@ -188,7 +191,7 @@ func (ss *sqlStore) SaveAlerts(ctx context.Context, dashID int64, alerts []*mode
return err
}
if err := updateAlerts(existingAlerts, alerts, sess, ss.log); err != nil {
if err := ss.UpdateAlerts(ctx, existingAlerts, alerts, sess, ss.log); err != nil {
return err
}
@ -200,7 +203,7 @@ func (ss *sqlStore) SaveAlerts(ctx context.Context, dashID int64, alerts []*mode
})
}
func updateAlerts(existingAlerts []*models.Alert, alerts []*models.Alert, sess *sqlstore.DBSession, log *log.ConcreteLogger) error {
func (ss *sqlStore) UpdateAlerts(ctx context.Context, existingAlerts []*models.Alert, alerts []*models.Alert, sess *sqlstore.DBSession, log *log.ConcreteLogger) error {
for _, alert := range alerts {
update := false
var alertToUpdate *models.Alert
@ -245,7 +248,7 @@ func updateAlerts(existingAlerts []*models.Alert, alerts []*models.Alert, sess *
return err
}
if tags != nil {
tags, err := sqlstore.EnsureTagsExist(sess, tags)
tags, err := ss.tagService.EnsureTagsExist(ctx, tags)
if err != nil {
return err
}

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@ -46,12 +47,15 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
var items []*models.Alert
setup := func(t *testing.T) {
ss := sqlstore.InitTestDB(t)
tagService := tagimpl.ProvideService(ss)
cfg := setting.NewCfg()
cfg.RBACEnabled = false
store = &sqlStore{
db: sqlstore.InitTestDB(t),
log: log.New(),
cfg: cfg,
db: ss,
log: log.New(),
cfg: cfg,
tagService: tagService,
}
testDash = insertTestDashboard(t, store.db, "dashboard with alerts", 1, 0, false, "alert")
@ -285,7 +289,8 @@ func TestIntegrationPausingAlerts(t *testing.T) {
defer resetTimeNow()
t.Run("Given an alert", func(t *testing.T) {
sqlStore := sqlStore{db: sqlstore.InitTestDB(t), log: log.New()}
ss := sqlstore.InitTestDB(t)
sqlStore := sqlStore{db: ss, log: log.New(), tagService: tagimpl.ProvideService(ss)}
testDash := insertTestDashboard(t, sqlStore.db, "dashboard with alerts", 1, 0, false, "alert")
alert, err := insertTestAlert("Alerting title", "Alerting message", testDash.OrgId, testDash.Id, simplejson.New(), sqlStore)

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/setting"
)
@ -13,12 +14,13 @@ type RepositoryImpl struct {
store store
}
func ProvideService(db db.DB, cfg *setting.Cfg) *RepositoryImpl {
func ProvideService(db db.DB, cfg *setting.Cfg, tagService tag.Service) *RepositoryImpl {
return &RepositoryImpl{
store: &SQLAnnotationRepo{
cfg: cfg,
db: db,
log: log.New("annotations"),
cfg: cfg,
db: db,
log: log.New("annotations"),
tagService: tagService,
},
}
}

View File

@ -8,7 +8,6 @@ import (
"strings"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
@ -17,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -41,30 +41,31 @@ func validateTimeRange(item *annotations.Item) error {
}
type SQLAnnotationRepo struct {
cfg *setting.Cfg
db db.DB
log log.Logger
cfg *setting.Cfg
db db.DB
log log.Logger
tagService tag.Service
}
func (r *SQLAnnotationRepo) Add(ctx context.Context, item *annotations.Item) error {
return r.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
tags := models.ParseTagPairs(item.Tags)
item.Tags = models.JoinTagPairs(tags)
item.Created = timeNow().UnixNano() / int64(time.Millisecond)
item.Updated = item.Created
if item.Epoch == 0 {
item.Epoch = item.Created
}
if err := validateTimeRange(item); err != nil {
return err
}
tags := tag.ParseTagPairs(item.Tags)
item.Tags = tag.JoinTagPairs(tags)
item.Created = timeNow().UnixNano() / int64(time.Millisecond)
item.Updated = item.Created
if item.Epoch == 0 {
item.Epoch = item.Created
}
if err := validateTimeRange(item); err != nil {
return err
}
return r.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
if _, err := sess.Table("annotation").Insert(item); err != nil {
return err
}
if item.Tags != nil {
tags, err := sqlstore.EnsureTagsExist(sess, tags)
tags, err := r.tagService.EnsureTagsExist(ctx, tags)
if err != nil {
return err
}
@ -74,7 +75,6 @@ func (r *SQLAnnotationRepo) Add(ctx context.Context, item *annotations.Item) err
}
}
}
return nil
})
}
@ -111,7 +111,7 @@ func (r *SQLAnnotationRepo) Update(ctx context.Context, item *annotations.Item)
}
if item.Tags != nil {
tags, err := sqlstore.EnsureTagsExist(sess, models.ParseTagPairs(item.Tags))
tags, err := r.tagService.EnsureTagsExist(ctx, tag.ParseTagPairs(item.Tags))
if err != nil {
return err
}
@ -205,7 +205,7 @@ func (r *SQLAnnotationRepo) Get(ctx context.Context, query *annotations.ItemQuer
if len(query.Tags) > 0 {
keyValueFilters := []string{}
tags := models.ParseTagPairs(query.Tags)
tags := tag.ParseTagPairs(query.Tags)
for _, tag := range tags {
if tag.Value == "" {
keyValueFilters = append(keyValueFilters, "(tag."+r.db.GetDialect().Quote("key")+" = ?)")
@ -249,8 +249,6 @@ func (r *SQLAnnotationRepo) Get(ctx context.Context, query *annotations.ItemQuer
// order of ORDER BY arguments match the order of a sql index for performance
sql.WriteString(" ORDER BY a.org_id, a.epoch_end DESC, a.epoch DESC" + r.db.GetDialect().Limit(query.Limit) + " ) dt on dt.id = annotation.id")
spew.Dump(">>>> query: ", sql.String())
if err := sess.SQL(sql.String(), params...).Find(&items); err != nil {
items = nil
return err

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -27,7 +28,7 @@ func TestIntegrationAnnotations(t *testing.T) {
t.Skip("skipping integration test")
}
sql := sqlstore.InitTestDB(t)
repo := SQLAnnotationRepo{db: sql, cfg: setting.NewCfg(), log: log.New("annotation.test")}
repo := SQLAnnotationRepo{db: sql, cfg: setting.NewCfg(), log: log.New("annotation.test"), tagService: tagimpl.ProvideService(sql)}
testUser := &user.SignedInUser{
OrgID: 1,
@ -52,7 +53,7 @@ func TestIntegrationAnnotations(t *testing.T) {
assert.NoError(t, err)
})
dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures())
dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql))
testDashboard1 := models.SaveDashboardCommand{
UserId: 1,
@ -61,7 +62,8 @@ func TestIntegrationAnnotations(t *testing.T) {
"title": "Dashboard 1",
}),
}
dashboard, err := dashboardStore.SaveDashboard(testDashboard1)
dashboard, err := dashboardStore.SaveDashboard(context.Background(), testDashboard1)
require.NoError(t, err)
testDashboard2 := models.SaveDashboardCommand{
@ -71,7 +73,7 @@ func TestIntegrationAnnotations(t *testing.T) {
"title": "Dashboard 2",
}),
}
dashboard2, err := dashboardStore.SaveDashboard(testDashboard2)
dashboard2, err := dashboardStore.SaveDashboard(context.Background(), testDashboard2)
require.NoError(t, err)
annotation := &annotations.Item{
@ -96,7 +98,7 @@ func TestIntegrationAnnotations(t *testing.T) {
Type: "alert",
Epoch: 21, // Should swap epoch & epochEnd
EpochEnd: 20,
Tags: []string{"outage", "error", "type:outage", "server:server-1"},
Tags: []string{"outage", "type:outage", "server:server-1", "error"},
}
err = repo.Add(context.Background(), annotation2)
require.NoError(t, err)
@ -392,8 +394,8 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
t.Skip("skipping integration test")
}
sql := sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{})
repo := SQLAnnotationRepo{db: sql, cfg: setting.NewCfg(), log: log.New("annotation.test")}
dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures())
repo := SQLAnnotationRepo{db: sql, cfg: setting.NewCfg(), log: log.New("annotation.test"), tagService: tagimpl.ProvideService(sql)}
dashboardStore := dashboardstore.ProvideDashboardStore(sql, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql))
testDashboard1 := models.SaveDashboardCommand{
UserId: 1,
@ -402,7 +404,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
"title": "Dashboard 1",
}),
}
dashboard, err := dashboardStore.SaveDashboard(testDashboard1)
dashboard, err := dashboardStore.SaveDashboard(context.Background(), testDashboard1)
require.NoError(t, err)
dash1UID := dashboard.Uid
@ -413,7 +415,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
"title": "Dashboard 2",
}),
}
_, err = dashboardStore.SaveDashboard(testDashboard2)
_, err = dashboardStore.SaveDashboard(context.Background(), testDashboard2)
require.NoError(t, err)
dash1Annotation := &annotations.Item{

View File

@ -39,9 +39,9 @@ type PluginService interface {
type DashboardProvisioningService interface {
DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error
DeleteProvisionedDashboard(ctx context.Context, dashboardID int64, orgID int64) error
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
SaveFolderForProvisionedDashboards(context.Context, *SaveDashboardDTO) (*models.Dashboard, error)
SaveProvisionedDashboard(ctx context.Context, dto *SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
UnprovisionDashboard(ctx context.Context, dashboardID int64) error
@ -61,19 +61,19 @@ type Store interface {
// GetDashboardsByPluginID retrieves dashboards identified by plugin.
GetDashboardsByPluginID(ctx context.Context, query *models.GetDashboardsByPluginIdQuery) error
GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error
HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error
// SaveAlerts saves dashboard alerts.
SaveAlerts(ctx context.Context, dashID int64, alerts []*models.Alert) error
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
SaveDashboard(ctx context.Context, cmd models.SaveDashboardCommand) (*models.Dashboard, error)
SaveProvisionedDashboard(ctx context.Context, cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
UnprovisionDashboard(ctx context.Context, id int64) error
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardACL) error
// ValidateDashboardBeforeSave validates a dashboard before save.
ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error)
ValidateDashboardBeforeSave(ctx context.Context, dashboard *models.Dashboard, overwrite bool) (bool, error)
DeleteACLByUser(context.Context, int64) error
FolderStore

View File

@ -45,7 +45,7 @@ func (_m *FakeDashboardProvisioning) DeleteProvisionedDashboard(ctx context.Cont
}
// GetProvisionedDashboardData provides a mock function with given fields: name
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error) {
ret := _m.Called(name)
var r0 []*models.DashboardProvisioning
@ -68,7 +68,7 @@ func (_m *FakeDashboardProvisioning) GetProvisionedDashboardData(name string) ([
}
// GetProvisionedDashboardDataByDashboardID provides a mock function with given fields: dashboardID
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error) {
ret := _m.Called(dashboardID)
var r0 *models.DashboardProvisioning
@ -91,7 +91,7 @@ func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardID(da
}
// GetProvisionedDashboardDataByDashboardUID provides a mock function with given fields: orgID, dashboardUID
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
ret := _m.Called(orgID, dashboardUID)
var r0 *models.DashboardProvisioning

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@ -22,7 +23,7 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) {
setup := func(t *testing.T) {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")

View File

@ -20,30 +20,32 @@ import (
"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/services/tag"
"github.com/grafana/grafana/pkg/util"
)
type DashboardStore struct {
sqlStore *sqlstore.SQLStore
log log.Logger
dialect migrator.Dialect
features featuremgmt.FeatureToggles
sqlStore *sqlstore.SQLStore
log log.Logger
dialect migrator.Dialect
features featuremgmt.FeatureToggles
tagService tag.Service
}
// DashboardStore implements the Store interface
var _ dashboards.Store = (*DashboardStore)(nil)
func ProvideDashboardStore(sqlStore *sqlstore.SQLStore, features featuremgmt.FeatureToggles) *DashboardStore {
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect, features: features}
func ProvideDashboardStore(sqlStore *sqlstore.SQLStore, features featuremgmt.FeatureToggles, tagService tag.Service) *DashboardStore {
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect, features: features, tagService: tagService}
}
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) {
func (d *DashboardStore) ValidateDashboardBeforeSave(ctx context.Context, dashboard *models.Dashboard, overwrite bool) (bool, error) {
isParentFolderChanged := false
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var err error
isParentFolderChanged, err = getExistingDashboardByIdOrUidForUpdate(sess, dashboard, d.sqlStore.Dialect, overwrite)
if err != nil {
@ -132,9 +134,9 @@ func (d *DashboardStore) GetFolderByUID(ctx context.Context, orgID int64, uid st
return models.DashboardToFolder(&dashboard), nil
}
func (d *DashboardStore) GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
func (d *DashboardStore) GetProvisionedDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error) {
var data models.DashboardProvisioning
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Where("dashboard_id = ?", dashboardID).Get(&data)
return err
})
@ -145,9 +147,9 @@ func (d *DashboardStore) GetProvisionedDataByDashboardID(dashboardID int64) (*mo
return &data, err
}
func (d *DashboardStore) GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
func (d *DashboardStore) GetProvisionedDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
var provisionedDashboard models.DashboardProvisioning
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var dashboard models.Dashboard
exists, err := sess.Where("org_id = ? AND uid = ?", orgID, dashboardUID).Get(&dashboard)
if err != nil {
@ -168,16 +170,16 @@ func (d *DashboardStore) GetProvisionedDataByDashboardUID(orgID int64, dashboard
return &provisionedDashboard, err
}
func (d *DashboardStore) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
func (d *DashboardStore) GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error) {
var result []*models.DashboardProvisioning
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
return sess.Where("name = ?", name).Find(&result)
})
return result, err
}
func (d *DashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
func (d *DashboardStore) SaveProvisionedDashboard(ctx context.Context, cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
if err := saveDashboard(sess, &cmd, d.emitEntityEvent()); err != nil {
return err
}
@ -192,8 +194,8 @@ func (d *DashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardComman
return cmd.Result, err
}
func (d *DashboardStore) SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error) {
err := d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
func (d *DashboardStore) SaveDashboard(ctx context.Context, cmd models.SaveDashboardCommand) (*models.Dashboard, error) {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
return saveDashboard(sess, &cmd, d.emitEntityEvent())
})
return cmd.Result, err
@ -230,13 +232,13 @@ func (d *DashboardStore) UpdateDashboardACL(ctx context.Context, dashboardID int
}
func (d *DashboardStore) SaveAlerts(ctx context.Context, dashID int64, alerts []*models.Alert) error {
return d.sqlStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
return d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
existingAlerts, err := GetAlertsByDashboardId2(dashID, sess)
if err != nil {
return err
}
if err := updateAlerts(existingAlerts, alerts, sess, d.log); err != nil {
if err := d.updateAlerts(ctx, existingAlerts, alerts, d.log); err != nil {
return err
}
@ -571,64 +573,65 @@ func GetAlertsByDashboardId2(dashboardId int64, sess *sqlstore.DBSession) ([]*mo
return alerts, nil
}
func updateAlerts(existingAlerts []*models.Alert, alerts []*models.Alert, sess *sqlstore.DBSession, log log.Logger) error {
for _, alert := range alerts {
update := false
var alertToUpdate *models.Alert
func (d *DashboardStore) updateAlerts(ctx context.Context, existingAlerts []*models.Alert, alerts []*models.Alert, log log.Logger) error {
return d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
for _, alert := range alerts {
update := false
var alertToUpdate *models.Alert
for _, k := range existingAlerts {
if alert.PanelId == k.PanelId {
update = true
alert.Id = k.Id
alertToUpdate = k
break
for _, k := range existingAlerts {
if alert.PanelId == k.PanelId {
update = true
alert.Id = k.Id
alertToUpdate = k
break
}
}
}
if update {
if alertToUpdate.ContainsUpdates(alert) {
if update {
if alertToUpdate.ContainsUpdates(alert) {
alert.Updated = time.Now()
alert.State = alertToUpdate.State
sess.MustCols("message", "for")
_, err := sess.ID(alert.Id).Update(alert)
if err != nil {
return err
}
log.Debug("Alert updated", "name", alert.Name, "id", alert.Id)
}
} else {
alert.Updated = time.Now()
alert.State = alertToUpdate.State
sess.MustCols("message", "for")
alert.Created = time.Now()
alert.State = models.AlertStateUnknown
alert.NewStateDate = time.Now()
_, err := sess.ID(alert.Id).Update(alert)
_, err := sess.Insert(alert)
if err != nil {
return err
}
log.Debug("Alert updated", "name", alert.Name, "id", alert.Id)
log.Debug("Alert inserted", "name", alert.Name, "id", alert.Id)
}
} else {
alert.Updated = time.Now()
alert.Created = time.Now()
alert.State = models.AlertStateUnknown
alert.NewStateDate = time.Now()
_, err := sess.Insert(alert)
if err != nil {
tags := alert.GetTagsFromSettings()
if _, err := sess.Exec("DELETE FROM alert_rule_tag WHERE alert_id = ?", alert.Id); err != nil {
return err
}
log.Debug("Alert inserted", "name", alert.Name, "id", alert.Id)
}
tags := alert.GetTagsFromSettings()
if _, err := sess.Exec("DELETE FROM alert_rule_tag WHERE alert_id = ?", alert.Id); err != nil {
return err
}
if tags != nil {
tags, err := EnsureTagsExist(sess, tags)
if err != nil {
return err
}
for _, tag := range tags {
if _, err := sess.Exec("INSERT INTO alert_rule_tag (alert_id, tag_id) VALUES(?,?)", alert.Id, tag.Id); err != nil {
if tags != nil {
tags, err := d.tagService.EnsureTagsExist(ctx, tags)
if err != nil {
return err
}
for _, tag := range tags {
if _, err := sess.Exec("INSERT INTO alert_rule_tag (alert_id, tag_id) VALUES(?,?)", alert.Id, tag.Id); err != nil {
return err
}
}
}
}
}
return nil
return nil
})
}
func (d *DashboardStore) deleteMissingAlerts(alerts []*models.Alert, existingAlerts []*models.Alert, sess *sqlstore.DBSession) error {
@ -676,28 +679,6 @@ func (d *DashboardStore) deleteAlertByIdInternal(alertId int64, reason string, s
return nil
}
func EnsureTagsExist(sess *sqlstore.DBSession, tags []*models.Tag) ([]*models.Tag, error) {
for _, tag := range tags {
var existingTag models.Tag
// check if it exists
exists, err := sess.Table("tag").Where("`key`=? AND `value`=?", tag.Key, tag.Value).Get(&existingTag)
if err != nil {
return nil, err
}
if exists {
tag.Id = existingTag.Id
} else {
_, err := sess.Table("tag").Insert(tag)
if err != nil {
return nil, err
}
}
}
return tags, nil
}
func (d *DashboardStore) GetDashboardsByPluginID(ctx context.Context, query *models.GetDashboardsByPluginIdQuery) error {
return d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
var dashboards = make([]*models.Dashboard, 0)

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
)
@ -30,7 +31,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
sqlStore.Cfg.RBACEnabled = false
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")
@ -183,7 +184,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
setup2 := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")
@ -288,7 +289,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
setup3 := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")
@ -470,7 +471,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var folder1, folder2 *models.Dashboard
sqlStore = sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")
@ -485,7 +486,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("GetFolderByUID", func(t *testing.T) {
var orgId int64 = 1
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
folder := insertTestDashboard(t, dashboardStore, "TEST", orgId, 0, true, "prod")
dash := insertTestDashboard(t, dashboardStore, "Very Unique Name", orgId, folder.Id, false, "prod")
@ -509,7 +510,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("GetFolderByID", func(t *testing.T) {
var orgId int64 = 1
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
folder := insertTestDashboard(t, dashboardStore, "TEST", orgId, 0, true, "prod")
dash := insertTestDashboard(t, dashboardStore, "Very Unique Name", orgId, folder.Id, false, "prod")
@ -542,7 +543,7 @@ func moveDashboard(t *testing.T, dashboardStore *DashboardStore, orgId int64, da
Dashboard: dashboard,
Overwrite: true,
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
return dash

View File

@ -6,6 +6,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
@ -18,7 +19,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
t.Skip("skipping integration test")
}
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
folderCmd := models.SaveDashboardCommand{
OrgId: 1,
@ -30,7 +31,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
}),
}
dash, err := dashboardStore.SaveDashboard(folderCmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), folderCmd)
require.Nil(t, err)
saveDashboardCmd := models.SaveDashboardCommand{
@ -52,7 +53,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
Updated: now.Unix(),
}
dash, err := dashboardStore.SaveProvisionedDashboard(saveDashboardCmd, provisioning)
dash, err := dashboardStore.SaveProvisionedDashboard(context.Background(), saveDashboardCmd, provisioning)
require.Nil(t, err)
require.NotNil(t, dash)
require.NotEqual(t, 0, dash.Id)
@ -74,7 +75,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
Updated: now.Unix(),
}
anotherDash, err := dashboardStore.SaveProvisionedDashboard(saveCmd, provisioning)
anotherDash, err := dashboardStore.SaveProvisionedDashboard(context.Background(), saveCmd, provisioning)
require.Nil(t, err)
query := &models.GetDashboardsQuery{DashboardIds: []int64{anotherDash.Id}}
@ -94,7 +95,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
})
t.Run("Can query for provisioned dashboards", func(t *testing.T) {
rslt, err := dashboardStore.GetProvisionedDashboardData("default")
rslt, err := dashboardStore.GetProvisionedDashboardData(context.Background(), "default")
require.Nil(t, err)
require.Equal(t, 1, len(rslt))
@ -103,13 +104,13 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
})
t.Run("Can query for one provisioned dashboard", func(t *testing.T) {
data, err := dashboardStore.GetProvisionedDataByDashboardID(dash.Id)
data, err := dashboardStore.GetProvisionedDataByDashboardID(context.Background(), dash.Id)
require.Nil(t, err)
require.NotNil(t, data)
})
t.Run("Can query for none provisioned dashboard", func(t *testing.T) {
data, err := dashboardStore.GetProvisionedDataByDashboardID(3000)
data, err := dashboardStore.GetProvisionedDataByDashboardID(context.Background(), 3000)
require.Nil(t, err)
require.Nil(t, data)
})
@ -122,7 +123,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
require.Nil(t, dashboardStore.DeleteDashboard(context.Background(), deleteCmd))
data, err := dashboardStore.GetProvisionedDataByDashboardID(dash.Id)
data, err := dashboardStore.GetProvisionedDataByDashboardID(context.Background(), dash.Id)
require.Nil(t, err)
require.Nil(t, data)
})
@ -130,7 +131,7 @@ func TestIntegrationDashboardProvisioningTest(t *testing.T) {
t.Run("UnprovisionDashboard should delete provisioning metadata", func(t *testing.T) {
require.Nil(t, dashboardStore.UnprovisionDashboard(context.Background(), dashId))
data, err := dashboardStore.GetProvisionedDataByDashboardID(dashId)
data, err := dashboardStore.GetProvisionedDataByDashboardID(context.Background(), dashId)
require.Nil(t, err)
require.Nil(t, data)
})

View File

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/services/star/starimpl"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
)
@ -34,7 +35,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
starService = starimpl.ProvideService(sqlStore, sqlStore.Cfg)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
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")
@ -162,7 +163,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
}),
UserId: 100,
}
dashboard, err := dashboardStore.SaveDashboard(cmd)
dashboard, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.EqualValues(t, dashboard.CreatedBy, 100)
require.False(t, dashboard.Created.IsZero())
@ -183,7 +184,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
FolderId: 2,
UserId: 100,
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.EqualValues(t, dash.FolderId, 2)
@ -198,7 +199,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
Overwrite: true,
UserId: 100,
}
_, err = dashboardStore.SaveDashboard(cmd)
_, err = dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
query := models.GetDashboardQuery{
@ -274,7 +275,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
}),
}
_, err := dashboardStore.SaveDashboard(cmd)
_, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.Equal(t, err, dashboards.ErrDashboardNotFound)
})
@ -288,7 +289,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
"tags": []interface{}{},
}),
}
_, err := dashboardStore.SaveDashboard(cmd)
_, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
})
@ -485,7 +486,7 @@ func TestIntegrationDashboardDataAccessGivenPluginWithImportedDashboards(t *test
t.Skip("skipping integration test")
}
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
pluginId := "test-app"
appFolder := insertTestDashboardForPlugin(t, dashboardStore, "app-test", 1, 0, true, pluginId)
@ -507,7 +508,7 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) {
t.Skip("skipping integration test")
}
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false)
dashA := insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false)
@ -556,7 +557,7 @@ func TestIntegrationDashboard_Filter(t *testing.T) {
t.Skip("skipping integration test")
}
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles)
dashboardStore := ProvideDashboardStore(sqlStore, testFeatureToggles, tagimpl.ProvideService(sqlStore))
insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false)
dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false)
qNoFilter := &models.FindPersistedDashboardsQuery{
@ -696,7 +697,7 @@ func insertTestDashboard(t *testing.T, dashboardStore *DashboardStore, title str
"tags": tags,
}),
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.NotNil(t, dash)
dash.Data.Set("id", dash.Id)
@ -718,7 +719,7 @@ func insertTestDashboardForPlugin(t *testing.T, dashboardStore *DashboardStore,
PluginId: pluginId,
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
return dash

View File

@ -62,16 +62,16 @@ func ProvideDashboardService(
}
}
func (dr *DashboardServiceImpl) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDashboardData(name)
func (dr *DashboardServiceImpl) GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDashboardData(ctx, name)
}
func (dr *DashboardServiceImpl) GetProvisionedDashboardDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDataByDashboardID(dashboardID)
func (dr *DashboardServiceImpl) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDataByDashboardID(ctx, dashboardID)
}
func (dr *DashboardServiceImpl) GetProvisionedDashboardDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDataByDashboardUID(orgID, dashboardUID)
func (dr *DashboardServiceImpl) GetProvisionedDashboardDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
return dr.dashboardStore.GetProvisionedDataByDashboardUID(ctx, orgID, dashboardUID)
}
func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards.SaveDashboardDTO, shouldValidateAlerts bool,
@ -112,7 +112,7 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
}
}
isParentFolderChanged, err := dr.dashboardStore.ValidateDashboardBeforeSave(dash, dto.Overwrite)
isParentFolderChanged, err := dr.dashboardStore.ValidateDashboardBeforeSave(ctx, dash, dto.Overwrite)
if err != nil {
return nil, err
}
@ -129,7 +129,7 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
}
if validateProvisionedDashboard {
provisionedData, err := dr.GetProvisionedDashboardDataByDashboardID(dash.Id)
provisionedData, err := dr.GetProvisionedDashboardDataByDashboardID(ctx, dash.Id)
if err != nil {
return nil, err
}
@ -225,7 +225,7 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
}
// dashboard
dash, err := dr.dashboardStore.SaveProvisionedDashboard(*cmd, provisioning)
dash, err := dr.dashboardStore.SaveProvisionedDashboard(ctx, *cmd, provisioning)
if err != nil {
return nil, err
}
@ -266,7 +266,7 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
return nil, err
}
dash, err := dr.dashboardStore.SaveDashboard(*cmd)
dash, err := dr.dashboardStore.SaveDashboard(ctx, *cmd)
if err != nil {
return nil, err
}
@ -313,7 +313,7 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboar
return nil, err
}
dash, err := dr.dashboardStore.SaveDashboard(*cmd)
dash, err := dr.dashboardStore.SaveDashboard(ctx, *cmd)
if err != nil {
return nil, fmt.Errorf("saving dashboard failed: %w", err)
}
@ -407,7 +407,7 @@ func (dr *DashboardServiceImpl) DeleteProvisionedDashboard(ctx context.Context,
func (dr *DashboardServiceImpl) deleteDashboard(ctx context.Context, dashboardId int64, orgId int64, validateProvisionedDashboard bool) error {
if validateProvisionedDashboard {
provisionedData, err := dr.GetProvisionedDashboardDataByDashboardID(dashboardId)
provisionedData, err := dr.GetProvisionedDashboardDataByDashboardID(ctx, dashboardId)
if err != nil {
return fmt.Errorf("%v: %w", "failed to check if dashboard is provisioned", err)
}
@ -434,7 +434,7 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashbo
return nil, err
}
dash, err := dr.dashboardStore.SaveDashboard(*cmd)
dash, err := dr.dashboardStore.SaveDashboard(ctx, *cmd)
if err != nil {
return nil, err
}

View File

@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -819,7 +820,7 @@ func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionSc
cfg := setting.NewCfg()
cfg.RBACEnabled = false
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
service := ProvideDashboardService(
cfg, dashboardStore, &dummyDashAlertExtractor{},
featuremgmt.WithFeatures(),
@ -873,7 +874,7 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
t.Helper()
dto := toSaveDashboardDto(cmd)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
cfg := setting.NewCfg()
cfg.RBACEnabled = false
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
@ -892,7 +893,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, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
cfg := setting.NewCfg()
cfg.RBACEnabled = false
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
@ -929,7 +930,7 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
},
}
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
cfg := setting.NewCfg()
cfg.RBACEnabled = false
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled
@ -967,7 +968,7 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
},
}
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
cfg := setting.NewCfg()
cfg.RBACEnabled = false
cfg.IsFeatureToggleEnabled = featuremgmt.WithFeatures().IsEnabled

View File

@ -164,7 +164,7 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedI
return nil, toFolderError(err)
}
dash, err := f.dashboardStore.SaveDashboard(*saveDashboardCmd)
dash, err := f.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd)
if err != nil {
return nil, toFolderError(err)
}
@ -228,7 +228,7 @@ func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *user.SignedI
return toFolderError(err)
}
dash, err := f.dashboardStore.SaveDashboard(*saveDashboardCmd)
dash, err := f.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd)
if err != nil {
return toFolderError(err)
}

View File

@ -231,7 +231,7 @@ func (_m *FakeDashboardStore) GetFolderByUID(ctx context.Context, orgID int64, u
}
// GetProvisionedDashboardData provides a mock function with given fields: name
func (_m *FakeDashboardStore) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
func (_m *FakeDashboardStore) GetProvisionedDashboardData(ctx context.Context, name string) ([]*models.DashboardProvisioning, error) {
ret := _m.Called(name)
var r0 []*models.DashboardProvisioning
@ -254,7 +254,7 @@ func (_m *FakeDashboardStore) GetProvisionedDashboardData(name string) ([]*model
}
// GetProvisionedDataByDashboardID provides a mock function with given fields: dashboardID
func (_m *FakeDashboardStore) GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error) {
func (_m *FakeDashboardStore) GetProvisionedDataByDashboardID(ctx context.Context, dashboardID int64) (*models.DashboardProvisioning, error) {
ret := _m.Called(dashboardID)
var r0 *models.DashboardProvisioning
@ -277,7 +277,7 @@ func (_m *FakeDashboardStore) GetProvisionedDataByDashboardID(dashboardID int64)
}
// GetProvisionedDataByDashboardUID provides a mock function with given fields: orgID, dashboardUID
func (_m *FakeDashboardStore) GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
func (_m *FakeDashboardStore) GetProvisionedDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*models.DashboardProvisioning, error) {
ret := _m.Called(orgID, dashboardUID)
var r0 *models.DashboardProvisioning
@ -342,7 +342,7 @@ func (_m *FakeDashboardStore) SaveAlerts(ctx context.Context, dashID int64, aler
}
// SaveDashboard provides a mock function with given fields: cmd
func (_m *FakeDashboardStore) SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error) {
func (_m *FakeDashboardStore) SaveDashboard(ctx context.Context, cmd models.SaveDashboardCommand) (*models.Dashboard, error) {
ret := _m.Called(cmd)
var r0 *models.Dashboard
@ -365,7 +365,7 @@ func (_m *FakeDashboardStore) SaveDashboard(cmd models.SaveDashboardCommand) (*m
}
// SaveProvisionedDashboard provides a mock function with given fields: cmd, provisioning
func (_m *FakeDashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
func (_m *FakeDashboardStore) SaveProvisionedDashboard(ctx context.Context, cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
ret := _m.Called(cmd, provisioning)
var r0 *models.Dashboard
@ -416,7 +416,7 @@ func (_m *FakeDashboardStore) UpdateDashboardACL(ctx context.Context, uid int64,
}
// ValidateDashboardBeforeSave provides a mock function with given fields: dashboard, overwrite
func (_m *FakeDashboardStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) {
func (_m *FakeDashboardStore) ValidateDashboardBeforeSave(ctx context.Context, dashboard *models.Dashboard, overwrite bool) (bool, error) {
ret := _m.Called(dashboard, overwrite)
var r0 bool

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
@ -589,8 +590,8 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce
toSave.SetUid(uid)
// seed dashboard
dashStore := dashdb.ProvideDashboardStore(store, featuremgmt.WithFeatures())
dash, err := dashStore.SaveDashboard(models.SaveDashboardCommand{
dashStore := dashdb.ProvideDashboardStore(store, featuremgmt.WithFeatures(), tagimpl.ProvideService(store))
dash, err := dashStore.SaveDashboard(context.Background(), models.SaveDashboardCommand{
Dashboard: toSave.Data,
UserId: 1,
OrgId: 1,

View File

@ -26,6 +26,7 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -271,7 +272,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user user.Signed
Overwrite: false,
}
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
dashAlertExtractor := alerting.ProvideDashAlertExtractorService(nil, nil, nil)
features := featuremgmt.WithFeatures()
cfg := setting.NewCfg()
@ -301,7 +302,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
ac := acmock.New()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
d := dashboardservice.ProvideDashboardService(
cfg, dashboardStore, nil,
@ -405,7 +406,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
orgID := int64(1)
role := org.RoleAdmin
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
features := featuremgmt.WithFeatures()
ac := acmock.New().WithDisabled()
// TODO: Update tests to work with rbac

View File

@ -24,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@ -1376,7 +1377,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *user.Signe
Overwrite: false,
}
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
dashAlertService := alerting.ProvideDashAlertExtractorService(nil, nil, nil)
cfg := setting.NewCfg()
cfg.RBACEnabled = false
@ -1403,7 +1404,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
features := featuremgmt.WithFeatures()
folderPermissions := acmock.NewMockedPermissionsService()
dashboardPermissions := acmock.NewMockedPermissionsService()
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac)
s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, folderPermissions, ac, busmock.New())
@ -1496,7 +1497,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
orgID := int64(1)
role := org.RoleAdmin
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
features := featuremgmt.WithFeatures()
ac := acmock.New()

View File

@ -29,6 +29,7 @@ import (
"github.com/grafana/grafana/pkg/services/secrets/database"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@ -61,7 +62,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, featuremgmt.WithFeatures())
dashboardStore := databasestore.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
ac := acmock.New()
features := featuremgmt.WithFeatures()

View File

@ -94,7 +94,7 @@ func (fr *FileReader) walkDisk(ctx context.Context) error {
return err
}
provisionedDashboardRefs, err := getProvisionedDashboardsByPath(fr.dashboardProvisioningService, fr.Cfg.Name)
provisionedDashboardRefs, err := getProvisionedDashboardsByPath(ctx, fr.dashboardProvisioningService, fr.Cfg.Name)
if err != nil {
return err
}
@ -279,9 +279,9 @@ func (fr *FileReader) saveDashboard(ctx context.Context, path string, folderID i
return provisioningMetadata, nil
}
func getProvisionedDashboardsByPath(service dashboards.DashboardProvisioningService, name string) (
func getProvisionedDashboardsByPath(ctx context.Context, service dashboards.DashboardProvisioningService, name string) (
map[string]*models.DashboardProvisioning, error) {
arr, err := service.GetProvisionedDashboardData(name)
arr, err := service.GetProvisionedDashboardData(ctx, name)
if err != nil {
return nil, err
}

View File

@ -27,6 +27,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources"
datasourcesService "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/publicdashboards"
@ -526,8 +527,8 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T)
}
// create dashboard
dashboardStoreService := dashboardStore.ProvideDashboardStore(db, featuremgmt.WithFeatures())
dashboard, err := dashboardStoreService.SaveDashboard(saveDashboardCmd)
dashboardStoreService := dashboardStore.ProvideDashboardStore(db, featuremgmt.WithFeatures(), tagimpl.ProvideService(db))
dashboard, err := dashboardStoreService.SaveDashboard(context.Background(), saveDashboardCmd)
require.NoError(t, err)
// Create public dashboard

View File

@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/util"
)
@ -36,7 +37,7 @@ func TestIntegrationGetDashboard(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore = ProvideStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
}
@ -60,7 +61,7 @@ func TestIntegrationGetPublicDashboard(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore = ProvideStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
}
@ -203,7 +204,7 @@ func TestIntegrationGetPublicDashboardConfig(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore = ProvideStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
}
@ -257,7 +258,7 @@ func TestIntegrationSavePublicDashboardConfig(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore = ProvideStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, true)
@ -318,7 +319,7 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore = dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore = ProvideStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
anotherSavedDashboard = insertTestDashboard(t, dashboardStore, "test another Dashie", 1, 0, true)
@ -401,7 +402,7 @@ func insertTestDashboard(t *testing.T, dashboardStore *dashboardsDB.DashboardSto
"tags": tags,
}),
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.NotNil(t, dash)
dash.Data.Set("id", dash.Id)

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/publicdashboards/internal"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/user"
"github.com/google/uuid"
@ -117,7 +118,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, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
@ -161,7 +162,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, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
@ -191,7 +192,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, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
templateVars := make([]map[string]interface{}, 1)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, templateVars)
@ -220,7 +221,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, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
@ -281,7 +282,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, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
@ -331,7 +332,7 @@ func TestUpdatePublicDashboard(t *testing.T) {
func TestBuildAnonymousUser(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
publicdashboardStore := database.ProvideStore(sqlStore)
service := &PublicDashboardServiceImpl{
@ -352,7 +353,7 @@ func TestBuildAnonymousUser(t *testing.T) {
func TestGetMetricRequest(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
publicDashboard := &PublicDashboard{
@ -395,7 +396,7 @@ func TestGetMetricRequest(t *testing.T) {
func TestBuildMetricRequest(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
dashboardStore := dashboardsDB.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore))
publicdashboardStore := database.ProvideStore(sqlStore)
publicDashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true, []map[string]interface{}{})
@ -562,7 +563,7 @@ func insertTestDashboard(t *testing.T, dashboardStore *dashboardsDB.DashboardSto
},
}),
}
dash, err := dashboardStore.SaveDashboard(cmd)
dash, err := dashboardStore.SaveDashboard(context.Background(), cmd)
require.NoError(t, err)
require.NotNil(t, dash)
dash.Data.Set("id", dash.Id)

View File

@ -34,13 +34,6 @@ func (ss *SQLStore) NewSession(ctx context.Context) *DBSession {
return sess
}
func (ss *SQLStore) newSession(ctx context.Context) *DBSession {
sess := &DBSession{Session: ss.engine.NewSession()}
sess.Session = sess.Session.Context(ctx)
return sess
}
func startSessionOrUseExisting(ctx context.Context, engine *xorm.Engine, beginTran bool) (*DBSession, bool, error) {
value := ctx.Value(ContextSessionKey{})
var sess *DBSession

View File

@ -1,26 +0,0 @@
package sqlstore
import "github.com/grafana/grafana/pkg/models"
// Will insert if needed any new key/value pars and return ids
func EnsureTagsExist(sess *DBSession, tags []*models.Tag) ([]*models.Tag, error) {
for _, tag := range tags {
var existingTag models.Tag
// check if it exists
exists, err := sess.Table("tag").Where("`key`=? AND `value`=?", tag.Key, tag.Value).Get(&existingTag)
if err != nil {
return nil, err
}
if exists {
tag.Id = existingTag.Id
} else {
_, err := sess.Table("tag").Insert(tag)
if err != nil {
return nil, err
}
}
}
return tags, nil
}

View File

@ -1,11 +1,11 @@
package models
package tag
import (
"strings"
)
type Tag struct {
Id int64
Id int64 `xorm:"pk autoincr 'id'"`
Key string
Value string
}

View File

@ -1,4 +1,4 @@
package models
package tag
import (
"testing"

9
pkg/services/tag/tag.go Normal file
View File

@ -0,0 +1,9 @@
package tag
import (
"context"
)
type Service interface {
EnsureTagsExist(ctx context.Context, tags []*Tag) ([]*Tag, error)
}

View File

@ -0,0 +1,39 @@
package tagimpl
import (
"context"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/tag"
)
type store interface {
EnsureTagsExist(context.Context, []*tag.Tag) ([]*tag.Tag, error)
}
type sqlStore struct {
db db.DB
}
func (s *sqlStore) EnsureTagsExist(ctx context.Context, tags []*tag.Tag) ([]*tag.Tag, error) {
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
for _, tagelement := range tags {
var existingTag tag.Tag
exists, err := sess.Table("tag").Where("`key`=? AND `value`=?", tagelement.Key, tagelement.Value).Get(&existingTag)
if err != nil {
return err
}
if exists {
tagelement.Id = existingTag.Id
} else {
_, err := sess.Table("tag").Insert(tagelement)
if err != nil {
return err
}
}
}
return nil
})
return tags, err
}

View File

@ -1,10 +1,11 @@
package sqlstore
package tagimpl
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/tag"
"github.com/stretchr/testify/require"
)
@ -13,15 +14,15 @@ func TestIntegrationSavingTags(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
ss := InitTestDB(t)
tagPairs := []*models.Tag{
ss := sqlstore.InitTestDB(t)
store := sqlStore{db: ss}
tagPairs := []*tag.Tag{
{Key: "outage"},
{Key: "type", Value: "outage"},
{Key: "server", Value: "server-1"},
{Key: "error"},
}
tags, err := EnsureTagsExist(ss.newSession(context.Background()), tagPairs)
tags, err := store.EnsureTagsExist(context.Background(), tagPairs)
require.Nil(t, err)
require.Equal(t, 4, len(tags))

View File

@ -0,0 +1,24 @@
package tagimpl
import (
"context"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/tag"
)
type Service struct {
store store
}
func ProvideService(db db.DB) *Service {
return &Service{
store: &sqlStore{
db: db,
},
}
}
func (s *Service) EnsureTagsExist(ctx context.Context, tags []*tag.Tag) ([]*tag.Tag, error) {
return s.store.EnsureTagsExist(ctx, tags)
}