Use path prefixes for backup paths (#4155)

<!-- PR description-->

---

#### 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

<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
* https://github.com/alcionai/corso/issues/4154

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Abin Simon 2023-08-31 12:04:13 +05:30 committed by GitHub
parent 2c4cd663d1
commit 91e4f455b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 177 additions and 97 deletions

View File

@ -182,9 +182,9 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
folderPath, err := pb.ToDataLayerOneDrivePath("tenant", "owner", false) folderPath, err := pb.ToDataLayerOneDrivePath("tenant", "owner", false)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
if test.service == path.SharePointService { if test.service == path.SharePointService {
mbh = mock.DefaultSharePointBH() mbh = mock.DefaultSharePointBH("a-site")
mbh.ItemInfo.SharePoint.Modified = now mbh.ItemInfo.SharePoint.Modified = now
mbh.ItemInfo.SharePoint.ItemName = stubItemName mbh.ItemInfo.SharePoint.ItemName = stubItemName
} else { } else {
@ -301,7 +301,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadError() {
folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false) folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.GI = mock.GetsItem{Err: assert.AnError} mbh.GI = mock.GetsItem{Err: assert.AnError}
mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()} mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()}
mbh.GetResps = []*http.Response{ mbh.GetResps = []*http.Response{
@ -378,7 +378,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadUnauthorizedErrorRetry()
folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false) folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false)
require.NoError(t, err) require.NoError(t, err)
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.GI = mock.GetsItem{Item: stubItem} mbh.GI = mock.GetsItem{Item: stubItem}
mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()} mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()}
mbh.GetResps = []*http.Response{ mbh.GetResps = []*http.Response{
@ -436,7 +436,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTim
folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false) folderPath, err := pb.ToDataLayerOneDrivePath("a-tenant", "a-user", false)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.ItemInfo = details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: "fakeName", Modified: time.Now()}} mbh.ItemInfo = details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: "fakeName", Modified: time.Now()}}
mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()} mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()}
mbh.GetResps = []*http.Response{{ mbh.GetResps = []*http.Response{{
@ -587,7 +587,7 @@ func (suite *GetDriveItemUnitTestSuite) TestGetDriveItem_error() {
true, true,
false) false)
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.GI = mock.GetsItem{Item: stubItem} mbh.GI = mock.GetsItem{Item: stubItem}
mbh.GetResps = []*http.Response{{StatusCode: http.StatusOK}} mbh.GetResps = []*http.Response{{StatusCode: http.StatusOK}}
mbh.GetErrs = []error{test.err} mbh.GetErrs = []error{test.err}
@ -766,7 +766,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
} }
} }
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.GI = test.mgi mbh.GI = test.mgi
mbh.ItemInfo = test.itemInfo mbh.ItemInfo = test.itemInfo
mbh.GetResps = resps mbh.GetResps = resps
@ -932,7 +932,7 @@ func (suite *CollectionUnitTestSuite) TestItemExtensions() {
wg.Add(1) wg.Add(1)
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.GI = mock.GetsItem{Err: assert.AnError} mbh.GI = mock.GetsItem{Err: assert.AnError}
mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()} mbh.GIP = mock.GetsItemPermission{Perm: models.NewPermissionCollectionResponse()}
mbh.GetResps = []*http.Response{ mbh.GetResps = []*http.Response{

View File

@ -349,7 +349,7 @@ func (c *Collections) Get(
continue continue
} }
p, err := c.handler.CanonicalPath(odConsts.DriveFolderPrefixBuilder(driveID), c.tenantID, c.resourceOwner) p, err := c.handler.CanonicalPath(odConsts.DriveFolderPrefixBuilder(driveID), c.tenantID)
if err != nil { if err != nil {
return nil, false, clues.Wrap(err, "making exclude prefix").WithClues(ictx) return nil, false, clues.Wrap(err, "making exclude prefix").WithClues(ictx)
} }
@ -413,7 +413,7 @@ func (c *Collections) Get(
// generate tombstones for drives that were removed. // generate tombstones for drives that were removed.
for driveID := range driveTombstones { for driveID := range driveTombstones {
prevDrivePath, err := c.handler.PathPrefix(c.tenantID, c.resourceOwner, driveID) prevDrivePath, err := c.handler.PathPrefix(c.tenantID, driveID)
if err != nil { if err != nil {
return nil, false, clues.Wrap(err, "making drive tombstone for previous path").WithClues(ctx) return nil, false, clues.Wrap(err, "making drive tombstone for previous path").WithClues(ctx)
} }
@ -642,7 +642,7 @@ func (c *Collections) getCollectionPath(
pb = path.Builder{}.Append(path.Split(ptr.Val(item.GetParentReference().GetPath()))...) pb = path.Builder{}.Append(path.Split(ptr.Val(item.GetParentReference().GetPath()))...)
} }
collectionPath, err := c.handler.CanonicalPath(pb, c.tenantID, c.resourceOwner) collectionPath, err := c.handler.CanonicalPath(pb, c.tenantID)
if err != nil { if err != nil {
return nil, clues.Wrap(err, "making item path") return nil, clues.Wrap(err, "making item path")
} }

View File

@ -40,7 +40,7 @@ type statePath struct {
func getExpectedStatePathGenerator( func getExpectedStatePathGenerator(
t *testing.T, t *testing.T,
bh BackupHandler, bh BackupHandler,
tenant, user, base string, tenant, base string,
) func(data.CollectionState, ...string) statePath { ) func(data.CollectionState, ...string) statePath {
return func(state data.CollectionState, pths ...string) statePath { return func(state data.CollectionState, pths ...string) statePath {
var ( var (
@ -56,12 +56,12 @@ func getExpectedStatePathGenerator(
} else { } else {
require.Len(t, pths, 2, "invalid number of paths to getExpectedStatePathGenerator") require.Len(t, pths, 2, "invalid number of paths to getExpectedStatePathGenerator")
pb := path.Builder{}.Append(path.Split(base + pths[1])...) pb := path.Builder{}.Append(path.Split(base + pths[1])...)
p2, err = bh.CanonicalPath(pb, tenant, user) p2, err = bh.CanonicalPath(pb, tenant)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
} }
pb := path.Builder{}.Append(path.Split(base + pths[0])...) pb := path.Builder{}.Append(path.Split(base + pths[0])...)
p1, err = bh.CanonicalPath(pb, tenant, user) p1, err = bh.CanonicalPath(pb, tenant)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
switch state { switch state {
@ -88,11 +88,11 @@ func getExpectedStatePathGenerator(
func getExpectedPathGenerator( func getExpectedPathGenerator(
t *testing.T, t *testing.T,
bh BackupHandler, bh BackupHandler,
tenant, user, base string, tenant, base string,
) func(string) string { ) func(string) string {
return func(p string) string { return func(p string) string {
pb := path.Builder{}.Append(path.Split(base + p)...) pb := path.Builder{}.Append(path.Split(base + p)...)
cp, err := bh.CanonicalPath(pb, tenant, user) cp, err := bh.CanonicalPath(pb, tenant)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
return cp.String() return cp.String()
@ -129,10 +129,10 @@ func (suite *OneDriveCollectionsUnitSuite) TestUpdateCollections() {
pkg = "/package" pkg = "/package"
) )
bh := itemBackupHandler{} bh := itemBackupHandler{userID: user}
testBaseDrivePath := odConsts.DriveFolderPrefixBuilder("driveID1").String() testBaseDrivePath := odConsts.DriveFolderPrefixBuilder("driveID1").String()
expectedPath := getExpectedPathGenerator(suite.T(), bh, tenant, user, testBaseDrivePath) expectedPath := getExpectedPathGenerator(suite.T(), bh, tenant, testBaseDrivePath)
expectedStatePath := getExpectedStatePathGenerator(suite.T(), bh, tenant, user, testBaseDrivePath) expectedStatePath := getExpectedStatePathGenerator(suite.T(), bh, tenant, testBaseDrivePath)
tests := []struct { tests := []struct {
testCase string testCase string
@ -744,7 +744,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestUpdateCollections() {
maps.Copy(outputFolderMap, tt.inputFolderMap) maps.Copy(outputFolderMap, tt.inputFolderMap)
c := NewCollections( c := NewCollections(
&itemBackupHandler{api.Drives{}, tt.scope}, &itemBackupHandler{api.Drives{}, user, tt.scope},
tenant, tenant,
user, user,
nil, nil,
@ -1208,13 +1208,13 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
drive2.SetName(&driveID2) drive2.SetName(&driveID2)
var ( var (
bh = itemBackupHandler{} bh = itemBackupHandler{userID: user}
driveBasePath1 = odConsts.DriveFolderPrefixBuilder(driveID1).String() driveBasePath1 = odConsts.DriveFolderPrefixBuilder(driveID1).String()
driveBasePath2 = odConsts.DriveFolderPrefixBuilder(driveID2).String() driveBasePath2 = odConsts.DriveFolderPrefixBuilder(driveID2).String()
expectedPath1 = getExpectedPathGenerator(suite.T(), bh, tenant, user, driveBasePath1) expectedPath1 = getExpectedPathGenerator(suite.T(), bh, tenant, driveBasePath1)
expectedPath2 = getExpectedPathGenerator(suite.T(), bh, tenant, user, driveBasePath2) expectedPath2 = getExpectedPathGenerator(suite.T(), bh, tenant, driveBasePath2)
rootFolderPath1 = expectedPath1("") rootFolderPath1 = expectedPath1("")
folderPath1 = expectedPath1("/folder") folderPath1 = expectedPath1("/folder")
@ -2279,7 +2279,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
} }
} }
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("a-user")
mbh.DrivePagerV = mockDrivePager mbh.DrivePagerV = mockDrivePager
mbh.ItemPagerV = itemPagers mbh.ItemPagerV = itemPagers
@ -2650,7 +2650,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
itemPagers := map[string]api.DeltaPager[models.DriveItemable]{} itemPagers := map[string]api.DeltaPager[models.DriveItemable]{}
itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{} itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{}
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH("test-user")
mbh.ItemPagerV = itemPagers mbh.ItemPagerV = itemPagers
c := NewCollections( c := NewCollections(
@ -2667,7 +2667,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
// Add a few collections // Add a few collections
for i := 0; i < collCount; i++ { for i := 0; i < collCount; i++ {
coll, err := NewCollection( coll, err := NewCollection(
&itemBackupHandler{api.Drives{}, anyFolder}, &itemBackupHandler{api.Drives{}, "test-user", anyFolder},
nil, nil,
nil, nil,
driveID, driveID,

View File

@ -1,6 +1,7 @@
package drive package drive
import ( import (
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/services/m365/api" "github.com/alcionai/corso/src/pkg/services/m365/api"
@ -14,10 +15,15 @@ type groupBackupHandler struct {
scope selectors.GroupsScope scope selectors.GroupsScope
} }
func NewGroupBackupHandler(groupID string, ac api.Drives, scope selectors.GroupsScope) groupBackupHandler { func NewGroupBackupHandler(
groupID, siteID string,
ac api.Drives,
scope selectors.GroupsScope,
) groupBackupHandler {
return groupBackupHandler{ return groupBackupHandler{
libraryBackupHandler{ libraryBackupHandler{
ac: ac, ac: ac,
siteID: siteID,
// Not adding scope here. Anything that needs scope has to // Not adding scope here. Anything that needs scope has to
// be from group handler // be from group handler
service: path.GroupsService, service: path.GroupsService,
@ -27,16 +33,36 @@ func NewGroupBackupHandler(groupID string, ac api.Drives, scope selectors.Groups
} }
} }
func (h groupBackupHandler) CanonicalPath( func (h groupBackupHandler) PathPrefix(
folders *path.Builder, tenantID, driveID string,
tenantID, resourceOwner string,
) (path.Path, error) { ) (path.Path, error) {
// TODO(meain): path fixes // TODO: move tenantID to struct
return folders.ToDataLayerPath(tenantID, h.groupID, h.service, path.LibrariesCategory, false) return path.Build(
tenantID,
h.groupID,
h.service,
path.LibrariesCategory,
false,
odConsts.SitesPathDir,
h.siteID,
odConsts.DrivesPathDir,
driveID,
odConsts.RootPathDir)
} }
func (h groupBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) { func (h groupBackupHandler) CanonicalPath(
return path.GroupsService, path.LibrariesCategory folders *path.Builder,
tenantID string,
) (path.Path, error) {
return folders.ToDataLayerPath(
tenantID,
h.groupID,
h.service,
path.LibrariesCategory,
false,
odConsts.SitesPathDir,
h.siteID,
)
} }
func (h groupBackupHandler) IsAllPass() bool { func (h groupBackupHandler) IsAllPass() bool {

View File

@ -39,14 +39,11 @@ type BackupHandler interface {
// PathPrefix constructs the service and category specific path prefix for // PathPrefix constructs the service and category specific path prefix for
// the given values. // the given values.
PathPrefix(tenantID, resourceOwner, driveID string) (path.Path, error) PathPrefix(tenantID, driveID string) (path.Path, error)
// CanonicalPath constructs the service and category specific path for // CanonicalPath constructs the service and category specific path for
// the given values. // the given values.
CanonicalPath( CanonicalPath(folders *path.Builder, tenantID string) (path.Path, error)
folders *path.Builder,
tenantID, resourceOwner string,
) (path.Path, error)
// ServiceCat returns the service and category used by this implementation. // ServiceCat returns the service and category used by this implementation.
ServiceCat() (path.ServiceType, path.CategoryType) ServiceCat() (path.ServiceType, path.CategoryType)

View File

@ -344,7 +344,7 @@ func (suite *OneDriveIntgSuite) TestOneDriveNewCollections() {
) )
colls := NewCollections( colls := NewCollections(
&itemBackupHandler{suite.ac.Drives(), scope}, &itemBackupHandler{suite.ac.Drives(), test.user, scope},
creds.AzureTenantID, creds.AzureTenantID,
test.user, test.user,
service.updateStatus, service.updateStatus,

View File

@ -24,11 +24,12 @@ var _ BackupHandler = &itemBackupHandler{}
type itemBackupHandler struct { type itemBackupHandler struct {
ac api.Drives ac api.Drives
userID string
scope selectors.OneDriveScope scope selectors.OneDriveScope
} }
func NewItemBackupHandler(ac api.Drives, scope selectors.OneDriveScope) *itemBackupHandler { func NewItemBackupHandler(ac api.Drives, userID string, scope selectors.OneDriveScope) *itemBackupHandler {
return &itemBackupHandler{ac, scope} return &itemBackupHandler{ac, userID, scope}
} }
func (h itemBackupHandler) Get( func (h itemBackupHandler) Get(
@ -40,11 +41,11 @@ func (h itemBackupHandler) Get(
} }
func (h itemBackupHandler) PathPrefix( func (h itemBackupHandler) PathPrefix(
tenantID, resourceOwner, driveID string, tenantID, driveID string,
) (path.Path, error) { ) (path.Path, error) {
return path.Build( return path.Build(
tenantID, tenantID,
resourceOwner, h.userID,
path.OneDriveService, path.OneDriveService,
path.FilesCategory, path.FilesCategory,
false, false,
@ -55,9 +56,9 @@ func (h itemBackupHandler) PathPrefix(
func (h itemBackupHandler) CanonicalPath( func (h itemBackupHandler) CanonicalPath(
folders *path.Builder, folders *path.Builder,
tenantID, resourceOwner string, tenantID string,
) (path.Path, error) { ) (path.Path, error) {
return folders.ToDataLayerOneDrivePath(tenantID, resourceOwner, false) return folders.ToDataLayerOneDrivePath(tenantID, h.userID, false)
} }
func (h itemBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) { func (h itemBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) {

View File

@ -36,10 +36,10 @@ func (suite *ItemBackupHandlerUnitSuite) TestCanonicalPath() {
for _, test := range table { for _, test := range table {
suite.Run(test.name, func() { suite.Run(test.name, func() {
t := suite.T() t := suite.T()
h := itemBackupHandler{} h := itemBackupHandler{userID: resourceOwner}
p := path.Builder{}.Append("prefix") p := path.Builder{}.Append("prefix")
result, err := h.CanonicalPath(p, tenantID, resourceOwner) result, err := h.CanonicalPath(p, tenantID)
test.expectErr(t, err, clues.ToCore(err)) test.expectErr(t, err, clues.ToCore(err))
if result != nil { if result != nil {

View File

@ -124,6 +124,7 @@ func (suite *ItemIntegrationSuite) TestItemReader_oneDrive() {
bh := itemBackupHandler{ bh := itemBackupHandler{
suite.service.ac.Drives(), suite.service.ac.Drives(),
suite.user,
(&selectors.OneDriveBackup{}).Folders(selectors.Any())[0], (&selectors.OneDriveBackup{}).Folders(selectors.Any())[0],
} }

View File

@ -21,16 +21,18 @@ var _ BackupHandler = &libraryBackupHandler{}
type libraryBackupHandler struct { type libraryBackupHandler struct {
ac api.Drives ac api.Drives
siteID string
scope selectors.SharePointScope scope selectors.SharePointScope
service path.ServiceType service path.ServiceType
} }
func NewLibraryBackupHandler( func NewLibraryBackupHandler(
ac api.Drives, ac api.Drives,
siteID string,
scope selectors.SharePointScope, scope selectors.SharePointScope,
service path.ServiceType, service path.ServiceType,
) libraryBackupHandler { ) libraryBackupHandler {
return libraryBackupHandler{ac, scope, service} return libraryBackupHandler{ac, siteID, scope, service}
} }
func (h libraryBackupHandler) Get( func (h libraryBackupHandler) Get(
@ -42,11 +44,11 @@ func (h libraryBackupHandler) Get(
} }
func (h libraryBackupHandler) PathPrefix( func (h libraryBackupHandler) PathPrefix(
tenantID, resourceOwner, driveID string, tenantID, driveID string,
) (path.Path, error) { ) (path.Path, error) {
return path.Build( return path.Build(
tenantID, tenantID,
resourceOwner, h.siteID,
h.service, h.service,
path.LibrariesCategory, path.LibrariesCategory,
false, false,
@ -57,13 +59,13 @@ func (h libraryBackupHandler) PathPrefix(
func (h libraryBackupHandler) CanonicalPath( func (h libraryBackupHandler) CanonicalPath(
folders *path.Builder, folders *path.Builder,
tenantID, resourceOwner string, tenantID string,
) (path.Path, error) { ) (path.Path, error) {
return folders.ToDataLayerPath(tenantID, resourceOwner, h.service, path.LibrariesCategory, false) return folders.ToDataLayerPath(tenantID, h.siteID, h.service, path.LibrariesCategory, false)
} }
func (h libraryBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) { func (h libraryBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) {
return path.SharePointService, path.LibrariesCategory return h.service, path.LibrariesCategory
} }
func (h libraryBackupHandler) NewDrivePager( func (h libraryBackupHandler) NewDrivePager(

View File

@ -36,10 +36,10 @@ func (suite *LibraryBackupHandlerUnitSuite) TestCanonicalPath() {
for _, test := range table { for _, test := range table {
suite.Run(test.name, func() { suite.Run(test.name, func() {
t := suite.T() t := suite.T()
h := libraryBackupHandler{service: path.SharePointService} h := libraryBackupHandler{service: path.SharePointService, siteID: resourceOwner}
p := path.Builder{}.Append("prefix") p := path.Builder{}.Append("prefix")
result, err := h.CanonicalPath(p, tenantID, resourceOwner) result, err := h.CanonicalPath(p, tenantID)
test.expectErr(t, err, clues.ToCore(err)) test.expectErr(t, err, clues.ToCore(err))
if result != nil { if result != nil {
@ -52,7 +52,7 @@ func (suite *LibraryBackupHandlerUnitSuite) TestCanonicalPath() {
func (suite *LibraryBackupHandlerUnitSuite) TestServiceCat() { func (suite *LibraryBackupHandlerUnitSuite) TestServiceCat() {
t := suite.T() t := suite.T()
s, c := libraryBackupHandler{}.ServiceCat() s, c := libraryBackupHandler{service: path.SharePointService}.ServiceCat()
assert.Equal(t, path.SharePointService, s) assert.Equal(t, path.SharePointService, s)
assert.Equal(t, path.LibrariesCategory, c) assert.Equal(t, path.LibrariesCategory, c)
} }

View File

@ -80,7 +80,12 @@ func ProduceBackupCollections(
dbcs, canUsePreviousBackup, err = site.CollectLibraries( dbcs, canUsePreviousBackup, err = site.CollectLibraries(
ctx, ctx,
sbpc, sbpc,
drive.NewGroupBackupHandler(bpc.ProtectedResource.ID(), ac.Drives(), scope), drive.NewGroupBackupHandler(
bpc.ProtectedResource.ID(),
ptr.Val(resp.GetId()),
ac.Drives(),
scope,
),
creds.AzureTenantID, creds.AzureTenantID,
ssmb, ssmb,
su, su,

View File

@ -49,7 +49,7 @@ func ProduceBackupCollections(
logger.Ctx(ctx).Debug("creating OneDrive collections") logger.Ctx(ctx).Debug("creating OneDrive collections")
nc := drive.NewCollections( nc := drive.NewCollections(
drive.NewItemBackupHandler(ac.Drives(), scope), drive.NewItemBackupHandler(ac.Drives(), bpc.ProtectedResource.ID(), scope),
tenant, tenant,
bpc.ProtectedResource.ID(), bpc.ProtectedResource.ID(),
su, su,

View File

@ -3,6 +3,7 @@ package onedrive
import "github.com/alcionai/corso/src/pkg/path" import "github.com/alcionai/corso/src/pkg/path"
const ( const (
SitesPathDir = "sites"
// const used as the root dir for the drive portion of a path prefix. // const used as the root dir for the drive portion of a path prefix.
// eg: tid/onedrive/ro/files/drives/driveid/... // eg: tid/onedrive/ro/files/drives/driveid/...
DrivesPathDir = "drives" DrivesPathDir = "drives"

View File

@ -31,6 +31,7 @@ type BackupHandler struct {
CanonPathFn canonPather CanonPathFn canonPather
CanonPathErr error CanonPathErr error
ResourceOwner string
Service path.ServiceType Service path.ServiceType
Category path.CategoryType Category path.CategoryType
@ -45,7 +46,7 @@ type BackupHandler struct {
GetErrs []error GetErrs []error
} }
func DefaultOneDriveBH() *BackupHandler { func DefaultOneDriveBH(resourceOwner string) *BackupHandler {
return &BackupHandler{ return &BackupHandler{
ItemInfo: details.ItemInfo{ ItemInfo: details.ItemInfo{
OneDrive: &details.OneDriveInfo{}, OneDrive: &details.OneDriveInfo{},
@ -55,6 +56,7 @@ func DefaultOneDriveBH() *BackupHandler {
GIP: GetsItemPermission{Err: clues.New("not defined")}, GIP: GetsItemPermission{Err: clues.New("not defined")},
PathPrefixFn: defaultOneDrivePathPrefixer, PathPrefixFn: defaultOneDrivePathPrefixer,
CanonPathFn: defaultOneDriveCanonPather, CanonPathFn: defaultOneDriveCanonPather,
ResourceOwner: resourceOwner,
Service: path.OneDriveService, Service: path.OneDriveService,
Category: path.FilesCategory, Category: path.FilesCategory,
LocationIDFn: defaultOneDriveLocationIDer, LocationIDFn: defaultOneDriveLocationIDer,
@ -63,7 +65,7 @@ func DefaultOneDriveBH() *BackupHandler {
} }
} }
func DefaultSharePointBH() *BackupHandler { func DefaultSharePointBH(resourceOwner string) *BackupHandler {
return &BackupHandler{ return &BackupHandler{
ItemInfo: details.ItemInfo{ ItemInfo: details.ItemInfo{
SharePoint: &details.SharePointInfo{}, SharePoint: &details.SharePointInfo{},
@ -73,6 +75,7 @@ func DefaultSharePointBH() *BackupHandler {
GIP: GetsItemPermission{Err: clues.New("not defined")}, GIP: GetsItemPermission{Err: clues.New("not defined")},
PathPrefixFn: defaultSharePointPathPrefixer, PathPrefixFn: defaultSharePointPathPrefixer,
CanonPathFn: defaultSharePointCanonPather, CanonPathFn: defaultSharePointCanonPather,
ResourceOwner: resourceOwner,
Service: path.SharePointService, Service: path.SharePointService,
Category: path.LibrariesCategory, Category: path.LibrariesCategory,
LocationIDFn: defaultSharePointLocationIDer, LocationIDFn: defaultSharePointLocationIDer,
@ -81,8 +84,8 @@ func DefaultSharePointBH() *BackupHandler {
} }
} }
func (h BackupHandler) PathPrefix(tID, ro, driveID string) (path.Path, error) { func (h BackupHandler) PathPrefix(tID, driveID string) (path.Path, error) {
pp, err := h.PathPrefixFn(tID, ro, driveID) pp, err := h.PathPrefixFn(tID, h.ResourceOwner, driveID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -90,8 +93,8 @@ func (h BackupHandler) PathPrefix(tID, ro, driveID string) (path.Path, error) {
return pp, h.PathPrefixErr return pp, h.PathPrefixErr
} }
func (h BackupHandler) CanonicalPath(pb *path.Builder, tID, ro string) (path.Path, error) { func (h BackupHandler) CanonicalPath(pb *path.Builder, tID string) (path.Path, error) {
cp, err := h.CanonPathFn(pb, tID, ro) cp, err := h.CanonPathFn(pb, tID, h.ResourceOwner)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -80,7 +80,11 @@ func ProduceBackupCollections(
spcs, canUsePreviousBackup, err = site.CollectLibraries( spcs, canUsePreviousBackup, err = site.CollectLibraries(
ctx, ctx,
bpc, bpc,
drive.NewLibraryBackupHandler(ac.Drives(), scope, bpc.Selector.PathService()), drive.NewLibraryBackupHandler(
ac.Drives(),
bpc.ProtectedResource.ID(),
scope,
bpc.Selector.PathService()),
creds.AzureTenantID, creds.AzureTenantID,
ssmb, ssmb,
su, su,

View File

@ -50,8 +50,8 @@ func (suite *LibrariesBackupUnitSuite) TestUpdateCollections() {
) )
pb := path.Builder{}.Append(testBaseDrivePath.Elements()...) pb := path.Builder{}.Append(testBaseDrivePath.Elements()...)
ep, err := drive.NewLibraryBackupHandler(api.Drives{}, nil, path.SharePointService). ep, err := drive.NewLibraryBackupHandler(api.Drives{}, siteID, nil, path.SharePointService).
CanonicalPath(pb, tenantID, siteID) CanonicalPath(pb, tenantID)
require.NoError(suite.T(), err, clues.ToCore(err)) require.NoError(suite.T(), err, clues.ToCore(err))
tests := []struct { tests := []struct {
@ -101,7 +101,7 @@ func (suite *LibrariesBackupUnitSuite) TestUpdateCollections() {
) )
c := drive.NewCollections( c := drive.NewCollections(
drive.NewLibraryBackupHandler(api.Drives{}, test.scope, path.SharePointService), drive.NewLibraryBackupHandler(api.Drives{}, siteID, test.scope, path.SharePointService),
tenantID, tenantID,
siteID, siteID,
nil, nil,

View File

@ -306,6 +306,7 @@ func (pb Builder) ToDataLayerPath(
service ServiceType, service ServiceType,
category CategoryType, category CategoryType,
isItem bool, isItem bool,
elems ...string,
) (Path, error) { ) (Path, error) {
if err := ValidateServiceAndCategory(service, category); err != nil { if err := ValidateServiceAndCategory(service, category); err != nil {
return nil, err return nil, err
@ -315,12 +316,15 @@ func (pb Builder) ToDataLayerPath(
return nil, err return nil, err
} }
return &dataLayerResourcePath{ prefixItems := append([]string{
Builder: *pb.withPrefix(
tenant, tenant,
service.String(), service.String(),
user, user,
category.String()), category.String(),
}, elems...)
return &dataLayerResourcePath{
Builder: *pb.withPrefix(prefixItems...),
service: service, service: service,
category: category, category: category,
hasItem: isItem, hasItem: isItem,

View File

@ -367,3 +367,39 @@ func (suite *BuilderUnitSuite) TestPIIHandling() {
}) })
} }
} }
func (suite *BuilderUnitSuite) TestToDataLayerPath() {
location := Builder{}.Append("foo", "bar")
table := []struct {
name string
extra []string
expect string
}{
{
name: "no extra",
extra: []string{},
expect: "t/onedrive/u/files/foo/bar",
},
{
name: "single extra",
extra: []string{"oof"},
expect: "t/onedrive/u/files/oof/foo/bar",
},
{
name: "multi extra",
extra: []string{"oof", "rab"},
expect: "t/onedrive/u/files/oof/rab/foo/bar",
},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
dlp, err := location.ToDataLayerPath("t", "u", OneDriveService, FilesCategory, false, test.extra...)
require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, test.expect, dlp.PlainString())
})
}
}