@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
145 lines (144 loc) • 7.11 kB
JavaScript
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
});