@azure/eventhubs-checkpointstore-blob 1.1.0-alpha.20231206.1 → 1.1.0-alpha.20240112.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var tslib = require('tslib');
|
|
6
5
|
var logger$1 = require('@azure/logger');
|
|
7
6
|
|
|
8
7
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -69,8 +68,6 @@ class BlobCheckpointStore {
|
|
|
69
68
|
* @returns Partition ownership details of all the partitions that have had an owner.
|
|
70
69
|
*/
|
|
71
70
|
async listOwnership(fullyQualifiedNamespace, eventHubName, consumerGroup, options = {}) {
|
|
72
|
-
var _a, e_1, _b, _c;
|
|
73
|
-
var _d;
|
|
74
71
|
const partitionOwnershipArray = [];
|
|
75
72
|
const { abortSignal, tracingOptions } = options;
|
|
76
73
|
const blobPrefix = BlobCheckpointStore.getBlobPrefix({
|
|
@@ -86,42 +83,30 @@ class BlobCheckpointStore {
|
|
|
86
83
|
prefix: blobPrefix,
|
|
87
84
|
tracingOptions,
|
|
88
85
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const blobName = blobPath[blobPath.length - 1];
|
|
96
|
-
const ownershipMetadata = (_d = blob.metadata) !== null && _d !== void 0 ? _d : {};
|
|
97
|
-
if (ownershipMetadata.ownerid == null) {
|
|
98
|
-
throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);
|
|
99
|
-
}
|
|
100
|
-
const partitionOwnership = {
|
|
101
|
-
fullyQualifiedNamespace,
|
|
102
|
-
eventHubName,
|
|
103
|
-
consumerGroup: consumerGroup,
|
|
104
|
-
ownerId: ownershipMetadata.ownerid,
|
|
105
|
-
partitionId: blobName,
|
|
106
|
-
lastModifiedTimeInMs: blob.properties.lastModified && blob.properties.lastModified.getTime(),
|
|
107
|
-
etag: blob.properties.etag,
|
|
108
|
-
};
|
|
109
|
-
partitionOwnershipArray.push(partitionOwnership);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
113
|
-
finally {
|
|
114
|
-
try {
|
|
115
|
-
if (!_e && !_a && (_b = blobs_1.return)) await _b.call(blobs_1);
|
|
86
|
+
for await (const blob of blobs) {
|
|
87
|
+
const blobPath = blob.name.split("/");
|
|
88
|
+
const blobName = blobPath[blobPath.length - 1];
|
|
89
|
+
const ownershipMetadata = blob.metadata ?? {};
|
|
90
|
+
if (ownershipMetadata.ownerid == null) {
|
|
91
|
+
throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);
|
|
116
92
|
}
|
|
117
|
-
|
|
93
|
+
const partitionOwnership = {
|
|
94
|
+
fullyQualifiedNamespace,
|
|
95
|
+
eventHubName,
|
|
96
|
+
consumerGroup: consumerGroup,
|
|
97
|
+
ownerId: ownershipMetadata.ownerid,
|
|
98
|
+
partitionId: blobName,
|
|
99
|
+
lastModifiedTimeInMs: blob.properties.lastModified && blob.properties.lastModified.getTime(),
|
|
100
|
+
etag: blob.properties.etag,
|
|
101
|
+
};
|
|
102
|
+
partitionOwnershipArray.push(partitionOwnership);
|
|
118
103
|
}
|
|
119
104
|
return partitionOwnershipArray;
|
|
120
105
|
}
|
|
121
106
|
catch (err) {
|
|
122
107
|
logger.warning(`Error occurred while fetching the list of blobs`, err.message);
|
|
123
108
|
logErrorStackTrace(err);
|
|
124
|
-
if (
|
|
109
|
+
if (err?.name === "AbortError")
|
|
125
110
|
throw err;
|
|
126
111
|
throw new Error(`Error occurred while fetching the list of blobs. \n${err}`);
|
|
127
112
|
}
|
|
@@ -139,7 +124,7 @@ class BlobCheckpointStore {
|
|
|
139
124
|
async claimOwnership(partitionOwnership, options = {}) {
|
|
140
125
|
const partitionOwnershipArray = [];
|
|
141
126
|
for (const ownership of partitionOwnership) {
|
|
142
|
-
const blobName = BlobCheckpointStore.getBlobPrefix(
|
|
127
|
+
const blobName = BlobCheckpointStore.getBlobPrefix({ type: "ownership", ...ownership });
|
|
143
128
|
try {
|
|
144
129
|
const updatedBlobResponse = await this._setBlobMetadata(blobName, {
|
|
145
130
|
ownerid: ownership.ownerId,
|
|
@@ -179,8 +164,6 @@ class BlobCheckpointStore {
|
|
|
179
164
|
* - `tracingOptions`: Options for configuring tracing.
|
|
180
165
|
*/
|
|
181
166
|
async listCheckpoints(fullyQualifiedNamespace, eventHubName, consumerGroup, options = {}) {
|
|
182
|
-
var _a, e_2, _b, _c;
|
|
183
|
-
var _d;
|
|
184
167
|
const { abortSignal, tracingOptions } = options;
|
|
185
168
|
const blobPrefix = BlobCheckpointStore.getBlobPrefix({
|
|
186
169
|
type: "checkpoint",
|
|
@@ -195,32 +178,20 @@ class BlobCheckpointStore {
|
|
|
195
178
|
tracingOptions,
|
|
196
179
|
});
|
|
197
180
|
const checkpoints = [];
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
partitionId: blobName,
|
|
213
|
-
offset,
|
|
214
|
-
sequenceNumber,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
219
|
-
finally {
|
|
220
|
-
try {
|
|
221
|
-
if (!_e && !_a && (_b = blobs_2.return)) await _b.call(blobs_2);
|
|
222
|
-
}
|
|
223
|
-
finally { if (e_2) throw e_2.error; }
|
|
181
|
+
for await (const blob of blobs) {
|
|
182
|
+
const blobPath = blob.name.split("/");
|
|
183
|
+
const blobName = blobPath[blobPath.length - 1];
|
|
184
|
+
const checkpointMetadata = blob.metadata ?? {};
|
|
185
|
+
const offset = parseIntOrThrow(blob.name, "offset", checkpointMetadata.offset);
|
|
186
|
+
const sequenceNumber = parseIntOrThrow(blob.name, "sequencenumber", checkpointMetadata.sequencenumber);
|
|
187
|
+
checkpoints.push({
|
|
188
|
+
consumerGroup,
|
|
189
|
+
eventHubName,
|
|
190
|
+
fullyQualifiedNamespace,
|
|
191
|
+
partitionId: blobName,
|
|
192
|
+
offset,
|
|
193
|
+
sequenceNumber,
|
|
194
|
+
});
|
|
224
195
|
}
|
|
225
196
|
return checkpoints;
|
|
226
197
|
}
|
|
@@ -236,7 +207,7 @@ class BlobCheckpointStore {
|
|
|
236
207
|
async updateCheckpoint(checkpoint, options = {}) {
|
|
237
208
|
throwTypeErrorIfParameterMissing("updateCheckpoint", "sequenceNumber", checkpoint.sequenceNumber);
|
|
238
209
|
throwTypeErrorIfParameterMissing("updateCheckpoint", "offset", checkpoint.offset);
|
|
239
|
-
const blobName = BlobCheckpointStore.getBlobPrefix(
|
|
210
|
+
const blobName = BlobCheckpointStore.getBlobPrefix({ type: "checkpoint", ...checkpoint });
|
|
240
211
|
try {
|
|
241
212
|
const metadataResponse = await this._setBlobMetadata(blobName, {
|
|
242
213
|
sequencenumber: checkpoint.sequenceNumber.toString(),
|
|
@@ -248,7 +219,7 @@ class BlobCheckpointStore {
|
|
|
248
219
|
catch (err) {
|
|
249
220
|
logger.warning(`Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`, err.message);
|
|
250
221
|
logErrorStackTrace(err);
|
|
251
|
-
if (
|
|
222
|
+
if (err?.name === "AbortError")
|
|
252
223
|
throw err;
|
|
253
224
|
throw new Error(`Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`);
|
|
254
225
|
}
|
|
@@ -292,11 +263,11 @@ class BlobCheckpointStore {
|
|
|
292
263
|
}
|
|
293
264
|
catch (err) {
|
|
294
265
|
// Check if the error is `BlobNotFound` and fallback to `upload` if it is.
|
|
295
|
-
if (
|
|
266
|
+
if (err?.name !== "RestError") {
|
|
296
267
|
throw err;
|
|
297
268
|
}
|
|
298
269
|
const errorDetails = err.details;
|
|
299
|
-
const errorCode = errorDetails
|
|
270
|
+
const errorCode = errorDetails?.errorCode;
|
|
300
271
|
if (!errorCode || errorCode !== "BlobNotFound") {
|
|
301
272
|
throw err;
|
|
302
273
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/log.ts","../src/util/error.ts","../src/blobCheckpointStore.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createClientLogger } from \"@azure/logger\";\n\n/**\n * The `@azure/logger` configuration for this package.\n * This will output logs using the `azure:eventhubs-checkpointstore-blob` namespace prefix.\n */\nexport const logger = createClientLogger(\"eventhubs-checkpointstore-blob\");\n\n/**\n * Logs the error's stack trace to \"verbose\" if a stack trace is available.\n * @param error - Error containing a stack trace.\n * @internal\n */\nexport function logErrorStackTrace(error: unknown): void {\n if (error && typeof error === \"object\" && \"stack\" in error) {\n logger.verbose((error as any).stack);\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { logger, logErrorStackTrace } from \"../log\";\n\n/**\n * @internal\n * Logs and Throws TypeError if given parameter is undefined or null\n * @param methodName - Name of the method that was passed the parameter\n * @param parameterName - Name of the parameter to check\n * @param parameterValue - Value of the parameter to check\n */\nexport function throwTypeErrorIfParameterMissing(\n methodName: string,\n parameterName: string,\n parameterValue: unknown\n): void {\n if (parameterValue === undefined || parameterValue === null) {\n const error = new TypeError(\n `${methodName} called without required argument \"${parameterName}\"`\n );\n logger.warning(error.message);\n logErrorStackTrace(error);\n throw error;\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n CheckpointStore,\n PartitionOwnership,\n Checkpoint,\n OperationOptions,\n} from \"@azure/event-hubs\";\nimport { Metadata, RestError, BlobSetMetadataResponse } from \"@azure/storage-blob\";\nimport { logger, logErrorStackTrace } from \"./log\";\nimport { ContainerClientLike } from \"./storageBlobInterfaces\";\nimport { throwTypeErrorIfParameterMissing } from \"./util/error\";\n\n/**\n * An implementation of CheckpointStore that uses Azure Blob Storage to persist checkpoint data.\n */\nexport class BlobCheckpointStore implements CheckpointStore {\n private _containerClient: ContainerClientLike;\n\n /**\n * Constructs a new instance of {@link BlobCheckpointStore}\n * @param containerClient - An instance of a storage blob ContainerClient.\n */\n constructor(containerClient: ContainerClientLike) {\n this._containerClient = containerClient;\n }\n /**\n * Get the list of all existing partition ownership from the underlying data store. May return empty\n * results if there are is no existing ownership information.\n * Partition Ownership contains the information on which `EventHubConsumerClient` subscribe call is currently processing the partition.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns Partition ownership details of all the partitions that have had an owner.\n */\n async listOwnership(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {}\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n const { abortSignal, tracingOptions } = options;\n\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"ownership\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n });\n\n try {\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const ownershipMetadata = (blob.metadata as OwnershipMetadata) ?? {};\n\n if (ownershipMetadata.ownerid == null) {\n throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);\n }\n\n const partitionOwnership: PartitionOwnership = {\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n ownerId: ownershipMetadata.ownerid,\n partitionId: blobName,\n lastModifiedTimeInMs:\n blob.properties.lastModified && blob.properties.lastModified.getTime(),\n etag: blob.properties.etag,\n };\n partitionOwnershipArray.push(partitionOwnership);\n }\n return partitionOwnershipArray;\n } catch (err: any) {\n logger.warning(`Error occurred while fetching the list of blobs`, err.message);\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(`Error occurred while fetching the list of blobs. \\n${err}`);\n }\n }\n\n /**\n * Claim ownership of a list of partitions. This will return the list of partitions that were\n * successfully claimed.\n *\n * @param partitionOwnership - The list of partition ownership this instance is claiming to own.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns A list partitions this instance successfully claimed ownership.\n */\n async claimOwnership(\n partitionOwnership: PartitionOwnership[],\n options: OperationOptions = {}\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n for (const ownership of partitionOwnership) {\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"ownership\", ...ownership });\n try {\n const updatedBlobResponse = await this._setBlobMetadata(\n blobName,\n {\n ownerid: ownership.ownerId,\n },\n ownership.etag,\n options\n );\n\n if (updatedBlobResponse.lastModified) {\n ownership.lastModifiedTimeInMs = updatedBlobResponse.lastModified.getTime();\n }\n\n ownership.etag = updatedBlobResponse.etag;\n partitionOwnershipArray.push(ownership);\n logger.info(\n `[${ownership.ownerId}] Claimed ownership successfully for partition: ${ownership.partitionId}`,\n `LastModifiedTime: ${ownership.lastModifiedTimeInMs}, ETag: ${ownership.etag}`\n );\n } catch (err: any) {\n const restError = err as RestError;\n\n if (restError.statusCode === 412) {\n // etag failures (precondition not met) aren't fatal errors. They happen\n // as multiple consumers attempt to claim the same partition (first one wins)\n // and losers get this error.\n logger.verbose(\n `[${ownership.ownerId}] Did not claim partition ${ownership.partitionId}. Another processor has already claimed it.`\n );\n continue;\n }\n\n logger.warning(\n `Error occurred while claiming ownership for partition: ${ownership.partitionId}`,\n err.message\n );\n logErrorStackTrace(err);\n\n throw err;\n }\n }\n return partitionOwnershipArray;\n }\n\n /**\n * Lists all the checkpoints in a data store for a given namespace, eventhub and consumer group.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n */\n async listCheckpoints(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {}\n ): Promise<Checkpoint[]> {\n const { abortSignal, tracingOptions } = options;\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"checkpoint\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup,\n });\n\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n const checkpoints: Checkpoint[] = [];\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const checkpointMetadata = (blob.metadata as CheckpointMetadata) ?? {};\n\n const offset = parseIntOrThrow(blob.name, \"offset\", checkpointMetadata.offset);\n const sequenceNumber = parseIntOrThrow(\n blob.name,\n \"sequencenumber\",\n checkpointMetadata.sequencenumber\n );\n\n checkpoints.push({\n consumerGroup,\n eventHubName,\n fullyQualifiedNamespace,\n partitionId: blobName,\n offset,\n sequenceNumber,\n });\n }\n\n return checkpoints;\n }\n\n /**\n * Updates the checkpoint in the data store for a partition.\n *\n * @param checkpoint - The checkpoint.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns The new etag on successful update.\n */\n async updateCheckpoint(checkpoint: Checkpoint, options: OperationOptions = {}): Promise<void> {\n throwTypeErrorIfParameterMissing(\n \"updateCheckpoint\",\n \"sequenceNumber\",\n checkpoint.sequenceNumber\n );\n throwTypeErrorIfParameterMissing(\"updateCheckpoint\", \"offset\", checkpoint.offset);\n\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"checkpoint\", ...checkpoint });\n try {\n const metadataResponse = await this._setBlobMetadata(\n blobName,\n {\n sequencenumber: checkpoint.sequenceNumber.toString(),\n offset: checkpoint.offset.toString(),\n },\n undefined,\n options\n );\n\n logger.verbose(\n `Updated checkpoint successfully for partition: ${checkpoint.partitionId}`,\n `LastModifiedTime: ${metadataResponse.lastModified!.toISOString()}, ETag: ${\n metadataResponse.etag\n }`\n );\n return;\n } catch (err: any) {\n logger.warning(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`,\n err.message\n );\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`\n );\n }\n }\n\n private static getBlobPrefix(params: {\n type: \"ownership\" | \"checkpoint\";\n fullyQualifiedNamespace: string;\n eventHubName: string;\n consumerGroup: string;\n partitionId?: string;\n }): string {\n // none of these are case-sensitive in eventhubs so we need to make sure we don't accidentally allow\n // the user to create a case-sensitive blob for their state!\n const consumerGroupName = params.consumerGroup.toLowerCase();\n const eventHubName = params.eventHubName.toLowerCase();\n const fullyQualifiedNamespace = params.fullyQualifiedNamespace.toLowerCase();\n\n if (params.partitionId) {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/${params.partitionId}`;\n } else {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/`;\n }\n }\n\n private async _setBlobMetadata(\n blobName: string,\n metadata: OwnershipMetadata | CheckpointMetadata,\n etag: string | undefined,\n options: OperationOptions = {}\n ): Promise<BlobSetMetadataResponse> {\n const { abortSignal, tracingOptions } = options;\n const blockBlobClient = this._containerClient.getBlobClient(blobName).getBlockBlobClient();\n\n // When we have an etag, we know the blob existed.\n // If we encounter an error we should fail.\n if (etag) {\n return blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n conditions: {\n ifMatch: etag,\n },\n tracingOptions,\n });\n } else {\n try {\n // Attempt to set metadata, and fallback to upload if the blob doesn't already exist.\n // This avoids poor performance in storage accounts with soft-delete or blob versioning enabled.\n // https://github.com/Azure/azure-sdk-for-js/issues/10132\n return await blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n tracingOptions,\n });\n } catch (err: any) {\n // Check if the error is `BlobNotFound` and fallback to `upload` if it is.\n if (err?.name !== \"RestError\") {\n throw err;\n }\n const errorDetails = (err as RestError).details as { [field: string]: string } | undefined;\n const errorCode = errorDetails?.errorCode;\n if (!errorCode || errorCode !== \"BlobNotFound\") {\n throw err;\n }\n\n return blockBlobClient.upload(\"\", 0, {\n abortSignal,\n metadata: metadata as Metadata,\n tracingOptions,\n });\n }\n }\n }\n}\n\ntype OwnershipMetadata = {\n [k in \"ownerid\"]: string | undefined;\n};\n\ntype CheckpointMetadata = {\n [k in \"sequencenumber\" | \"offset\"]: string | undefined;\n};\n\n/**\n * @internal\n */\nexport function parseIntOrThrow(\n blobName: string,\n fieldName: string,\n numStr: string | undefined\n): number {\n if (numStr == null) {\n throw new Error(`Missing metadata property '${fieldName}' on blob '${blobName}'`);\n }\n\n const num = parseInt(numStr, 10);\n\n if (isNaN(num)) {\n throw new Error(\n `Failed to parse metadata property '${fieldName}' on blob '${blobName}' as a number`\n );\n }\n\n return num;\n}\n"],"names":["createClientLogger","__asyncValues"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/log.ts","../src/util/error.ts","../src/blobCheckpointStore.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createClientLogger } from \"@azure/logger\";\n\n/**\n * The `@azure/logger` configuration for this package.\n * This will output logs using the `azure:eventhubs-checkpointstore-blob` namespace prefix.\n */\nexport const logger = createClientLogger(\"eventhubs-checkpointstore-blob\");\n\n/**\n * Logs the error's stack trace to \"verbose\" if a stack trace is available.\n * @param error - Error containing a stack trace.\n * @internal\n */\nexport function logErrorStackTrace(error: unknown): void {\n if (error && typeof error === \"object\" && \"stack\" in error) {\n logger.verbose((error as any).stack);\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { logger, logErrorStackTrace } from \"../log\";\n\n/**\n * @internal\n * Logs and Throws TypeError if given parameter is undefined or null\n * @param methodName - Name of the method that was passed the parameter\n * @param parameterName - Name of the parameter to check\n * @param parameterValue - Value of the parameter to check\n */\nexport function throwTypeErrorIfParameterMissing(\n methodName: string,\n parameterName: string,\n parameterValue: unknown,\n): void {\n if (parameterValue === undefined || parameterValue === null) {\n const error = new TypeError(\n `${methodName} called without required argument \"${parameterName}\"`,\n );\n logger.warning(error.message);\n logErrorStackTrace(error);\n throw error;\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n CheckpointStore,\n PartitionOwnership,\n Checkpoint,\n OperationOptions,\n} from \"@azure/event-hubs\";\nimport { Metadata, RestError, BlobSetMetadataResponse } from \"@azure/storage-blob\";\nimport { logger, logErrorStackTrace } from \"./log\";\nimport { ContainerClientLike } from \"./storageBlobInterfaces\";\nimport { throwTypeErrorIfParameterMissing } from \"./util/error\";\n\n/**\n * An implementation of CheckpointStore that uses Azure Blob Storage to persist checkpoint data.\n */\nexport class BlobCheckpointStore implements CheckpointStore {\n private _containerClient: ContainerClientLike;\n\n /**\n * Constructs a new instance of {@link BlobCheckpointStore}\n * @param containerClient - An instance of a storage blob ContainerClient.\n */\n constructor(containerClient: ContainerClientLike) {\n this._containerClient = containerClient;\n }\n /**\n * Get the list of all existing partition ownership from the underlying data store. May return empty\n * results if there are is no existing ownership information.\n * Partition Ownership contains the information on which `EventHubConsumerClient` subscribe call is currently processing the partition.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns Partition ownership details of all the partitions that have had an owner.\n */\n async listOwnership(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {},\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n const { abortSignal, tracingOptions } = options;\n\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"ownership\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n });\n\n try {\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const ownershipMetadata = (blob.metadata as OwnershipMetadata) ?? {};\n\n if (ownershipMetadata.ownerid == null) {\n throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);\n }\n\n const partitionOwnership: PartitionOwnership = {\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n ownerId: ownershipMetadata.ownerid,\n partitionId: blobName,\n lastModifiedTimeInMs:\n blob.properties.lastModified && blob.properties.lastModified.getTime(),\n etag: blob.properties.etag,\n };\n partitionOwnershipArray.push(partitionOwnership);\n }\n return partitionOwnershipArray;\n } catch (err: any) {\n logger.warning(`Error occurred while fetching the list of blobs`, err.message);\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(`Error occurred while fetching the list of blobs. \\n${err}`);\n }\n }\n\n /**\n * Claim ownership of a list of partitions. This will return the list of partitions that were\n * successfully claimed.\n *\n * @param partitionOwnership - The list of partition ownership this instance is claiming to own.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns A list partitions this instance successfully claimed ownership.\n */\n async claimOwnership(\n partitionOwnership: PartitionOwnership[],\n options: OperationOptions = {},\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n for (const ownership of partitionOwnership) {\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"ownership\", ...ownership });\n try {\n const updatedBlobResponse = await this._setBlobMetadata(\n blobName,\n {\n ownerid: ownership.ownerId,\n },\n ownership.etag,\n options,\n );\n\n if (updatedBlobResponse.lastModified) {\n ownership.lastModifiedTimeInMs = updatedBlobResponse.lastModified.getTime();\n }\n\n ownership.etag = updatedBlobResponse.etag;\n partitionOwnershipArray.push(ownership);\n logger.info(\n `[${ownership.ownerId}] Claimed ownership successfully for partition: ${ownership.partitionId}`,\n `LastModifiedTime: ${ownership.lastModifiedTimeInMs}, ETag: ${ownership.etag}`,\n );\n } catch (err: any) {\n const restError = err as RestError;\n\n if (restError.statusCode === 412) {\n // etag failures (precondition not met) aren't fatal errors. They happen\n // as multiple consumers attempt to claim the same partition (first one wins)\n // and losers get this error.\n logger.verbose(\n `[${ownership.ownerId}] Did not claim partition ${ownership.partitionId}. Another processor has already claimed it.`,\n );\n continue;\n }\n\n logger.warning(\n `Error occurred while claiming ownership for partition: ${ownership.partitionId}`,\n err.message,\n );\n logErrorStackTrace(err);\n\n throw err;\n }\n }\n return partitionOwnershipArray;\n }\n\n /**\n * Lists all the checkpoints in a data store for a given namespace, eventhub and consumer group.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n */\n async listCheckpoints(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {},\n ): Promise<Checkpoint[]> {\n const { abortSignal, tracingOptions } = options;\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"checkpoint\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup,\n });\n\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n const checkpoints: Checkpoint[] = [];\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const checkpointMetadata = (blob.metadata as CheckpointMetadata) ?? {};\n\n const offset = parseIntOrThrow(blob.name, \"offset\", checkpointMetadata.offset);\n const sequenceNumber = parseIntOrThrow(\n blob.name,\n \"sequencenumber\",\n checkpointMetadata.sequencenumber,\n );\n\n checkpoints.push({\n consumerGroup,\n eventHubName,\n fullyQualifiedNamespace,\n partitionId: blobName,\n offset,\n sequenceNumber,\n });\n }\n\n return checkpoints;\n }\n\n /**\n * Updates the checkpoint in the data store for a partition.\n *\n * @param checkpoint - The checkpoint.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns The new etag on successful update.\n */\n async updateCheckpoint(checkpoint: Checkpoint, options: OperationOptions = {}): Promise<void> {\n throwTypeErrorIfParameterMissing(\n \"updateCheckpoint\",\n \"sequenceNumber\",\n checkpoint.sequenceNumber,\n );\n throwTypeErrorIfParameterMissing(\"updateCheckpoint\", \"offset\", checkpoint.offset);\n\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"checkpoint\", ...checkpoint });\n try {\n const metadataResponse = await this._setBlobMetadata(\n blobName,\n {\n sequencenumber: checkpoint.sequenceNumber.toString(),\n offset: checkpoint.offset.toString(),\n },\n undefined,\n options,\n );\n\n logger.verbose(\n `Updated checkpoint successfully for partition: ${checkpoint.partitionId}`,\n `LastModifiedTime: ${metadataResponse.lastModified!.toISOString()}, ETag: ${\n metadataResponse.etag\n }`,\n );\n return;\n } catch (err: any) {\n logger.warning(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`,\n err.message,\n );\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`,\n );\n }\n }\n\n private static getBlobPrefix(params: {\n type: \"ownership\" | \"checkpoint\";\n fullyQualifiedNamespace: string;\n eventHubName: string;\n consumerGroup: string;\n partitionId?: string;\n }): string {\n // none of these are case-sensitive in eventhubs so we need to make sure we don't accidentally allow\n // the user to create a case-sensitive blob for their state!\n const consumerGroupName = params.consumerGroup.toLowerCase();\n const eventHubName = params.eventHubName.toLowerCase();\n const fullyQualifiedNamespace = params.fullyQualifiedNamespace.toLowerCase();\n\n if (params.partitionId) {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/${params.partitionId}`;\n } else {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/`;\n }\n }\n\n private async _setBlobMetadata(\n blobName: string,\n metadata: OwnershipMetadata | CheckpointMetadata,\n etag: string | undefined,\n options: OperationOptions = {},\n ): Promise<BlobSetMetadataResponse> {\n const { abortSignal, tracingOptions } = options;\n const blockBlobClient = this._containerClient.getBlobClient(blobName).getBlockBlobClient();\n\n // When we have an etag, we know the blob existed.\n // If we encounter an error we should fail.\n if (etag) {\n return blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n conditions: {\n ifMatch: etag,\n },\n tracingOptions,\n });\n } else {\n try {\n // Attempt to set metadata, and fallback to upload if the blob doesn't already exist.\n // This avoids poor performance in storage accounts with soft-delete or blob versioning enabled.\n // https://github.com/Azure/azure-sdk-for-js/issues/10132\n return await blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n tracingOptions,\n });\n } catch (err: any) {\n // Check if the error is `BlobNotFound` and fallback to `upload` if it is.\n if (err?.name !== \"RestError\") {\n throw err;\n }\n const errorDetails = (err as RestError).details as { [field: string]: string } | undefined;\n const errorCode = errorDetails?.errorCode;\n if (!errorCode || errorCode !== \"BlobNotFound\") {\n throw err;\n }\n\n return blockBlobClient.upload(\"\", 0, {\n abortSignal,\n metadata: metadata as Metadata,\n tracingOptions,\n });\n }\n }\n }\n}\n\ntype OwnershipMetadata = {\n [k in \"ownerid\"]: string | undefined;\n};\n\ntype CheckpointMetadata = {\n [k in \"sequencenumber\" | \"offset\"]: string | undefined;\n};\n\n/**\n * @internal\n */\nexport function parseIntOrThrow(\n blobName: string,\n fieldName: string,\n numStr: string | undefined,\n): number {\n if (numStr == null) {\n throw new Error(`Missing metadata property '${fieldName}' on blob '${blobName}'`);\n }\n\n const num = parseInt(numStr, 10);\n\n if (isNaN(num)) {\n throw new Error(\n `Failed to parse metadata property '${fieldName}' on blob '${blobName}' as a number`,\n );\n }\n\n return num;\n}\n"],"names":["createClientLogger"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT license.
|
|
3
|
-
import { __asyncValues } from "tslib";
|
|
4
3
|
import { logger, logErrorStackTrace } from "./log";
|
|
5
4
|
import { throwTypeErrorIfParameterMissing } from "./util/error";
|
|
6
5
|
/**
|
|
@@ -29,8 +28,6 @@ export class BlobCheckpointStore {
|
|
|
29
28
|
* @returns Partition ownership details of all the partitions that have had an owner.
|
|
30
29
|
*/
|
|
31
30
|
async listOwnership(fullyQualifiedNamespace, eventHubName, consumerGroup, options = {}) {
|
|
32
|
-
var _a, e_1, _b, _c;
|
|
33
|
-
var _d;
|
|
34
31
|
const partitionOwnershipArray = [];
|
|
35
32
|
const { abortSignal, tracingOptions } = options;
|
|
36
33
|
const blobPrefix = BlobCheckpointStore.getBlobPrefix({
|
|
@@ -46,42 +43,30 @@ export class BlobCheckpointStore {
|
|
|
46
43
|
prefix: blobPrefix,
|
|
47
44
|
tracingOptions,
|
|
48
45
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const blobName = blobPath[blobPath.length - 1];
|
|
56
|
-
const ownershipMetadata = (_d = blob.metadata) !== null && _d !== void 0 ? _d : {};
|
|
57
|
-
if (ownershipMetadata.ownerid == null) {
|
|
58
|
-
throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);
|
|
59
|
-
}
|
|
60
|
-
const partitionOwnership = {
|
|
61
|
-
fullyQualifiedNamespace,
|
|
62
|
-
eventHubName,
|
|
63
|
-
consumerGroup: consumerGroup,
|
|
64
|
-
ownerId: ownershipMetadata.ownerid,
|
|
65
|
-
partitionId: blobName,
|
|
66
|
-
lastModifiedTimeInMs: blob.properties.lastModified && blob.properties.lastModified.getTime(),
|
|
67
|
-
etag: blob.properties.etag,
|
|
68
|
-
};
|
|
69
|
-
partitionOwnershipArray.push(partitionOwnership);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
73
|
-
finally {
|
|
74
|
-
try {
|
|
75
|
-
if (!_e && !_a && (_b = blobs_1.return)) await _b.call(blobs_1);
|
|
46
|
+
for await (const blob of blobs) {
|
|
47
|
+
const blobPath = blob.name.split("/");
|
|
48
|
+
const blobName = blobPath[blobPath.length - 1];
|
|
49
|
+
const ownershipMetadata = blob.metadata ?? {};
|
|
50
|
+
if (ownershipMetadata.ownerid == null) {
|
|
51
|
+
throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);
|
|
76
52
|
}
|
|
77
|
-
|
|
53
|
+
const partitionOwnership = {
|
|
54
|
+
fullyQualifiedNamespace,
|
|
55
|
+
eventHubName,
|
|
56
|
+
consumerGroup: consumerGroup,
|
|
57
|
+
ownerId: ownershipMetadata.ownerid,
|
|
58
|
+
partitionId: blobName,
|
|
59
|
+
lastModifiedTimeInMs: blob.properties.lastModified && blob.properties.lastModified.getTime(),
|
|
60
|
+
etag: blob.properties.etag,
|
|
61
|
+
};
|
|
62
|
+
partitionOwnershipArray.push(partitionOwnership);
|
|
78
63
|
}
|
|
79
64
|
return partitionOwnershipArray;
|
|
80
65
|
}
|
|
81
66
|
catch (err) {
|
|
82
67
|
logger.warning(`Error occurred while fetching the list of blobs`, err.message);
|
|
83
68
|
logErrorStackTrace(err);
|
|
84
|
-
if (
|
|
69
|
+
if (err?.name === "AbortError")
|
|
85
70
|
throw err;
|
|
86
71
|
throw new Error(`Error occurred while fetching the list of blobs. \n${err}`);
|
|
87
72
|
}
|
|
@@ -99,7 +84,7 @@ export class BlobCheckpointStore {
|
|
|
99
84
|
async claimOwnership(partitionOwnership, options = {}) {
|
|
100
85
|
const partitionOwnershipArray = [];
|
|
101
86
|
for (const ownership of partitionOwnership) {
|
|
102
|
-
const blobName = BlobCheckpointStore.getBlobPrefix(
|
|
87
|
+
const blobName = BlobCheckpointStore.getBlobPrefix({ type: "ownership", ...ownership });
|
|
103
88
|
try {
|
|
104
89
|
const updatedBlobResponse = await this._setBlobMetadata(blobName, {
|
|
105
90
|
ownerid: ownership.ownerId,
|
|
@@ -139,8 +124,6 @@ export class BlobCheckpointStore {
|
|
|
139
124
|
* - `tracingOptions`: Options for configuring tracing.
|
|
140
125
|
*/
|
|
141
126
|
async listCheckpoints(fullyQualifiedNamespace, eventHubName, consumerGroup, options = {}) {
|
|
142
|
-
var _a, e_2, _b, _c;
|
|
143
|
-
var _d;
|
|
144
127
|
const { abortSignal, tracingOptions } = options;
|
|
145
128
|
const blobPrefix = BlobCheckpointStore.getBlobPrefix({
|
|
146
129
|
type: "checkpoint",
|
|
@@ -155,32 +138,20 @@ export class BlobCheckpointStore {
|
|
|
155
138
|
tracingOptions,
|
|
156
139
|
});
|
|
157
140
|
const checkpoints = [];
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
partitionId: blobName,
|
|
173
|
-
offset,
|
|
174
|
-
sequenceNumber,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
179
|
-
finally {
|
|
180
|
-
try {
|
|
181
|
-
if (!_e && !_a && (_b = blobs_2.return)) await _b.call(blobs_2);
|
|
182
|
-
}
|
|
183
|
-
finally { if (e_2) throw e_2.error; }
|
|
141
|
+
for await (const blob of blobs) {
|
|
142
|
+
const blobPath = blob.name.split("/");
|
|
143
|
+
const blobName = blobPath[blobPath.length - 1];
|
|
144
|
+
const checkpointMetadata = blob.metadata ?? {};
|
|
145
|
+
const offset = parseIntOrThrow(blob.name, "offset", checkpointMetadata.offset);
|
|
146
|
+
const sequenceNumber = parseIntOrThrow(blob.name, "sequencenumber", checkpointMetadata.sequencenumber);
|
|
147
|
+
checkpoints.push({
|
|
148
|
+
consumerGroup,
|
|
149
|
+
eventHubName,
|
|
150
|
+
fullyQualifiedNamespace,
|
|
151
|
+
partitionId: blobName,
|
|
152
|
+
offset,
|
|
153
|
+
sequenceNumber,
|
|
154
|
+
});
|
|
184
155
|
}
|
|
185
156
|
return checkpoints;
|
|
186
157
|
}
|
|
@@ -196,7 +167,7 @@ export class BlobCheckpointStore {
|
|
|
196
167
|
async updateCheckpoint(checkpoint, options = {}) {
|
|
197
168
|
throwTypeErrorIfParameterMissing("updateCheckpoint", "sequenceNumber", checkpoint.sequenceNumber);
|
|
198
169
|
throwTypeErrorIfParameterMissing("updateCheckpoint", "offset", checkpoint.offset);
|
|
199
|
-
const blobName = BlobCheckpointStore.getBlobPrefix(
|
|
170
|
+
const blobName = BlobCheckpointStore.getBlobPrefix({ type: "checkpoint", ...checkpoint });
|
|
200
171
|
try {
|
|
201
172
|
const metadataResponse = await this._setBlobMetadata(blobName, {
|
|
202
173
|
sequencenumber: checkpoint.sequenceNumber.toString(),
|
|
@@ -208,7 +179,7 @@ export class BlobCheckpointStore {
|
|
|
208
179
|
catch (err) {
|
|
209
180
|
logger.warning(`Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`, err.message);
|
|
210
181
|
logErrorStackTrace(err);
|
|
211
|
-
if (
|
|
182
|
+
if (err?.name === "AbortError")
|
|
212
183
|
throw err;
|
|
213
184
|
throw new Error(`Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`);
|
|
214
185
|
}
|
|
@@ -252,11 +223,11 @@ export class BlobCheckpointStore {
|
|
|
252
223
|
}
|
|
253
224
|
catch (err) {
|
|
254
225
|
// Check if the error is `BlobNotFound` and fallback to `upload` if it is.
|
|
255
|
-
if (
|
|
226
|
+
if (err?.name !== "RestError") {
|
|
256
227
|
throw err;
|
|
257
228
|
}
|
|
258
229
|
const errorDetails = err.details;
|
|
259
|
-
const errorCode = errorDetails
|
|
230
|
+
const errorCode = errorDetails?.errorCode;
|
|
260
231
|
if (!errorCode || errorCode !== "BlobNotFound") {
|
|
261
232
|
throw err;
|
|
262
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blobCheckpointStore.js","sourceRoot":"","sources":["../../src/blobCheckpointStore.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n CheckpointStore,\n PartitionOwnership,\n Checkpoint,\n OperationOptions,\n} from \"@azure/event-hubs\";\nimport { Metadata, RestError, BlobSetMetadataResponse } from \"@azure/storage-blob\";\nimport { logger, logErrorStackTrace } from \"./log\";\nimport { ContainerClientLike } from \"./storageBlobInterfaces\";\nimport { throwTypeErrorIfParameterMissing } from \"./util/error\";\n\n/**\n * An implementation of CheckpointStore that uses Azure Blob Storage to persist checkpoint data.\n */\nexport class BlobCheckpointStore implements CheckpointStore {\n private _containerClient: ContainerClientLike;\n\n /**\n * Constructs a new instance of {@link BlobCheckpointStore}\n * @param containerClient - An instance of a storage blob ContainerClient.\n */\n constructor(containerClient: ContainerClientLike) {\n this._containerClient = containerClient;\n }\n /**\n * Get the list of all existing partition ownership from the underlying data store. May return empty\n * results if there are is no existing ownership information.\n * Partition Ownership contains the information on which `EventHubConsumerClient` subscribe call is currently processing the partition.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns Partition ownership details of all the partitions that have had an owner.\n */\n async listOwnership(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {}\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n const { abortSignal, tracingOptions } = options;\n\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"ownership\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n });\n\n try {\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const ownershipMetadata = (blob.metadata as OwnershipMetadata) ?? {};\n\n if (ownershipMetadata.ownerid == null) {\n throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);\n }\n\n const partitionOwnership: PartitionOwnership = {\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n ownerId: ownershipMetadata.ownerid,\n partitionId: blobName,\n lastModifiedTimeInMs:\n blob.properties.lastModified && blob.properties.lastModified.getTime(),\n etag: blob.properties.etag,\n };\n partitionOwnershipArray.push(partitionOwnership);\n }\n return partitionOwnershipArray;\n } catch (err: any) {\n logger.warning(`Error occurred while fetching the list of blobs`, err.message);\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(`Error occurred while fetching the list of blobs. \\n${err}`);\n }\n }\n\n /**\n * Claim ownership of a list of partitions. This will return the list of partitions that were\n * successfully claimed.\n *\n * @param partitionOwnership - The list of partition ownership this instance is claiming to own.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns A list partitions this instance successfully claimed ownership.\n */\n async claimOwnership(\n partitionOwnership: PartitionOwnership[],\n options: OperationOptions = {}\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n for (const ownership of partitionOwnership) {\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"ownership\", ...ownership });\n try {\n const updatedBlobResponse = await this._setBlobMetadata(\n blobName,\n {\n ownerid: ownership.ownerId,\n },\n ownership.etag,\n options\n );\n\n if (updatedBlobResponse.lastModified) {\n ownership.lastModifiedTimeInMs = updatedBlobResponse.lastModified.getTime();\n }\n\n ownership.etag = updatedBlobResponse.etag;\n partitionOwnershipArray.push(ownership);\n logger.info(\n `[${ownership.ownerId}] Claimed ownership successfully for partition: ${ownership.partitionId}`,\n `LastModifiedTime: ${ownership.lastModifiedTimeInMs}, ETag: ${ownership.etag}`\n );\n } catch (err: any) {\n const restError = err as RestError;\n\n if (restError.statusCode === 412) {\n // etag failures (precondition not met) aren't fatal errors. They happen\n // as multiple consumers attempt to claim the same partition (first one wins)\n // and losers get this error.\n logger.verbose(\n `[${ownership.ownerId}] Did not claim partition ${ownership.partitionId}. Another processor has already claimed it.`\n );\n continue;\n }\n\n logger.warning(\n `Error occurred while claiming ownership for partition: ${ownership.partitionId}`,\n err.message\n );\n logErrorStackTrace(err);\n\n throw err;\n }\n }\n return partitionOwnershipArray;\n }\n\n /**\n * Lists all the checkpoints in a data store for a given namespace, eventhub and consumer group.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n */\n async listCheckpoints(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {}\n ): Promise<Checkpoint[]> {\n const { abortSignal, tracingOptions } = options;\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"checkpoint\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup,\n });\n\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n const checkpoints: Checkpoint[] = [];\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const checkpointMetadata = (blob.metadata as CheckpointMetadata) ?? {};\n\n const offset = parseIntOrThrow(blob.name, \"offset\", checkpointMetadata.offset);\n const sequenceNumber = parseIntOrThrow(\n blob.name,\n \"sequencenumber\",\n checkpointMetadata.sequencenumber\n );\n\n checkpoints.push({\n consumerGroup,\n eventHubName,\n fullyQualifiedNamespace,\n partitionId: blobName,\n offset,\n sequenceNumber,\n });\n }\n\n return checkpoints;\n }\n\n /**\n * Updates the checkpoint in the data store for a partition.\n *\n * @param checkpoint - The checkpoint.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns The new etag on successful update.\n */\n async updateCheckpoint(checkpoint: Checkpoint, options: OperationOptions = {}): Promise<void> {\n throwTypeErrorIfParameterMissing(\n \"updateCheckpoint\",\n \"sequenceNumber\",\n checkpoint.sequenceNumber\n );\n throwTypeErrorIfParameterMissing(\"updateCheckpoint\", \"offset\", checkpoint.offset);\n\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"checkpoint\", ...checkpoint });\n try {\n const metadataResponse = await this._setBlobMetadata(\n blobName,\n {\n sequencenumber: checkpoint.sequenceNumber.toString(),\n offset: checkpoint.offset.toString(),\n },\n undefined,\n options\n );\n\n logger.verbose(\n `Updated checkpoint successfully for partition: ${checkpoint.partitionId}`,\n `LastModifiedTime: ${metadataResponse.lastModified!.toISOString()}, ETag: ${\n metadataResponse.etag\n }`\n );\n return;\n } catch (err: any) {\n logger.warning(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`,\n err.message\n );\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`\n );\n }\n }\n\n private static getBlobPrefix(params: {\n type: \"ownership\" | \"checkpoint\";\n fullyQualifiedNamespace: string;\n eventHubName: string;\n consumerGroup: string;\n partitionId?: string;\n }): string {\n // none of these are case-sensitive in eventhubs so we need to make sure we don't accidentally allow\n // the user to create a case-sensitive blob for their state!\n const consumerGroupName = params.consumerGroup.toLowerCase();\n const eventHubName = params.eventHubName.toLowerCase();\n const fullyQualifiedNamespace = params.fullyQualifiedNamespace.toLowerCase();\n\n if (params.partitionId) {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/${params.partitionId}`;\n } else {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/`;\n }\n }\n\n private async _setBlobMetadata(\n blobName: string,\n metadata: OwnershipMetadata | CheckpointMetadata,\n etag: string | undefined,\n options: OperationOptions = {}\n ): Promise<BlobSetMetadataResponse> {\n const { abortSignal, tracingOptions } = options;\n const blockBlobClient = this._containerClient.getBlobClient(blobName).getBlockBlobClient();\n\n // When we have an etag, we know the blob existed.\n // If we encounter an error we should fail.\n if (etag) {\n return blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n conditions: {\n ifMatch: etag,\n },\n tracingOptions,\n });\n } else {\n try {\n // Attempt to set metadata, and fallback to upload if the blob doesn't already exist.\n // This avoids poor performance in storage accounts with soft-delete or blob versioning enabled.\n // https://github.com/Azure/azure-sdk-for-js/issues/10132\n return await blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n tracingOptions,\n });\n } catch (err: any) {\n // Check if the error is `BlobNotFound` and fallback to `upload` if it is.\n if (err?.name !== \"RestError\") {\n throw err;\n }\n const errorDetails = (err as RestError).details as { [field: string]: string } | undefined;\n const errorCode = errorDetails?.errorCode;\n if (!errorCode || errorCode !== \"BlobNotFound\") {\n throw err;\n }\n\n return blockBlobClient.upload(\"\", 0, {\n abortSignal,\n metadata: metadata as Metadata,\n tracingOptions,\n });\n }\n }\n }\n}\n\ntype OwnershipMetadata = {\n [k in \"ownerid\"]: string | undefined;\n};\n\ntype CheckpointMetadata = {\n [k in \"sequencenumber\" | \"offset\"]: string | undefined;\n};\n\n/**\n * @internal\n */\nexport function parseIntOrThrow(\n blobName: string,\n fieldName: string,\n numStr: string | undefined\n): number {\n if (numStr == null) {\n throw new Error(`Missing metadata property '${fieldName}' on blob '${blobName}'`);\n }\n\n const num = parseInt(numStr, 10);\n\n if (isNaN(num)) {\n throw new Error(\n `Failed to parse metadata property '${fieldName}' on blob '${blobName}' as a number`\n );\n }\n\n return num;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"blobCheckpointStore.js","sourceRoot":"","sources":["../../src/blobCheckpointStore.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AASlC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAG9B;;;OAGG;IACH,YAAY,eAAoC;QAC9C,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;IAC1C,CAAC;IACD;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,aAAa,CACjB,uBAA+B,EAC/B,YAAoB,EACpB,aAAqB,EACrB,UAA4B,EAAE;QAE9B,MAAM,uBAAuB,GAAyB,EAAE,CAAC;QACzD,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;QAEhD,MAAM,UAAU,GAAG,mBAAmB,CAAC,aAAa,CAAC;YACnD,IAAI,EAAE,WAAW;YACjB,uBAAuB;YACvB,YAAY;YACZ,aAAa,EAAE,aAAa;SAC7B,CAAC,CAAC;QAEH,IAAI;YACF,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC;gBAChD,WAAW;gBACX,eAAe,EAAE,IAAI;gBACrB,MAAM,EAAE,UAAU;gBAClB,cAAc;aACf,CAAC,CAAC;YAEH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE;gBAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAE/C,MAAM,iBAAiB,GAAI,IAAI,CAAC,QAA8B,IAAI,EAAE,CAAC;gBAErE,IAAI,iBAAiB,CAAC,OAAO,IAAI,IAAI,EAAE;oBACrC,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;iBACtE;gBAED,MAAM,kBAAkB,GAAuB;oBAC7C,uBAAuB;oBACvB,YAAY;oBACZ,aAAa,EAAE,aAAa;oBAC5B,OAAO,EAAE,iBAAiB,CAAC,OAAO;oBAClC,WAAW,EAAE,QAAQ;oBACrB,oBAAoB,EAClB,IAAI,CAAC,UAAU,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE;oBACxE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;iBAC3B,CAAC;gBACF,uBAAuB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;aAClD;YACD,OAAO,uBAAuB,CAAC;SAChC;QAAC,OAAO,GAAQ,EAAE;YACjB,MAAM,CAAC,OAAO,CAAC,iDAAiD,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/E,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAExB,IAAI,GAAG,EAAE,IAAI,KAAK,YAAY;gBAAE,MAAM,GAAG,CAAC;YAE1C,MAAM,IAAI,KAAK,CAAC,sDAAsD,GAAG,EAAE,CAAC,CAAC;SAC9E;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,cAAc,CAClB,kBAAwC,EACxC,UAA4B,EAAE;QAE9B,MAAM,uBAAuB,GAAyB,EAAE,CAAC;QACzD,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE;YAC1C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;YACxF,IAAI;gBACF,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACrD,QAAQ,EACR;oBACE,OAAO,EAAE,SAAS,CAAC,OAAO;iBAC3B,EACD,SAAS,CAAC,IAAI,EACd,OAAO,CACR,CAAC;gBAEF,IAAI,mBAAmB,CAAC,YAAY,EAAE;oBACpC,SAAS,CAAC,oBAAoB,GAAG,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;iBAC7E;gBAED,SAAS,CAAC,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC;gBAC1C,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC,OAAO,mDAAmD,SAAS,CAAC,WAAW,EAAE,EAC/F,qBAAqB,SAAS,CAAC,oBAAoB,WAAW,SAAS,CAAC,IAAI,EAAE,CAC/E,CAAC;aACH;YAAC,OAAO,GAAQ,EAAE;gBACjB,MAAM,SAAS,GAAG,GAAgB,CAAC;gBAEnC,IAAI,SAAS,CAAC,UAAU,KAAK,GAAG,EAAE;oBAChC,wEAAwE;oBACxE,6EAA6E;oBAC7E,6BAA6B;oBAC7B,MAAM,CAAC,OAAO,CACZ,IAAI,SAAS,CAAC,OAAO,6BAA6B,SAAS,CAAC,WAAW,6CAA6C,CACrH,CAAC;oBACF,SAAS;iBACV;gBAED,MAAM,CAAC,OAAO,CACZ,0DAA0D,SAAS,CAAC,WAAW,EAAE,EACjF,GAAG,CAAC,OAAO,CACZ,CAAC;gBACF,kBAAkB,CAAC,GAAG,CAAC,CAAC;gBAExB,MAAM,GAAG,CAAC;aACX;SACF;QACD,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,eAAe,CACnB,uBAA+B,EAC/B,YAAoB,EACpB,aAAqB,EACrB,UAA4B,EAAE;QAE9B,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;QAChD,MAAM,UAAU,GAAG,mBAAmB,CAAC,aAAa,CAAC;YACnD,IAAI,EAAE,YAAY;YAClB,uBAAuB;YACvB,YAAY;YACZ,aAAa;SACd,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC;YAChD,WAAW;YACX,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,UAAU;YAClB,cAAc;SACf,CAAC,CAAC;QAEH,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAE/C,MAAM,kBAAkB,GAAI,IAAI,CAAC,QAA+B,IAAI,EAAE,CAAC;YAEvE,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC/E,MAAM,cAAc,GAAG,eAAe,CACpC,IAAI,CAAC,IAAI,EACT,gBAAgB,EAChB,kBAAkB,CAAC,cAAc,CAClC,CAAC;YAEF,WAAW,CAAC,IAAI,CAAC;gBACf,aAAa;gBACb,YAAY;gBACZ,uBAAuB;gBACvB,WAAW,EAAE,QAAQ;gBACrB,MAAM;gBACN,cAAc;aACf,CAAC,CAAC;SACJ;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,gBAAgB,CAAC,UAAsB,EAAE,UAA4B,EAAE;QAC3E,gCAAgC,CAC9B,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,CAAC,cAAc,CAC1B,CAAC;QACF,gCAAgC,CAAC,kBAAkB,EAAE,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAElF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;QAC1F,IAAI;YACF,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAClD,QAAQ,EACR;gBACE,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,QAAQ,EAAE;gBACpD,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;aACrC,EACD,SAAS,EACT,OAAO,CACR,CAAC;YAEF,MAAM,CAAC,OAAO,CACZ,kDAAkD,UAAU,CAAC,WAAW,EAAE,EAC1E,qBAAqB,gBAAgB,CAAC,YAAa,CAAC,WAAW,EAAE,WAC/D,gBAAgB,CAAC,IACnB,EAAE,CACH,CAAC;YACF,OAAO;SACR;QAAC,OAAO,GAAQ,EAAE;YACjB,MAAM,CAAC,OAAO,CACZ,8DAA8D,UAAU,CAAC,WAAW,GAAG,EACvF,GAAG,CAAC,OAAO,CACZ,CAAC;YACF,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAExB,IAAI,GAAG,EAAE,IAAI,KAAK,YAAY;gBAAE,MAAM,GAAG,CAAC;YAE1C,MAAM,IAAI,KAAK,CACb,8DAA8D,UAAU,CAAC,WAAW,KAAK,GAAG,EAAE,CAC/F,CAAC;SACH;IACH,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,MAM5B;QACC,oGAAoG;QACpG,4DAA4D;QAC5D,MAAM,iBAAiB,GAAG,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QAC7D,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC,WAAW,EAAE,CAAC;QAE7E,IAAI,MAAM,CAAC,WAAW,EAAE;YACtB,OAAO,GAAG,uBAAuB,IAAI,YAAY,IAAI,iBAAiB,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;SAC/G;aAAM;YACL,OAAO,GAAG,uBAAuB,IAAI,YAAY,IAAI,iBAAiB,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC;SAC1F;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,QAAgB,EAChB,QAAgD,EAChD,IAAwB,EACxB,UAA4B,EAAE;QAE9B,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAE3F,kDAAkD;QAClD,2CAA2C;QAC3C,IAAI,IAAI,EAAE;YACR,OAAO,eAAe,CAAC,WAAW,CAAC,QAAoB,EAAE;gBACvD,WAAW;gBACX,UAAU,EAAE;oBACV,OAAO,EAAE,IAAI;iBACd;gBACD,cAAc;aACf,CAAC,CAAC;SACJ;aAAM;YACL,IAAI;gBACF,qFAAqF;gBACrF,gGAAgG;gBAChG,yDAAyD;gBACzD,OAAO,MAAM,eAAe,CAAC,WAAW,CAAC,QAAoB,EAAE;oBAC7D,WAAW;oBACX,cAAc;iBACf,CAAC,CAAC;aACJ;YAAC,OAAO,GAAQ,EAAE;gBACjB,0EAA0E;gBAC1E,IAAI,GAAG,EAAE,IAAI,KAAK,WAAW,EAAE;oBAC7B,MAAM,GAAG,CAAC;iBACX;gBACD,MAAM,YAAY,GAAI,GAAiB,CAAC,OAAkD,CAAC;gBAC3F,MAAM,SAAS,GAAG,YAAY,EAAE,SAAS,CAAC;gBAC1C,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,cAAc,EAAE;oBAC9C,MAAM,GAAG,CAAC;iBACX;gBAED,OAAO,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE;oBACnC,WAAW;oBACX,QAAQ,EAAE,QAAoB;oBAC9B,cAAc;iBACf,CAAC,CAAC;aACJ;SACF;IACH,CAAC;CACF;AAUD;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,SAAiB,EACjB,MAA0B;IAE1B,IAAI,MAAM,IAAI,IAAI,EAAE;QAClB,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,cAAc,QAAQ,GAAG,CAAC,CAAC;KACnF;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEjC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;QACd,MAAM,IAAI,KAAK,CACb,sCAAsC,SAAS,cAAc,QAAQ,eAAe,CACrF,CAAC;KACH;IAED,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n CheckpointStore,\n PartitionOwnership,\n Checkpoint,\n OperationOptions,\n} from \"@azure/event-hubs\";\nimport { Metadata, RestError, BlobSetMetadataResponse } from \"@azure/storage-blob\";\nimport { logger, logErrorStackTrace } from \"./log\";\nimport { ContainerClientLike } from \"./storageBlobInterfaces\";\nimport { throwTypeErrorIfParameterMissing } from \"./util/error\";\n\n/**\n * An implementation of CheckpointStore that uses Azure Blob Storage to persist checkpoint data.\n */\nexport class BlobCheckpointStore implements CheckpointStore {\n private _containerClient: ContainerClientLike;\n\n /**\n * Constructs a new instance of {@link BlobCheckpointStore}\n * @param containerClient - An instance of a storage blob ContainerClient.\n */\n constructor(containerClient: ContainerClientLike) {\n this._containerClient = containerClient;\n }\n /**\n * Get the list of all existing partition ownership from the underlying data store. May return empty\n * results if there are is no existing ownership information.\n * Partition Ownership contains the information on which `EventHubConsumerClient` subscribe call is currently processing the partition.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns Partition ownership details of all the partitions that have had an owner.\n */\n async listOwnership(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {},\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n const { abortSignal, tracingOptions } = options;\n\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"ownership\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n });\n\n try {\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const ownershipMetadata = (blob.metadata as OwnershipMetadata) ?? {};\n\n if (ownershipMetadata.ownerid == null) {\n throw new Error(`Missing ownerid in metadata for blob ${blob.name}`);\n }\n\n const partitionOwnership: PartitionOwnership = {\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup: consumerGroup,\n ownerId: ownershipMetadata.ownerid,\n partitionId: blobName,\n lastModifiedTimeInMs:\n blob.properties.lastModified && blob.properties.lastModified.getTime(),\n etag: blob.properties.etag,\n };\n partitionOwnershipArray.push(partitionOwnership);\n }\n return partitionOwnershipArray;\n } catch (err: any) {\n logger.warning(`Error occurred while fetching the list of blobs`, err.message);\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(`Error occurred while fetching the list of blobs. \\n${err}`);\n }\n }\n\n /**\n * Claim ownership of a list of partitions. This will return the list of partitions that were\n * successfully claimed.\n *\n * @param partitionOwnership - The list of partition ownership this instance is claiming to own.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns A list partitions this instance successfully claimed ownership.\n */\n async claimOwnership(\n partitionOwnership: PartitionOwnership[],\n options: OperationOptions = {},\n ): Promise<PartitionOwnership[]> {\n const partitionOwnershipArray: PartitionOwnership[] = [];\n for (const ownership of partitionOwnership) {\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"ownership\", ...ownership });\n try {\n const updatedBlobResponse = await this._setBlobMetadata(\n blobName,\n {\n ownerid: ownership.ownerId,\n },\n ownership.etag,\n options,\n );\n\n if (updatedBlobResponse.lastModified) {\n ownership.lastModifiedTimeInMs = updatedBlobResponse.lastModified.getTime();\n }\n\n ownership.etag = updatedBlobResponse.etag;\n partitionOwnershipArray.push(ownership);\n logger.info(\n `[${ownership.ownerId}] Claimed ownership successfully for partition: ${ownership.partitionId}`,\n `LastModifiedTime: ${ownership.lastModifiedTimeInMs}, ETag: ${ownership.etag}`,\n );\n } catch (err: any) {\n const restError = err as RestError;\n\n if (restError.statusCode === 412) {\n // etag failures (precondition not met) aren't fatal errors. They happen\n // as multiple consumers attempt to claim the same partition (first one wins)\n // and losers get this error.\n logger.verbose(\n `[${ownership.ownerId}] Did not claim partition ${ownership.partitionId}. Another processor has already claimed it.`,\n );\n continue;\n }\n\n logger.warning(\n `Error occurred while claiming ownership for partition: ${ownership.partitionId}`,\n err.message,\n );\n logErrorStackTrace(err);\n\n throw err;\n }\n }\n return partitionOwnershipArray;\n }\n\n /**\n * Lists all the checkpoints in a data store for a given namespace, eventhub and consumer group.\n *\n * @param fullyQualifiedNamespace - The fully qualified Event Hubs namespace. This is likely to be similar to\n * <yournamespace>.servicebus.windows.net.\n * @param eventHubName - The event hub name.\n * @param consumerGroup - The consumer group name.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n */\n async listCheckpoints(\n fullyQualifiedNamespace: string,\n eventHubName: string,\n consumerGroup: string,\n options: OperationOptions = {},\n ): Promise<Checkpoint[]> {\n const { abortSignal, tracingOptions } = options;\n const blobPrefix = BlobCheckpointStore.getBlobPrefix({\n type: \"checkpoint\",\n fullyQualifiedNamespace,\n eventHubName,\n consumerGroup,\n });\n\n const blobs = this._containerClient.listBlobsFlat({\n abortSignal,\n includeMetadata: true,\n prefix: blobPrefix,\n tracingOptions,\n });\n\n const checkpoints: Checkpoint[] = [];\n\n for await (const blob of blobs) {\n const blobPath = blob.name.split(\"/\");\n const blobName = blobPath[blobPath.length - 1];\n\n const checkpointMetadata = (blob.metadata as CheckpointMetadata) ?? {};\n\n const offset = parseIntOrThrow(blob.name, \"offset\", checkpointMetadata.offset);\n const sequenceNumber = parseIntOrThrow(\n blob.name,\n \"sequencenumber\",\n checkpointMetadata.sequencenumber,\n );\n\n checkpoints.push({\n consumerGroup,\n eventHubName,\n fullyQualifiedNamespace,\n partitionId: blobName,\n offset,\n sequenceNumber,\n });\n }\n\n return checkpoints;\n }\n\n /**\n * Updates the checkpoint in the data store for a partition.\n *\n * @param checkpoint - The checkpoint.\n * @param options - A set of options that can be specified to influence the behavior of this method.\n * - `abortSignal`: A signal used to request operation cancellation.\n * - `tracingOptions`: Options for configuring tracing.\n * @returns The new etag on successful update.\n */\n async updateCheckpoint(checkpoint: Checkpoint, options: OperationOptions = {}): Promise<void> {\n throwTypeErrorIfParameterMissing(\n \"updateCheckpoint\",\n \"sequenceNumber\",\n checkpoint.sequenceNumber,\n );\n throwTypeErrorIfParameterMissing(\"updateCheckpoint\", \"offset\", checkpoint.offset);\n\n const blobName = BlobCheckpointStore.getBlobPrefix({ type: \"checkpoint\", ...checkpoint });\n try {\n const metadataResponse = await this._setBlobMetadata(\n blobName,\n {\n sequencenumber: checkpoint.sequenceNumber.toString(),\n offset: checkpoint.offset.toString(),\n },\n undefined,\n options,\n );\n\n logger.verbose(\n `Updated checkpoint successfully for partition: ${checkpoint.partitionId}`,\n `LastModifiedTime: ${metadataResponse.lastModified!.toISOString()}, ETag: ${\n metadataResponse.etag\n }`,\n );\n return;\n } catch (err: any) {\n logger.warning(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}.`,\n err.message,\n );\n logErrorStackTrace(err);\n\n if (err?.name === \"AbortError\") throw err;\n\n throw new Error(\n `Error occurred while upating the checkpoint for partition: ${checkpoint.partitionId}, ${err}`,\n );\n }\n }\n\n private static getBlobPrefix(params: {\n type: \"ownership\" | \"checkpoint\";\n fullyQualifiedNamespace: string;\n eventHubName: string;\n consumerGroup: string;\n partitionId?: string;\n }): string {\n // none of these are case-sensitive in eventhubs so we need to make sure we don't accidentally allow\n // the user to create a case-sensitive blob for their state!\n const consumerGroupName = params.consumerGroup.toLowerCase();\n const eventHubName = params.eventHubName.toLowerCase();\n const fullyQualifiedNamespace = params.fullyQualifiedNamespace.toLowerCase();\n\n if (params.partitionId) {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/${params.partitionId}`;\n } else {\n return `${fullyQualifiedNamespace}/${eventHubName}/${consumerGroupName}/${params.type}/`;\n }\n }\n\n private async _setBlobMetadata(\n blobName: string,\n metadata: OwnershipMetadata | CheckpointMetadata,\n etag: string | undefined,\n options: OperationOptions = {},\n ): Promise<BlobSetMetadataResponse> {\n const { abortSignal, tracingOptions } = options;\n const blockBlobClient = this._containerClient.getBlobClient(blobName).getBlockBlobClient();\n\n // When we have an etag, we know the blob existed.\n // If we encounter an error we should fail.\n if (etag) {\n return blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n conditions: {\n ifMatch: etag,\n },\n tracingOptions,\n });\n } else {\n try {\n // Attempt to set metadata, and fallback to upload if the blob doesn't already exist.\n // This avoids poor performance in storage accounts with soft-delete or blob versioning enabled.\n // https://github.com/Azure/azure-sdk-for-js/issues/10132\n return await blockBlobClient.setMetadata(metadata as Metadata, {\n abortSignal,\n tracingOptions,\n });\n } catch (err: any) {\n // Check if the error is `BlobNotFound` and fallback to `upload` if it is.\n if (err?.name !== \"RestError\") {\n throw err;\n }\n const errorDetails = (err as RestError).details as { [field: string]: string } | undefined;\n const errorCode = errorDetails?.errorCode;\n if (!errorCode || errorCode !== \"BlobNotFound\") {\n throw err;\n }\n\n return blockBlobClient.upload(\"\", 0, {\n abortSignal,\n metadata: metadata as Metadata,\n tracingOptions,\n });\n }\n }\n }\n}\n\ntype OwnershipMetadata = {\n [k in \"ownerid\"]: string | undefined;\n};\n\ntype CheckpointMetadata = {\n [k in \"sequencenumber\" | \"offset\"]: string | undefined;\n};\n\n/**\n * @internal\n */\nexport function parseIntOrThrow(\n blobName: string,\n fieldName: string,\n numStr: string | undefined,\n): number {\n if (numStr == null) {\n throw new Error(`Missing metadata property '${fieldName}' on blob '${blobName}'`);\n }\n\n const num = parseInt(numStr, 10);\n\n if (isNaN(num)) {\n throw new Error(\n `Failed to parse metadata property '${fieldName}' on blob '${blobName}' as a number`,\n );\n }\n\n return num;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageBlobInterfaces.js","sourceRoot":"","sources":["../../src/storageBlobInterfaces.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n Metadata,\n BlobItem,\n ContainerListBlobFlatSegmentResponse,\n ContainerListBlobsOptions,\n BlockBlobUploadOptions,\n BlockBlobUploadResponse,\n HttpRequestBody,\n BlobSetMetadataOptions,\n ContainerSetMetadataResponse,\n} from \"@azure/storage-blob\";\nimport { PagedAsyncIterableIterator } from \"@azure/core-paging\";\n\n/**\n * An interface compatible with an instance of {@link BlobClient}.\n */\nexport interface BlobClientLike {\n /**\n * Creates a BlockBlobClient object.\n */\n getBlockBlobClient(): BlockBlobClientLike;\n}\n\n/**\n * An interface compatible with Storage Blob's ContainerClient class.\n */\nexport interface ContainerClientLike {\n /**\n * Creates a {@link BlobClient}\n */\n getBlobClient(blobName: string): BlobClientLike;\n /**\n * Returns an async iterable iterator to list all the blobs\n * under the specified account.\n */\n listBlobsFlat(\n options?: ContainerListBlobsOptions
|
|
1
|
+
{"version":3,"file":"storageBlobInterfaces.js","sourceRoot":"","sources":["../../src/storageBlobInterfaces.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n Metadata,\n BlobItem,\n ContainerListBlobFlatSegmentResponse,\n ContainerListBlobsOptions,\n BlockBlobUploadOptions,\n BlockBlobUploadResponse,\n HttpRequestBody,\n BlobSetMetadataOptions,\n ContainerSetMetadataResponse,\n} from \"@azure/storage-blob\";\nimport { PagedAsyncIterableIterator } from \"@azure/core-paging\";\n\n/**\n * An interface compatible with an instance of {@link BlobClient}.\n */\nexport interface BlobClientLike {\n /**\n * Creates a BlockBlobClient object.\n */\n getBlockBlobClient(): BlockBlobClientLike;\n}\n\n/**\n * An interface compatible with Storage Blob's ContainerClient class.\n */\nexport interface ContainerClientLike {\n /**\n * Creates a {@link BlobClient}\n */\n getBlobClient(blobName: string): BlobClientLike;\n /**\n * Returns an async iterable iterator to list all the blobs\n * under the specified account.\n */\n listBlobsFlat(\n options?: ContainerListBlobsOptions,\n ): PagedAsyncIterableIterator<BlobItem, ContainerListBlobFlatSegmentResponse>;\n}\n\n/**\n * An interface compatible with Storage Blob's BlockBlobClient class.\n */\nexport interface BlockBlobClientLike {\n /**\n * Creates a new block blob, or updated the content of an existing block blob.\n */\n upload(\n body: HttpRequestBody,\n contentLength: number,\n options?: BlockBlobUploadOptions,\n ): Promise<BlockBlobUploadResponse>;\n /**\n * Sets user-defined metadata for the specified blob as one or more name-value pairs.\n */\n setMetadata(\n metadata?: Metadata,\n options?: BlobSetMetadataOptions,\n ): Promise<ContainerSetMetadataResponse>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/util/error.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,UAAU,gCAAgC,CAC9C,UAAkB,EAClB,aAAqB,EACrB,cAAuB;IAEvB,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,EAAE;QAC3D,MAAM,KAAK,GAAG,IAAI,SAAS,CACzB,GAAG,UAAU,sCAAsC,aAAa,GAAG,CACpE,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,KAAK,CAAC;KACb;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { logger, logErrorStackTrace } from \"../log\";\n\n/**\n * @internal\n * Logs and Throws TypeError if given parameter is undefined or null\n * @param methodName - Name of the method that was passed the parameter\n * @param parameterName - Name of the parameter to check\n * @param parameterValue - Value of the parameter to check\n */\nexport function throwTypeErrorIfParameterMissing(\n methodName: string,\n parameterName: string,\n parameterValue: unknown
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/util/error.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,UAAU,gCAAgC,CAC9C,UAAkB,EAClB,aAAqB,EACrB,cAAuB;IAEvB,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,EAAE;QAC3D,MAAM,KAAK,GAAG,IAAI,SAAS,CACzB,GAAG,UAAU,sCAAsC,aAAa,GAAG,CACpE,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,KAAK,CAAC;KACb;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { logger, logErrorStackTrace } from \"../log\";\n\n/**\n * @internal\n * Logs and Throws TypeError if given parameter is undefined or null\n * @param methodName - Name of the method that was passed the parameter\n * @param parameterName - Name of the parameter to check\n * @param parameterValue - Value of the parameter to check\n */\nexport function throwTypeErrorIfParameterMissing(\n methodName: string,\n parameterName: string,\n parameterValue: unknown,\n): void {\n if (parameterValue === undefined || parameterValue === null) {\n const error = new TypeError(\n `${methodName} called without required argument \"${parameterName}\"`,\n );\n logger.warning(error.message);\n logErrorStackTrace(error);\n throw error;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure/eventhubs-checkpointstore-blob",
|
|
3
3
|
"sdk-type": "client",
|
|
4
|
-
"version": "1.1.0-alpha.
|
|
4
|
+
"version": "1.1.0-alpha.20240112.1",
|
|
5
5
|
"description": "An Azure Storage Blob solution to store checkpoints when using Event Hubs.",
|
|
6
6
|
"author": "Microsoft Corporation",
|
|
7
7
|
"license": "MIT",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
"build:test:node": "tsc -p . && dev-tool run bundle",
|
|
40
40
|
"build:test": "npm run build:test:node",
|
|
41
41
|
"build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local",
|
|
42
|
-
"check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
|
|
42
|
+
"check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
|
|
43
43
|
"clean": "rimraf dist dist-* typings *.tgz *.log",
|
|
44
44
|
"execute:samples": "dev-tool samples run samples-dev",
|
|
45
45
|
"extract-api": "tsc -p . && api-extractor run --local",
|
|
46
|
-
"format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
|
|
46
|
+
"format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
|
|
47
47
|
"integration-test:browser": "echo skipped",
|
|
48
48
|
"integration-test:node": "dev-tool run test:node-js-input -- --timeout 1200000 \"dist-esm/test/*.spec.js\"",
|
|
49
49
|
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
|
|
@@ -97,7 +97,6 @@
|
|
|
97
97
|
"karma-sourcemap-loader": "^0.3.8",
|
|
98
98
|
"mocha": "^10.0.0",
|
|
99
99
|
"c8": "^8.0.0",
|
|
100
|
-
"prettier": "^2.5.1",
|
|
101
100
|
"rimraf": "^3.0.0",
|
|
102
101
|
"ts-node": "^10.0.0",
|
|
103
102
|
"typescript": "~5.2.0",
|