UNPKG

@azure/cosmos

Version:
155 lines 7.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChangeFeedForPartitionKey = void 0; const ChangeFeedIteratorResponse_js_1 = require("./ChangeFeedIteratorResponse.js"); const index_js_1 = require("../../common/index.js"); const index_js_2 = require("../../request/index.js"); const ContinuationTokenForPartitionKey_js_1 = require("./ContinuationTokenForPartitionKey.js"); const index_js_3 = require("../../documents/index.js"); const diagnostics_js_1 = require("../../utils/diagnostics.js"); const changeFeedUtils_js_1 = require("./changeFeedUtils.js"); const ClientUtils_js_1 = require("../ClientUtils.js"); /** * @hidden * Provides iterator for change feed for one partition key. * * Use `Items.getChangeFeedIterator()` to get an instance of the iterator. */ class ChangeFeedForPartitionKey { clientContext; container; resourceId; resourceLink; partitionKey; changeFeedOptions; continuationToken; startTime; rId; isInstantiated; startFromNow; /** * @internal */ constructor(clientContext, container, resourceId, resourceLink, partitionKey, changeFeedOptions) { this.clientContext = clientContext; this.container = container; this.resourceId = resourceId; this.resourceLink = resourceLink; this.partitionKey = partitionKey; this.changeFeedOptions = changeFeedOptions; this.continuationToken = changeFeedOptions.continuationToken ? JSON.parse(changeFeedOptions.continuationToken) : undefined; this.isInstantiated = false; // startTime is used to store and specify time from which change feed should start reading new changes. StartFromNow flag is used to indicate fetching changes from now. if (changeFeedOptions.startFromNow) { this.startFromNow = true; } else if (changeFeedOptions.startTime) { this.startTime = changeFeedOptions.startTime.toUTCString(); } } async instantiateIterator(diagnosticNode) { await this.setIteratorRid(diagnosticNode); if (this.clientContext.enableEncryption) { await this.container.checkAndInitializeEncryption(); // returns copy of object to avoid encryption of original partition key passed this.partitionKey = (0, index_js_1.copyObject)(this.partitionKey); diagnosticNode.beginEncryptionDiagnostics(index_js_1.Constants.Encryption.DiagnosticsEncryptOperation); const { partitionKeyList, encryptedCount } = await this.container.encryptionProcessor.getEncryptedPartitionKeyValue((0, index_js_3.convertToInternalPartitionKey)(this.partitionKey)); this.partitionKey = partitionKeyList; diagnosticNode.endEncryptionDiagnostics(index_js_1.Constants.Encryption.DiagnosticsEncryptOperation, encryptedCount); } if (this.continuationToken) { if (!this.continuationTokenRidMatchContainerRid()) { throw new index_js_2.ErrorResponse("The continuation is not for the current container definition."); } } else { this.continuationToken = new ContinuationTokenForPartitionKey_js_1.ContinuationTokenForPartitionKey(this.rId, this.partitionKey, ""); } this.isInstantiated = true; } continuationTokenRidMatchContainerRid() { if (this.continuationToken.rid !== this.rId) { return false; } return true; } async setIteratorRid(diagnosticNode) { const { resource } = await this.container.readInternal(diagnosticNode); this.rId = resource._rid; } /** * Change feed is an infinite feed. hasMoreResults is always true. */ get hasMoreResults() { return true; } /** * Gets an async iterator which will yield change feed results. */ async *getAsyncIterator() { do { const result = await this.readNext(); yield result; } while (this.hasMoreResults); } /** * Returns the result of change feed from Azure Cosmos DB. */ async readNext() { return (0, diagnostics_js_1.withDiagnostics)(async (diagnosticNode) => { if (!this.isInstantiated) { await this.instantiateIterator(diagnosticNode); } const result = await this.fetchNext(diagnosticNode); if (result.statusCode === index_js_1.StatusCodes.Ok) { if (this.clientContext.enableEncryption) { await (0, changeFeedUtils_js_1.decryptChangeFeedResponse)(result, diagnosticNode, this.changeFeedOptions.changeFeedMode, this.container.encryptionProcessor); } } return result; }, this.clientContext); } /** * Read feed and retrieves the next set of results in Azure Cosmos DB. */ async fetchNext(diagnosticNode) { const response = await this.getFeedResponse(diagnosticNode); this.continuationToken.Continuation = response.headers[index_js_1.Constants.HttpHeaders.ETag]; response.headers[index_js_1.Constants.HttpHeaders.ContinuationToken] = JSON.stringify(this.continuationToken); return response; } async getFeedResponse(diagnosticNode) { const feedOptions = (0, changeFeedUtils_js_1.buildFeedOptions)(this.changeFeedOptions, this.continuationToken?.Continuation, this.startFromNow, this.startTime); if (this.clientContext.enableEncryption) { feedOptions.containerRid = this.container._rid; } try { const isPartitionLevelFailOverEnabled = this.clientContext.isPartitionLevelFailOverEnabled(); const partitionKeyRangeId = await (0, ClientUtils_js_1.computePartitionKeyRangeId)(diagnosticNode, (0, index_js_3.convertToInternalPartitionKey)(this.partitionKey), this.clientContext.partitionKeyRangeCache, isPartitionLevelFailOverEnabled, this.container); const response = await this.clientContext.queryFeed({ path: this.resourceLink, resourceType: index_js_1.ResourceType.item, resourceId: this.resourceId, resultFn: (result) => (result ? result.Documents : []), diagnosticNode, query: undefined, options: feedOptions, partitionKey: this.partitionKey, partitionKeyRangeId, }); return new ChangeFeedIteratorResponse_js_1.ChangeFeedIteratorResponse(response.result, response.result ? response.result.length : 0, response.code, response.headers, (0, diagnostics_js_1.getEmptyCosmosDiagnostics)()); } catch (err) { // If any errors are encountered, throw the error. const errorResponse = new index_js_2.ErrorResponse(err.message); errorResponse.code = err.code; errorResponse.headers = err.headers; throw errorResponse; } } } exports.ChangeFeedForPartitionKey = ChangeFeedForPartitionKey; //# sourceMappingURL=ChangeFeedForPartitionKey.js.map