UNPKG

@microsoft/microsoft-graph-client

Version:
245 lines 11.2 kB
"use strict"; /** * ------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ChaosHandler = void 0; var tslib_1 = require("tslib"); var MiddlewareControl_1 = require("./MiddlewareControl"); var MiddlewareUtil_1 = require("./MiddlewareUtil"); var ChaosHandlerData_1 = require("./options/ChaosHandlerData"); var ChaosHandlerOptions_1 = require("./options/ChaosHandlerOptions"); var ChaosStrategy_1 = require("./options/ChaosStrategy"); /** * Class representing ChaosHandler * @class * Class * @implements Middleware */ var ChaosHandler = /** @class */ (function () { /** * @public * @constructor * To create an instance of Testing Handler * @param {ChaosHandlerOptions} [options = new ChaosHandlerOptions()] - The testing handler options instance * @param manualMap - The Map passed by user containing url-statusCode info * @returns An instance of Testing Handler */ function ChaosHandler(options, manualMap) { if (options === void 0) { options = new ChaosHandlerOptions_1.ChaosHandlerOptions(); } this.options = options; this.manualMap = manualMap; } /** * Generates responseHeader * @private * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object * @param {string} requestID - request id * @param {string} requestDate - date of the request * @returns response Header */ ChaosHandler.prototype.createResponseHeaders = function (chaosHandlerOptions, requestID, requestDate) { var responseHeader = chaosHandlerOptions.headers ? new Headers(chaosHandlerOptions.headers) : new Headers(); responseHeader.append("Cache-Control", "no-store"); responseHeader.append("request-id", requestID); responseHeader.append("client-request-id", requestID); responseHeader.append("x-ms-ags-diagnostic", ""); responseHeader.append("Date", requestDate); responseHeader.append("Strict-Transport-Security", ""); if (chaosHandlerOptions.statusCode === 429) { // throttling case has to have a timeout scenario responseHeader.append("retry-after", "3"); } return responseHeader; }; /** * Generates responseBody * @private * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object * @param {string} requestID - request id * @param {string} requestDate - date of the request * * @returns response body */ ChaosHandler.prototype.createResponseBody = function (chaosHandlerOptions, requestID, requestDate) { if (chaosHandlerOptions.responseBody) { return chaosHandlerOptions.responseBody; } var body; if (chaosHandlerOptions.statusCode >= 400) { var codeMessage = ChaosHandlerData_1.httpStatusCode[chaosHandlerOptions.statusCode]; var errMessage = chaosHandlerOptions.statusMessage; body = { error: { code: codeMessage, message: errMessage, innerError: { "request-id": requestID, date: requestDate, }, }, }; } else { body = {}; } return body; }; /** * creates a response * @private * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object * @param {Context} context - Contains the context of the request */ ChaosHandler.prototype.createResponse = function (chaosHandlerOptions, context) { var requestURL = context.request; var requestID = (0, MiddlewareUtil_1.generateUUID)(); var requestDate = new Date(); var responseHeader = this.createResponseHeaders(chaosHandlerOptions, requestID, requestDate.toString()); var responseBody = this.createResponseBody(chaosHandlerOptions, requestID, requestDate.toString()); var init = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; context.response = new Response(typeof responseBody === "string" ? responseBody : JSON.stringify(responseBody), init); }; /** * Decides whether to send the request to the graph or not * @private * @param {ChaosHandlerOptions} chaosHandlerOptions - A ChaosHandlerOptions object * @param {Context} context - Contains the context of the request * @returns nothing */ ChaosHandler.prototype.sendRequest = function (chaosHandlerOptions, context) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: this.setStatusCode(chaosHandlerOptions, context.request, context.options.method); if (!((chaosHandlerOptions.chaosStrategy === ChaosStrategy_1.ChaosStrategy.MANUAL && !this.nextMiddleware) || Math.floor(Math.random() * 100) < chaosHandlerOptions.chaosPercentage)) return [3 /*break*/, 1]; this.createResponse(chaosHandlerOptions, context); return [3 /*break*/, 3]; case 1: if (!this.nextMiddleware) return [3 /*break*/, 3]; return [4 /*yield*/, this.nextMiddleware.execute(context)]; case 2: _a.sent(); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }; /** * Fetches a random status code for the RANDOM mode from the predefined array * @private * @param {string} requestMethod - the API method for the request * @returns a random status code from a given set of status codes */ ChaosHandler.prototype.getRandomStatusCode = function (requestMethod) { var statusCodeArray = ChaosHandlerData_1.methodStatusCode[requestMethod]; return statusCodeArray[Math.floor(Math.random() * statusCodeArray.length)]; }; /** * To fetch the relative URL out of the complete URL using a predefined regex pattern * @private * @param {string} urlMethod - the complete URL * @returns the string as relative URL */ ChaosHandler.prototype.getRelativeURL = function (urlMethod) { var pattern = /https?:\/\/graph\.microsoft\.com\/[^/]+(.+?)(\?|$)/; var relativeURL; if (pattern.exec(urlMethod) !== null) { relativeURL = pattern.exec(urlMethod)[1]; } return relativeURL; }; /** * To fetch the status code from the map(if needed), then returns response by calling createResponse * @private * @param {ChaosHandlerOptions} chaosHandlerOptions - The ChaosHandlerOptions object * @param {string} requestURL - the URL for the request * @param {string} requestMethod - the API method for the request */ ChaosHandler.prototype.setStatusCode = function (chaosHandlerOptions, requestURL, requestMethod) { var _this = this; if (chaosHandlerOptions.chaosStrategy === ChaosStrategy_1.ChaosStrategy.MANUAL) { if (chaosHandlerOptions.statusCode === undefined) { // manual mode with no status code, can be a global level or request level without statusCode var relativeURL_1 = this.getRelativeURL(requestURL); if (this.manualMap.get(relativeURL_1) !== undefined) { // checking Manual Map for exact match if (this.manualMap.get(relativeURL_1).get(requestMethod) !== undefined) { chaosHandlerOptions.statusCode = this.manualMap.get(relativeURL_1).get(requestMethod); } // else statusCode would be undefined } else { // checking for regex match if exact match doesn't work this.manualMap.forEach(function (value, key) { var regexURL = new RegExp(key + "$"); if (regexURL.test(relativeURL_1)) { if (_this.manualMap.get(key).get(requestMethod) !== undefined) { chaosHandlerOptions.statusCode = _this.manualMap.get(key).get(requestMethod); } // else statusCode would be undefined } }); } // Case of redirection or request url not in map ---> statusCode would be undefined } } else { // Handling the case of Random here chaosHandlerOptions.statusCode = this.getRandomStatusCode(requestMethod); // else statusCode would be undefined } }; /** * To get the options for execution of the middleware * @private * @param {Context} context - The context object * @returns options for middleware execution */ ChaosHandler.prototype.getOptions = function (context) { var options; if (context.middlewareControl instanceof MiddlewareControl_1.MiddlewareControl) { options = context.middlewareControl.getMiddlewareOptions(ChaosHandlerOptions_1.ChaosHandlerOptions); } if (typeof options === "undefined") { options = Object.assign(new ChaosHandlerOptions_1.ChaosHandlerOptions(), this.options); } return options; }; /** * To execute the current middleware * @public * @async * @param {Context} context - The context object of the request * @returns A Promise that resolves to nothing */ ChaosHandler.prototype.execute = function (context) { return tslib_1.__awaiter(this, void 0, void 0, function () { var chaosHandlerOptions; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: chaosHandlerOptions = this.getOptions(context); return [4 /*yield*/, this.sendRequest(chaosHandlerOptions, context)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * @public * To set the next middleware in the chain * @param {Middleware} next - The middleware instance * @returns Nothing */ ChaosHandler.prototype.setNext = function (next) { this.nextMiddleware = next; }; return ChaosHandler; }()); exports.ChaosHandler = ChaosHandler; //# sourceMappingURL=ChaosHandler.js.map