Populate function Refactor to single function (#585)
Populate functions streamlined into one function with a few additional abstractions
This commit is contained in:
parent
854635ac24
commit
9d18d50cf8
@ -6,8 +6,10 @@ package exchange
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
absser "github.com/microsoft/kiota-abstractions-go/serialization"
|
||||||
kw "github.com/microsoft/kiota-serialization-json-go"
|
kw "github.com/microsoft/kiota-serialization-json-go"
|
||||||
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
|
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
@ -46,25 +48,14 @@ type Collection struct {
|
|||||||
jobs []string
|
jobs []string
|
||||||
// service - client/adapter pair used to access M365 back store
|
// service - client/adapter pair used to access M365 back store
|
||||||
service graph.Service
|
service graph.Service
|
||||||
// populate - Utility function to populate collection based on the M365 application type and granularity
|
|
||||||
populate populater
|
collectionType optionIdentifier
|
||||||
statusCh chan<- *support.ConnectorOperationStatus
|
statusCh chan<- *support.ConnectorOperationStatus
|
||||||
// FullPath is the slice representation of the action context passed down through the hierarchy.
|
// FullPath is the slice representation of the action context passed down through the hierarchy.
|
||||||
// The original request can be gleaned from the slice. (e.g. {<tenant ID>, <user ID>, "emails"})
|
// The original request can be gleaned from the slice. (e.g. {<tenant ID>, <user ID>, "emails"})
|
||||||
fullPath []string
|
fullPath []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populater are a class of functions that can be used to fill exchange.Collections with
|
|
||||||
// the corresponding information
|
|
||||||
type populater func(
|
|
||||||
ctx context.Context,
|
|
||||||
service graph.Service,
|
|
||||||
user string,
|
|
||||||
jobs []string,
|
|
||||||
dataChannel chan<- data.Stream,
|
|
||||||
statusChannel chan<- *support.ConnectorOperationStatus,
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewExchangeDataCollection creates an ExchangeDataCollection with fullPath is annotated
|
// NewExchangeDataCollection creates an ExchangeDataCollection with fullPath is annotated
|
||||||
func NewCollection(
|
func NewCollection(
|
||||||
user string,
|
user string,
|
||||||
@ -80,189 +71,129 @@ func NewCollection(
|
|||||||
service: service,
|
service: service,
|
||||||
statusCh: statusCh,
|
statusCh: statusCh,
|
||||||
fullPath: fullPath,
|
fullPath: fullPath,
|
||||||
populate: getPopulateFunction(collectionType),
|
collectionType: collectionType,
|
||||||
}
|
}
|
||||||
return collection
|
return collection
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPopulateFunction is a function to set populate function field
|
|
||||||
// with exchange-application specific functions
|
|
||||||
func getPopulateFunction(optID optionIdentifier) populater {
|
|
||||||
switch optID {
|
|
||||||
case messages:
|
|
||||||
return PopulateForMailCollection
|
|
||||||
case contacts:
|
|
||||||
return PopulateForContactCollection
|
|
||||||
case events:
|
|
||||||
return PopulateForEventCollection
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddJob appends additional objectID to structure's jobs field
|
// AddJob appends additional objectID to structure's jobs field
|
||||||
func (eoc *Collection) AddJob(objID string) {
|
func (col *Collection) AddJob(objID string) {
|
||||||
eoc.jobs = append(eoc.jobs, objID)
|
col.jobs = append(col.jobs, objID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Items utility function to asynchronously execute process to fill data channel with
|
// Items utility function to asynchronously execute process to fill data channel with
|
||||||
// M365 exchange objects and returns the data channel
|
// M365 exchange objects and returns the data channel
|
||||||
func (eoc *Collection) Items() <-chan data.Stream {
|
func (col *Collection) Items() <-chan data.Stream {
|
||||||
if eoc.populate != nil {
|
go col.populateByOptionIdentifier(context.TODO())
|
||||||
go eoc.populate(
|
return col.data
|
||||||
context.TODO(),
|
}
|
||||||
eoc.service,
|
|
||||||
eoc.user,
|
// GetQueryAndSerializeFunc helper function that returns the two functions functions
|
||||||
eoc.jobs,
|
// required to convert M365 identifier into a byte array filled with the serialized data
|
||||||
eoc.data,
|
func GetQueryAndSerializeFunc(optID optionIdentifier) (GraphRetrievalFunc, GraphSerializeFunc) {
|
||||||
eoc.statusCh,
|
switch optID {
|
||||||
)
|
case contacts:
|
||||||
|
return RetrieveContactDataForUser, contactToDataCollection
|
||||||
|
case events:
|
||||||
|
return RetrieveEventDataForUser, eventToDataCollection
|
||||||
|
case messages:
|
||||||
|
return RetrieveMessageDataForUser, messageToDataCollection
|
||||||
|
// Unsupported options returns nil, nil
|
||||||
|
default:
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
return eoc.data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullPath returns the Collection's fullPath []string
|
// FullPath returns the Collection's fullPath []string
|
||||||
func (eoc *Collection) FullPath() []string {
|
func (col *Collection) FullPath() []string {
|
||||||
return append([]string{}, eoc.fullPath...)
|
return append([]string{}, col.fullPath...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PopulateForContactCollection(
|
// populateByOptionIdentifier is a utility function that uses col.collectionType to be able to serialize
|
||||||
|
// all the M365IDs defined in the jobs field. data channel is closed by this function
|
||||||
|
func (col *Collection) populateByOptionIdentifier(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
service graph.Service,
|
|
||||||
user string,
|
|
||||||
jobs []string,
|
|
||||||
dataChannel chan<- data.Stream,
|
|
||||||
statusChannel chan<- *support.ConnectorOperationStatus,
|
|
||||||
) {
|
) {
|
||||||
var (
|
var (
|
||||||
errs error
|
errs error
|
||||||
success int
|
success int
|
||||||
)
|
)
|
||||||
|
defer func() {
|
||||||
|
col.finishPopulation(ctx, success, errs)
|
||||||
|
}()
|
||||||
|
user := col.user
|
||||||
objectWriter := kw.NewJsonSerializationWriter()
|
objectWriter := kw.NewJsonSerializationWriter()
|
||||||
|
// get QueryBasedonIdentifier
|
||||||
for _, task := range jobs {
|
// verify that it is the correct type in called function
|
||||||
response, err := service.Client().UsersById(user).ContactsById(task).Get()
|
// serializationFunction
|
||||||
if err != nil {
|
query, serializeFunc := GetQueryAndSerializeFunc(col.collectionType)
|
||||||
trace := support.ConnectorStackErrorTrace(err)
|
if query == nil {
|
||||||
errs = support.WrapAndAppend(
|
errs = fmt.Errorf("unrecognized collection type: %s", col.collectionType.String())
|
||||||
user,
|
return
|
||||||
errors.Wrapf(err, "unable to retrieve item %s; details: %s", task, trace),
|
|
||||||
errs,
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
err = contactToDataCollection(ctx, service.Client(), objectWriter, dataChannel, response, user)
|
|
||||||
|
for _, identifier := range col.jobs {
|
||||||
|
response, err := query(col.service, user, identifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = support.WrapAndAppendf(user, err, errs)
|
errs = support.WrapAndAppendf(user, err, errs)
|
||||||
|
|
||||||
if service.ErrPolicy() {
|
if col.service.ErrPolicy() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
err = serializeFunc(ctx, col.service.Client(), objectWriter, col.data, response, user)
|
||||||
success++
|
|
||||||
|
|
||||||
}
|
|
||||||
close(dataChannel)
|
|
||||||
attemptedItems := len(jobs)
|
|
||||||
status := support.CreateStatus(ctx, support.Backup, attemptedItems, success, 1, errs)
|
|
||||||
logger.Ctx(ctx).Debug(status.String())
|
|
||||||
statusChannel <- status
|
|
||||||
}
|
|
||||||
|
|
||||||
// PopulateForMailCollection async call to fill DataCollection via channel implementation
|
|
||||||
func PopulateForMailCollection(
|
|
||||||
ctx context.Context,
|
|
||||||
service graph.Service,
|
|
||||||
user string,
|
|
||||||
jobs []string,
|
|
||||||
dataChannel chan<- data.Stream,
|
|
||||||
statusChannel chan<- *support.ConnectorOperationStatus,
|
|
||||||
) {
|
|
||||||
var errs error
|
|
||||||
var attemptedItems, success int
|
|
||||||
objectWriter := kw.NewJsonSerializationWriter()
|
|
||||||
|
|
||||||
for _, task := range jobs {
|
|
||||||
response, err := service.Client().UsersById(user).MessagesById(task).Get()
|
|
||||||
if err != nil {
|
|
||||||
trace := support.ConnectorStackErrorTrace(err)
|
|
||||||
errs = support.WrapAndAppend(user, errors.Wrapf(err, "unable to retrieve item %s; details %s", task, trace), errs)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = messageToDataCollection(ctx, service.Client(), objectWriter, dataChannel, response, user)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = support.WrapAndAppendf(user, err, errs)
|
errs = support.WrapAndAppendf(user, err, errs)
|
||||||
|
|
||||||
if service.ErrPolicy() {
|
if col.service.ErrPolicy() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
success++
|
success++
|
||||||
}
|
}
|
||||||
close(dataChannel)
|
|
||||||
attemptedItems += len(jobs)
|
|
||||||
|
|
||||||
status := support.CreateStatus(ctx, support.Backup, attemptedItems, success, 1, errs)
|
|
||||||
logger.Ctx(ctx).Debug(status.String())
|
|
||||||
statusChannel <- status
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PopulateForEventCollection(
|
// terminatePopulateSequence is a utility function used to close a Collection's data channel
|
||||||
|
// and to send the status update through the channel.
|
||||||
|
func (col *Collection) finishPopulation(ctx context.Context, success int, errs error) {
|
||||||
|
close(col.data)
|
||||||
|
attempted := len(col.jobs)
|
||||||
|
status := support.CreateStatus(ctx, support.Backup, attempted, success, 1, errs)
|
||||||
|
logger.Ctx(ctx).Debug(status.String())
|
||||||
|
col.statusCh <- status
|
||||||
|
}
|
||||||
|
|
||||||
|
// GraphSerializeFunc are class of functions that are used by Collections to transform GraphRetrievalFunc
|
||||||
|
// responses into data.Stream items contained within the Collection
|
||||||
|
type GraphSerializeFunc func(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
service graph.Service,
|
client *msgraphsdk.GraphServiceClient,
|
||||||
user string,
|
objectWriter *kw.JsonSerializationWriter,
|
||||||
jobs []string,
|
|
||||||
dataChannel chan<- data.Stream,
|
dataChannel chan<- data.Stream,
|
||||||
statusChannel chan<- *support.ConnectorOperationStatus,
|
parsable absser.Parsable,
|
||||||
) {
|
user string,
|
||||||
var (
|
) error
|
||||||
errs error
|
|
||||||
attemptedItems, success int
|
|
||||||
)
|
|
||||||
objectWriter := kw.NewJsonSerializationWriter()
|
|
||||||
|
|
||||||
for _, task := range jobs {
|
|
||||||
response, err := service.Client().UsersById(user).EventsById(task).Get()
|
|
||||||
if err != nil {
|
|
||||||
trace := support.ConnectorStackErrorTrace(err)
|
|
||||||
errs = support.WrapAndAppend(
|
|
||||||
user,
|
|
||||||
errors.Wrapf(err, "unable to retrieve items %s; details: %s", task, trace),
|
|
||||||
errs,
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = eventToDataCollection(ctx, service.Client(), objectWriter, dataChannel, response, user)
|
|
||||||
if err != nil {
|
|
||||||
errs = support.WrapAndAppend(user, err, errs)
|
|
||||||
|
|
||||||
if service.ErrPolicy() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
success++
|
|
||||||
}
|
|
||||||
close(dataChannel)
|
|
||||||
attemptedItems += len(jobs)
|
|
||||||
status := support.CreateStatus(ctx, support.Backup, attemptedItems, success, 1, errs)
|
|
||||||
logger.Ctx(ctx).Debug(status.String())
|
|
||||||
statusChannel <- status
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// eventToDataCollection is a GraphSerializeFunc used to serialize models.Eventable objects into
|
||||||
|
// data.Stream objects. Returns an error the process finishes unsuccessfully.
|
||||||
func eventToDataCollection(
|
func eventToDataCollection(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
client *msgraphsdk.GraphServiceClient,
|
client *msgraphsdk.GraphServiceClient,
|
||||||
objectWriter *kw.JsonSerializationWriter,
|
objectWriter *kw.JsonSerializationWriter,
|
||||||
dataChannel chan<- data.Stream,
|
dataChannel chan<- data.Stream,
|
||||||
event models.Eventable,
|
parsable absser.Parsable,
|
||||||
user string,
|
user string,
|
||||||
) error {
|
) error {
|
||||||
var err error
|
var err error
|
||||||
defer objectWriter.Close()
|
defer objectWriter.Close()
|
||||||
|
event, ok := parsable.(models.Eventable)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected Eventable, got %T", parsable)
|
||||||
|
}
|
||||||
|
|
||||||
if *event.GetHasAttachments() {
|
if *event.GetHasAttachments() {
|
||||||
var retriesErr error
|
var retriesErr error
|
||||||
for count := 0; count < numberOfRetries; count++ {
|
for count := 0; count < numberOfRetries; count++ {
|
||||||
@ -299,15 +230,20 @@ func eventToDataCollection(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// contactToDataCollection is a GraphSerializeFunc for models.Contactable
|
||||||
func contactToDataCollection(
|
func contactToDataCollection(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
client *msgraphsdk.GraphServiceClient,
|
client *msgraphsdk.GraphServiceClient,
|
||||||
objectWriter *kw.JsonSerializationWriter,
|
objectWriter *kw.JsonSerializationWriter,
|
||||||
dataChannel chan<- data.Stream,
|
dataChannel chan<- data.Stream,
|
||||||
contact models.Contactable,
|
parsable absser.Parsable,
|
||||||
user string,
|
user string,
|
||||||
) error {
|
) error {
|
||||||
defer objectWriter.Close()
|
defer objectWriter.Close()
|
||||||
|
contact, ok := parsable.(models.Contactable)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected Contactable, got %T", parsable)
|
||||||
|
}
|
||||||
err := objectWriter.WriteObjectValue("", contact)
|
err := objectWriter.WriteObjectValue("", contact)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return support.SetNonRecoverableError(errors.Wrap(err, *contact.GetId()))
|
return support.SetNonRecoverableError(errors.Wrap(err, *contact.GetId()))
|
||||||
@ -317,24 +253,29 @@ func contactToDataCollection(
|
|||||||
return support.WrapAndAppend(*contact.GetId(), err, nil)
|
return support.WrapAndAppend(*contact.GetId(), err, nil)
|
||||||
}
|
}
|
||||||
if byteArray != nil {
|
if byteArray != nil {
|
||||||
dataChannel <- &Stream{id: *contact.GetId(), message: byteArray, info: nil}
|
dataChannel <- &Stream{id: *contact.GetId(), message: byteArray, info: ContactInfo(contact)}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// messageToDataCollection is the GraphSerializeFunc for models.Messageable
|
||||||
func messageToDataCollection(
|
func messageToDataCollection(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
client *msgraphsdk.GraphServiceClient,
|
client *msgraphsdk.GraphServiceClient,
|
||||||
objectWriter *kw.JsonSerializationWriter,
|
objectWriter *kw.JsonSerializationWriter,
|
||||||
dataChannel chan<- data.Stream,
|
dataChannel chan<- data.Stream,
|
||||||
message models.Messageable,
|
parsable absser.Parsable,
|
||||||
user string,
|
user string,
|
||||||
) error {
|
) error {
|
||||||
var err error
|
var err error
|
||||||
aMessage := message
|
defer objectWriter.Close()
|
||||||
adtl := message.GetAdditionalData()
|
aMessage, ok := parsable.(models.Messageable)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected Messageable, got %T", parsable)
|
||||||
|
}
|
||||||
|
adtl := aMessage.GetAdditionalData()
|
||||||
if len(adtl) > 2 {
|
if len(adtl) > 2 {
|
||||||
aMessage, err = support.ConvertFromMessageable(adtl, message)
|
aMessage, err = support.ConvertFromMessageable(adtl, aMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -349,7 +290,7 @@ func messageToDataCollection(
|
|||||||
Attachments().
|
Attachments().
|
||||||
Get()
|
Get()
|
||||||
retriesErr = err
|
retriesErr = err
|
||||||
if err == nil && attached != nil {
|
if err == nil {
|
||||||
aMessage.SetAttachments(attached.GetValue())
|
aMessage.SetAttachments(attached.GetValue())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -359,19 +300,19 @@ func messageToDataCollection(
|
|||||||
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(retriesErr, "attachment failed"), nil)
|
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(retriesErr, "attachment failed"), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = objectWriter.WriteObjectValue("", aMessage)
|
err = objectWriter.WriteObjectValue("", aMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return support.SetNonRecoverableError(errors.Wrapf(err, "%s", *aMessage.GetId()))
|
return support.SetNonRecoverableError(errors.Wrapf(err, "%s", *aMessage.GetId()))
|
||||||
}
|
}
|
||||||
|
|
||||||
byteArray, err := objectWriter.GetSerializedContent()
|
byteArray, err := objectWriter.GetSerializedContent()
|
||||||
objectWriter.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(err, "serializing mail content"), nil)
|
err = support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(err, "serializing mail content"), nil)
|
||||||
|
return support.SetNonRecoverableError(err)
|
||||||
}
|
}
|
||||||
if byteArray != nil {
|
|
||||||
dataChannel <- &Stream{id: *aMessage.GetId(), message: byteArray, info: MessageInfo(aMessage)}
|
dataChannel <- &Stream{id: *aMessage.GetId(), message: byteArray, info: MessageInfo(aMessage)}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,19 +2,10 @@ package exchange
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/alcionai/corso/internal/connector/graph"
|
|
||||||
"github.com/alcionai/corso/internal/connector/mockconnector"
|
|
||||||
"github.com/alcionai/corso/internal/connector/support"
|
|
||||||
"github.com/alcionai/corso/internal/data"
|
|
||||||
"github.com/alcionai/corso/pkg/backup/details"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExchangeDataCollectionSuite struct {
|
type ExchangeDataCollectionSuite struct {
|
||||||
@ -82,38 +73,3 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeCollection_AddJob() {
|
|||||||
}
|
}
|
||||||
suite.Equal(len(shopping), len(eoc.jobs))
|
suite.Equal(len(shopping), len(eoc.jobs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestExchangeCollection_Items() tests for the Collection.Items() ability
|
|
||||||
// to asynchronously fill `data` field with Stream objects
|
|
||||||
func (suite *ExchangeDataCollectionSuite) TestExchangeCollection_Items() {
|
|
||||||
expected := 5
|
|
||||||
testFunction := func(ctx context.Context,
|
|
||||||
service graph.Service,
|
|
||||||
user string,
|
|
||||||
jobs []string,
|
|
||||||
dataChannel chan<- data.Stream,
|
|
||||||
notUsed chan<- *support.ConnectorOperationStatus,
|
|
||||||
) {
|
|
||||||
detail := &details.ExchangeInfo{Sender: "foo@bar.com", Subject: "Hello world!", Received: time.Now()}
|
|
||||||
for i := 0; i < expected; i++ {
|
|
||||||
temp := NewStream(uuid.NewString(), mockconnector.GetMockMessageBytes("Test_Items()"), *detail)
|
|
||||||
dataChannel <- &temp
|
|
||||||
}
|
|
||||||
close(dataChannel)
|
|
||||||
}
|
|
||||||
|
|
||||||
eoc := Collection{
|
|
||||||
user: "Dexter",
|
|
||||||
fullPath: []string{"Today", "is", "currently", "different"},
|
|
||||||
data: make(chan data.Stream, expected),
|
|
||||||
populate: testFunction,
|
|
||||||
}
|
|
||||||
t := suite.T()
|
|
||||||
itemsReturn := eoc.Items()
|
|
||||||
retrieved := 0
|
|
||||||
for item := range itemsReturn {
|
|
||||||
assert.NotNil(t, item)
|
|
||||||
retrieved++
|
|
||||||
}
|
|
||||||
suite.Equal(expected, retrieved)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -93,7 +93,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GraphQuery represents functions which perform exchange-specific queries
|
// GraphQuery represents functions which perform exchange-specific queries
|
||||||
// into M365 backstore.
|
// into M365 backstore. Responses -> returned items will only contain the information
|
||||||
|
// that is included in the options
|
||||||
// TODO: use selector or path for granularity into specific folders or specific date ranges
|
// TODO: use selector or path for granularity into specific folders or specific date ranges
|
||||||
type GraphQuery func(graph.Service, string) (absser.Parsable, error)
|
type GraphQuery func(graph.Service, string) (absser.Parsable, error)
|
||||||
|
|
||||||
@ -131,10 +132,10 @@ func GetAllFolderNamesForUser(gs graph.Service, user string) (absser.Parsable, e
|
|||||||
return gs.Client().UsersById(user).MailFolders().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
return gs.Client().UsersById(user).MailFolders().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllEvents for User. Default returns EventResponseCollection for events in the future
|
// GetAllEvents for User. Default returns EventResponseCollection for future events.
|
||||||
// of the time that the call was made. There a
|
// of the time that the call was made. There a
|
||||||
func GetAllEventsForUser(gs graph.Service, user string) (absser.Parsable, error) {
|
func GetAllEventsForUser(gs graph.Service, user string) (absser.Parsable, error) {
|
||||||
options, err := optionsForEvents([]string{"id", "calendar"})
|
options, err := optionsForEvents([]string{"id"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -142,6 +143,28 @@ func GetAllEventsForUser(gs graph.Service, user string) (absser.Parsable, error)
|
|||||||
return gs.Client().UsersById(user).Events().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
return gs.Client().UsersById(user).Events().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GraphRetrievalFunctions are functions from the Microsoft Graph API that retrieve
|
||||||
|
// the default associated data of a M365 object. This varies by object. Additional
|
||||||
|
// Queries must be run to obtain the omitted fields.
|
||||||
|
type GraphRetrievalFunc func(gs graph.Service, user, m365ID string) (absser.Parsable, error)
|
||||||
|
|
||||||
|
// RetrieveContactDataForUser is a GraphRetrievalFun that returns all associated fields.
|
||||||
|
func RetrieveContactDataForUser(gs graph.Service, user, m365ID string) (absser.Parsable, error) {
|
||||||
|
return gs.Client().UsersById(user).ContactsById(m365ID).Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetrieveEventDataForUser is a GraphRetrievalFunc that returns event data.
|
||||||
|
// Calendarable and attachment fields are omitted due to size
|
||||||
|
func RetrieveEventDataForUser(gs graph.Service, user, m365ID string) (absser.Parsable, error) {
|
||||||
|
return gs.Client().UsersById(user).EventsById(m365ID).Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetrieveMessageDataForUser is a GraphRetrievalFunc that returns message data.
|
||||||
|
// Attachment field is omitted due to size.
|
||||||
|
func RetrieveMessageDataForUser(gs graph.Service, user, m365ID string) (absser.Parsable, error) {
|
||||||
|
return gs.Client().UsersById(user).MessagesById(m365ID).Get()
|
||||||
|
}
|
||||||
|
|
||||||
// GraphIterateFuncs are iterate functions to be used with the M365 iterators (e.g. msgraphgocore.NewPageIterator)
|
// 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
|
// @returns a callback func that works with msgraphgocore.PageIterator.Iterate function
|
||||||
type GraphIterateFunc func(
|
type GraphIterateFunc func(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user