Skip to content

Commit

Permalink
Merge pull request microsoftgraph#239 from microsoftgraph/build_middl…
Browse files Browse the repository at this point in the history
…eware_chain

Simplify building middleware chain
  • Loading branch information
krototype authored Oct 18, 2019
2 parents 7baaf98 + b2f7d3b commit de8a55b
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 0 deletions.
39 changes: 39 additions & 0 deletions spec/core/HTTPClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@

import { assert } from "chai";

import { Client } from "../../src/Client";
import { HTTPClient } from "../../src/HTTPClient";
import { Context } from "../../src/IContext";
import { FetchOptions } from "../../src/IFetchOptions";
import { RedirectHandlerOptions } from "../../src/middleware/options/RedirectHandlerOptions";
import { RedirectHandler } from "../../src/middleware/RedirectHandler";
import { TelemetryHandler } from "../../src/middleware/TelemetryHandler";
import { DummyHTTPMessageHandler } from "../DummyHTTPMessageHandler";

describe("HTTPClient.ts", () => {
Expand Down Expand Up @@ -68,4 +72,39 @@ describe("HTTPClient.ts", () => {
}
});
});

describe("getMiddlewareArray", () => {
it("Should work fine for a single middleware in the chain, which does have a getNext method", () => {
const telemetryHandler = new TelemetryHandler();
const tempHttpClient: HTTPClient = new HTTPClient(telemetryHandler);
assert.equal(tempHttpClient.getMiddlewareArray().length, 1);
});

it("Should work fine for a single middleware in the chain, which doesn't have a getNext method", () => {
const tempHttpClient: HTTPClient = new HTTPClient(httpMessageHandler);
assert.equal(tempHttpClient.getMiddlewareArray().length, 1);
});

it("Should work fine for a chain containing many middlewares", () => {
const telemetryHandler = new TelemetryHandler();
const redirectHandler = new RedirectHandler(new RedirectHandlerOptions());
redirectHandler.setNext(telemetryHandler);
telemetryHandler.setNext(httpMessageHandler);
const tempHttpClient: HTTPClient = new HTTPClient(redirectHandler);
assert.equal(tempHttpClient.getMiddlewareArray().length, 3);
});
});

describe("setMiddlewareArray", () => {
it("Should make a chain out of the provided array of middlewares", () => {
const telemetryHandler = new TelemetryHandler();
const redirectHandler = new RedirectHandler(new RedirectHandlerOptions());
redirectHandler.setNext(httpMessageHandler);
const tempHttpClient: HTTPClient = new HTTPClient(redirectHandler);
const middlewareArray = tempHttpClient.getMiddlewareArray();
middlewareArray.splice(1, 0, telemetryHandler);
tempHttpClient.setMiddlewareArray(middlewareArray);
assert.equal(tempHttpClient.getMiddlewareArray().length, 3);
});
});
});
19 changes: 19 additions & 0 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { HTTPClient } from "./HTTPClient";
import { HTTPClientFactory } from "./HTTPClientFactory";
import { ClientOptions } from "./IClientOptions";
import { Options } from "./IOptions";
import { Middleware } from "./middleware/IMiddleware";
import { validatePolyFilling } from "./ValidatePolyFilling";

export class Client {
Expand Down Expand Up @@ -103,6 +104,24 @@ export class Client {
this.httpClient = httpClient;
}

/**
* @public
* function to get the array of middlewares in use right now
* @returns An array of middlewares
*/
public getMiddlewareChain() {
return this.httpClient.getMiddlewareArray();
}

/**
* @public
* function to set the middleware chain
* @param {Middleware[]} middlewareArray - An array of middlewares
*/
public setMiddlewareChain(middlewareArray: Middleware[]) {
return this.httpClient.setMiddlewareArray(middlewareArray);
}

/**
* @public
* Entry point to make requests
Expand Down
31 changes: 31 additions & 0 deletions src/HTTPClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,37 @@ export class HTTPClient {
this.middleware = middleware;
}

/**
* @public
* To get an array of Middleware, used in middleware chain
* @returns An array of middlewares
*/
public getMiddlewareArray(): Middleware[] {
const middlewareArray: Middleware[] = [];
let currentMiddleware = this.middleware;
while (currentMiddleware) {
middlewareArray.push(currentMiddleware);
if (typeof currentMiddleware.getNext !== "undefined") {
currentMiddleware = currentMiddleware.getNext();
} else {
break;
}
}
return middlewareArray;
}

/**
* @public
* To set the middleware chain
* @param {Middleware[]} middlewareArray - The array containing the middlewares
*/
public setMiddlewareArray(middlewareArray: Middleware[]) {
for (let num = 0; num < middlewareArray.length - 1; num += 1) {
middlewareArray[num].setNext(middlewareArray[num + 1]);
}
this.middleware = middlewareArray[0];
}

/**
* @public
* @async
Expand Down
9 changes: 9 additions & 0 deletions src/middleware/AuthenticationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,13 @@ export class AuthenticationHandler implements Middleware {
public setNext(next: Middleware): void {
this.nextMiddleware = next;
}

/**
* @public
* To get the next middleware in the chain
* @returns next Middleware instance
*/
public getNext(): Middleware {
return this.nextMiddleware;
}
}
1 change: 1 addition & 0 deletions src/middleware/IMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ import { Context } from "../IContext";
export interface Middleware {
execute: (context: Context) => Promise<void>;
setNext?: (middleware: Middleware) => void;
getNext?: () => Middleware;
}
9 changes: 9 additions & 0 deletions src/middleware/RedirectHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,13 @@ export class RedirectHandler implements Middleware {
public setNext(next: Middleware): void {
this.nextMiddleware = next;
}

/**
* @public
* To get the next middleware in the chain
* @returns next Middleware instance
*/
public getNext(): Middleware {
return this.nextMiddleware;
}
}
9 changes: 9 additions & 0 deletions src/middleware/RetryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,13 @@ export class RetryHandler implements Middleware {
public setNext(next: Middleware): void {
this.nextMiddleware = next;
}

/**
* @public
* To get the next middleware in the chain
* @returns next Middleware instance
*/
public getNext(): Middleware {
return this.nextMiddleware;
}
}
9 changes: 9 additions & 0 deletions src/middleware/TelemetryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,13 @@ export class TelemetryHandler implements Middleware {
public setNext(next: Middleware): void {
this.nextMiddleware = next;
}

/**
* @public
* To get the next middleware in the chain
* @returns next Middleware instance
*/
public getNext(): Middleware {
return this.nextMiddleware;
}
}

0 comments on commit de8a55b

Please sign in to comment.