From 53baecd71f5519e0ef300f3067cb89eab2908e2f Mon Sep 17 00:00:00 2001 From: Serge Zaitsev Date: Mon, 10 Oct 2022 21:47:53 +0200 Subject: [PATCH] Chore: Move folder service into a separate package (#56591) * Chore: move folder service interface into a separate package * copy implementation into a standalone package * move implementation and tests to the new folder package * remove leftovers from wire * add test doubles for folder service * fix tests in library panels/elements * fix provideservice in ngalert --- pkg/api/dashboard_test.go | 3 +- pkg/api/folder_permission_test.go | 24 +-- pkg/api/folder_test.go | 38 ++-- pkg/api/http_server.go | 5 +- pkg/cmd/grafana-cli/runner/wire.go | 2 - pkg/server/wire.go | 4 +- .../dashboards/folder_service_mock.go | 194 ------------------ pkg/services/{dashboards => folder}/folder.go | 8 +- .../folderimpl/folder.go} | 81 ++++---- .../folderimpl/folder_test.go} | 9 +- pkg/services/folder/foldertest/foldertest.go | 40 ++++ .../libraryelements/libraryelements.go | 6 +- .../libraryelements/libraryelements_test.go | 15 +- .../librarypanels/librarypanels_test.go | 8 +- pkg/services/ngalert/ngalert.go | 5 +- pkg/services/ngalert/store/database.go | 5 +- pkg/services/ngalert/tests/util.go | 6 +- pkg/services/provisioning/provisioning.go | 3 +- 18 files changed, 148 insertions(+), 308 deletions(-) delete mode 100644 pkg/services/dashboards/folder_service_mock.go rename pkg/services/{dashboards => folder}/folder.go (82%) rename pkg/services/{dashboards/service/folder_service.go => folder/folderimpl/folder.go} (69%) rename pkg/services/{dashboards/service/folder_service_test.go => folder/folderimpl/folder_test.go} (96%) create mode 100644 pkg/services/folder/foldertest/foldertest.go diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index c41c9be06a6..7ce47fccb90 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -30,6 +30,7 @@ import ( dashver "github.com/grafana/grafana/pkg/services/dashboardversion" "github.com/grafana/grafana/pkg/services/dashboardversion/dashvertest" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/libraryelements" "github.com/grafana/grafana/pkg/services/live" @@ -1017,7 +1018,7 @@ func callPostDashboardShouldReturnSuccess(sc *scenarioContext) { assert.Equal(sc.t, 200, sc.resp.Code) } -func postDashboardScenario(t *testing.T, desc string, url string, routePattern string, cmd models.SaveDashboardCommand, dashboardService dashboards.DashboardService, folderService dashboards.FolderService, fn scenarioFunc) { +func postDashboardScenario(t *testing.T, desc string, url string, routePattern string, cmd models.SaveDashboardCommand, dashboardService dashboards.DashboardService, folderService folder.Service, fn scenarioFunc) { t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { cfg := setting.NewCfg() hs := HTTPServer{ diff --git a/pkg/api/folder_permission_test.go b/pkg/api/folder_permission_test.go index 987bdc0dcb5..c41b0ea3313 100644 --- a/pkg/api/folder_permission_test.go +++ b/pkg/api/folder_permission_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards" service "github.com/grafana/grafana/pkg/services/dashboards/service" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore/mockstore" @@ -26,8 +27,7 @@ import ( func TestFolderPermissionAPIEndpoint(t *testing.T) { settings := setting.NewCfg() - folderService := &dashboards.FakeFolderService{} - defer folderService.AssertExpectations(t) + folderService := &foldertest.FakeService{} dashboardStore := &dashboards.FakeDashboardStore{} defer dashboardStore.AssertExpectations(t) @@ -50,7 +50,10 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { } t.Run("Given folder not exists", func(t *testing.T) { - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, dashboards.ErrFolderNotFound).Twice() + t.Cleanup(func() { + folderService.ExpectedError = nil + }) + folderService.ExpectedError = dashboards.ErrFolderNotFound mockSQLStore := mockstore.NewSQLStoreMock() loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleEditor, func(sc *scenarioContext) { callGetFolderPermissions(sc, hs) @@ -79,10 +82,11 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { origNewGuardian := guardian.New t.Cleanup(func() { guardian.New = origNewGuardian + folderService.ExpectedError = nil }) guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanAdminValue: false}) - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, dashboards.ErrFolderAccessDenied).Twice() + folderService.ExpectedError = dashboards.ErrFolderAccessDenied mockSQLStore := mockstore.NewSQLStoreMock() loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/folders/uid/permissions", "/api/folders/:uid/permissions", org.RoleEditor, func(sc *scenarioContext) { @@ -126,8 +130,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { }, }) - folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Twice() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() mockSQLStore := mockstore.NewSQLStoreMock() @@ -184,8 +187,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { CheckPermissionBeforeUpdateError: guardian.ErrGuardianPermissionExists, }) - folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Once() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} cmd := dtos.UpdateDashboardACLCommand{ Items: []dtos.DashboardACLUpdateItem{ @@ -249,8 +251,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { CheckPermissionBeforeUpdateError: guardian.ErrGuardianOverride}, ) - folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Once() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} cmd := dtos.UpdateDashboardACLCommand{ Items: []dtos.DashboardACLUpdateItem{ @@ -296,8 +297,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { var gotItems []*models.DashboardACL - folderResponse := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResponse, nil).Twice() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} dashboardStore.On("UpdateDashboardACL", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { gotItems = args.Get(2).([]*models.DashboardACL) }).Return(nil).Once() diff --git a/pkg/api/folder_test.go b/pkg/api/folder_test.go index 7bd1a30fec0..bc7ace258a9 100644 --- a/pkg/api/folder_test.go +++ b/pkg/api/folder_test.go @@ -19,6 +19,8 @@ import ( acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder" + "github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore/mockstore" @@ -29,8 +31,7 @@ import ( ) func TestFoldersAPIEndpoint(t *testing.T) { - folderService := &dashboards.FakeFolderService{} - defer folderService.AssertExpectations(t) + folderService := &foldertest.FakeService{} t.Run("Given a correct request for creating a folder", func(t *testing.T) { cmd := models.CreateFolderCommand{ @@ -38,8 +39,7 @@ func TestFoldersAPIEndpoint(t *testing.T) { Title: "Folder", } - folderResult := &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} - folderService.On("CreateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(folderResult, nil).Once() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder"} createFolderScenario(t, "When calling POST on", "/api/folders", "/api/folders", folderService, cmd, func(sc *scenarioContext) { @@ -55,6 +55,9 @@ func TestFoldersAPIEndpoint(t *testing.T) { }) t.Run("Given incorrect requests for creating a folder", func(t *testing.T) { + t.Cleanup(func() { + folderService.ExpectedError = nil + }) testCases := []struct { Error error ExpectedStatusCode int @@ -76,7 +79,7 @@ func TestFoldersAPIEndpoint(t *testing.T) { } for _, tc := range testCases { - folderService.On("CreateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, tc.Error).Once() + folderService.ExpectedError = tc.Error createFolderScenario(t, fmt.Sprintf("Expect '%s' error when calling POST on", tc.Error.Error()), "/api/folders", "/api/folders", folderService, cmd, func(sc *scenarioContext) { @@ -91,10 +94,7 @@ func TestFoldersAPIEndpoint(t *testing.T) { Title: "Folder upd", } - folderService.On("UpdateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - cmd := args.Get(4).(*models.UpdateFolderCommand) - cmd.Result = &models.Folder{Id: 1, Uid: "uid", Title: "Folder upd"} - }).Return(nil).Once() + folderService.ExpectedFolder = &models.Folder{Id: 1, Uid: "uid", Title: "Folder upd"} updateFolderScenario(t, "When calling PUT on", "/api/folders/uid", "/api/folders/:uid", folderService, cmd, func(sc *scenarioContext) { @@ -130,7 +130,7 @@ func TestFoldersAPIEndpoint(t *testing.T) { } for _, tc := range testCases { - folderService.On("UpdateFolder", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.Error).Once() + folderService.ExpectedError = tc.Error updateFolderScenario(t, fmt.Sprintf("Expect '%s' error when calling PUT on", tc.Error.Error()), "/api/folders/uid", "/api/folders/:uid", folderService, cmd, func(sc *scenarioContext) { callUpdateFolder(sc) @@ -142,7 +142,7 @@ func TestFoldersAPIEndpoint(t *testing.T) { func TestHTTPServer_FolderMetadata(t *testing.T) { setUpRBACGuardian(t) - folderService := dashboards.NewFakeFolderService(t) + folderService := &foldertest.FakeService{} server := SetupAPITestServer(t, func(hs *HTTPServer) { hs.folderService = folderService hs.AccessControl = acmock.New() @@ -150,11 +150,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) { }) t.Run("Should attach access control metadata to multiple folders", func(t *testing.T) { - folderService.On("GetFolders", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*models.Folder{ - {Uid: "1"}, - {Uid: "2"}, - {Uid: "3"}, - }, nil) + folderService.ExpectedFolders = []*models.Folder{{Uid: "1"}, {Uid: "2"}, {Uid: "3"}} req := server.NewGetRequest("/api/folders?accesscontrol=true") webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{ @@ -183,7 +179,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) { }) t.Run("Should attach access control metadata to folder response", func(t *testing.T) { - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil) + folderService.ExpectedFolder = &models.Folder{Uid: "folderUid"} req := server.NewGetRequest("/api/folders/folderUid?accesscontrol=true") webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{ @@ -206,7 +202,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) { }) t.Run("Should attach access control metadata to folder response", func(t *testing.T) { - folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&models.Folder{Uid: "folderUid"}, nil) + folderService.ExpectedFolder = &models.Folder{Uid: "folderUid"} req := server.NewGetRequest("/api/folders/folderUid") webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{ @@ -233,7 +229,7 @@ func callCreateFolder(sc *scenarioContext) { sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() } -func createFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService, +func createFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService folder.Service, cmd models.CreateFolderCommand, fn scenarioFunc) { setUpRBACGuardian(t) t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { @@ -273,7 +269,7 @@ func callUpdateFolder(sc *scenarioContext) { sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() } -func updateFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService dashboards.FolderService, +func updateFolderScenario(t *testing.T, desc string, url string, routePattern string, folderService folder.Service, cmd models.UpdateFolderCommand, fn scenarioFunc) { setUpRBACGuardian(t) t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { @@ -300,7 +296,7 @@ func updateFolderScenario(t *testing.T, desc string, url string, routePattern st } type fakeFolderService struct { - dashboards.FolderService + folder.Service GetFoldersResult []*models.Folder GetFoldersError error diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 23d7b1245f9..4fb0fd818a2 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/middleware/csrf" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/querylibrary" "github.com/grafana/grafana/pkg/services/searchV2" "github.com/grafana/grafana/pkg/services/store/object" @@ -176,7 +177,7 @@ type HTTPServer struct { NotificationService *notifications.NotificationService DashboardService dashboards.DashboardService dashboardProvisioningService dashboards.DashboardProvisioningService - folderService dashboards.FolderService + folderService folder.Service DatasourcePermissionsService permissions.DatasourcePermissionsService commentsService *comments.Service AlertNotificationService *alerting.AlertNotificationService @@ -232,7 +233,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi ldapGroups ldap.Groups, teamGuardian teamguardian.TeamGuardian, serviceaccountsService serviceaccounts.Service, authInfoService login.AuthInfoService, storageService store.StorageService, httpObjectStore object.HTTPObjectStore, notificationService *notifications.NotificationService, dashboardService dashboards.DashboardService, - dashboardProvisioningService dashboards.DashboardProvisioningService, folderService dashboards.FolderService, + dashboardProvisioningService dashboards.DashboardProvisioningService, folderService folder.Service, datasourcePermissionsService permissions.DatasourcePermissionsService, alertNotificationService *alerting.AlertNotificationService, dashboardsnapshotsService dashboardsnapshots.Service, commentsService *comments.Service, pluginSettings pluginSettings.Service, avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service, diff --git a/pkg/cmd/grafana-cli/runner/wire.go b/pkg/cmd/grafana-cli/runner/wire.go index fd9a97837ad..beb7f785203 100644 --- a/pkg/cmd/grafana-cli/runner/wire.go +++ b/pkg/cmd/grafana-cli/runner/wire.go @@ -281,12 +281,10 @@ var wireSet = wire.NewSet( wire.Bind(new(teamguardian.Store), new(*teamguardianDatabase.TeamGuardianStoreImpl)), teamguardianManager.ProvideService, dashboardservice.ProvideDashboardService, - dashboardservice.ProvideFolderService, dashboardstore.ProvideDashboardStore, wire.Bind(new(dashboards.DashboardService), new(*dashboardservice.DashboardServiceImpl)), wire.Bind(new(dashboards.DashboardProvisioningService), new(*dashboardservice.DashboardServiceImpl)), wire.Bind(new(dashboards.PluginService), new(*dashboardservice.DashboardServiceImpl)), - wire.Bind(new(dashboards.FolderService), new(*dashboardservice.FolderServiceImpl)), wire.Bind(new(dashboards.Store), new(*dashboardstore.DashboardStore)), dashboardimportservice.ProvideService, wire.Bind(new(dashboardimport.Service), new(*dashboardimportservice.ImportDashboardService)), diff --git a/pkg/server/wire.go b/pkg/server/wire.go index 51448589286..05052db1405 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -70,6 +70,7 @@ import ( encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" "github.com/grafana/grafana/pkg/services/export" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/grpcserver" grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context" "github.com/grafana/grafana/pkg/services/grpcserver/interceptors" @@ -308,12 +309,11 @@ var wireBasicSet = wire.NewSet( featuremgmt.ProvideManagerService, featuremgmt.ProvideToggles, dashboardservice.ProvideDashboardService, - dashboardservice.ProvideFolderService, dashboardstore.ProvideDashboardStore, + folderimpl.ProvideService, wire.Bind(new(dashboards.DashboardService), new(*dashboardservice.DashboardServiceImpl)), wire.Bind(new(dashboards.DashboardProvisioningService), new(*dashboardservice.DashboardServiceImpl)), wire.Bind(new(dashboards.PluginService), new(*dashboardservice.DashboardServiceImpl)), - wire.Bind(new(dashboards.FolderService), new(*dashboardservice.FolderServiceImpl)), wire.Bind(new(dashboards.Store), new(*dashboardstore.DashboardStore)), dashboardimportservice.ProvideService, wire.Bind(new(dashboardimport.Service), new(*dashboardimportservice.ImportDashboardService)), diff --git a/pkg/services/dashboards/folder_service_mock.go b/pkg/services/dashboards/folder_service_mock.go deleted file mode 100644 index aaa0499a496..00000000000 --- a/pkg/services/dashboards/folder_service_mock.go +++ /dev/null @@ -1,194 +0,0 @@ -// Code generated by mockery v2.12.1. DO NOT EDIT. - -package dashboards - -import ( - context "context" - - models "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/user" - mock "github.com/stretchr/testify/mock" - - testing "testing" -) - -// FakeFolderService is an autogenerated mock type for the FolderService type -type FakeFolderService struct { - mock.Mock -} - -// CreateFolder provides a mock function with given fields: ctx, user, orgID, title, uid -func (_m *FakeFolderService) CreateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, title string, uid string) (*models.Folder, error) { - ret := _m.Called(ctx, usr, orgID, title, uid) - - var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, string) *models.Folder); ok { - r0 = rf(ctx, usr, orgID, title, uid) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, string) error); ok { - r1 = rf(ctx, usr, orgID, title, uid) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteFolder provides a mock function with given fields: ctx, user, orgID, uid, forceDeleteRules -func (_m *FakeFolderService) DeleteFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { - ret := _m.Called(ctx, usr, orgID, uid, forceDeleteRules) - - var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, bool) *models.Folder); ok { - r0 = rf(ctx, usr, orgID, uid, forceDeleteRules) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, bool) error); ok { - r1 = rf(ctx, usr, orgID, uid, forceDeleteRules) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetFolderByID provides a mock function with given fields: ctx, user, id, orgID -func (_m *FakeFolderService) GetFolderByID(ctx context.Context, usr *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { - ret := _m.Called(ctx, usr, id, orgID) - - var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64) *models.Folder); ok { - r0 = rf(ctx, usr, id, orgID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64) error); ok { - r1 = rf(ctx, usr, id, orgID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetFolderByTitle provides a mock function with given fields: ctx, user, orgID, title -func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, usr *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { - ret := _m.Called(ctx, usr, orgID, title) - - var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok { - r0 = rf(ctx, usr, orgID, title) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok { - r1 = rf(ctx, usr, orgID, title) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetFolderByUID provides a mock function with given fields: ctx, user, orgID, uid -func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { - ret := _m.Called(ctx, usr, orgID, uid) - - var r0 *models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok { - r0 = rf(ctx, usr, orgID, uid) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok { - r1 = rf(ctx, usr, orgID, uid) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetFolders provides a mock function with given fields: ctx, user, orgID, limit, page -func (_m *FakeFolderService) GetFolders(ctx context.Context, usr *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { - ret := _m.Called(ctx, usr, orgID, limit, page) - - var r0 []*models.Folder - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64, int64) []*models.Folder); ok { - r0 = rf(ctx, usr, orgID, limit, page) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*models.Folder) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64, int64) error); ok { - r1 = rf(ctx, usr, orgID, limit, page) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MakeUserAdmin provides a mock function with given fields: ctx, orgID, userID, folderID, setViewAndEditPermissions -func (_m *FakeFolderService) MakeUserAdmin(ctx context.Context, orgID int64, userID int64, folderID int64, setViewAndEditPermissions bool) error { - ret := _m.Called(ctx, orgID, userID, folderID, setViewAndEditPermissions) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int64, int64, int64, bool) error); ok { - r0 = rf(ctx, orgID, userID, folderID, setViewAndEditPermissions) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// UpdateFolder provides a mock function with given fields: ctx, user, orgID, existingUid, cmd -func (_m *FakeFolderService) UpdateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { - ret := _m.Called(ctx, usr, orgID, existingUid, cmd) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, *models.UpdateFolderCommand) error); ok { - r0 = rf(ctx, usr, orgID, existingUid, cmd) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// NewFakeFolderService creates a new instance of FakeFolderService. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. -func NewFakeFolderService(t testing.TB) *FakeFolderService { - mock := &FakeFolderService{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/services/dashboards/folder.go b/pkg/services/folder/folder.go similarity index 82% rename from pkg/services/dashboards/folder.go rename to pkg/services/folder/folder.go index e52c2af3665..0ece68d59df 100644 --- a/pkg/services/dashboards/folder.go +++ b/pkg/services/folder/folder.go @@ -1,4 +1,4 @@ -package dashboards +package folder import ( "context" @@ -7,10 +7,8 @@ import ( "github.com/grafana/grafana/pkg/services/user" ) -// FolderService is a service for operating on folders. -// -//go:generate mockery --name FolderService --structname FakeFolderService --inpackage --filename folder_service_mock.go -type FolderService interface { +//go:generate mockery --name Service --structname FakeService --inpackage --filename foldertest/folder_service_mock.go +type Service interface { GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) diff --git a/pkg/services/dashboards/service/folder_service.go b/pkg/services/folder/folderimpl/folder.go similarity index 69% rename from pkg/services/dashboards/service/folder_service.go rename to pkg/services/folder/folderimpl/folder.go index 96367181242..5aff3238881 100644 --- a/pkg/services/dashboards/service/folder_service.go +++ b/pkg/services/folder/folderimpl/folder.go @@ -1,4 +1,4 @@ -package service +package folderimpl import ( "context" @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/search" @@ -19,7 +20,7 @@ import ( "github.com/grafana/grafana/pkg/setting" ) -type FolderServiceImpl struct { +type Service struct { log log.Logger cfg *setting.Cfg dashboardService dashboards.DashboardService @@ -32,15 +33,19 @@ type FolderServiceImpl struct { bus bus.Bus } -func ProvideFolderService( - cfg *setting.Cfg, dashboardService dashboards.DashboardService, dashboardStore dashboards.Store, - searchService *search.SearchService, features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService, - ac accesscontrol.AccessControl, bus bus.Bus, -) *FolderServiceImpl { +func ProvideService( + ac accesscontrol.AccessControl, + bus bus.Bus, + cfg *setting.Cfg, + dashboardService dashboards.DashboardService, + dashboardStore dashboards.Store, + features featuremgmt.FeatureToggles, + folderPermissionsService accesscontrol.FolderPermissionsService, + searchService *search.SearchService, +) folder.Service { ac.RegisterScopeAttributeResolver(dashboards.NewFolderNameScopeResolver(dashboardStore)) ac.RegisterScopeAttributeResolver(dashboards.NewFolderIDScopeResolver(dashboardStore)) - - return &FolderServiceImpl{ + return &Service{ cfg: cfg, log: log.New("folder-service"), dashboardService: dashboardService, @@ -52,7 +57,7 @@ func ProvideFolderService( } } -func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { +func (s *Service) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { searchQuery := search.Query{ SignedInUser: user, DashboardIds: make([]int64, 0), @@ -64,7 +69,7 @@ func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *user.SignedInU Page: page, } - if err := f.searchService.SearchHandler(ctx, &searchQuery); err != nil { + if err := s.searchService.SearchHandler(ctx, &searchQuery); err != nil { return nil, err } @@ -81,11 +86,11 @@ func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *user.SignedInU return folders, nil } -func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { +func (s *Service) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { if id == 0 { return &models.Folder{Id: id, Title: "General"}, nil } - dashFolder, err := f.dashboardStore.GetFolderByID(ctx, orgID, id) + dashFolder, err := s.dashboardStore.GetFolderByID(ctx, orgID, id) if err != nil { return nil, err } @@ -101,8 +106,8 @@ func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *user.Signed return dashFolder, nil } -func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { - dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid) +func (s *Service) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { + dashFolder, err := s.dashboardStore.GetFolderByUID(ctx, orgID, uid) if err != nil { return nil, err } @@ -118,8 +123,8 @@ func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *user.Signe return dashFolder, nil } -func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { - dashFolder, err := f.dashboardStore.GetFolderByTitle(ctx, orgID, title) +func (s *Service) GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { + dashFolder, err := s.dashboardStore.GetFolderByTitle(ctx, orgID, title) if err != nil { return nil, err } @@ -135,7 +140,7 @@ func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *user.Sig return dashFolder, nil } -func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) { +func (s *Service) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) { dashFolder := models.NewDashboardFolder(title) dashFolder.OrgId = orgID @@ -159,24 +164,24 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedI User: user, } - saveDashboardCmd, err := f.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false) + saveDashboardCmd, err := s.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false) if err != nil { return nil, toFolderError(err) } - dash, err := f.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd) + dash, err := s.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd) if err != nil { return nil, toFolderError(err) } var folder *models.Folder - folder, err = f.dashboardStore.GetFolderByID(ctx, orgID, dash.Id) + folder, err = s.dashboardStore.GetFolderByID(ctx, orgID, dash.Id) if err != nil { return nil, err } var permissionErr error - if !accesscontrol.IsDisabled(f.cfg) { + if !accesscontrol.IsDisabled(s.cfg) { var permissions []accesscontrol.SetResourcePermissionCommand if user.IsRealUser() && !user.IsAnonymous { permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ @@ -189,21 +194,21 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedI {BuiltinRole: string(org.RoleViewer), Permission: models.PERMISSION_VIEW.String()}, }...) - _, permissionErr = f.permissions.SetPermissions(ctx, orgID, folder.Uid, permissions...) - } else if f.cfg.EditorsCanAdmin && user.IsRealUser() && !user.IsAnonymous { - permissionErr = f.MakeUserAdmin(ctx, orgID, userID, folder.Id, true) + _, permissionErr = s.permissions.SetPermissions(ctx, orgID, folder.Uid, permissions...) + } else if s.cfg.EditorsCanAdmin && user.IsRealUser() && !user.IsAnonymous { + permissionErr = s.MakeUserAdmin(ctx, orgID, userID, folder.Id, true) } if permissionErr != nil { - f.log.Error("Could not make user admin", "folder", folder.Title, "user", userID, "error", permissionErr) + s.log.Error("Could not make user admin", "folder", folder.Title, "user", userID, "error", permissionErr) } return folder, nil } -func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { +func (s *Service) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid} - if _, err := f.dashboardStore.GetDashboard(ctx, &query); err != nil { + if _, err := s.dashboardStore.GetDashboard(ctx, &query); err != nil { return toFolderError(err) } @@ -223,40 +228,40 @@ func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *user.SignedI Overwrite: cmd.Overwrite, } - saveDashboardCmd, err := f.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false) + saveDashboardCmd, err := s.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false) if err != nil { return toFolderError(err) } - dash, err := f.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd) + dash, err := s.dashboardStore.SaveDashboard(ctx, *saveDashboardCmd) if err != nil { return toFolderError(err) } var folder *models.Folder - folder, err = f.dashboardStore.GetFolderByID(ctx, orgID, dash.Id) + folder, err = s.dashboardStore.GetFolderByID(ctx, orgID, dash.Id) if err != nil { return err } cmd.Result = folder if currentTitle != folder.Title { - if err := f.bus.Publish(ctx, &events.FolderTitleUpdated{ + if err := s.bus.Publish(ctx, &events.FolderTitleUpdated{ Timestamp: folder.Updated, Title: folder.Title, ID: dash.Id, UID: dash.Uid, OrgID: orgID, }); err != nil { - f.log.Error("failed to publish FolderTitleUpdated event", "folder", folder.Title, "user", user.UserID, "error", err) + s.log.Error("failed to publish FolderTitleUpdated event", "folder", folder.Title, "user", user.UserID, "error", err) } } return nil } -func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { - dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid) +func (s *Service) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { + dashFolder, err := s.dashboardStore.GetFolderByUID(ctx, orgID, uid) if err != nil { return nil, err } @@ -271,15 +276,15 @@ func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *user.SignedI deleteCmd := models.DeleteDashboardCommand{OrgId: orgID, Id: dashFolder.Id, ForceDeleteFolderRules: forceDeleteRules} - if err := f.dashboardStore.DeleteDashboard(ctx, &deleteCmd); err != nil { + if err := s.dashboardStore.DeleteDashboard(ctx, &deleteCmd); err != nil { return nil, toFolderError(err) } return dashFolder, nil } -func (f *FolderServiceImpl) MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error { - return f.dashboardService.MakeUserAdmin(ctx, orgID, userID, folderID, setViewAndEditPermissions) +func (s *Service) MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error { + return s.dashboardService.MakeUserAdmin(ctx, orgID, userID, folderID, setViewAndEditPermissions) } func toFolderError(err error) error { diff --git a/pkg/services/dashboards/service/folder_service_test.go b/pkg/services/folder/folderimpl/folder_test.go similarity index 96% rename from pkg/services/dashboards/service/folder_service_test.go rename to pkg/services/folder/folderimpl/folder_test.go index e6277e82b47..8457ae55465 100644 --- a/pkg/services/dashboards/service/folder_service_test.go +++ b/pkg/services/folder/folderimpl/folder_test.go @@ -1,4 +1,4 @@ -package service +package folderimpl import ( "context" @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/models" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/dashboards" + dashboardsvc "github.com/grafana/grafana/pkg/services/dashboards/service" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/user" @@ -32,7 +33,7 @@ func TestIntegrationProvideFolderService(t *testing.T) { cfg := setting.NewCfg() ac := acmock.New() - ProvideFolderService(cfg, nil, nil, nil, nil, nil, ac, busmock.New()) + ProvideService(ac, busmock.New(), cfg, nil, nil, nil, nil, nil) require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2) }) @@ -50,9 +51,9 @@ func TestIntegrationFolderService(t *testing.T) { cfg.IsFeatureToggleEnabled = features.IsEnabled folderPermissions := acmock.NewMockedPermissionsService() dashboardPermissions := acmock.NewMockedPermissionsService() - dashboardService := ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions, acmock.New()) + dashboardService := dashboardsvc.ProvideDashboardService(cfg, store, nil, features, folderPermissions, dashboardPermissions, acmock.New()) - service := FolderServiceImpl{ + service := &Service{ cfg: cfg, log: log.New("test-folder-service"), dashboardService: dashboardService, diff --git a/pkg/services/folder/foldertest/foldertest.go b/pkg/services/folder/foldertest/foldertest.go new file mode 100644 index 00000000000..f58d1c97a18 --- /dev/null +++ b/pkg/services/folder/foldertest/foldertest.go @@ -0,0 +1,40 @@ +package foldertest + +import ( + "context" + + "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/user" +) + +type FakeService struct { + ExpectedFolders []*models.Folder + ExpectedFolder *models.Folder + ExpectedError error +} + +func (s *FakeService) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) { + return s.ExpectedFolders, s.ExpectedError +} +func (s *FakeService) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) { + return s.ExpectedFolder, s.ExpectedError +} +func (s *FakeService) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) { + return s.ExpectedFolder, s.ExpectedError +} +func (s *FakeService) GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) { + return s.ExpectedFolder, s.ExpectedError +} +func (s *FakeService) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) { + return s.ExpectedFolder, s.ExpectedError +} +func (s *FakeService) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error { + cmd.Result = s.ExpectedFolder + return s.ExpectedError +} +func (s *FakeService) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) { + return s.ExpectedFolder, s.ExpectedError +} +func (s *FakeService) MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error { + return s.ExpectedError +} diff --git a/pkg/services/libraryelements/libraryelements.go b/pkg/services/libraryelements/libraryelements.go index 5cdfc76023f..10c09afbe9e 100644 --- a/pkg/services/libraryelements/libraryelements.go +++ b/pkg/services/libraryelements/libraryelements.go @@ -5,13 +5,13 @@ import ( "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) -func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister routing.RouteRegister, folderService dashboards.FolderService) *LibraryElementService { +func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister routing.RouteRegister, folderService folder.Service) *LibraryElementService { l := &LibraryElementService{ Cfg: cfg, SQLStore: sqlStore, @@ -38,7 +38,7 @@ type LibraryElementService struct { Cfg *setting.Cfg SQLStore *sqlstore.SQLStore RouteRegister routing.RouteRegister - folderService dashboards.FolderService + folderService folder.Service log log.Logger } diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index 4d755fafa2a..881d87f5df4 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -22,6 +22,7 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards/database" dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/sqlstore" @@ -308,10 +309,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac, ) - s := dashboardservice.ProvideFolderService( - cfg, d, dashboardStore, nil, - features, folderPermissions, ac, busmock.New(), - ) + s := folderimpl.ProvideService(ac, busmock.New(), cfg, d, dashboardStore, features, folderPermissions, nil) t.Logf("Creating folder with title and UID %q", title) folder, err := s.CreateFolder(context.Background(), &user, user.OrgID, title, title) require.NoError(t, err) @@ -419,12 +417,9 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo ) guardian.InitLegacyGuardian(sqlStore, dashboardService, &teamtest.FakeService{}) service := LibraryElementService{ - Cfg: sqlStore.Cfg, - SQLStore: sqlStore, - folderService: dashboardservice.ProvideFolderService( - sqlStore.Cfg, dashboardService, dashboardStore, nil, - features, folderPermissions, ac, busmock.New(), - ), + Cfg: sqlStore.Cfg, + SQLStore: sqlStore, + folderService: folderimpl.ProvideService(ac, busmock.New(), sqlStore.Cfg, dashboardService, dashboardStore, features, folderPermissions, nil), } usr := user.SignedInUser{ diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index 5f757bfd8be..c9306f64bcb 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/services/dashboards/database" dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/libraryelements" "github.com/grafana/grafana/pkg/services/org" @@ -1406,7 +1407,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string dashboardPermissions := acmock.NewMockedPermissionsService() dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg)) d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, folderPermissions, dashboardPermissions, ac) - s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, folderPermissions, ac, busmock.New()) + s := folderimpl.ProvideService(ac, busmock.New(), cfg, d, dashboardStore, features, folderPermissions, nil) t.Logf("Creating folder with title and UID %q", title) folder, err := s.CreateFolder(context.Background(), user, user.OrgID, title, title) @@ -1508,10 +1509,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo cfg, dashboardStore, &alerting.DashAlertExtractorService{}, features, folderPermissions, dashboardPermissions, ac, ) - folderService := dashboardservice.ProvideFolderService( - cfg, dashboardService, dashboardStore, nil, - features, folderPermissions, ac, busmock.New(), - ) + folderService := folderimpl.ProvideService(ac, busmock.New(), cfg, dashboardService, dashboardStore, features, folderPermissions, nil) elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService) service := LibraryPanelService{ diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index d0aade7bc43..6fb99398784 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -20,6 +20,7 @@ import ( "github.com/grafana/grafana/pkg/services/datasourceproxy" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/ngalert/api" "github.com/grafana/grafana/pkg/services/ngalert/eval" "github.com/grafana/grafana/pkg/services/ngalert/image" @@ -54,7 +55,7 @@ func ProvideService( secretsService secrets.Service, notificationService notifications.Service, m *metrics.NGAlert, - folderService dashboards.FolderService, + folderService folder.Service, ac accesscontrol.AccessControl, dashboardService dashboards.DashboardService, renderService rendering.Service, @@ -117,7 +118,7 @@ type AlertNG struct { imageService image.ImageService schedule schedule.ScheduleService stateManager *state.Manager - folderService dashboards.FolderService + folderService folder.Service dashboardService dashboards.DashboardService // Alerting notification services diff --git a/pkg/services/ngalert/store/database.go b/pkg/services/ngalert/store/database.go index 99632f1b8ad..c62c0a85348 100644 --- a/pkg/services/ngalert/store/database.go +++ b/pkg/services/ngalert/store/database.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/setting" @@ -34,13 +35,13 @@ type DBstore struct { FeatureToggles featuremgmt.FeatureToggles SQLStore *sqlstore.SQLStore Logger log.Logger - FolderService dashboards.FolderService + FolderService folder.Service AccessControl accesscontrol.AccessControl DashboardService dashboards.DashboardService } func ProvideDBStore( - cfg *setting.Cfg, featureToggles featuremgmt.FeatureToggles, sqlstore *sqlstore.SQLStore, folderService dashboards.FolderService, + cfg *setting.Cfg, featureToggles featuremgmt.FeatureToggles, sqlstore *sqlstore.SQLStore, folderService folder.Service, access accesscontrol.AccessControl, dashboards dashboards.DashboardService) *DBstore { return &DBstore{ Cfg: cfg.UnifiedAlerting, diff --git a/pkg/services/ngalert/tests/util.go b/pkg/services/ngalert/tests/util.go index fef92b40f03..6d60a2107fa 100644 --- a/pkg/services/ngalert/tests/util.go +++ b/pkg/services/ngalert/tests/util.go @@ -20,6 +20,7 @@ import ( databasestore "github.com/grafana/grafana/pkg/services/dashboards/database" dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/folder/folderimpl" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/ngalert" "github.com/grafana/grafana/pkg/services/ngalert/metrics" @@ -88,10 +89,7 @@ func SetupTestEnv(tb testing.TB, baseInterval time.Duration) (*ngalert.AlertNG, ) bus := busmock.New() - folderService := dashboardservice.ProvideFolderService( - cfg, dashboardService, dashboardStore, nil, - features, folderPermissions, ac, bus, - ) + folderService := folderimpl.ProvideService(ac, bus, cfg, dashboardService, dashboardStore, features, folderPermissions, nil) ng, err := ngalert.ProvideService( cfg, &FakeFeatures{}, nil, nil, routing.NewRouteRegister(), sqlStore, nil, nil, nil, nil, diff --git a/pkg/services/provisioning/provisioning.go b/pkg/services/provisioning/provisioning.go index 1edbcbc8176..322ab02f517 100644 --- a/pkg/services/provisioning/provisioning.go +++ b/pkg/services/provisioning/provisioning.go @@ -15,6 +15,7 @@ import ( dashboardservice "github.com/grafana/grafana/pkg/services/dashboards" datasourceservice "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/encryption" + "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/store" "github.com/grafana/grafana/pkg/services/notifications" @@ -44,7 +45,7 @@ func ProvideService( datasourceService datasourceservice.DataSourceService, correlationsService correlations.Service, dashboardService dashboardservice.DashboardService, - folderService dashboardservice.FolderService, + folderService folder.Service, alertingService *alerting.AlertNotificationService, pluginSettings pluginsettings.Service, searchService searchV2.SearchService,