diff --git a/src/internal/m365/collection/exchange/backup_test.go b/src/internal/m365/collection/exchange/backup_test.go index 75b3f2bfe..b15a1631b 100644 --- a/src/internal/m365/collection/exchange/backup_test.go +++ b/src/internal/m365/collection/exchange/backup_test.go @@ -91,12 +91,10 @@ func (mg mockGetter) GetAddedAndRemovedItemIDs( var _ graph.ContainerResolver = &mockResolver{} -type ( - mockResolver struct { - items []graph.CachedContainer - added map[string]string - } -) +type mockResolver struct { + items []graph.CachedContainer + added map[string]string +} func newMockResolver(items ...mockContainer) mockResolver { is := make([]graph.CachedContainer, 0, len(items)) @@ -125,9 +123,10 @@ func (m mockResolver) DestinationNameToID(dest string) string { return m.added[d func (m mockResolver) IDToPath(context.Context, string) (*path.Builder, *path.Builder, error) { return nil, nil, nil } -func (m mockResolver) PathInCache(string) (string, bool) { return "", false } -func (m mockResolver) LocationInCache(string) (string, bool) { return "", false } -func (m mockResolver) Populate(context.Context, *fault.Bus, string, ...string) error { return nil } +func (m mockResolver) PathInCache(string) (string, bool) { return "", false } +func (m mockResolver) LocationInCache(string) (string, bool) { return "", false } +func (m mockResolver) Populate(context.Context, *fault.Bus, string) error { return nil } +func (m mockResolver) DefaultRootLocation() string { return "" } // --------------------------------------------------------------------------- // Unit tests diff --git a/src/internal/m365/collection/exchange/contacts_container_cache.go b/src/internal/m365/collection/exchange/contacts_container_cache.go index aa9a45518..5518367d1 100644 --- a/src/internal/m365/collection/exchange/contacts_container_cache.go +++ b/src/internal/m365/collection/exchange/contacts_container_cache.go @@ -37,25 +37,27 @@ func (r *contactRefresher) refreshContainer( type contactContainerCache struct { *containerResolver - enumer containersEnumerator - getter containerGetter - userID string + enumer containersEnumerator + getter containerGetter + userID string + rootLocation string } func (cfc *contactContainerCache) populateContactRoot( ctx context.Context, directoryID string, - baseContainerPath []string, ) error { f, err := cfc.getter.GetContainerByID(ctx, cfc.userID, directoryID) if err != nil { return clues.Wrap(err, "fetching root folder") } + cfc.rootLocation = ptr.Val(f.GetDisplayName()) + temp := graph.NewCacheFolder( f, - path.Builder{}.Append(ptr.Val(f.GetId())), // path of IDs - path.Builder{}.Append(baseContainerPath...)) // display location + path.Builder{}.Append(ptr.Val(f.GetId())), // path of IDs + path.Builder{}.Append(cfc.rootLocation)) // display location if err := cfc.addFolder(&temp); err != nil { return clues.Wrap(err, "adding resolver dir").WithClues(ctx) } @@ -71,9 +73,8 @@ func (cfc *contactContainerCache) Populate( ctx context.Context, errs *fault.Bus, baseID string, - baseContainerPath ...string, ) error { - if err := cfc.init(ctx, baseID, baseContainerPath); err != nil { + if err := cfc.init(ctx, baseID); err != nil { return clues.Wrap(err, "initializing") } @@ -92,7 +93,6 @@ func (cfc *contactContainerCache) Populate( func (cfc *contactContainerCache) init( ctx context.Context, baseNode string, - baseContainerPath []string, ) error { if len(baseNode) == 0 { return clues.New("m365 folderID required for base contact folder").WithClues(ctx) @@ -105,5 +105,9 @@ func (cfc *contactContainerCache) init( }) } - return cfc.populateContactRoot(ctx, baseNode, baseContainerPath) + return cfc.populateContactRoot(ctx, baseNode) +} + +func (cfc *contactContainerCache) DefaultRootLocation() string { + return cfc.rootLocation } diff --git a/src/internal/m365/collection/exchange/container_resolver_test.go b/src/internal/m365/collection/exchange/container_resolver_test.go index 12f8c06ee..a414c47b2 100644 --- a/src/internal/m365/collection/exchange/container_resolver_test.go +++ b/src/internal/m365/collection/exchange/container_resolver_test.go @@ -719,16 +719,15 @@ func (suite *ContainerResolverSuite) TestPopulate() { } tests := []struct { - name, folderInCache, root, basePath string - resolverFunc func(t *testing.T) graph.ContainerResolver - canFind assert.BoolAssertionFunc + name, folderInCache, root string + resolverFunc func(t *testing.T) graph.ContainerResolver + canFind assert.BoolAssertionFunc }{ { name: "Default Event Cache", // Fine as long as this isn't running against a migrated Exchange server. folderInCache: api.DefaultCalendar, root: api.DefaultCalendar, - basePath: api.DefaultCalendar, resolverFunc: eventFunc, canFind: assert.True, }, @@ -750,7 +749,6 @@ func (suite *ContainerResolverSuite) TestPopulate() { name: "Default Contact Cache", folderInCache: api.DefaultContacts, root: api.DefaultContacts, - basePath: api.DefaultContacts, canFind: assert.True, resolverFunc: contactFunc, }, @@ -778,7 +776,7 @@ func (suite *ContainerResolverSuite) TestPopulate() { resolver := test.resolverFunc(t) - err := resolver.Populate(ctx, fault.New(true), test.root, test.basePath) + err := resolver.Populate(ctx, fault.New(true), test.root) require.NoError(t, err, clues.ToCore(err)) _, isFound := resolver.LocationInCache(test.folderInCache) diff --git a/src/internal/m365/collection/exchange/events_container_cache.go b/src/internal/m365/collection/exchange/events_container_cache.go index eb8a70ae4..dce5b6182 100644 --- a/src/internal/m365/collection/exchange/events_container_cache.go +++ b/src/internal/m365/collection/exchange/events_container_cache.go @@ -64,7 +64,6 @@ func (ecc *eventContainerCache) Populate( ctx context.Context, errs *fault.Bus, baseID string, - baseContainerPath ...string, ) error { if err := ecc.init(ctx); err != nil { return clues.Wrap(err, "initializing") @@ -112,3 +111,7 @@ func (ecc *eventContainerCache) AddToCache(ctx context.Context, f graph.Containe return nil } + +func (ecc *eventContainerCache) DefaultRootLocation() string { + return "" +} diff --git a/src/internal/m365/collection/exchange/mail_container_cache.go b/src/internal/m365/collection/exchange/mail_container_cache.go index c499de40b..9eb6943c1 100644 --- a/src/internal/m365/collection/exchange/mail_container_cache.go +++ b/src/internal/m365/collection/exchange/mail_container_cache.go @@ -94,7 +94,6 @@ func (mc *mailContainerCache) Populate( ctx context.Context, errs *fault.Bus, baseID string, - baseContainerPath ...string, ) error { if err := mc.init(ctx); err != nil { return clues.Wrap(err, "initializing") @@ -111,3 +110,7 @@ func (mc *mailContainerCache) Populate( return nil } + +func (mc *mailContainerCache) DefaultRootLocation() string { + return "" +} diff --git a/src/internal/m365/collection/exchange/mail_container_cache_test.go b/src/internal/m365/collection/exchange/mail_container_cache_test.go index de0694749..86ca2b107 100644 --- a/src/internal/m365/collection/exchange/mail_container_cache_test.go +++ b/src/internal/m365/collection/exchange/mail_container_cache_test.go @@ -69,11 +69,6 @@ func (suite *MailFolderCacheIntegrationSuite) TestDeltaFetch() { name: "Node Root", root: topFolderID, }, - { - name: "Node Root Non-empty Path", - root: topFolderID, - path: []string{"some", "leading", "path"}, - }, } userID := tconfig.M365UserID(suite.T()) @@ -95,7 +90,7 @@ func (suite *MailFolderCacheIntegrationSuite) TestDeltaFetch() { getter: acm, } - err = mfc.Populate(ctx, fault.New(true), test.root, test.path...) + err = mfc.Populate(ctx, fault.New(true), test.root) require.NoError(t, err, clues.ToCore(err)) p, l, err := mfc.IDToPath(ctx, testFolderID) diff --git a/src/internal/m365/collection/exchange/restore.go b/src/internal/m365/collection/exchange/restore.go index 6d6b6721c..04c6bb43b 100644 --- a/src/internal/m365/collection/exchange/restore.go +++ b/src/internal/m365/collection/exchange/restore.go @@ -135,11 +135,15 @@ func CreateDestination( errs *fault.Bus, ) (string, graph.ContainerResolver, error) { var ( - cache = gcr - restoreLoc = &path.Builder{} - containerParentID string + restoreLoc = &path.Builder{} + containerParentID string + defaultRootLocation = gcr.DefaultRootLocation() ) + if len(defaultRootLocation) > 0 { + restoreLoc = restoreLoc.Append(defaultRootLocation) + } + for _, container := range destination.Elements() { restoreLoc = restoreLoc.Append(container) @@ -152,14 +156,14 @@ func CreateDestination( containerID, err := getOrPopulateContainer( ictx, ca, - cache, + gcr, restoreLoc, resourceID, containerParentID, container, errs) if err != nil { - return "", cache, clues.Stack(err) + return "", gcr, clues.Stack(err) } containerParentID = containerID @@ -167,7 +171,7 @@ func CreateDestination( // containerParentID now identifies the last created container, // not its parent. - return containerParentID, cache, nil + return containerParentID, gcr, nil } func getOrPopulateContainer( diff --git a/src/internal/m365/graph/cache_container.go b/src/internal/m365/graph/cache_container.go index d83b17d74..7bdb4e8e2 100644 --- a/src/internal/m365/graph/cache_container.go +++ b/src/internal/m365/graph/cache_container.go @@ -64,7 +64,7 @@ type ContainerResolver interface { // @param ctx is necessary param for Graph API tracing // @param baseFolderID represents the M365ID base that the resolver will // conclude its search. Default input is "". - Populate(ctx context.Context, errs *fault.Bus, baseFolderID string, baseContainerPath ...string) error + Populate(ctx context.Context, errs *fault.Bus, baseFolderID string) error // PathInCache performs a look up of a path representation // and returns the m365ID of directory iff the pathString @@ -81,6 +81,11 @@ type ContainerResolver interface { // Items returns the containers in the cache. Items() []CachedContainer + + // DefaultRootLocation provides implementations which hard-code a parent + // folder root in their location path with a way to give downstream comparators + // that same location name. + DefaultRootLocation() string } // ======================================