UNPKG

@azure/cosmos

Version:
145 lines (144 loc) • 7.11 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var sessionContainer_exports = {}; __export(sessionContainer_exports, { SessionContainer: () => SessionContainer }); module.exports = __toCommonJS(sessionContainer_exports); var import_atob = __toESM(require("../utils/atob.js")); var import_common = require("../common/index.js"); var import_VectorSessionToken = require("./VectorSessionToken.js"); class SessionContainer { constructor(collectionNameToCollectionResourceId = /* @__PURE__ */ new Map(), collectionResourceIdToSessionTokens = /* @__PURE__ */ new Map()) { this.collectionNameToCollectionResourceId = collectionNameToCollectionResourceId; this.collectionResourceIdToSessionTokens = collectionResourceIdToSessionTokens; } static EMPTY_SESSION_TOKEN = ""; static SESSION_TOKEN_SEPARATOR = ","; static SESSION_TOKEN_PARTITION_SPLITTER = ":"; get(request) { if (!request) { throw new Error("request cannot be null"); } const collectionName = (0, import_common.getContainerLink)((0, import_common.trimSlashes)(request.resourceAddress)); const rangeIdToTokenMap = this.getPartitionKeyRangeIdToTokenMap(collectionName); return SessionContainer.getCombinedSessionTokenString(rangeIdToTokenMap); } remove(request) { let collectionResourceId; const resourceAddress = (0, import_common.trimSlashes)(request.resourceAddress); const collectionName = (0, import_common.getContainerLink)(resourceAddress); if (collectionName) { collectionResourceId = this.collectionNameToCollectionResourceId.get(collectionName); this.collectionNameToCollectionResourceId.delete(collectionName); } if (collectionResourceId !== void 0) { this.collectionResourceIdToSessionTokens.delete(collectionResourceId); } } set(request, resHeaders) { if (!resHeaders || SessionContainer.isReadingFromMaster(request.resourceType, request.operationType)) { return; } const sessionTokenString = resHeaders[import_common.Constants.HttpHeaders.SessionToken]; if (!sessionTokenString) { return; } const containerName = this.getContainerName(request, resHeaders); const ownerId = !request.isNameBased ? request.resourceId : resHeaders[import_common.Constants.HttpHeaders.OwnerId] || request.resourceId; if (!ownerId) { return; } if (containerName && this.validateOwnerID(ownerId)) { if (!this.collectionResourceIdToSessionTokens.has(ownerId)) { this.collectionResourceIdToSessionTokens.set(ownerId, /* @__PURE__ */ new Map()); } if (!this.collectionNameToCollectionResourceId.has(containerName)) { this.collectionNameToCollectionResourceId.set(containerName, ownerId); } const containerSessionContainer = this.collectionResourceIdToSessionTokens.get(ownerId); SessionContainer.compareAndSetToken(sessionTokenString, containerSessionContainer); } } validateOwnerID(ownerId) { return (0, import_atob.default)(ownerId.replace(/-/g, "/")).length === 8; } getPartitionKeyRangeIdToTokenMap(collectionName) { let rangeIdToTokenMap = null; if (collectionName && this.collectionNameToCollectionResourceId.has(collectionName)) { rangeIdToTokenMap = this.collectionResourceIdToSessionTokens.get( this.collectionNameToCollectionResourceId.get(collectionName) ); } return rangeIdToTokenMap; } static getCombinedSessionTokenString(tokens) { if (!tokens || tokens.size === 0) { return SessionContainer.EMPTY_SESSION_TOKEN; } let result = ""; for (const [range, token] of tokens.entries()) { result += range + SessionContainer.SESSION_TOKEN_PARTITION_SPLITTER + token.toString() + SessionContainer.SESSION_TOKEN_SEPARATOR; } return result.slice(0, -1); } static compareAndSetToken(newTokenString, containerSessionTokens) { if (!newTokenString) { return; } const partitionsParts = newTokenString.split(SessionContainer.SESSION_TOKEN_SEPARATOR); for (const partitionPart of partitionsParts) { const newTokenParts = partitionPart.split(SessionContainer.SESSION_TOKEN_PARTITION_SPLITTER); if (newTokenParts.length !== 2) { return; } const range = newTokenParts[0]; const newToken = import_VectorSessionToken.VectorSessionToken.create(newTokenParts[1]); const tokenForRange = !containerSessionTokens.get(range) ? newToken : containerSessionTokens.get(range).merge(newToken); containerSessionTokens.set(range, tokenForRange); } } // TODO: have a assert if the type doesn't mastch known types static isReadingFromMaster(resourceType, operationType) { if (resourceType === import_common.Constants.Path.OffersPathSegment || resourceType === import_common.Constants.Path.DatabasesPathSegment || resourceType === import_common.Constants.Path.UsersPathSegment || resourceType === import_common.Constants.Path.PermissionsPathSegment || resourceType === import_common.Constants.Path.TopologyPathSegment || resourceType === import_common.Constants.Path.DatabaseAccountPathSegment || resourceType === import_common.Constants.Path.PartitionKeyRangesPathSegment || resourceType === import_common.Constants.Path.CollectionsPathSegment && operationType === import_common.OperationType.Query) { return true; } return false; } getContainerName(request, headers) { let ownerFullName = headers[import_common.Constants.HttpHeaders.OwnerFullName]; if (!ownerFullName) { ownerFullName = (0, import_common.trimSlashes)(request.resourceAddress); } return (0, import_common.getContainerLink)(ownerFullName); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { SessionContainer });