Skip to content

Commit 875b2e6

Browse files
Merge pull request #240 from microsoftgraph/shweaver/component-header
Add component header to graph calls
2 parents a2ce8d6 + b58a8cd commit 875b2e6

File tree

9 files changed

+96
-40
lines changed

9 files changed

+96
-40
lines changed

src/Graph.ts

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import {
99
AuthenticationHandler,
1010
Client,
1111
HTTPMessageHandler,
12+
Middleware,
1213
ResponseType,
1314
RetryHandler,
1415
RetryHandlerOptions,
1516
TelemetryHandler
1617
} from '@microsoft/microsoft-graph-client';
1718
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
1819
import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta';
20+
import { MgtBaseComponent } from './components/baseComponent';
1921
import { IProvider } from './providers/IProvider';
2022
import { Batch } from './utils/Batch';
2123
import { prepScopes } from './utils/GraphHelpers';
@@ -36,25 +38,38 @@ export class Graph {
3638
*/
3739
public client: Client;
3840

39-
constructor(provider: IProvider) {
41+
private _provider: IProvider;
42+
43+
constructor(provider: IProvider, component?: MgtBaseComponent) {
4044
if (provider) {
41-
const authenticationHandler = new AuthenticationHandler(provider);
42-
const retryHandler = new RetryHandler(new RetryHandlerOptions());
43-
const telemetryHandler = new TelemetryHandler();
44-
const sdkVersionMiddleware = new SdkVersionMiddleware();
45-
const httpMessageHandler = new HTTPMessageHandler();
45+
this._provider = provider;
4646

47-
authenticationHandler.setNext(retryHandler);
48-
retryHandler.setNext(telemetryHandler);
49-
telemetryHandler.setNext(sdkVersionMiddleware);
50-
sdkVersionMiddleware.setNext(httpMessageHandler);
47+
const middleware: Middleware[] = [
48+
new AuthenticationHandler(provider),
49+
new RetryHandler(new RetryHandlerOptions()),
50+
new TelemetryHandler(),
51+
new SdkVersionMiddleware(component),
52+
new HTTPMessageHandler()
53+
];
5154

5255
this.client = Client.initWithMiddleware({
53-
middleware: authenticationHandler
56+
middleware: this.chainMiddleware(...middleware)
5457
});
5558
}
5659
}
5760

61+
/**
62+
* Returns a new instance of the Graph using the same
63+
* provider and the provided component.
64+
*
65+
* @param {MgtBaseComponent} component
66+
* @returns
67+
* @memberof Graph
68+
*/
69+
public forComponent(component: MgtBaseComponent): Graph {
70+
return new Graph(this._provider, component);
71+
}
72+
5873
/**
5974
* creates batch request
6075
*
@@ -608,6 +623,19 @@ export class Graph {
608623
.delete();
609624
}
610625

626+
private chainMiddleware(...middleware: Middleware[]): Middleware {
627+
const rootMiddleware = middleware[0];
628+
let current = rootMiddleware;
629+
for (let i = 1; i < middleware.length; ++i) {
630+
const next = middleware[i];
631+
if (current.setNext) {
632+
current.setNext(next);
633+
}
634+
current = next;
635+
}
636+
return rootMiddleware;
637+
}
638+
611639
private blobToBase64(blob: Blob): Promise<string> {
612640
return new Promise((resolve, reject) => {
613641
const reader = new FileReader();

src/components/mgt-agenda/mgt-agenda.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ export class MgtAgenda extends MgtTemplatedComponent {
219219
query = this.eventQuery;
220220
}
221221

222-
let request = await p.graph.client.api(query);
222+
const graph = p.graph.forComponent(this);
223+
let request = await graph.client.api(query);
223224

224225
if (scope) {
225226
request = request.middlewareOptions(prepScopes(scope));

src/components/mgt-get/mgt-get.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ export class MgtGet extends MgtTemplatedComponent {
152152

153153
let response = null;
154154
try {
155-
let request = provider.graph.client.api(this.resource).version(this.version);
155+
const graph = provider.graph.forComponent(this);
156+
let request = graph.client.api(this.resource).version(this.version);
156157

157158
if (this.scopes && this.scopes.length) {
158159
request = request.middlewareOptions(prepScopes(...this.scopes));
@@ -166,7 +167,7 @@ export class MgtGet extends MgtTemplatedComponent {
166167
while ((pageCount < this.maxPages || this.maxPages <= 0) && page && page['@odata.nextLink']) {
167168
pageCount++;
168169
const nextResource = page['@odata.nextLink'].split(this.version)[1];
169-
page = await provider.graph.client
170+
page = await graph.client
170171
.api(nextResource)
171172
.version(this.version)
172173
.get();

src/components/mgt-login/mgt-login.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ export class MgtLogin extends MgtBaseComponent {
264264
if (provider) {
265265
this._loading = true;
266266
if (provider.state === ProviderState.SignedIn) {
267-
const batch = provider.graph.createBatch();
267+
const graph = provider.graph.forComponent(this);
268+
const batch = graph.createBatch();
268269
batch.get('me', 'me', ['user.read']);
269270
batch.get('photo', 'me/photo/$value', ['user.read']);
270271
const response = await batch.execute();

src/components/mgt-people-picker/mgt-people-picker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
210210
private async findGroup() {
211211
const provider = Providers.globalProvider;
212212
if (provider && provider.state === ProviderState.SignedIn) {
213-
const client = Providers.globalProvider.graph;
214-
this.groupPeople = await client.getPeopleFromGroup(this.groupId);
213+
const graph = provider.graph.forComponent(this);
214+
this.groupPeople = await graph.getPeopleFromGroup(this.groupId);
215215
}
216216
}
217217

@@ -328,13 +328,13 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
328328
this.showLoading = this.isLoading;
329329
}, 400);
330330

331-
const client = Providers.globalProvider.graph;
331+
const graph = provider.graph.forComponent(this);
332332

333333
// filtering groups
334334
if (this.groupId) {
335335
people = this.groupPeople;
336336
} else {
337-
people = await client.findPerson(name);
337+
people = await graph.findPerson(name);
338338
}
339339

340340
if (people) {

src/components/mgt-people/mgt-people.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,18 @@ export class MgtPeople extends MgtTemplatedComponent {
159159
const provider = Providers.globalProvider;
160160

161161
if (provider && provider.state === ProviderState.SignedIn) {
162-
const client = Providers.globalProvider.graph;
162+
const graph = provider.graph.forComponent(this);
163163

164164
if (this.groupId) {
165-
this.people = await client.getPeopleFromGroup(this.groupId);
165+
this.people = await graph.getPeopleFromGroup(this.groupId);
166166
} else if (this.userIds) {
167167
this.people = await Promise.all(
168168
this.userIds.map(async userId => {
169-
return await client.getUser(userId);
169+
return await graph.getUser(userId);
170170
})
171171
);
172172
} else {
173-
this.people = await client.getPeople();
173+
this.people = await graph.getPeople();
174174
}
175175
}
176176
}

src/components/mgt-person/mgt-person.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ export class MgtPerson extends MgtTemplatedComponent {
257257
}
258258

259259
if (this.userId || (this.personQuery && this.personQuery === 'me')) {
260-
const batch = provider.graph.createBatch();
260+
const graph = provider.graph.forComponent(this);
261+
const batch = graph.createBatch();
261262

262263
if (this.userId) {
263264
batch.get('user', `/users/${this.userId}`, ['user.readbasic.all']);
@@ -273,7 +274,8 @@ export class MgtPerson extends MgtTemplatedComponent {
273274
this.personImage = response.photo;
274275
(this.personDetails as any).personImage = response.photo;
275276
} else if (!this.personDetails && this.personQuery) {
276-
const people = await provider.graph.findPerson(this.personQuery);
277+
const graph = provider.graph.forComponent(this);
278+
const people = await graph.findPerson(this.personQuery);
277279
if (people && people.length > 0) {
278280
const person = people[0] as MicrosoftGraph.Person;
279281
this.personDetails = person;
@@ -285,27 +287,26 @@ export class MgtPerson extends MgtTemplatedComponent {
285287

286288
private async loadImage() {
287289
const provider = Providers.globalProvider;
290+
const graph = provider.graph.forComponent(this);
288291

289292
const person = this.personDetails;
290293
let image: string;
291294

292295
if ((person as MicrosoftGraph.Person).userPrincipalName) {
293296
const userPrincipalName = (person as MicrosoftGraph.Person).userPrincipalName;
294-
image = await provider.graph.getUserPhoto(userPrincipalName);
297+
image = await graph.getUserPhoto(userPrincipalName);
295298
} else {
296299
const email = getEmailFromGraphEntity(person);
297300
if (email) {
298301
// try to find a user by e-mail
299-
const users = await provider.graph.findUserByEmail(email);
302+
const users = await graph.findUserByEmail(email);
300303

301304
if (users && users.length) {
302305
if ((users[0] as any).personType && (users[0] as any).personType.subclass === 'OrganizationUser') {
303-
image = await provider.graph.getUserPhoto(
304-
(users[0] as MicrosoftGraph.Person).scoredEmailAddresses[0].address
305-
);
306+
image = await graph.getUserPhoto((users[0] as MicrosoftGraph.Person).scoredEmailAddresses[0].address);
306307
} else {
307308
const contactId = users[0].id;
308-
image = await provider.graph.getContactPhoto(contactId);
309+
image = await graph.getContactPhoto(contactId);
309310
}
310311
}
311312
}

src/components/mgt-tasks/mgt-tasks.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ export class MgtTasks extends MgtTemplatedComponent {
384384
this._inTaskLoad = true;
385385
let meTask;
386386
if (!this._me) {
387-
meTask = provider.graph.getMe();
387+
const graph = provider.graph.forComponent(this);
388+
meTask = graph.getMe();
388389
}
389390

390391
if (this.groupId && this.dataSource === TasksSource.planner) {
@@ -1199,10 +1200,11 @@ export class MgtTasks extends MgtTemplatedComponent {
11991200
return null;
12001201
}
12011202

1203+
const graph = p.graph.forComponent(this);
12021204
if (this.dataSource === TasksSource.planner) {
1203-
return new PlannerTaskSource(p.graph);
1205+
return new PlannerTaskSource(graph);
12041206
} else if (this.dataSource === TasksSource.todo) {
1205-
return new TodoTaskSource(p.graph);
1207+
return new TodoTaskSource(graph);
12061208
} else {
12071209
return null;
12081210
}

src/utils/SdkVersionMiddleware.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import { Context, Middleware } from '@microsoft/microsoft-graph-client';
99
import { getRequestHeader, setRequestHeader } from '@microsoft/microsoft-graph-client/lib/es/middleware/MiddlewareUtil';
10+
import { MgtBaseComponent } from '../components/baseComponent';
1011
import { PACKAGE_VERSION } from './version';
1112

1213
/**
@@ -21,17 +22,38 @@ export class SdkVersionMiddleware implements Middleware {
2122
* @private
2223
* A member to hold next middleware in the middleware chain
2324
*/
24-
private nextMiddleware: Middleware;
25+
private _nextMiddleware: Middleware;
26+
private _component?: MgtBaseComponent;
27+
28+
constructor(component?: MgtBaseComponent) {
29+
this._component = component;
30+
}
2531

2632
// tslint:disable-next-line: completed-docs
2733
public async execute(context: Context): Promise<void> {
2834
try {
29-
let sdkVersionValue: string = `mgt/${PACKAGE_VERSION}`;
35+
// Header parts must follow the format: 'name/version'
36+
const headerParts: string[] = [];
37+
38+
// Component version
39+
if (this._component) {
40+
const componentTagName = this._component.tagName.toLowerCase();
41+
const componentVersion: string = `${componentTagName}/${PACKAGE_VERSION}`;
42+
headerParts.push(componentVersion);
43+
}
44+
45+
// Package version
46+
const packageVersion: string = `mgt/${PACKAGE_VERSION}`;
47+
headerParts.push(packageVersion);
48+
49+
// Existing SdkVersion header value
50+
headerParts.push(getRequestHeader(context.request, context.options, 'SdkVersion'));
3051

31-
sdkVersionValue += ', ' + getRequestHeader(context.request, context.options, 'SdkVersion');
52+
// Join the header parts together and update the SdkVersion request header value
53+
const sdkVersionHeaderValue = headerParts.join(', ');
54+
setRequestHeader(context.request, context.options, 'SdkVersion', sdkVersionHeaderValue);
3255

33-
setRequestHeader(context.request, context.options, 'SdkVersion', sdkVersionValue);
34-
return await this.nextMiddleware.execute(context);
56+
return await this._nextMiddleware.execute(context);
3557
} catch (error) {
3658
throw error;
3759
}
@@ -43,6 +65,6 @@ export class SdkVersionMiddleware implements Middleware {
4365
* @memberof SdkVersionMiddleware
4466
*/
4567
public setNext(next: Middleware): void {
46-
this.nextMiddleware = next;
68+
this._nextMiddleware = next;
4769
}
4870
}

0 commit comments

Comments
 (0)