1. moves the m365/graph package from internal to pkg/services/api so that options are accessible to sdk users. 2. exposes graph.Options in the api client.Service call. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🌻 Feature
123 lines
3.0 KiB
Go
123 lines
3.0 KiB
Go
package exchange
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/alcionai/clues"
|
|
|
|
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
|
"github.com/alcionai/corso/src/internal/data"
|
|
"github.com/alcionai/corso/src/internal/m365/collection/exchange"
|
|
"github.com/alcionai/corso/src/internal/m365/support"
|
|
"github.com/alcionai/corso/src/internal/operations/inject"
|
|
"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"
|
|
"github.com/alcionai/corso/src/pkg/services/m365/api/graph"
|
|
)
|
|
|
|
// ProduceBackupCollections returns a DataCollection which the caller can
|
|
// use to read mailbox data out for the specified user
|
|
func ProduceBackupCollections(
|
|
ctx context.Context,
|
|
bpc inject.BackupProducerConfig,
|
|
ac api.Client,
|
|
tenantID string,
|
|
su support.StatusUpdater,
|
|
errs *fault.Bus,
|
|
) ([]data.BackupCollection, *prefixmatcher.StringSetMatcher, bool, error) {
|
|
eb, err := bpc.Selector.ToExchangeBackup()
|
|
if err != nil {
|
|
return nil, nil, false, clues.Wrap(err, "exchange dataCollection selector").WithClues(ctx)
|
|
}
|
|
|
|
var (
|
|
collections = []data.BackupCollection{}
|
|
el = errs.Local()
|
|
categories = map[path.CategoryType]struct{}{}
|
|
handlers = exchange.BackupHandlers(ac)
|
|
)
|
|
|
|
canMakeDeltaQueries, err := canMakeDeltaQueries(ctx, ac.Users(), bpc.ProtectedResource.ID())
|
|
if err != nil {
|
|
return nil, nil, false, clues.Stack(err)
|
|
}
|
|
|
|
if !canMakeDeltaQueries {
|
|
logger.Ctx(ctx).Info("delta requests not available")
|
|
|
|
bpc.Options.ToggleFeatures.DisableDelta = true
|
|
}
|
|
|
|
// Turn on concurrency limiter middleware for exchange backups
|
|
// unless explicitly disabled through DisableConcurrencyLimiterFN cli flag
|
|
graph.InitializeConcurrencyLimiter(
|
|
ctx,
|
|
bpc.Options.ToggleFeatures.DisableConcurrencyLimiter,
|
|
bpc.Options.Parallelism.ItemFetch)
|
|
|
|
cdps, canUsePreviousBackup, err := exchange.ParseMetadataCollections(ctx, bpc.MetadataCollections)
|
|
if err != nil {
|
|
return nil, nil, false, err
|
|
}
|
|
|
|
ctx = clues.Add(ctx, "can_use_previous_backup", canUsePreviousBackup)
|
|
|
|
for _, scope := range eb.Scopes() {
|
|
if el.Failure() != nil {
|
|
break
|
|
}
|
|
|
|
dcs, err := exchange.CreateCollections(
|
|
ctx,
|
|
bpc,
|
|
handlers,
|
|
tenantID,
|
|
scope,
|
|
cdps[scope.Category().PathType()],
|
|
su,
|
|
errs)
|
|
if err != nil {
|
|
el.AddRecoverable(ctx, err)
|
|
continue
|
|
}
|
|
|
|
categories[scope.Category().PathType()] = struct{}{}
|
|
|
|
collections = append(collections, dcs...)
|
|
}
|
|
|
|
if len(collections) > 0 {
|
|
baseCols, err := graph.BaseCollections(
|
|
ctx,
|
|
collections,
|
|
tenantID,
|
|
bpc.ProtectedResource.ID(),
|
|
path.ExchangeService,
|
|
categories,
|
|
su,
|
|
errs)
|
|
if err != nil {
|
|
return nil, nil, false, err
|
|
}
|
|
|
|
collections = append(collections, baseCols...)
|
|
}
|
|
|
|
return collections, nil, canUsePreviousBackup, el.Failure()
|
|
}
|
|
|
|
func canMakeDeltaQueries(
|
|
ctx context.Context,
|
|
gmi getMailboxer,
|
|
resourceOwner string,
|
|
) (bool, error) {
|
|
mi, err := GetMailboxInfo(ctx, gmi, resourceOwner)
|
|
if err != nil {
|
|
return false, clues.Stack(err)
|
|
}
|
|
|
|
return !mi.QuotaExceeded, nil
|
|
}
|