add newClient constructor in api

This commit is contained in:
ryanfkeepers 2023-01-03 14:50:12 -07:00
parent 5ebbdd1b4e
commit 3246f6135e
13 changed files with 86 additions and 110 deletions

View File

@ -101,7 +101,10 @@ func runDisplayM365JSON(
cat = graph.StringToPathCategory(category)
)
ac := api.Client{Credentials: creds}
ac, err := api.NewClient(creds)
if err != nil {
return err
}
switch cat {
case path.EmailCategory, path.EventsCategory, path.ContactsCategory:

View File

@ -50,17 +50,38 @@ type GraphRetrievalFunc func(
// from the exchange package's broader intents.
type Client struct {
Credentials account.M365Config
// The stable service is re-usable for any non-paged request.
// This allows us to maintain performance across async requests.
stable graph.Servicer
}
// NewClient produces a new exchange api client. Must be used in
// place of creating an ad-hoc client struct.
func NewClient(creds account.M365Config) (Client, error) {
s, err := newService(creds)
if err != nil {
return Client{}, err
}
return Client{creds, s}, nil
}
// service generates a new service. Used for paged and other long-running
// requests instead of the client's stable service, so that in-flight state
// within the adapter doesn't get clobbered
func (c Client) service() (*graph.Service, error) {
return newService(c.Credentials)
}
func newService(creds account.M365Config) (*graph.Service, error) {
adapter, err := graph.CreateAdapter(
c.Credentials.AzureTenantID,
c.Credentials.AzureClientID,
c.Credentials.AzureClientSecret,
creds.AzureTenantID,
creds.AzureClientID,
creds.AzureClientSecret,
)
if err != nil {
return nil, errors.Wrap(err, "generating graph api service client")
}
return graph.NewService(adapter), nil
}

View File

@ -19,16 +19,11 @@ func (c Client) CreateContactFolder(
ctx context.Context,
user, folderName string,
) (models.ContactFolderable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
requestBody := models.NewContactFolder()
temp := folderName
requestBody.SetDisplayName(&temp)
return service.Client().UsersById(user).ContactFolders().Post(ctx, requestBody, nil)
return c.stable.Client().UsersById(user).ContactFolders().Post(ctx, requestBody, nil)
}
// DeleteContactFolder deletes the ContactFolder associated with the M365 ID if permissions are valid.
@ -37,12 +32,7 @@ func (c Client) DeleteContactFolder(
ctx context.Context,
user, folderID string,
) error {
service, err := c.service()
if err != nil {
return err
}
return service.Client().UsersById(user).ContactFoldersById(folderID).Delete(ctx, nil)
return c.stable.Client().UsersById(user).ContactFoldersById(folderID).Delete(ctx, nil)
}
// RetrieveContactDataForUser is a GraphRetrievalFun that returns all associated fields.
@ -50,12 +40,7 @@ func (c Client) RetrieveContactDataForUser(
ctx context.Context,
user, m365ID string,
) (serialization.Parsable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
return service.Client().UsersById(user).ContactsById(m365ID).Get(ctx, nil)
return c.stable.Client().UsersById(user).ContactsById(m365ID).Get(ctx, nil)
}
// GetAllContactFolderNamesForUser is a GraphQuery function for getting
@ -65,17 +50,12 @@ func (c Client) GetAllContactFolderNamesForUser(
ctx context.Context,
user string,
) (serialization.Parsable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
options, err := optionsForContactFolders([]string{"displayName", "parentFolderId"})
if err != nil {
return nil, err
}
return service.Client().UsersById(user).ContactFolders().Get(ctx, options)
return c.stable.Client().UsersById(user).ContactFolders().Get(ctx, options)
}
func (c Client) GetContactFolderByID(
@ -83,11 +63,6 @@ func (c Client) GetContactFolderByID(
userID, dirID string,
optionalFields ...string,
) (models.ContactFolderable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
fields := append([]string{"displayName", "parentFolderId"}, optionalFields...)
ofcf, err := optionsForContactFolderByID(fields)
@ -95,7 +70,7 @@ func (c Client) GetContactFolderByID(
return nil, errors.Wrapf(err, "options for contact folder: %v", fields)
}
return service.Client().
return c.stable.Client().
UsersById(userID).
ContactFoldersById(dirID).
Get(ctx, ofcf)

View File

@ -19,15 +19,10 @@ func (c Client) CreateCalendar(
ctx context.Context,
user, calendarName string,
) (models.Calendarable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
requestbody := models.NewCalendar()
requestbody.SetName(&calendarName)
return service.Client().UsersById(user).Calendars().Post(ctx, requestbody, nil)
return c.stable.Client().UsersById(user).Calendars().Post(ctx, requestbody, nil)
}
// DeleteCalendar removes calendar from user's M365 account
@ -36,12 +31,7 @@ func (c Client) DeleteCalendar(
ctx context.Context,
user, calendarID string,
) error {
service, err := c.service()
if err != nil {
return err
}
return service.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
return c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
}
// RetrieveEventDataForUser is a GraphRetrievalFunc that returns event data.
@ -50,29 +40,19 @@ func (c Client) RetrieveEventDataForUser(
ctx context.Context,
user, m365ID string,
) (serialization.Parsable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
return service.Client().UsersById(user).EventsById(m365ID).Get(ctx, nil)
return c.stable.Client().UsersById(user).EventsById(m365ID).Get(ctx, nil)
}
func (c Client) GetAllCalendarNamesForUser(
ctx context.Context,
user string,
) (serialization.Parsable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
options, err := optionsForCalendars([]string{"name", "owner"})
if err != nil {
return nil, err
}
return service.Client().UsersById(user).Calendars().Get(ctx, options)
return c.stable.Client().UsersById(user).Calendars().Get(ctx, options)
}
// TODO: we want this to be the full handler, not only the builder.

View File

@ -19,17 +19,12 @@ func (c Client) CreateMailFolder(
ctx context.Context,
user, folder string,
) (models.MailFolderable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
isHidden := false
requestBody := models.NewMailFolder()
requestBody.SetDisplayName(&folder)
requestBody.SetIsHidden(&isHidden)
return service.Client().UsersById(user).MailFolders().Post(ctx, requestBody, nil)
return c.stable.Client().UsersById(user).MailFolders().Post(ctx, requestBody, nil)
}
func (c Client) CreateMailFolderWithParent(
@ -60,12 +55,7 @@ func (c Client) DeleteMailFolder(
ctx context.Context,
user, folderID string,
) error {
service, err := c.service()
if err != nil {
return err
}
return service.Client().UsersById(user).MailFoldersById(folderID).Delete(ctx, nil)
return c.stable.Client().UsersById(user).MailFoldersById(folderID).Delete(ctx, nil)
}
// RetrieveMessageDataForUser is a GraphRetrievalFunc that returns message data.
@ -74,12 +64,7 @@ func (c Client) RetrieveMessageDataForUser(
ctx context.Context,
user, m365ID string,
) (serialization.Parsable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
return service.Client().UsersById(user).MessagesById(m365ID).Get(ctx, nil)
return c.stable.Client().UsersById(user).MessagesById(m365ID).Get(ctx, nil)
}
// GetMailFoldersBuilder retrieves all of the users current mail folders.
@ -113,17 +98,12 @@ func (c Client) GetMailFolderByID(
userID, dirID string,
optionalFields ...string,
) (models.MailFolderable, error) {
service, err := c.service()
if err != nil {
return nil, err
}
ofmf, err := optionsForMailFoldersItem(optionalFields)
if err != nil {
return nil, errors.Wrapf(err, "options for mail folder: %v", optionalFields)
}
return service.Client().UsersById(userID).MailFoldersById(dirID).Get(ctx, ofmf)
return c.stable.Client().UsersById(userID).MailFoldersById(dirID).Get(ctx, ofmf)
}
// FetchMessageIDsFromDirectory function that returns a list of all the m365IDs of the exchange.Mail

View File

@ -44,17 +44,20 @@ func (suite *CacheResolverSuite) TestPopulate() {
ctx, flush := tester.NewContext()
defer flush()
ac, err := api.NewClient(suite.credentials)
require.NoError(suite.T(), err)
eventFunc := func(t *testing.T) graph.ContainerResolver {
return &eventCalendarCache{
userID: tester.M365UserID(t),
ac: api.Client{Credentials: suite.credentials},
ac: ac,
}
}
contactFunc := func(t *testing.T) graph.ContainerResolver {
return &contactFolderCache{
userID: tester.M365UserID(t),
ac: api.Client{Credentials: suite.credentials},
ac: ac,
}
}

View File

@ -85,7 +85,7 @@ func (suite *ExchangeIteratorSuite) TestCollectionFunctions() {
tests := []struct {
name string
queryFunc func(account.M365Config) api.GraphQuery
queryFunc func(*testing.T, account.M365Config) api.GraphQuery
scope selectors.ExchangeScope
iterativeFunction func(
container map[string]graph.Container,
@ -95,16 +95,20 @@ func (suite *ExchangeIteratorSuite) TestCollectionFunctions() {
}{
{
name: "Contacts Iterative Check",
queryFunc: func(amc account.M365Config) api.GraphQuery {
return api.Client{Credentials: amc}.GetAllContactFolderNamesForUser
queryFunc: func(t *testing.T, amc account.M365Config) api.GraphQuery {
ac, err := api.NewClient(amc)
require.NoError(t, err)
return ac.GetAllContactFolderNamesForUser
},
transformer: models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
iterativeFunction: IterativeCollectContactContainers,
},
{
name: "Events Iterative Check",
queryFunc: func(amc account.M365Config) api.GraphQuery {
return api.Client{Credentials: amc}.GetAllCalendarNamesForUser
queryFunc: func(t *testing.T, amc account.M365Config) api.GraphQuery {
ac, err := api.NewClient(amc)
require.NoError(t, err)
return ac.GetAllCalendarNamesForUser
},
transformer: models.CreateCalendarCollectionResponseFromDiscriminatorValue,
iterativeFunction: IterativeCollectCalendarContainers,
@ -119,7 +123,7 @@ func (suite *ExchangeIteratorSuite) TestCollectionFunctions() {
service, err := createService(m365)
require.NoError(t, err)
response, err := test.queryFunc(m365)(ctx, userID)
response, err := test.queryFunc(t, m365)(ctx, userID)
require.NoError(t, err)
// Iterator Creation

View File

@ -81,9 +81,12 @@ func (suite *MailFolderCacheIntegrationSuite) TestDeltaFetch() {
for _, test := range tests {
suite.T().Run(test.name, func(t *testing.T) {
ac, err := api.NewClient(suite.credentials)
require.NoError(t, err)
mfc := mailFolderCache{
userID: userID,
ac: api.Client{Credentials: suite.credentials},
ac: ac,
}
require.NoError(t, mfc.Populate(ctx, test.root, test.path...))

View File

@ -45,15 +45,8 @@ func (suite *ExchangeRestoreSuite) SetupSuite() {
require.NoError(t, err)
suite.credentials = m365
suite.ac = api.Client{Credentials: m365}
// adpt, err := graph.CreateAdapter(
// m365.AzureTenantID,
// m365.AzureClientID,
// m365.AzureClientSecret)
// require.NoError(t, err)
// suite.gs = graph.NewService(adpt)
suite.ac, err = api.NewClient(m365)
require.NoError(t, err)
require.NoError(suite.T(), err)
}

View File

@ -41,25 +41,30 @@ func PopulateExchangeContainerResolver(
cacheRoot string
)
ac, err := api.NewClient(qp.Credentials)
if err != nil {
return nil, err
}
switch qp.Category {
case path.EmailCategory:
res = &mailFolderCache{
userID: qp.ResourceOwner,
ac: api.Client{Credentials: qp.Credentials},
ac: ac,
}
cacheRoot = rootFolderAlias
case path.ContactsCategory:
res = &contactFolderCache{
userID: qp.ResourceOwner,
ac: api.Client{Credentials: qp.Credentials},
ac: ac,
}
cacheRoot = DefaultContactFolder
case path.EventsCategory:
res = &eventCalendarCache{
userID: qp.ResourceOwner,
ac: api.Client{Credentials: qp.Credentials},
ac: ac,
}
cacheRoot = DefaultCalendar

View File

@ -35,7 +35,6 @@ func filterContainersAndFillCollections(
) error {
var (
errs error
ac = api.Client{Credentials: qp.Credentials}
// folder ID -> delta url or folder path lookups
deltaURLs = map[string]string{}
currPaths = map[string]string{}
@ -44,6 +43,12 @@ func filterContainersAndFillCollections(
tombstones = makeTombstones(dps)
)
// TODO(rkeepers): pass in the api client instead of generating it here.
ac, err := api.NewClient(qp.Credentials)
if err != nil {
return err
}
getJobs, err := getFetchIDFunc(ac, qp.Category)
if err != nil {
return support.WrapAndAppend(qp.ResourceOwner, err, errs)

View File

@ -439,7 +439,6 @@ func CreateContainerDestinaion(
caches map[path.CategoryType]graph.ContainerResolver,
) (string, error) {
var (
ac = api.Client{Credentials: creds}
newCache = false
user = directory.ResourceOwner()
category = directory.Category()
@ -447,6 +446,12 @@ func CreateContainerDestinaion(
newPathFolders = append([]string{destination}, directory.Folders()...)
)
// TODO(rkeepers): pass the api client into this func, rather than generating one.
ac, err := api.NewClient(creds)
if err != nil {
return "", err
}
switch category {
case path.EmailCategory:
if directoryCache == nil {

View File

@ -134,10 +134,9 @@ func (suite *GraphConnectorUnitSuite) TestUnionSiteIDsAndWebURLs() {
type GraphConnectorIntegrationSuite struct {
suite.Suite
connector *GraphConnector
user string
acct account.Account
credentials account.M365Config
connector *GraphConnector
user string
acct account.Account
}
func TestGraphConnectorIntegrationSuite(t *testing.T) {