Add functions used for restore to existing service-level handlers (#4687)
This continues the push towards having service-level handlers that know how to perform different operations. It adds the helper functions that will be used during restore operations to the existing handler code This logic is not currently used nor does this PR change the restore call path --- #### Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No #### Type of change - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Supportability/Tests - [ ] 💻 CI/Deployment - [x] 🧹 Tech Debt/Cleanup #### Issue(s) * #4254 #### Test Plan - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
dbdd3f236c
commit
51f44c2988
@ -21,13 +21,13 @@ func (ctrl *Controller) NewServiceHandler(
|
||||
|
||||
switch service {
|
||||
case path.OneDriveService:
|
||||
return onedrive.NewOneDriveHandler(opts), nil
|
||||
return onedrive.NewOneDriveHandler(opts, ctrl.AC, ctrl.resourceHandler), nil
|
||||
|
||||
case path.SharePointService:
|
||||
return sharepoint.NewSharePointHandler(opts), nil
|
||||
return sharepoint.NewSharePointHandler(opts, ctrl.AC, ctrl.resourceHandler), nil
|
||||
|
||||
case path.GroupsService:
|
||||
return groups.NewGroupsHandler(opts), nil
|
||||
return groups.NewGroupsHandler(opts, ctrl.AC, ctrl.resourceHandler), nil
|
||||
}
|
||||
|
||||
return nil, clues.New("unrecognized service").
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
package resource
|
||||
|
||||
import "github.com/alcionai/clues"
|
||||
|
||||
var ErrNoResourceLookup = clues.New("missing resource lookup client")
|
||||
|
||||
type Category string
|
||||
|
||||
const (
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/groups"
|
||||
"github.com/alcionai/corso/src/internal/m365/resource"
|
||||
"github.com/alcionai/corso/src/internal/operations/inject"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
@ -17,20 +18,33 @@ import (
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
var _ inject.ServiceHandler = &baseGroupsHandler{}
|
||||
var _ inject.ServiceHandler = &groupsHandler{}
|
||||
|
||||
func NewGroupsHandler(
|
||||
opts control.Options,
|
||||
) *baseGroupsHandler {
|
||||
return &baseGroupsHandler{
|
||||
apiClient api.Client,
|
||||
resourceGetter idname.GetResourceIDAndNamer,
|
||||
) *groupsHandler {
|
||||
return &groupsHandler{
|
||||
baseGroupsHandler: baseGroupsHandler{
|
||||
opts: opts,
|
||||
backupDriveIDNames: idname.NewCache(nil),
|
||||
backupSiteIDWebURL: idname.NewCache(nil),
|
||||
},
|
||||
apiClient: apiClient,
|
||||
resourceGetter: resourceGetter,
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================== //
|
||||
// baseGroupsHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// baseGroupsHandler contains logic for tracking data and doing operations
|
||||
// (e.x. export) that don't require contact with external M356 services.
|
||||
type baseGroupsHandler struct {
|
||||
opts control.Options
|
||||
|
||||
@ -134,3 +148,39 @@ func (h *baseGroupsHandler) ProduceExportCollections(
|
||||
|
||||
return ec, el.Failure()
|
||||
}
|
||||
|
||||
// ========================================================================== //
|
||||
// groupsHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// groupsHandler contains logic for handling data and performing operations
|
||||
// (e.x. restore) regardless of whether they require contact with external M365
|
||||
// services or not.
|
||||
type groupsHandler struct {
|
||||
baseGroupsHandler
|
||||
apiClient api.Client
|
||||
resourceGetter idname.GetResourceIDAndNamer
|
||||
}
|
||||
|
||||
func (h *groupsHandler) IsServiceEnabled(
|
||||
ctx context.Context,
|
||||
resourceID string,
|
||||
) (bool, error) {
|
||||
// TODO(ashmrtn): Move free function implementation to this function.
|
||||
res, err := IsServiceEnabled(ctx, h.apiClient.Groups(), resourceID)
|
||||
return res, clues.Stack(err).OrNil()
|
||||
}
|
||||
|
||||
func (h *groupsHandler) PopulateProtectedResourceIDAndName(
|
||||
ctx context.Context,
|
||||
resourceID string, // Can be either ID or name.
|
||||
ins idname.Cacher,
|
||||
) (idname.Provider, error) {
|
||||
if h.resourceGetter == nil {
|
||||
return nil, clues.StackWC(ctx, resource.ErrNoResourceLookup)
|
||||
}
|
||||
|
||||
pr, err := h.resourceGetter.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
|
||||
return pr, clues.Wrap(err, "identifying resource owner").OrNil()
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"github.com/alcionai/corso/src/pkg/export"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
type ExportUnitSuite struct {
|
||||
@ -96,7 +97,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_messages() {
|
||||
|
||||
stats := data.ExportStats{}
|
||||
|
||||
ecs, err := NewGroupsHandler(control.DefaultOptions()).
|
||||
ecs, err := NewGroupsHandler(control.DefaultOptions(), api.Client{}, nil).
|
||||
ProduceExportCollections(
|
||||
ctx,
|
||||
int(version.Backup),
|
||||
@ -196,7 +197,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections_libraries() {
|
||||
},
|
||||
}
|
||||
|
||||
handler := NewGroupsHandler(control.DefaultOptions())
|
||||
handler := NewGroupsHandler(control.DefaultOptions(), api.Client{}, nil)
|
||||
handler.CacheItemInfo(dii)
|
||||
|
||||
stats := data.ExportStats{}
|
||||
|
||||
@ -5,35 +5,58 @@ import (
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive"
|
||||
"github.com/alcionai/corso/src/internal/m365/resource"
|
||||
"github.com/alcionai/corso/src/internal/operations/inject"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
"github.com/alcionai/corso/src/pkg/export"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
var _ inject.ServiceHandler = &baseOnedriveHandler{}
|
||||
var _ inject.ServiceHandler = &onedriveHandler{}
|
||||
|
||||
func NewOneDriveHandler(
|
||||
opts control.Options,
|
||||
) *baseOnedriveHandler {
|
||||
return &baseOnedriveHandler{
|
||||
apiClient api.Client,
|
||||
resourceGetter idname.GetResourceIDAndNamer,
|
||||
) *onedriveHandler {
|
||||
return &onedriveHandler{
|
||||
baseOneDriveHandler: baseOneDriveHandler{
|
||||
opts: opts,
|
||||
backupDriveIDNames: idname.NewCache(nil),
|
||||
},
|
||||
apiClient: apiClient,
|
||||
resourceGetter: resourceGetter,
|
||||
}
|
||||
}
|
||||
|
||||
type baseOnedriveHandler struct {
|
||||
// ========================================================================== //
|
||||
// baseOneDriveHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// baseOneDriveHandler contains logic for tracking data and doing operations
|
||||
// (e.x. export) that don't require contact with external M356 services.
|
||||
type baseOneDriveHandler struct {
|
||||
opts control.Options
|
||||
backupDriveIDNames idname.CacheBuilder
|
||||
}
|
||||
|
||||
func (h *baseOnedriveHandler) CacheItemInfo(v details.ItemInfo) {}
|
||||
func (h *baseOneDriveHandler) CacheItemInfo(v details.ItemInfo) {
|
||||
if v.OneDrive == nil {
|
||||
return
|
||||
}
|
||||
|
||||
h.backupDriveIDNames.Add(v.OneDrive.DriveID, v.OneDrive.DriveName)
|
||||
}
|
||||
|
||||
// ProduceExportCollections will create the export collections for the
|
||||
// given restore collections.
|
||||
func (h *baseOnedriveHandler) ProduceExportCollections(
|
||||
func (h *baseOneDriveHandler) ProduceExportCollections(
|
||||
ctx context.Context,
|
||||
backupVersion int,
|
||||
exportCfg control.ExportConfig,
|
||||
@ -65,3 +88,39 @@ func (h *baseOnedriveHandler) ProduceExportCollections(
|
||||
|
||||
return ec, el.Failure()
|
||||
}
|
||||
|
||||
// ========================================================================== //
|
||||
// onedriveHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// onedriveHandler contains logic for handling data and performing operations
|
||||
// (e.x. restore) regardless of whether they require contact with external M365
|
||||
// services or not.
|
||||
type onedriveHandler struct {
|
||||
baseOneDriveHandler
|
||||
apiClient api.Client
|
||||
resourceGetter idname.GetResourceIDAndNamer
|
||||
}
|
||||
|
||||
func (h *onedriveHandler) IsServiceEnabled(
|
||||
ctx context.Context,
|
||||
resourceID string,
|
||||
) (bool, error) {
|
||||
// TODO(ashmrtn): Move free function implementation to this function.
|
||||
res, err := IsServiceEnabled(ctx, h.apiClient.Users(), resourceID)
|
||||
return res, clues.Stack(err).OrNil()
|
||||
}
|
||||
|
||||
func (h *onedriveHandler) PopulateProtectedResourceIDAndName(
|
||||
ctx context.Context,
|
||||
resourceID string, // Can be either ID or name.
|
||||
ins idname.Cacher,
|
||||
) (idname.Provider, error) {
|
||||
if h.resourceGetter == nil {
|
||||
return nil, clues.StackWC(ctx, resource.ErrNoResourceLookup)
|
||||
}
|
||||
|
||||
pr, err := h.resourceGetter.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
|
||||
return pr, clues.Wrap(err, "identifying resource owner").OrNil()
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"github.com/alcionai/corso/src/pkg/export"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
type ExportUnitSuite struct {
|
||||
@ -341,7 +342,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections() {
|
||||
|
||||
stats := data.ExportStats{}
|
||||
|
||||
ecs, err := NewOneDriveHandler(control.DefaultOptions()).
|
||||
ecs, err := NewOneDriveHandler(control.DefaultOptions(), api.Client{}, nil).
|
||||
ProduceExportCollections(
|
||||
ctx,
|
||||
int(version.Backup),
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/common/idname"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/internal/m365/collection/drive"
|
||||
"github.com/alcionai/corso/src/internal/m365/resource"
|
||||
"github.com/alcionai/corso/src/internal/operations/inject"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/control"
|
||||
@ -15,25 +16,38 @@ import (
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
var _ inject.ServiceHandler = &baseSharepointHandler{}
|
||||
var _ inject.ServiceHandler = &sharepointHandler{}
|
||||
|
||||
func NewSharePointHandler(
|
||||
opts control.Options,
|
||||
) *baseSharepointHandler {
|
||||
return &baseSharepointHandler{
|
||||
apiClient api.Client,
|
||||
resourceGetter idname.GetResourceIDAndNamer,
|
||||
) *sharepointHandler {
|
||||
return &sharepointHandler{
|
||||
baseSharePointHandler: baseSharePointHandler{
|
||||
opts: opts,
|
||||
backupDriveIDNames: idname.NewCache(nil),
|
||||
},
|
||||
apiClient: apiClient,
|
||||
resourceGetter: resourceGetter,
|
||||
}
|
||||
}
|
||||
|
||||
type baseSharepointHandler struct {
|
||||
// ========================================================================== //
|
||||
// baseSharePointHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// baseSharePointHandler contains logic for tracking data and doing operations
|
||||
// (e.x. export) that don't require contact with external M356 services.
|
||||
type baseSharePointHandler struct {
|
||||
opts control.Options
|
||||
backupDriveIDNames idname.CacheBuilder
|
||||
}
|
||||
|
||||
func (h *baseSharepointHandler) CacheItemInfo(v details.ItemInfo) {
|
||||
func (h *baseSharePointHandler) CacheItemInfo(v details.ItemInfo) {
|
||||
// Old versions would store SharePoint data as OneDrive.
|
||||
switch {
|
||||
case v.SharePoint != nil:
|
||||
@ -46,7 +60,7 @@ func (h *baseSharepointHandler) CacheItemInfo(v details.ItemInfo) {
|
||||
|
||||
// ProduceExportCollections will create the export collections for the
|
||||
// given restore collections.
|
||||
func (h *baseSharepointHandler) ProduceExportCollections(
|
||||
func (h *baseSharePointHandler) ProduceExportCollections(
|
||||
ctx context.Context,
|
||||
backupVersion int,
|
||||
exportCfg control.ExportConfig,
|
||||
@ -88,3 +102,39 @@ func (h *baseSharepointHandler) ProduceExportCollections(
|
||||
|
||||
return ec, el.Failure()
|
||||
}
|
||||
|
||||
// ========================================================================== //
|
||||
// sharepointHandler
|
||||
// ========================================================================== //
|
||||
|
||||
// sharepointHandler contains logic for handling data and performing operations
|
||||
// (e.x. restore) regardless of whether they require contact with external M365
|
||||
// services or not.
|
||||
type sharepointHandler struct {
|
||||
baseSharePointHandler
|
||||
apiClient api.Client
|
||||
resourceGetter idname.GetResourceIDAndNamer
|
||||
}
|
||||
|
||||
func (h *sharepointHandler) IsServiceEnabled(
|
||||
ctx context.Context,
|
||||
resourceID string,
|
||||
) (bool, error) {
|
||||
// TODO(ashmrtn): Move free function implementation to this function.
|
||||
res, err := IsServiceEnabled(ctx, h.apiClient.Sites(), resourceID)
|
||||
return res, clues.Stack(err).OrNil()
|
||||
}
|
||||
|
||||
func (h *sharepointHandler) PopulateProtectedResourceIDAndName(
|
||||
ctx context.Context,
|
||||
resourceID string, // Can be either ID or name.
|
||||
ins idname.Cacher,
|
||||
) (idname.Provider, error) {
|
||||
if h.resourceGetter == nil {
|
||||
return nil, clues.StackWC(ctx, resource.ErrNoResourceLookup)
|
||||
}
|
||||
|
||||
pr, err := h.resourceGetter.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
|
||||
return pr, clues.Wrap(err, "identifying resource owner").OrNil()
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"github.com/alcionai/corso/src/pkg/export"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
"github.com/alcionai/corso/src/pkg/services/m365/api"
|
||||
)
|
||||
|
||||
type ExportUnitSuite struct {
|
||||
@ -125,7 +126,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections() {
|
||||
},
|
||||
}
|
||||
|
||||
handler := NewSharePointHandler(control.DefaultOptions())
|
||||
handler := NewSharePointHandler(control.DefaultOptions(), api.Client{}, nil)
|
||||
handler.CacheItemInfo(test.itemInfo)
|
||||
|
||||
stats := data.ExportStats{}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user