Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
add teamschats restore shim for export support (#5127)
Browse files Browse the repository at this point in the history
more boilerplate adaptation
  • Loading branch information
ryanfkeepers authored Feb 15, 2024
1 parent b9f7128 commit d7ca5e4
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
100 changes: 100 additions & 0 deletions src/internal/m365/service/teamschats/restore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package teamschats

import (
"context"
"errors"

"github.com/alcionai/clues"

"github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/m365/support"
"github.com/alcionai/corso/src/internal/operations/inject"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/count"
"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/graph"
)

// ConsumeRestoreCollections will restore the specified data collections
func (h *teamsChatsHandler) ConsumeRestoreCollections(
ctx context.Context,
rcc inject.RestoreConsumerConfig,
dcs []data.RestoreCollection,
errs *fault.Bus,
ctr *count.Bus,
) (*details.Details, *data.CollectionStats, error) {
if len(dcs) == 0 {
return nil, nil, clues.WrapWC(ctx, data.ErrNoData, "performing restore")
}

// TODO(ashmrtn): We should stop relying on the context for rate limiter stuff
// and instead configure this when we make the handler instance. We can't
// initialize it in the NewHandler call right now because those functions
// aren't (and shouldn't be) returning a context along with the handler. Since
// that call isn't directly calling into this function even if we did
// initialize the rate limiter there it would be lost because it wouldn't get
// stored in an ancestor of the context passed to this function.
ctx = graph.BindRateLimiterConfig(
ctx,
graph.LimiterCfg{Service: path.TeamsChatsService})

var (
deets = &details.Builder{}
restoreMetrics support.CollectionMetrics
el = errs.Local()
)

// Reorder collections so that the parents directories are created
// before the child directories; a requirement for permissions.
data.SortRestoreCollections(dcs)

// Iterate through the data collections and restore the contents of each
for _, dc := range dcs {
if el.Failure() != nil {
break
}

var (
err error
category = dc.FullPath().Category()
metrics support.CollectionMetrics
ictx = clues.Add(ctx,
"category", category,
"restore_location", clues.Hide(rcc.RestoreConfig.Location),
"protected_resource", clues.Hide(dc.FullPath().ProtectedResource()),
"full_path", dc.FullPath())
)

switch dc.FullPath().Category() {
case path.ChatsCategory:
// chats cannot be restored using Graph API.
// a delegated token is required, and Corso has no
// good way of obtaining such a token.
logger.Ctx(ictx).Debug("Skipping restore for channel messages")
default:
return nil, nil, clues.NewWC(ictx, "data category not supported").
With("category", category)
}

restoreMetrics = support.CombineMetrics(restoreMetrics, metrics)

if err != nil {
el.AddRecoverable(ictx, err)
}

if errors.Is(err, context.Canceled) {
break
}
}

status := support.CreateStatus(
ctx,
support.Restore,
len(dcs),
restoreMetrics,
rcc.RestoreConfig.Location)

return deets.Details(), status.ToCollectionStats(), el.Failure()
}
54 changes: 54 additions & 0 deletions src/internal/m365/service/teamschats/restore_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package teamschats

import (
"testing"

"github.com/alcionai/clues"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/data/mock"
"github.com/alcionai/corso/src/internal/operations/inject"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)

type RestoreUnitSuite struct {
tester.Suite
}

func TestRestoreUnitSuite(t *testing.T) {
suite.Run(t, &RestoreUnitSuite{Suite: tester.NewUnitSuite(t)})
}

func (suite *RestoreUnitSuite) TestConsumeRestoreCollections_noErrorOnChats() {
t := suite.T()

ctx, flush := tester.NewContext(t)
defer flush()

rcc := inject.RestoreConsumerConfig{}
pth, err := path.BuildPrefix(
"t",
"pr",
path.TeamsChatsService,
path.ChatsCategory)
require.NoError(t, err, clues.ToCore(err))

dcs := []data.RestoreCollection{
mock.Collection{Path: pth},
}

_, _, err = NewTeamsChatsHandler(api.Client{}, nil).
ConsumeRestoreCollections(
ctx,
rcc,
dcs,
fault.New(false),
nil)
assert.NoError(t, err, "Chats restore")
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func makeRestorePathsForEntry(
// * OneDrive/SharePoint (needs drive information)
switch true {
case ent.Exchange != nil ||
ent.TeamsChats != nil ||
(ent.Groups != nil && ent.Groups.ItemType == details.GroupsChannelMessage) ||
(ent.SharePoint != nil && ent.SharePoint.ItemType == details.SharePointList):
// TODO(ashmrtn): Eventually make Events have it's own function to handle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,30 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
},
},
},
{
name: "TeamsChats Chats",
backupVersion: version.Groups9Update,
input: []*details.Entry{
{
RepoRef: testdata.ExchangeEmailItemPath3.RR.String(),
LocationRef: testdata.ExchangeEmailItemPath3.Loc.String(),
ItemInfo: details.ItemInfo{
Exchange: &details.ExchangeInfo{
ItemType: details.ExchangeMail,
},
},
},
},
expectErr: assert.NoError,
expected: []expectPaths{
{
storage: testdata.ExchangeEmailItemPath3.RR.String(),
restore: toRestore(
testdata.ExchangeEmailItemPath3.RR,
testdata.ExchangeEmailItemPath3.Loc.Elements()...),
},
},
},
}

for _, test := range table {
Expand Down

0 comments on commit d7ca5e4

Please sign in to comment.