Metadata related path changes (#4156)

This adds a `MetadataPathPrefix` func to any drive related handlers. And in case of exchange, we will create a path. These generated paths, in both scenario is what now gets passed to `MakeMetadataCollection` instead of passing the different values.
<!-- 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 13:50:37 +05:30 committed by GitHub
parent 98eae90924
commit 7c281d3fa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 54 deletions

View File

@ -436,12 +436,18 @@ func (c *Collections) Get(
} }
// add metadata collections // add metadata collections
service, category := c.handler.ServiceCat() pathPrefix, err := c.handler.MetadataPathPrefix(c.tenantID)
if err != nil {
// It's safe to return here because the logic for starting an
// incremental backup should eventually find that the metadata files are
// empty/missing and default to a full backup.
logger.CtxErr(ctx, err).Info("making metadata collection path prefixes")
return collections, canUsePreviousBackup, nil
}
md, err := graph.MakeMetadataCollection( md, err := graph.MakeMetadataCollection(
c.tenantID, pathPrefix,
c.resourceOwner,
service,
category,
[]graph.MetadataCollectionEntry{ []graph.MetadataCollectionEntry{
graph.NewMetadataEntry(graph.PreviousPathFileName, folderPaths), graph.NewMetadataEntry(graph.PreviousPathFileName, folderPaths),
graph.NewMetadataEntry(graph.DeltaURLsFileName, deltaURLs), graph.NewMetadataEntry(graph.DeltaURLsFileName, deltaURLs),

View File

@ -1129,11 +1129,16 @@ func (suite *OneDriveCollectionsUnitSuite) TestDeserializeMetadata() {
cols := []data.RestoreCollection{} cols := []data.RestoreCollection{}
for _, c := range test.cols { for _, c := range test.cols {
mc, err := graph.MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenant, tenant,
user, user,
path.OneDriveService, path.OneDriveService,
path.FilesCategory, path.FilesCategory,
false)
require.NoError(t, err, clues.ToCore(err))
mc, err := graph.MakeMetadataCollection(
pathPrefix,
c(), c(),
func(*support.ControllerOperationStatus) {}) func(*support.ControllerOperationStatus) {})
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -2291,11 +2296,12 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
control.Options{ToggleFeatures: control.Toggles{}}) control.Options{ToggleFeatures: control.Toggles{}})
prevDelta := "prev-delta" prevDelta := "prev-delta"
pathPrefix, err := mbh.MetadataPathPrefix(tenant)
require.NoError(t, err, clues.ToCore(err))
mc, err := graph.MakeMetadataCollection( mc, err := graph.MakeMetadataCollection(
tenant, pathPrefix,
user,
path.OneDriveService,
path.FilesCategory,
[]graph.MetadataCollectionEntry{ []graph.MetadataCollectionEntry{
graph.NewMetadataEntry( graph.NewMetadataEntry(
graph.DeltaURLsFileName, graph.DeltaURLsFileName,

View File

@ -1,6 +1,8 @@
package drive package drive
import ( import (
"github.com/alcionai/clues"
odConsts "github.com/alcionai/corso/src/internal/m365/service/onedrive/consts" 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"
@ -50,6 +52,20 @@ func (h groupBackupHandler) PathPrefix(
odConsts.RootPathDir) odConsts.RootPathDir)
} }
func (h groupBackupHandler) MetadataPathPrefix(tenantID string) (path.Path, error) {
p, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenantID,
h.groupID,
h.service,
path.LibrariesCategory,
false)
if err != nil {
return nil, clues.Wrap(err, "making metadata path")
}
return p, nil
}
func (h groupBackupHandler) CanonicalPath( func (h groupBackupHandler) CanonicalPath(
folders *path.Builder, folders *path.Builder,
tenantID string, tenantID string,

View File

@ -41,6 +41,9 @@ type BackupHandler interface {
// the given values. // the given values.
PathPrefix(tenantID, driveID string) (path.Path, error) PathPrefix(tenantID, driveID string) (path.Path, error)
// MetadataPathPrefix returns the prefix path for metadata
MetadataPathPrefix(tenantID 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(folders *path.Builder, tenantID string) (path.Path, error) CanonicalPath(folders *path.Builder, tenantID string) (path.Path, error)

View File

@ -54,6 +54,22 @@ func (h itemBackupHandler) PathPrefix(
odConsts.RootPathDir) odConsts.RootPathDir)
} }
func (h itemBackupHandler) MetadataPathPrefix(
tenantID string,
) (path.Path, error) {
p, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenantID,
h.userID,
path.OneDriveService,
path.FilesCategory,
false)
if err != nil {
return nil, clues.Wrap(err, "making metadata path")
}
return p, nil
}
func (h itemBackupHandler) CanonicalPath( func (h itemBackupHandler) CanonicalPath(
folders *path.Builder, folders *path.Builder,
tenantID string, tenantID string,

View File

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/drives" "github.com/microsoftgraph/msgraph-sdk-go/drives"
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
@ -57,6 +58,22 @@ func (h libraryBackupHandler) PathPrefix(
odConsts.RootPathDir) odConsts.RootPathDir)
} }
func (h libraryBackupHandler) MetadataPathPrefix(
tenantID string,
) (path.Path, error) {
p, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenantID,
h.siteID,
h.service,
path.LibrariesCategory,
false)
if err != nil {
return nil, clues.Wrap(err, "making metadata path")
}
return p, nil
}
func (h libraryBackupHandler) CanonicalPath( func (h libraryBackupHandler) CanonicalPath(
folders *path.Builder, folders *path.Builder,
tenantID string, tenantID string,

View File

@ -266,11 +266,18 @@ func populateCollections(
"num_paths_entries", len(currPaths), "num_paths_entries", len(currPaths),
"num_deltas_entries", len(deltaURLs)) "num_deltas_entries", len(deltaURLs))
col, err := graph.MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
qp.TenantID, qp.TenantID,
qp.ProtectedResource.ID(), qp.ProtectedResource.ID(),
path.ExchangeService, path.ExchangeService,
qp.Category, qp.Category,
false)
if err != nil {
return nil, clues.Wrap(err, "making metadata path")
}
col, err := graph.MakeMetadataCollection(
pathPrefix,
[]graph.MetadataCollectionEntry{ []graph.MetadataCollectionEntry{
graph.NewMetadataEntry(graph.PreviousPathFileName, currPaths), graph.NewMetadataEntry(graph.PreviousPathFileName, currPaths),
graph.NewMetadataEntry(graph.DeltaURLsFileName, deltaURLs), graph.NewMetadataEntry(graph.DeltaURLsFileName, deltaURLs),

View File

@ -299,10 +299,15 @@ func (suite *DataCollectionsUnitSuite) TestParseMetadataCollections() {
graph.NewMetadataEntry(d.fileName, map[string]string{"key": d.value})) graph.NewMetadataEntry(d.fileName, map[string]string{"key": d.value}))
} }
coll, err := graph.MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
"t", "u", "t", "u",
path.ExchangeService, path.ExchangeService,
path.EmailCategory, path.EmailCategory,
false)
require.NoError(t, err, "path prefix")
coll, err := graph.MakeMetadataCollection(
pathPrefix,
entries, entries,
func(cos *support.ControllerOperationStatus) {}, func(cos *support.ControllerOperationStatus) {},
) )

View File

@ -43,9 +43,6 @@ func CollectLibraries(
bpc.Options) bpc.Options)
) )
// TODO(meain): backup resource owner should be group id in case
// of group sharepoint site backup. As of now, we always use
// sharepoint site ids.
odcs, canUsePreviousBackup, err := colls.Get(ctx, bpc.MetadataCollections, ssmb, errs) odcs, canUsePreviousBackup, err := colls.Get(ctx, bpc.MetadataCollections, ssmb, errs)
if err != nil { if err != nil {
return nil, false, graph.Wrap(ctx, err, "getting library") return nil, false, graph.Wrap(ctx, err, "getting library")

View File

@ -63,9 +63,7 @@ func (mce MetadataCollectionEntry) toMetadataItem() (MetadataItem, error) {
// containing all the provided metadata as a single json object. Returns // containing all the provided metadata as a single json object. Returns
// nil if the map does not have any entries. // nil if the map does not have any entries.
func MakeMetadataCollection( func MakeMetadataCollection(
tenant, resourceOwner string, pathPrefix path.Path,
service path.ServiceType,
cat path.CategoryType,
metadata []MetadataCollectionEntry, metadata []MetadataCollectionEntry,
statusUpdater support.StatusUpdater, statusUpdater support.StatusUpdater,
) (data.BackupCollection, error) { ) (data.BackupCollection, error) {
@ -73,16 +71,6 @@ func MakeMetadataCollection(
return nil, nil return nil, nil
} }
p, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenant,
resourceOwner,
service,
cat,
false)
if err != nil {
return nil, clues.Wrap(err, "making metadata path")
}
items := make([]MetadataItem, 0, len(metadata)) items := make([]MetadataItem, 0, len(metadata))
for _, md := range metadata { for _, md := range metadata {
@ -94,7 +82,7 @@ func MakeMetadataCollection(
items = append(items, item) items = append(items, item)
} }
coll := NewMetadataCollection(p, items, statusUpdater) coll := NewMetadataCollection(pathPrefix, items, statusUpdater)
return coll, nil return coll, nil
} }

View File

@ -116,6 +116,7 @@ func (suite *MetadataCollectionUnitSuite) TestMakeMetadataCollection() {
cat path.CategoryType cat path.CategoryType
metadata MetadataCollectionEntry metadata MetadataCollectionEntry
collectionCheck assert.ValueAssertionFunc collectionCheck assert.ValueAssertionFunc
pathPrefixCheck assert.ErrorAssertionFunc
errCheck assert.ErrorAssertionFunc errCheck assert.ErrorAssertionFunc
}{ }{
{ {
@ -124,6 +125,7 @@ func (suite *MetadataCollectionUnitSuite) TestMakeMetadataCollection() {
cat: path.EmailCategory, cat: path.EmailCategory,
metadata: NewMetadataEntry("", nil), metadata: NewMetadataEntry("", nil),
collectionCheck: assert.Nil, collectionCheck: assert.Nil,
pathPrefixCheck: assert.NoError,
errCheck: assert.Error, errCheck: assert.Error,
}, },
{ {
@ -137,6 +139,7 @@ func (suite *MetadataCollectionUnitSuite) TestMakeMetadataCollection() {
"hola": "mundo", "hola": "mundo",
}), }),
collectionCheck: assert.NotNil, collectionCheck: assert.NotNil,
pathPrefixCheck: assert.NoError,
errCheck: assert.NoError, errCheck: assert.NoError,
}, },
{ {
@ -150,7 +153,8 @@ func (suite *MetadataCollectionUnitSuite) TestMakeMetadataCollection() {
"hola": "mundo", "hola": "mundo",
}), }),
collectionCheck: assert.Nil, collectionCheck: assert.Nil,
errCheck: assert.Error, pathPrefixCheck: assert.Error,
errCheck: assert.NoError,
}, },
} }
@ -161,11 +165,19 @@ func (suite *MetadataCollectionUnitSuite) TestMakeMetadataCollection() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
col, err := MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenant, tenant,
user, user,
test.service, test.service,
test.cat, test.cat,
false)
test.pathPrefixCheck(t, err, "path prefix")
if err != nil {
return
}
col, err := MakeMetadataCollection(
pathPrefix,
[]MetadataCollectionEntry{test.metadata}, []MetadataCollectionEntry{test.metadata},
func(*support.ControllerOperationStatus) {}) func(*support.ControllerOperationStatus) {})

View File

@ -28,6 +28,9 @@ type BackupHandler struct {
PathPrefixFn pathPrefixer PathPrefixFn pathPrefixer
PathPrefixErr error PathPrefixErr error
MetadataPathPrefixFn metadataPathPrefixer
MetadataPathPrefixErr error
CanonPathFn canonPather CanonPathFn canonPather
CanonPathErr error CanonPathErr error
@ -55,6 +58,7 @@ func DefaultOneDriveBH(resourceOwner string) *BackupHandler {
GI: GetsItem{Err: clues.New("not defined")}, GI: GetsItem{Err: clues.New("not defined")},
GIP: GetsItemPermission{Err: clues.New("not defined")}, GIP: GetsItemPermission{Err: clues.New("not defined")},
PathPrefixFn: defaultOneDrivePathPrefixer, PathPrefixFn: defaultOneDrivePathPrefixer,
MetadataPathPrefixFn: defaultOneDriveMetadataPathPrefixer,
CanonPathFn: defaultOneDriveCanonPather, CanonPathFn: defaultOneDriveCanonPather,
ResourceOwner: resourceOwner, ResourceOwner: resourceOwner,
Service: path.OneDriveService, Service: path.OneDriveService,
@ -74,6 +78,7 @@ func DefaultSharePointBH(resourceOwner string) *BackupHandler {
GI: GetsItem{Err: clues.New("not defined")}, GI: GetsItem{Err: clues.New("not defined")},
GIP: GetsItemPermission{Err: clues.New("not defined")}, GIP: GetsItemPermission{Err: clues.New("not defined")},
PathPrefixFn: defaultSharePointPathPrefixer, PathPrefixFn: defaultSharePointPathPrefixer,
MetadataPathPrefixFn: defaultSharePointMetadataPathPrefixer,
CanonPathFn: defaultSharePointCanonPather, CanonPathFn: defaultSharePointCanonPather,
ResourceOwner: resourceOwner, ResourceOwner: resourceOwner,
Service: path.SharePointService, Service: path.SharePointService,
@ -93,6 +98,15 @@ func (h BackupHandler) PathPrefix(tID, driveID string) (path.Path, error) {
return pp, h.PathPrefixErr return pp, h.PathPrefixErr
} }
func (h BackupHandler) MetadataPathPrefix(tID string) (path.Path, error) {
pp, err := h.MetadataPathPrefixFn(tID, h.ResourceOwner)
if err != nil {
return nil, err
}
return pp, h.PathPrefixErr
}
func (h BackupHandler) CanonicalPath(pb *path.Builder, tID string) (path.Path, error) { func (h BackupHandler) CanonicalPath(pb *path.Builder, tID string) (path.Path, error) {
cp, err := h.CanonPathFn(pb, tID, h.ResourceOwner) cp, err := h.CanonPathFn(pb, tID, h.ResourceOwner)
if err != nil { if err != nil {
@ -159,7 +173,10 @@ var defaultSharePointCanonPather = func(pb *path.Builder, tID, ro string) (path.
return pb.ToDataLayerSharePointPath(tID, ro, path.LibrariesCategory, false) return pb.ToDataLayerSharePointPath(tID, ro, path.LibrariesCategory, false)
} }
type pathPrefixer func(tID, ro, driveID string) (path.Path, error) type (
pathPrefixer func(tID, ro, driveID string) (path.Path, error)
metadataPathPrefixer func(tID, ro string) (path.Path, error)
)
var defaultOneDrivePathPrefixer = func(tID, ro, driveID string) (path.Path, error) { var defaultOneDrivePathPrefixer = func(tID, ro, driveID string) (path.Path, error) {
return path.Build( return path.Build(
@ -173,6 +190,15 @@ var defaultOneDrivePathPrefixer = func(tID, ro, driveID string) (path.Path, erro
odConsts.RootPathDir) odConsts.RootPathDir)
} }
var defaultOneDriveMetadataPathPrefixer = func(tID, ro string) (path.Path, error) {
return path.Builder{}.ToServiceCategoryMetadataPath(
tID,
ro,
path.OneDriveService,
path.FilesCategory,
false)
}
var defaultSharePointPathPrefixer = func(tID, ro, driveID string) (path.Path, error) { var defaultSharePointPathPrefixer = func(tID, ro, driveID string) (path.Path, error) {
return path.Build( return path.Build(
tID, tID,
@ -185,6 +211,15 @@ var defaultSharePointPathPrefixer = func(tID, ro, driveID string) (path.Path, er
odConsts.RootPathDir) odConsts.RootPathDir)
} }
var defaultSharePointMetadataPathPrefixer = func(tID, ro string) (path.Path, error) {
return path.Builder{}.ToServiceCategoryMetadataPath(
tID,
ro,
path.SharePointService,
path.LibrariesCategory,
false)
}
type locationIDer func(string, ...string) details.LocationIDer type locationIDer func(string, ...string) details.LocationIDer
var defaultOneDriveLocationIDer = func(driveID string, elems ...string) details.LocationIDer { var defaultOneDriveLocationIDer = func(driveID string, elems ...string) details.LocationIDer {

View File

@ -1871,11 +1871,16 @@ func (suite *AssistBackupIntegrationSuite) TestBackupTypesForFailureModes() {
cs := test.collFunc() cs := test.collFunc()
mc, err := graph.MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenantID, tenantID,
userID, userID,
path.OneDriveService, path.OneDriveService,
path.FilesCategory, path.FilesCategory,
false)
require.NoError(t, err, clues.ToCore(err))
mc, err := graph.MakeMetadataCollection(
pathPrefix,
makeMetadataCollectionEntries("url/1", driveID, folderID, tmp), makeMetadataCollectionEntries("url/1", driveID, folderID, tmp),
func(*support.ControllerOperationStatus) {}) func(*support.ControllerOperationStatus) {})
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -2184,11 +2189,16 @@ func (suite *AssistBackupIntegrationSuite) TestExtensionsIncrementals() {
cs := test.collFunc() cs := test.collFunc()
mc, err := graph.MakeMetadataCollection( pathPrefix, err := path.Builder{}.ToServiceCategoryMetadataPath(
tenantID, tenantID,
userID, userID,
path.OneDriveService, path.OneDriveService,
path.FilesCategory, path.FilesCategory,
false)
require.NoError(t, err, clues.ToCore(err))
mc, err := graph.MakeMetadataCollection(
pathPrefix,
makeMetadataCollectionEntries("url/1", driveID, folderID, tmp), makeMetadataCollectionEntries("url/1", driveID, folderID, tmp),
func(*support.ControllerOperationStatus) {}) func(*support.ControllerOperationStatus) {})
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))