GC: Iterate "Select All Messages/Contacts" Consolidation with new Interface (#663)

`Descendable` interface used to move "IterateSelectAll" functions into a singular function.
Test suites are modified to support changes.
This commit is contained in:
Danny 2022-08-29 12:29:15 -04:00 committed by GitHub
parent 9f6b1bc1b8
commit d55ee98d7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 69 deletions

View File

@ -320,13 +320,13 @@ func (suite *ExchangeServiceSuite) TestIterativeFunctions() {
{
name: "Mail Iterative Check",
queryFunction: GetAllMessagesForUser,
iterativeFunction: IterateSelectAllMessagesForCollections,
iterativeFunction: IterateSelectAllDescendablesForCollections,
scope: mailScope,
transformer: models.CreateMessageCollectionResponseFromDiscriminatorValue,
}, {
name: "Contacts Iterative Check",
queryFunction: GetAllContactsForUser,
iterativeFunction: IterateAllContactsForCollection,
iterativeFunction: IterateSelectAllDescendablesForCollections,
scope: contactScope,
transformer: models.CreateContactFromDiscriminatorValue,
}, {
@ -352,7 +352,6 @@ func (suite *ExchangeServiceSuite) TestIterativeFunctions() {
// callbackFunc iterates through all models.Messageable and fills exchange.Collection.jobs[]
// with corresponding item IDs. New collections are created for each directory
callbackFunc := test.iterativeFunction(
"testingTenant",
userID,
test.scope,
errs, false,

View File

@ -211,7 +211,7 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
if scope.IsAny(selectors.ExchangeMailFolder) {
return models.CreateMessageCollectionResponseFromDiscriminatorValue,
GetAllMessagesForUser,
IterateSelectAllMessagesForCollections,
IterateSelectAllDescendablesForCollections,
nil
}
@ -230,7 +230,7 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
if scope.IncludesCategory(selectors.ExchangeContact) {
return models.CreateContactFromDiscriminatorValue,
GetAllContactsForUser,
IterateAllContactsForCollection,
IterateSelectAllDescendablesForCollections,
nil
}

View File

@ -35,7 +35,6 @@ type displayable interface {
// GraphIterateFuncs are iterate functions to be used with the M365 iterators (e.g. msgraphgocore.NewPageIterator)
// @returns a callback func that works with msgraphgocore.PageIterator.Iterate function
type GraphIterateFunc func(
tenant string,
user string,
scope selectors.ExchangeScope,
errs error,
@ -45,12 +44,11 @@ type GraphIterateFunc func(
graphStatusChannel chan<- *support.ConnectorOperationStatus,
) func(any) bool
// IterateSelectAllMessageForCollection utility function for
// Iterating through MessagesCollectionResponse
// During iteration, messages belonging to any folder are
// IterateSelectAllDescendablesForCollection utility function for
// Iterating through MessagesCollectionResponse or ContactsCollectionResponse,
// objects belonging to any folder are
// placed into a Collection based on the parent folder
func IterateSelectAllMessagesForCollections(
tenant string,
func IterateSelectAllDescendablesForCollections(
user string,
scope selectors.ExchangeScope,
errs error,
@ -59,17 +57,30 @@ func IterateSelectAllMessagesForCollections(
collections map[string]*Collection,
statusCh chan<- *support.ConnectorOperationStatus,
) func(any) bool {
return func(messageItem any) bool {
var isCategorySet bool
var collectionType optionIdentifier
var category string
return func(pageItem any) bool {
// Defines the type of collection being created within the function
collectionType := messages
if !isCategorySet {
if scope.IncludesCategory(selectors.ExchangeMail) {
collectionType = messages
category = mailCategory
}
if scope.IncludesCategory(selectors.ExchangeContact) {
collectionType = contacts
category = contactsCategory
}
isCategorySet = true
}
message, ok := messageItem.(models.Messageable)
entry, ok := pageItem.(descendable)
if !ok {
errs = support.WrapAndAppendf(user, errors.New("message iteration failure"), errs)
errs = support.WrapAndAppendf(user, errors.New("descendable conversion failure"), errs)
return true
}
// Saving to messages to list. Indexed by folder
directory := *message.GetParentFolderId()
directory := *entry.GetParentFolderId()
if _, ok = collections[directory]; !ok {
service, err := createService(credentials, failFast)
if err != nil {
@ -78,14 +89,14 @@ func IterateSelectAllMessagesForCollections(
}
edc := NewCollection(
user,
[]string{tenant, user, mailCategory, directory},
[]string{credentials.TenantID, user, category, directory},
collectionType,
service,
statusCh,
)
collections[directory] = &edc
}
collections[directory].AddJob(*message.GetId())
collections[directory].AddJob(*entry.GetId())
return true
}
}
@ -95,7 +106,6 @@ func IterateSelectAllMessagesForCollections(
// and storing events in collections based on
// the calendarID which originates from M365.
func IterateSelectAllEventsForCollections(
tenant string,
user string,
scope selectors.ExchangeScope,
errs error,
@ -155,7 +165,7 @@ func IterateSelectAllEventsForCollections(
}
edc := NewCollection(
user,
[]string{tenant, user, eventsCategory, directory},
[]string{credentials.TenantID, user, eventsCategory, directory},
events,
service,
statusCh,
@ -168,51 +178,10 @@ func IterateSelectAllEventsForCollections(
}
}
// IterateAllContactsForCollection GraphIterateFunc for moving through
// a ContactsCollectionsResponse using the msgraphgocore paging interface.
// Contacts Ids are placed into a collection based upon the parent folder
func IterateAllContactsForCollection(
tenant string,
user string,
scope selectors.ExchangeScope,
errs error,
failFast bool,
credentials account.M365Config,
collections map[string]*Collection,
statusCh chan<- *support.ConnectorOperationStatus,
) func(any) bool {
return func(contactsItem any) bool {
contact, ok := contactsItem.(models.Contactable)
if !ok {
errs = support.WrapAndAppend(user, errors.New("contact iteration failure"), errs)
return true
}
directory := *contact.GetParentFolderId()
if _, ok := collections[directory]; !ok {
service, err := createService(credentials, failFast)
if err != nil {
errs = support.WrapAndAppend(user, err, errs)
return true
}
edc := NewCollection(
user,
[]string{tenant, user, contactsCategory, directory},
contacts,
service,
statusCh,
)
collections[directory] = &edc
}
collections[directory].AddJob(*contact.GetId())
return true
}
}
// IterateAndFilterMessagesForCollections is a filtering GraphIterateFunc
// that places exchange mail message ids belonging to specific directories
// into a Collection. Messages outside of those directories are omitted.
func IterateAndFilterMessagesForCollections(
tenant string,
user string,
scope selectors.ExchangeScope,
errs error,
@ -227,7 +196,6 @@ func IterateAndFilterMessagesForCollections(
err := CollectMailFolders(
scope,
tenant,
user,
collections,
credentials,
@ -241,7 +209,7 @@ func IterateAndFilterMessagesForCollections(
isFilterSet = true
}
message, ok := messageItem.(models.Messageable)
message, ok := messageItem.(descendable)
if !ok {
errs = support.WrapAndAppend(user, errors.New("message iteration failure"), errs)
return true
@ -257,7 +225,6 @@ func IterateAndFilterMessagesForCollections(
}
func IterateFilterFolderDirectoriesForCollections(
tenant string,
user string,
scope selectors.ExchangeScope,
errs error,
@ -271,7 +238,7 @@ func IterateFilterFolderDirectoriesForCollections(
err error
)
return func(folderItem any) bool {
folder, ok := folderItem.(models.MailFolderable)
folder, ok := folderItem.(displayable)
if !ok {
errs = support.WrapAndAppend(
user,
@ -303,7 +270,7 @@ func IterateFilterFolderDirectoriesForCollections(
}
temp := NewCollection(
user,
[]string{tenant, user, mailCategory, directory},
[]string{credentials.TenantID, user, mailCategory, directory},
messages,
service,
statusCh,

View File

@ -101,7 +101,6 @@ func RetrieveMessageDataForUser(gs graph.Service, user, m365ID string) (absser.P
func CollectMailFolders(
scope selectors.ExchangeScope,
tenant string,
user string,
collections map[string]*Collection,
credentials account.M365Config,
@ -132,7 +131,6 @@ func CollectMailFolders(
}
callbackFunc := IterateFilterFolderDirectoriesForCollections(
tenant,
user,
scope,
err,

View File

@ -323,7 +323,7 @@ func (gc *GraphConnector) createCollections(
// callbackFunc iterates through all M365 object target and fills exchange.Collection.jobs[]
// with corresponding item M365IDs. New collections are created for each directory.
// Each directory used the M365 Identifier. The use of ID stops collisions betweens users
callbackFunc := gIter(gc.tenant, user, scope, errs, gc.failFast, gc.credentials, collections, gc.statusCh)
callbackFunc := gIter(user, scope, errs, gc.failFast, gc.credentials, collections, gc.statusCh)
iterateError := pageIterator.Iterate(callbackFunc)
if iterateError != nil {
errs = support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), iterateError, errs)