GC async population of m365 objects mail (#332)
-- Changes made to incorporate async population of a DataCollection
This commit is contained in:
parent
5a9f2e4601
commit
d00332f328
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@ -27,11 +27,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
|
|
||||||
- name: go-cache-paths
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=go-build::$(go env GOCACHE)"
|
|
||||||
echo "::set-output name=go-mod::$(go env GOMODCACHE)"
|
|
||||||
|
|
||||||
- name: Cache Go build
|
- name: Cache Go build
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
id: mybuild
|
id: mybuild
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
az "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
az "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||||
ka "github.com/microsoft/kiota-authentication-azure-go"
|
ka "github.com/microsoft/kiota-authentication-azure-go"
|
||||||
@ -23,7 +24,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
numberOfRetries = 3
|
numberOfRetries = 4
|
||||||
mailCategory = "mail"
|
mailCategory = "mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,12 +32,18 @@ const (
|
|||||||
// GraphRequestAdapter from the msgraph-sdk-go. Additional fields are for
|
// GraphRequestAdapter from the msgraph-sdk-go. Additional fields are for
|
||||||
// bookkeeping and interfacing with other component.
|
// bookkeeping and interfacing with other component.
|
||||||
type GraphConnector struct {
|
type GraphConnector struct {
|
||||||
tenant string
|
graphService
|
||||||
adapter msgraphsdk.GraphRequestAdapter
|
tenant string
|
||||||
|
Users map[string]string //key<email> value<id>
|
||||||
|
status *support.ConnectorOperationStatus // contains the status of the last run status
|
||||||
|
statusCh chan *support.ConnectorOperationStatus
|
||||||
|
awaitingMessages int32
|
||||||
|
credentials account.M365Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type graphService struct {
|
||||||
client msgraphsdk.GraphServiceClient
|
client msgraphsdk.GraphServiceClient
|
||||||
Users map[string]string //key<email> value<id>
|
adapter msgraphsdk.GraphRequestAdapter
|
||||||
Streams string //Not implemented for ease of code check-in
|
|
||||||
status *support.ConnectorOperationStatus // contains the status of the last run status
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGraphConnector(acct account.Account) (*GraphConnector, error) {
|
func NewGraphConnector(acct account.Account) (*GraphConnector, error) {
|
||||||
@ -44,8 +51,28 @@ func NewGraphConnector(acct account.Account) (*GraphConnector, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "retrieving m356 account configuration")
|
return nil, errors.Wrap(err, "retrieving m356 account configuration")
|
||||||
}
|
}
|
||||||
|
gc := GraphConnector{
|
||||||
|
tenant: m365.TenantID,
|
||||||
|
Users: make(map[string]string, 0),
|
||||||
|
status: nil,
|
||||||
|
statusCh: make(chan *support.ConnectorOperationStatus),
|
||||||
|
credentials: m365,
|
||||||
|
}
|
||||||
|
aService, err := gc.createService()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gc.graphService = *aService
|
||||||
|
err = gc.setTenantUsers()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &gc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createAdapter(tenant, client, secret string) (*msgraphsdk.GraphRequestAdapter, error) {
|
||||||
// Client Provider: Uses Secret for access to tenant-level data
|
// Client Provider: Uses Secret for access to tenant-level data
|
||||||
cred, err := az.NewClientSecretCredential(m365.TenantID, m365.ClientID, m365.ClientSecret, nil)
|
cred, err := az.NewClientSecretCredential(tenant, client, secret, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -54,22 +81,20 @@ func NewGraphConnector(acct account.Account) (*GraphConnector, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
adapter, err := msgraphsdk.NewGraphRequestAdapter(auth)
|
adapter, err := msgraphsdk.NewGraphRequestAdapter(auth)
|
||||||
|
return adapter, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// createSubConnector private constructor method for subConnector
|
||||||
|
func (gc *GraphConnector) createService() (*graphService, error) {
|
||||||
|
adapter, err := createAdapter(gc.credentials.TenantID, gc.credentials.ClientID, gc.credentials.ClientSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
gc := GraphConnector{
|
connector := graphService{
|
||||||
tenant: m365.TenantID,
|
|
||||||
adapter: *adapter,
|
adapter: *adapter,
|
||||||
client: *msgraphsdk.NewGraphServiceClient(adapter),
|
client: *msgraphsdk.NewGraphServiceClient(adapter),
|
||||||
Users: make(map[string]string, 0),
|
|
||||||
status: nil,
|
|
||||||
}
|
}
|
||||||
// TODO: Revisit Query all users.
|
return &connector, err
|
||||||
err = gc.setTenantUsers()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &gc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTenantUsers queries the M365 to identify the users in the
|
// setTenantUsers queries the M365 to identify the users in the
|
||||||
@ -83,7 +108,7 @@ func (gc *GraphConnector) setTenantUsers() error {
|
|||||||
options := &msuser.UsersRequestBuilderGetRequestConfiguration{
|
options := &msuser.UsersRequestBuilderGetRequestConfiguration{
|
||||||
QueryParameters: requestParams,
|
QueryParameters: requestParams,
|
||||||
}
|
}
|
||||||
response, err := gc.client.Users().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
response, err := gc.graphService.client.Users().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -91,7 +116,7 @@ func (gc *GraphConnector) setTenantUsers() error {
|
|||||||
err = support.WrapAndAppend("general access", errors.New("connector failed: No access"), err)
|
err = support.WrapAndAppend("general access", errors.New("connector failed: No access"), err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
userIterator, err := msgraphgocore.NewPageIterator(response, &gc.adapter, models.CreateUserCollectionResponseFromDiscriminatorValue)
|
userIterator, err := msgraphgocore.NewPageIterator(response, &gc.graphService.adapter, models.CreateUserCollectionResponseFromDiscriminatorValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -99,7 +124,7 @@ func (gc *GraphConnector) setTenantUsers() error {
|
|||||||
callbackFunc := func(userItem interface{}) bool {
|
callbackFunc := func(userItem interface{}) bool {
|
||||||
user, ok := userItem.(models.Userable)
|
user, ok := userItem.(models.Userable)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = support.WrapAndAppend(gc.adapter.GetBaseUrl(), errors.New("user iteration failure"), err)
|
err = support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), errors.New("user iteration failure"), err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
gc.Users[*user.GetMail()] = *user.GetId()
|
gc.Users[*user.GetMail()] = *user.GetId()
|
||||||
@ -107,7 +132,7 @@ func (gc *GraphConnector) setTenantUsers() error {
|
|||||||
}
|
}
|
||||||
iterateError = userIterator.Iterate(callbackFunc)
|
iterateError = userIterator.Iterate(callbackFunc)
|
||||||
if iterateError != nil {
|
if iterateError != nil {
|
||||||
err = support.WrapAndAppend(gc.adapter.GetBaseUrl(), iterateError, err)
|
err = support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), iterateError, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -171,17 +196,16 @@ func (gc *GraphConnector) ExchangeDataCollection(ctx context.Context, selector s
|
|||||||
}
|
}
|
||||||
dcs, err := gc.serializeMessages(ctx, user)
|
dcs, err := gc.serializeMessages(ctx, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = support.WrapAndAppend(user, err, errs)
|
return nil, support.WrapAndAppend(user, err, errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dcs) > 0 {
|
if len(dcs) > 0 {
|
||||||
collections = append(collections, dcs...)
|
for _, collection := range dcs {
|
||||||
|
collections = append(collections, collection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO replace with completion of Issue 124:
|
|
||||||
|
|
||||||
//TODO: Retry handler to convert return: (DataCollection, error)
|
|
||||||
return collections, errs
|
return collections, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +259,7 @@ func (gc *GraphConnector) RestoreMessages(ctx context.Context, dcs []DataCollect
|
|||||||
clone.SetSingleValueExtendedProperties(svlep)
|
clone.SetSingleValueExtendedProperties(svlep)
|
||||||
draft := false
|
draft := false
|
||||||
clone.SetIsDraft(&draft)
|
clone.SetIsDraft(&draft)
|
||||||
sentMessage, err := gc.client.UsersById(user).MailFoldersById(address).Messages().Post(clone)
|
sentMessage, err := gc.graphService.client.UsersById(user).MailFoldersById(address).Messages().Post(clone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = support.WrapAndAppend(
|
errs = support.WrapAndAppend(
|
||||||
data.UUID()+": "+support.ConnectorStackErrorTrace(err),
|
data.UUID()+": "+support.ConnectorStackErrorTrace(err),
|
||||||
@ -263,13 +287,13 @@ func (gc *GraphConnector) RestoreMessages(ctx context.Context, dcs []DataCollect
|
|||||||
|
|
||||||
// serializeMessages: Temp Function as place Holder until Collections have been added
|
// serializeMessages: Temp Function as place Holder until Collections have been added
|
||||||
// to the GraphConnector struct.
|
// to the GraphConnector struct.
|
||||||
func (gc *GraphConnector) serializeMessages(ctx context.Context, user string) ([]DataCollection, error) {
|
func (gc *GraphConnector) serializeMessages(ctx context.Context, user string) (map[string]*ExchangeDataCollection, error) {
|
||||||
options := optionsForMessageSnapshot()
|
options := optionsForMessageSnapshot()
|
||||||
response, err := gc.client.UsersById(user).Messages().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
response, err := gc.graphService.client.UsersById(user).Messages().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pageIterator, err := msgraphgocore.NewPageIterator(response, &gc.adapter, models.CreateMessageCollectionResponseFromDiscriminatorValue)
|
pageIterator, err := msgraphgocore.NewPageIterator(response, &gc.graphService.adapter, models.CreateMessageCollectionResponseFromDiscriminatorValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -277,7 +301,7 @@ func (gc *GraphConnector) serializeMessages(ctx context.Context, user string) ([
|
|||||||
callbackFunc := func(messageItem any) bool {
|
callbackFunc := func(messageItem any) bool {
|
||||||
message, ok := messageItem.(models.Messageable)
|
message, ok := messageItem.(models.Messageable)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = support.WrapAndAppendf(gc.adapter.GetBaseUrl(), errors.New("message iteration failure"), err)
|
err = support.WrapAndAppendf(gc.graphService.adapter.GetBaseUrl(), errors.New("message iteration failure"), err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Saving to messages to list. Indexed by folder
|
// Saving to messages to list. Indexed by folder
|
||||||
@ -286,48 +310,89 @@ func (gc *GraphConnector) serializeMessages(ctx context.Context, user string) ([
|
|||||||
}
|
}
|
||||||
iterateError := pageIterator.Iterate(callbackFunc)
|
iterateError := pageIterator.Iterate(callbackFunc)
|
||||||
if iterateError != nil {
|
if iterateError != nil {
|
||||||
err = support.WrapAndAppend(gc.adapter.GetBaseUrl(), iterateError, err)
|
err = support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), iterateError, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err // return error if snapshot is incomplete
|
return nil, err // return error if snapshot is incomplete
|
||||||
}
|
}
|
||||||
// Time to create Exchange data Holder
|
// Create collection of ExchangeDataCollection and create data Holder
|
||||||
collections := make([]DataCollection, 0)
|
collections := make(map[string]*ExchangeDataCollection)
|
||||||
objectWriter := kw.NewJsonSerializationWriter()
|
|
||||||
var errs error
|
|
||||||
var attemptedItems, success int
|
|
||||||
|
|
||||||
for aFolder, tasks := range tasklist {
|
for aFolder := range tasklist {
|
||||||
// prep the items for handoff to the backup consumer
|
// prep the items for handoff to the backup consumer
|
||||||
edc := NewExchangeDataCollection(user, []string{gc.tenant, user, mailCategory, aFolder})
|
edc := NewExchangeDataCollection(user, []string{gc.tenant, user, mailCategory, aFolder})
|
||||||
|
collections[aFolder] = &edc
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(collections) == 0 {
|
||||||
|
if len(tasklist) != 0 {
|
||||||
|
// Below error message needs revising. Assumption is that it should always
|
||||||
|
// find both items to fetch and a DataCollection to put them in
|
||||||
|
return nil, support.WrapAndAppend(
|
||||||
|
user, errors.New("found items but no directories"), err)
|
||||||
|
}
|
||||||
|
// return empty collection when no items found
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
service, err := gc.createService()
|
||||||
|
if err != nil {
|
||||||
|
return nil, support.WrapAndAppend(user, err, err)
|
||||||
|
}
|
||||||
|
// async call to populate
|
||||||
|
go service.populateFromTaskList(ctx, tasklist, collections, gc.statusCh)
|
||||||
|
gc.incrementAwaitingMessages()
|
||||||
|
|
||||||
|
return collections, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// populateFromTaskList async call to fill DataCollection via channel implementation
|
||||||
|
func (sc *graphService) populateFromTaskList(
|
||||||
|
context context.Context,
|
||||||
|
tasklist TaskList,
|
||||||
|
collections map[string]*ExchangeDataCollection,
|
||||||
|
statusChannel chan<- *support.ConnectorOperationStatus,
|
||||||
|
) {
|
||||||
|
var errs error
|
||||||
|
var attemptedItems, success int
|
||||||
|
objectWriter := kw.NewJsonSerializationWriter()
|
||||||
|
//Todo this has to return all the errors in the status
|
||||||
|
for aFolder, tasks := range tasklist {
|
||||||
|
// Get the same folder
|
||||||
|
edc := collections[aFolder]
|
||||||
|
if edc == nil {
|
||||||
|
for _, task := range tasks {
|
||||||
|
errs = support.WrapAndAppend(task, errors.New("unable to query: collection not found during populateFromTaskList"), errs)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for _, task := range tasks {
|
for _, task := range tasks {
|
||||||
response, err := gc.client.UsersById(user).MessagesById(task).Get()
|
response, err := sc.client.UsersById(edc.user).MessagesById(task).Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
details := support.ConnectorStackErrorTrace(err)
|
details := support.ConnectorStackErrorTrace(err)
|
||||||
errs = support.WrapAndAppend(user, errors.Wrapf(err, "unable to retrieve %s, %s", task, details), errs)
|
errs = support.WrapAndAppend(edc.user, errors.Wrapf(err, "unable to retrieve %s, %s", task, details), errs)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = gc.messageToDataCollection(ctx, objectWriter, edc, response, user)
|
err = messageToDataCollection(&sc.client, context, objectWriter, edc.data, response, edc.user)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = support.WrapAndAppendf(user, err, errs)
|
errs = support.WrapAndAppendf(edc.user, err, errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edc.FinishPopulation()
|
edc.FinishPopulation()
|
||||||
attemptedItems += len(tasks)
|
attemptedItems += len(tasks)
|
||||||
success += edc.Length()
|
success += edc.Length()
|
||||||
collections = append(collections, &edc)
|
|
||||||
}
|
}
|
||||||
status := support.CreateStatus(ctx, support.Backup, attemptedItems, success, len(tasklist), errs)
|
status := support.CreateStatus(context, support.Backup, attemptedItems, success, len(tasklist), errs)
|
||||||
gc.SetStatus(*status)
|
logger.Ctx(context).Debug(status.String())
|
||||||
logger.Ctx(ctx).Debugw(gc.PrintableStatus())
|
statusChannel <- status
|
||||||
return collections, errs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphConnector) messageToDataCollection(
|
func messageToDataCollection(
|
||||||
|
client *msgraphsdk.GraphServiceClient,
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
objectWriter *kw.JsonSerializationWriter,
|
objectWriter *kw.JsonSerializationWriter,
|
||||||
edc ExchangeDataCollection,
|
dataChannel chan<- DataStream,
|
||||||
message models.Messageable,
|
message models.Messageable,
|
||||||
user string,
|
user string,
|
||||||
) error {
|
) error {
|
||||||
@ -344,7 +409,7 @@ func (gc *GraphConnector) messageToDataCollection(
|
|||||||
// getting all the attachments might take a couple attempts due to filesize
|
// getting all the attachments might take a couple attempts due to filesize
|
||||||
var retriesErr error
|
var retriesErr error
|
||||||
for count := 0; count < numberOfRetries; count++ {
|
for count := 0; count < numberOfRetries; count++ {
|
||||||
attached, err := gc.client.
|
attached, err := client.
|
||||||
UsersById(user).
|
UsersById(user).
|
||||||
MessagesById(*aMessage.GetId()).
|
MessagesById(*aMessage.GetId()).
|
||||||
Attachments().
|
Attachments().
|
||||||
@ -371,9 +436,8 @@ func (gc *GraphConnector) messageToDataCollection(
|
|||||||
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(err, "serializing mail content"), nil)
|
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(err, "serializing mail content"), nil)
|
||||||
}
|
}
|
||||||
if byteArray != nil {
|
if byteArray != nil {
|
||||||
edc.PopulateCollection(&ExchangeData{id: *aMessage.GetId(), message: byteArray})
|
dataChannel <- &ExchangeData{id: *aMessage.GetId(), message: byteArray}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,6 +446,16 @@ func (gc *GraphConnector) SetStatus(cos support.ConnectorOperationStatus) {
|
|||||||
gc.status = &cos
|
gc.status = &cos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AwaitStatus updates status field based on item within statusChannel.
|
||||||
|
func (gc *GraphConnector) AwaitStatus() *support.ConnectorOperationStatus {
|
||||||
|
if gc.awaitingMessages > 0 {
|
||||||
|
gc.status = <-gc.statusCh
|
||||||
|
atomic.AddInt32(&gc.awaitingMessages, -1)
|
||||||
|
return gc.status
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Status returns the current status of the graphConnector operaion.
|
// Status returns the current status of the graphConnector operaion.
|
||||||
func (gc *GraphConnector) Status() *support.ConnectorOperationStatus {
|
func (gc *GraphConnector) Status() *support.ConnectorOperationStatus {
|
||||||
return gc.status
|
return gc.status
|
||||||
@ -395,6 +469,10 @@ func (gc *GraphConnector) PrintableStatus() string {
|
|||||||
return gc.status.String()
|
return gc.status.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gc *GraphConnector) incrementAwaitingMessages() {
|
||||||
|
atomic.AddInt32(&gc.awaitingMessages, 1)
|
||||||
|
}
|
||||||
|
|
||||||
// IsRecoverableError returns true iff error is a RecoverableGCEerror
|
// IsRecoverableError returns true iff error is a RecoverableGCEerror
|
||||||
func IsRecoverableError(e error) bool {
|
func IsRecoverableError(e error) bool {
|
||||||
var recoverable support.RecoverableGCError
|
var recoverable support.RecoverableGCError
|
||||||
|
|||||||
@ -59,11 +59,15 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_setTenantUsers()
|
|||||||
|
|
||||||
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataCollection() {
|
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataCollection() {
|
||||||
sel := selectors.NewExchangeBackup()
|
sel := selectors.NewExchangeBackup()
|
||||||
sel.Include(sel.Users("lidiah@8qzvrj.onmicrosoft.com"))
|
sel.Include(sel.Users("meganb@8qzvrj.onmicrosoft.com"))
|
||||||
collectionList, err := suite.connector.ExchangeDataCollection(context.Background(), sel.Selector)
|
collectionList, err := suite.connector.ExchangeDataCollection(context.Background(), sel.Selector)
|
||||||
assert.NotNil(suite.T(), collectionList, "collection list")
|
assert.NotNil(suite.T(), collectionList, "collection list")
|
||||||
assert.Nil(suite.T(), err)
|
assert.Nil(suite.T(), err)
|
||||||
assert.NotNil(suite.T(), suite.connector.status, "connector status")
|
assert.True(suite.T(), suite.connector.awaitingMessages > 0)
|
||||||
|
assert.Nil(suite.T(), suite.connector.status)
|
||||||
|
status := suite.connector.AwaitStatus()
|
||||||
|
assert.NotNil(suite.T(), status, "status not blocking on async call")
|
||||||
|
|
||||||
exchangeData := collectionList[0]
|
exchangeData := collectionList[0]
|
||||||
suite.Greater(len(exchangeData.FullPath()), 2)
|
suite.Greater(len(exchangeData.FullPath()), 2)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,6 @@ func (op *BackupOperation) Run(ctx context.Context) error {
|
|||||||
stats.readErr = err
|
stats.readErr = err
|
||||||
return errors.Wrap(err, "retrieving service data")
|
return errors.Wrap(err, "retrieving service data")
|
||||||
}
|
}
|
||||||
stats.gc = gc.Status()
|
|
||||||
|
|
||||||
// hand the results to the consumer
|
// hand the results to the consumer
|
||||||
var details *backup.Details
|
var details *backup.Details
|
||||||
@ -99,6 +98,7 @@ func (op *BackupOperation) Run(ctx context.Context) error {
|
|||||||
stats.writeErr = err
|
stats.writeErr = err
|
||||||
return errors.Wrap(err, "backing up service data")
|
return errors.Wrap(err, "backing up service data")
|
||||||
}
|
}
|
||||||
|
stats.gc = gc.AwaitStatus()
|
||||||
|
|
||||||
err = op.createBackupModels(ctx, stats.k.SnapshotID, details)
|
err = op.createBackupModels(ctx, stats.k.SnapshotID, details)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user