Exchange restore service level handler functions (#4693)

Add service-level restore handlers for exchange

---

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

- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #4254

merge after:
* #4687
* #4651

#### Test Plan

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2023-11-16 10:22:33 -08:00 committed by GitHub
parent e0f51943a5
commit 1cbabdb73a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 5 deletions

View File

@ -31,7 +31,7 @@ func (ctrl *Controller) NewServiceHandler(
return groups.NewGroupsHandler(opts, ctrl.AC, ctrl.resourceHandler), nil
case path.ExchangeService:
return exchange.NewExchangeHandler(opts), nil
return exchange.NewExchangeHandler(opts, ctrl.AC, ctrl.resourceHandler), nil
}
return nil, clues.New("unrecognized service").

View File

@ -5,8 +5,10 @@ import (
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/m365/collection/exchange"
"github.com/alcionai/corso/src/internal/m365/resource"
"github.com/alcionai/corso/src/internal/operations/inject"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/control"
@ -14,18 +16,31 @@ import (
"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"
)
var _ inject.ServiceHandler = &baseExchangeHandler{}
func NewExchangeHandler(
opts control.Options,
) *baseExchangeHandler {
return &baseExchangeHandler{
apiClient api.Client,
resourceClient idname.GetResourceIDAndNamer,
) *exchangeHandler {
return &exchangeHandler{
baseExchangeHandler: baseExchangeHandler{
opts: opts,
},
apiClient: apiClient,
resourceClient: resourceClient,
}
}
// ========================================================================== //
// baseExchangeHandler
// ========================================================================== //
// baseExchangeHandler contains logic for tracking data and doing operations
// (e.x. export) that don't require contact with external M356 services.
type baseExchangeHandler struct {
opts control.Options
}
@ -72,3 +87,39 @@ func (h *baseExchangeHandler) ProduceExportCollections(
return ec, el.Failure()
}
// ========================================================================== //
// exchangeHandler
// ========================================================================== //
// exchangeHandler contains logic for handling data and performing operations
// (e.x. restore) regardless of whether they require contact with external M365
// services or not.
type exchangeHandler struct {
baseExchangeHandler
apiClient api.Client
resourceClient idname.GetResourceIDAndNamer
}
func (h *exchangeHandler) IsServiceEnabled(
ctx context.Context,
resourceID string,
) (bool, error) {
// TODO(ashmrtn): Move free function implementation to this function.
res, err := IsServiceEnabled(ctx, h.apiClient.Users(), resourceID)
return res, clues.Stack(err).OrNil()
}
func (h *exchangeHandler) PopulateProtectedResourceIDAndName(
ctx context.Context,
resourceID string, // Can be either ID or name.
ins idname.Cacher,
) (idname.Provider, error) {
if h.resourceClient == nil {
return nil, clues.StackWC(ctx, resource.ErrNoResourceLookup)
}
pr, err := h.resourceClient.GetResourceIDAndNameFrom(ctx, resourceID, ins)
return pr, clues.Wrap(err, "identifying resource owner").OrNil()
}

View File

@ -19,6 +19,7 @@ import (
"github.com/alcionai/corso/src/pkg/export"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type ExportUnitSuite struct {
@ -373,7 +374,7 @@ func (suite *ExportUnitSuite) TestExportRestoreCollections() {
exportCfg := control.ExportConfig{}
stats := data.ExportStats{}
ecs, err := NewExchangeHandler(control.DefaultOptions()).
ecs, err := NewExchangeHandler(control.DefaultOptions(), api.Client{}, nil).
ProduceExportCollections(
ctx,
int(version.Backup),