From 29858fe225fd1c219ed20fdcb61dca7969c00276 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 4 Dec 2019 15:49:47 -0800 Subject: [PATCH 01/32] starting the migration guide --- event hubs migration guide.md | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 event hubs migration guide.md diff --git a/event hubs migration guide.md b/event hubs migration guide.md new file mode 100644 index 000000000000..f5e7332c8e87 --- /dev/null +++ b/event hubs migration guide.md @@ -0,0 +1,81 @@ +# Migration Guide (EventHubs 2 to 5) + +## Class changes + +`EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending +messages) and `EventHubConsumerClient` (for subscribing to messages). + +| In v2 | Equivalent in v5 | Sample | +|---------------------------------------------|------------------------------------------------------------------|--------| +| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) +| `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventHubClient.createSender` | `EventHubProducerClient.createProducer` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | + +### Migrating code from `EventHubClient` to `EventHubConsumerClient` + +In V2, event handlers were passed as positional arguments to `receive`. + +In V5, event handlers are passed as part of a `SubscriptionEventHandlers` shaped object. + +For example, this code which receives from a partition in V2: + +```typescript +const rcvHandler = client.receive(partitionId, onMessageHandler, onErrorHandler, { + eventPosition: EventPosition.fromStart(), + consumerGroup: "$Default" +}); +``` + +Becomes this in V5: + +```typescript +const eventHubConsumerClient = new EventHubConsumerClient("$Default", connectionString); + +const subscription = eventHubConsumerClient.subscribe( + partitionId, { + processInitialize: (initContext) => { + initContext.setStartingPosition(EventPosition.fromStart()); + }, + processEvents: onMessageHandler, + processError: onErrorHandler +}); + +await subscription.close(); +``` + +See [`receiveEvents.ts`](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) +for a sample program demonstrating this. + +### Migrating code from `EventHubClient` to `EventHubProducerClient` + +In V2, there were multiple options on how to send data. + +In V5, this has been consolidated into a more efficient `sendBatch` method. + +So in V2: +```typescript +console.log(`Sending event: ${eventData.body}`); +await client.send(eventData, partitionId); +``` + +In V5: +```typescript +const eventHubProducerClient = new EventHubProducerClient(connectionString); +console.log(`Sending event: ${eventData.body}`); + +// note that the partition ID is now specified as part of the +// batch, rather than as part of the sendBatch call. +const batch = await eventHubProducerClient.createBatch({ + partitionId: partitionId +}); + +const added = batch.tryAdd(eventData); + +if (!added) { + throw new Error("Failed to add event - larger than maximum allowed size"); +} + +await eventHubProducerClient.sendBatch(batch); +``` \ No newline at end of file From 45065e3130929692093bdb02daebec5eb773665b Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Wed, 4 Dec 2019 16:07:19 -0800 Subject: [PATCH 02/32] Update event hubs migration guide.md Co-Authored-By: chradek <51000525+chradek@users.noreply.github.com> --- event hubs migration guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index f5e7332c8e87..43e4e5672c87 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -10,7 +10,7 @@ messages) and `EventHubConsumerClient` (for subscribing to messages). | `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) | `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventHubClient.createSender` | `EventHubProducerClient.createProducer` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| `EventHubClient.createSender` | `new EventHubProducerClient` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | ### Migrating code from `EventHubClient` to `EventHubConsumerClient` @@ -78,4 +78,4 @@ if (!added) { } await eventHubProducerClient.sendBatch(batch); -``` \ No newline at end of file +``` From a1c6ebd851e7be2eec14a499855119ef44af9e25 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 5 Dec 2019 16:38:32 -0800 Subject: [PATCH 03/32] Change wording to 'receiving' --- event hubs migration guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index f5e7332c8e87..d2f08567e263 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -3,7 +3,7 @@ ## Class changes `EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending -messages) and `EventHubConsumerClient` (for subscribing to messages). +messages) and `EventHubConsumerClient` (for receiving messages). | In v2 | Equivalent in v5 | Sample | |---------------------------------------------|------------------------------------------------------------------|--------| @@ -78,4 +78,4 @@ if (!added) { } await eventHubProducerClient.sendBatch(batch); -``` \ No newline at end of file +``` From e7b1def0574355aabe7b911fa1dfbeee4a8ea275 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 5 Dec 2019 16:40:25 -0800 Subject: [PATCH 04/32] AAD line --- event hubs migration guide.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index d2f08567e263..5f3cfd87e851 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -5,13 +5,14 @@ `EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending messages) and `EventHubConsumerClient` (for receiving messages). -| In v2 | Equivalent in v5 | Sample | -|---------------------------------------------|------------------------------------------------------------------|--------| -| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) -| `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventHubClient.createSender` | `EventHubProducerClient.createProducer` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | -| `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| In v2 | Equivalent in v5 | Sample | +|------------------------------------------------|------------------------------------------------------------------|--------| +| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) +| `EventHubClient.createFromAADTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) +| `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventHubClient.createSender` | `EventHubProducerClient.createProducer` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | ### Migrating code from `EventHubClient` to `EventHubConsumerClient` From 7ca497181a76a2da9ef63cd136a984173a859fc4 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 5 Dec 2019 16:42:41 -0800 Subject: [PATCH 05/32] * Checked against code - casing for AAD was incorrect (should have been Aad). * Remove createSender (doesn't exist!) --- event hubs migration guide.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 5f3cfd87e851..c48ae08a0220 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -8,10 +8,9 @@ messages) and `EventHubConsumerClient` (for receiving messages). | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| | `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) -| `EventHubClient.createFromAADTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) +| `EventHubClient.createFromAadTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) | `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventHubClient.createSender` | `EventHubProducerClient.createProducer` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | ### Migrating code from `EventHubClient` to `EventHubConsumerClient` From 5d7dceb672e8bddabb5bea80441e303132406974 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 5 Dec 2019 16:52:01 -0800 Subject: [PATCH 06/32] Applying Ramya's changes Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index cd9a3332e028..faed14b467f7 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -13,7 +13,7 @@ messages) and `EventHubConsumerClient` (for receiving messages). | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | -### Migrating code from `EventHubClient` to `EventHubConsumerClient` +### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events In V2, event handlers were passed as positional arguments to `receive`. @@ -22,10 +22,12 @@ In V5, event handlers are passed as part of a `SubscriptionEventHandlers` shaped For example, this code which receives from a partition in V2: ```typescript +const client = EventHubClient.createFromConnectionString(connectionString); const rcvHandler = client.receive(partitionId, onMessageHandler, onErrorHandler, { eventPosition: EventPosition.fromStart(), consumerGroup: "$Default" }); +await rcvHandler.stop(); ``` Becomes this in V5: @@ -48,7 +50,7 @@ await subscription.close(); See [`receiveEvents.ts`](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) for a sample program demonstrating this. -### Migrating code from `EventHubClient` to `EventHubProducerClient` +### Migrating code from `EventHubClient` to `EventHubProducerClient` for sending events. In V2, there were multiple options on how to send data. @@ -56,6 +58,7 @@ In V5, this has been consolidated into a more efficient `sendBatch` method. So in V2: ```typescript +const client = EventHubClient.createFromConnectionString(connectionString); console.log(`Sending event: ${eventData.body}`); await client.send(eventData, partitionId); ``` From 686dc6aafd657c46dd5dcc7f8723366cf019af5d Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 5 Dec 2019 17:03:26 -0800 Subject: [PATCH 07/32] Took part of a description from our REST documentation and tailored it a bit. --- event hubs migration guide.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index cd9a3332e028..e5b97b364054 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -13,7 +13,7 @@ messages) and `EventHubConsumerClient` (for receiving messages). | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | -### Migrating code from `EventHubClient` to `EventHubConsumerClient` +### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events In V2, event handlers were passed as positional arguments to `receive`. @@ -48,11 +48,13 @@ await subscription.close(); See [`receiveEvents.ts`](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) for a sample program demonstrating this. -### Migrating code from `EventHubClient` to `EventHubProducerClient` +### Migrating code from `EventHubClient` to `EventHubProducerClient` for sending events In V2, there were multiple options on how to send data. -In V5, this has been consolidated into a more efficient `sendBatch` method. +In V5, this has been consolidated into a more efficient `sendBatch` method. +Batching merges information from multiple messages into a single send, reducing +the amount of network communication needed vs sending messages one at a time. So in V2: ```typescript From 8edaf442fd7a0aee6401198c2bcd439044feec66 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Fri, 6 Dec 2019 11:14:18 -0800 Subject: [PATCH 08/32] Updating migration guide sample for sending. --- event hubs migration guide.md | 53 +++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index d07f0f3f8feb..0e92349418e1 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -60,27 +60,56 @@ the amount of network communication needed vs sending messages one at a time. So in V2: ```typescript +const eventsToSend = [ + // events go here +]; + const client = EventHubClient.createFromConnectionString(connectionString); console.log(`Sending event: ${eventData.body}`); -await client.send(eventData, partitionId); + +// Would fail if the total size of events exceed the max size supported by the library. +await client.send(eventsToSend, partitionId); ``` In V5: ```typescript -const eventHubProducerClient = new EventHubProducerClient(connectionString); -console.log(`Sending event: ${eventData.body}`); +const producer = new EventHubProducerClient(connectionString); -// note that the partition ID is now specified as part of the -// batch, rather than as part of the sendBatch call. -const batch = await eventHubProducerClient.createBatch({ - partitionId: partitionId -}); +const eventsToSend = [ + // events go here +]; -const added = batch.tryAdd(eventData); +let batch = await producer.createBatch(); -if (!added) { - throw new Error("Failed to add event - larger than maximum allowed size"); +for (const event of eventsToSend) { + // messages can fail to be added to the batch if they exceed the maximum size configured for + // the EventHub. + const isAdded = batch.tryAdd({ body: event }); + + if (!isAdded) { + if (batch.count === 0) { + // if we can't add it and the batch is empty that means the message we're trying to send + // is too large, even when it would be the _only_ message in the batch. + // + // To fix this you'll need to potentially split the message up across multiple batches or + // skip it. In this example, we'll skip the message. + console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); + continue; + } + + // otherwise this just signals a good spot to send our batch + console.log(`Batch is full - sending ${batch.count} messages as a single batch.`) + await producer.sendBatch(batch); + + // and create a new one to house the next set of messages + batch = await producer.createBatch(); + continue; + } } -await eventHubProducerClient.sendBatch(batch); +// send any remaining messages, if any. +if (batch.count > 0) { + console.log(`Sending remaining ${batch.count} messages as a single batch.`) + await producer.sendBatch(batch); +} ``` From 52bce991b7bf25ddbe591517ebdadb05838b49fe Mon Sep 17 00:00:00 2001 From: Richard Park Date: Fri, 6 Dec 2019 11:22:18 -0800 Subject: [PATCH 09/32] Add in a description of EventProcessorHost --- event hubs migration guide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 0e92349418e1..856277f12b20 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -5,12 +5,15 @@ `EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending messages) and `EventHubConsumerClient` (for receiving messages). +`EventProcessorHost`'s functionality has been merged into `EventHubConsumerClient` as well. + | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| | `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) | | `EventHubClient.createFromAadTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) | `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventProcessorHost` | `new EventHubConsumerClient(with checkpointStore)` | [receiveEventsUsingCheckpointStore](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts) | | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | ### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events From 79fdac1dd7d2940ababd21edbfd06798a5446114 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Fri, 6 Dec 2019 11:29:32 -0800 Subject: [PATCH 10/32] Removed the 'as well' --- event hubs migration guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 856277f12b20..7c70d784a899 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -1,11 +1,11 @@ -# Migration Guide (EventHubs 2 to 5) +# Migration Guide (EventHubs v2 to v5) ## Class changes `EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending messages) and `EventHubConsumerClient` (for receiving messages). -`EventProcessorHost`'s functionality has been merged into `EventHubConsumerClient` as well. +`EventProcessorHost`'s functionality has been merged into `EventHubConsumerClient`. | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| From a46af7a467eeef7ee8b913fa9decbd40e2c74514 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Mon, 9 Dec 2019 18:18:32 -0800 Subject: [PATCH 11/32] Unlink dependencies if tests fail (#6483) - Results are published for both success and failure - Unlink dependencies should use the same condition as publish - Continuation of #6418 --- eng/pipelines/templates/jobs/archetype-sdk-client.yml | 1 + eng/pipelines/templates/jobs/archetype-sdk-integration.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/eng/pipelines/templates/jobs/archetype-sdk-client.yml b/eng/pipelines/templates/jobs/archetype-sdk-client.yml index f6375c861773..1e911ef29ac5 100644 --- a/eng/pipelines/templates/jobs/archetype-sdk-client.yml +++ b/eng/pipelines/templates/jobs/archetype-sdk-client.yml @@ -257,6 +257,7 @@ jobs: # which need to walk the directory tree (and are hardcoded to follow symlinks). - script: | node eng/tools/rush-runner.js unlink + condition: succeededOrFailed() displayName: "Unlink dependencies" # It's important for performance to pass "sdk" as "searchFolder" to avoid looking under root "node_modules". diff --git a/eng/pipelines/templates/jobs/archetype-sdk-integration.yml b/eng/pipelines/templates/jobs/archetype-sdk-integration.yml index 4b2b4f73f136..dfb8988877fa 100644 --- a/eng/pipelines/templates/jobs/archetype-sdk-integration.yml +++ b/eng/pipelines/templates/jobs/archetype-sdk-integration.yml @@ -134,6 +134,7 @@ jobs: # which need to walk the directory tree (and are hardcoded to follow symlinks). - script: | node eng/tools/rush-runner.js unlink + condition: succeededOrFailed() displayName: "Unlink dependencies" # It's important for performance to pass "sdk" as "searchFolder" to avoid looking under root "node_modules". From 1ff3be664b7342f8d70e93709a93ca9fa245edc8 Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Tue, 10 Dec 2019 00:51:50 -0800 Subject: [PATCH 12/32] [Storage] Add more tests covering progress events (#6428) * [Storage] Add more tests covering progress event Related to #6352. --- ...ding_appendblock_with_progress_report.json | 118 +++++++++ ...cording_download_with_progress_report.json | 52 ++++ ...rding_stageblock_with_progress_report.json | 136 ++++++++++ ...recording_upload_with_progress_report.json | 97 ++++++++ ...ding_uploadpages_with_progress_report.json | 192 +++++++++++++++ ...ording_appendblock_with_progress_report.js | 127 ++++++++++ ...recording_download_with_progress_report.js | 103 ++++++++ ...cording_stageblock_with_progress_report.js | 131 ++++++++++ .../recording_upload_with_progress_report.js | 103 ++++++++ ...ording_uploadpages_with_progress_report.js | 233 ++++++++++++++++++ sdk/storage/storage-blob/src/Clients.ts | 2 +- .../test/appendblobclient.spec.ts | 13 + .../storage-blob/test/blobclient.spec.ts | 15 ++ .../storage-blob/test/blockblobclient.spec.ts | 26 ++ .../storage-blob/test/pageblobclient.spec.ts | 20 ++ ...cording_download_with_progress_report.json | 157 ++++++++++++ ...rding_uploadrange_with_progress_event.json | 48 ++-- ...recording_download_with_progress_report.js | 183 ++++++++++++++ ...cording_uploadrange_with_progress_event.js | 126 +++++++--- ...ording_uploadrange_with_progress_report.js | 209 ++++++++++++++++ .../storage-file-share/src/ShareFileClient.ts | 2 +- .../test/fileclient.spec.ts | 19 +- 22 files changed, 2043 insertions(+), 69 deletions(-) create mode 100644 sdk/storage/storage-blob/recordings/browsers/appendblobclient/recording_appendblock_with_progress_report.json create mode 100644 sdk/storage/storage-blob/recordings/browsers/blobclient/recording_download_with_progress_report.json create mode 100644 sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_stageblock_with_progress_report.json create mode 100644 sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_upload_with_progress_report.json create mode 100644 sdk/storage/storage-blob/recordings/browsers/pageblobclient/recording_uploadpages_with_progress_report.json create mode 100644 sdk/storage/storage-blob/recordings/node/appendblobclient/recording_appendblock_with_progress_report.js create mode 100644 sdk/storage/storage-blob/recordings/node/blobclient/recording_download_with_progress_report.js create mode 100644 sdk/storage/storage-blob/recordings/node/blockblobclient/recording_stageblock_with_progress_report.js create mode 100644 sdk/storage/storage-blob/recordings/node/blockblobclient/recording_upload_with_progress_report.js create mode 100644 sdk/storage/storage-blob/recordings/node/pageblobclient/recording_uploadpages_with_progress_report.js create mode 100644 sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_download_with_progress_report.json create mode 100644 sdk/storage/storage-file-share/recordings/node/fileclient/recording_download_with_progress_report.js create mode 100644 sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_report.js diff --git a/sdk/storage/storage-blob/recordings/browsers/appendblobclient/recording_appendblock_with_progress_report.json b/sdk/storage/storage-blob/recordings/browsers/appendblobclient/recording_appendblock_with_progress_report.json new file mode 100644 index 000000000000..c059fc2e2aa6 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/appendblobclient/recording_appendblock_with_progress_report.json @@ -0,0 +1,118 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592673181609702", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:25:31 GMT", + "etag": "\"0x8D77CEE5224BFBB\"", + "last-modified": "Mon, 09 Dec 2019 21:25:31 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "179fd26a-7aac-4159-b5e1-1cced44f177a", + "x-ms-request-id": "84fe935a-a01e-007f-6ad7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592673181609702/blob157592673187508711", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:25:31 GMT", + "etag": "\"0x8D77CEE522E08E9\"", + "last-modified": "Mon, 09 Dec 2019 21:25:31 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5b97e91c-4b31-4d69-b3bc-9f5b3b29794e", + "x-ms-request-id": "84fe9383-a01e-007f-0fd7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592673181609702/blob157592673187508711", + "query": { + "comp": "appendblock" + }, + "requestBody": "Hello World!", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:25:31 GMT", + "etag": "\"0x8D77CEE523A40F8\"", + "last-modified": "Mon, 09 Dec 2019 21:25:31 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-append-offset": "0", + "x-ms-blob-committed-block-count": "1", + "x-ms-client-request-id": "77cc8019-f8d3-407e-aa64-715baf4e96ba", + "x-ms-content-crc64": "peH8Xsgc5QI=", + "x-ms-request-id": "84fe93ba-a01e-007f-3ed7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592673181609702/blob157592673187508711", + "query": {}, + "requestBody": null, + "status": 200, + "response": "Hello World!", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "12", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:25:32 GMT", + "etag": "\"0x8D77CEE523A40F8\"", + "last-modified": "Mon, 09 Dec 2019 21:25:31 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-committed-block-count": "1", + "x-ms-blob-type": "AppendBlob", + "x-ms-client-request-id": "93881d34-23f5-4c9b-a4aa-e9ed1dacf3dd", + "x-ms-creation-time": "Mon, 09 Dec 2019 21:25:31 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "84fe93ef-a01e-007f-6ed7-aeae44000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592673181609702", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:25:32 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "635419ab-35cd-47ca-b8b9-2dcb7a16c5c9", + "x-ms-request-id": "84fe9431-a01e-007f-27d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container157592673181609702", + "blob": "blob157592673187508711" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_download_with_progress_report.json b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_download_with_progress_report.json new file mode 100644 index 000000000000..f8276b51dfd8 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_download_with_progress_report.json @@ -0,0 +1,52 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592676289306866", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:02 GMT", + "etag": "\"0x8D77CEE64ACB3EC\"", + "last-modified": "Mon, 09 Dec 2019 21:26:02 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "03a3f560-bd92-4298-be6c-0efac8e40c9a", + "x-ms-request-id": "84fefc28-a01e-007f-1cd7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592676289306866/blob157592676296800919", + "query": {}, + "requestBody": "Hello World", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "date": "Mon, 09 Dec 2019 21:26:02 GMT", + "etag": "\"0x8D77CEE64B664B3\"", + "last-modified": "Mon, 09 Dec 2019 21:26:02 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "48621337-e89d-4d61-9b48-ce74a79572d9", + "x-ms-content-crc64": "YeJLfssylmU=", + "x-ms-request-id": "84fefc67-a01e-007f-56d7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container157592676289306866", + "blob": "blob157592676296800919" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_stageblock_with_progress_report.json b/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_stageblock_with_progress_report.json new file mode 100644 index 000000000000..356249852ec2 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_stageblock_with_progress_report.json @@ -0,0 +1,136 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "etag": "\"0x8D77CEE70467CC8\"", + "last-modified": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "7f53369d-3246-44a1-9296-24172abd2776", + "x-ms-request-id": "84ff3789-a01e-007f-45d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446/blob157592678242804877", + "query": { + "blockid": "MQ==", + "comp": "block" + }, + "requestBody": "HelloWorld", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1dd13c51-fb13-4d50-9328-584202c57c91", + "x-ms-content-crc64": "8R2aIe9T07E=", + "x-ms-request-id": "84ff37c7-a01e-007f-7ed7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446/blob157592678242804877", + "query": { + "blockid": "Mg==", + "comp": "block" + }, + "requestBody": "HelloWorld", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d7b03d1a-8f78-451c-936b-9db43066a10c", + "x-ms-content-crc64": "8R2aIe9T07E=", + "x-ms-request-id": "84ff380a-a01e-007f-3bd7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446/blob157592678242804877", + "query": { + "comp": "blocklist" + }, + "requestBody": "MQ==Mg==", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "etag": "\"0x8D77CEE706166CE\"", + "last-modified": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9bc7fabe-5470-480e-846a-43aebd123fdf", + "x-ms-content-crc64": "GFi/o1BSQtU=", + "x-ms-request-id": "84ff3847-a01e-007f-74d7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446/blob157592678242804877", + "query": { + "blocklisttype": "committed", + "comp": "blocklist" + }, + "requestBody": null, + "status": 200, + "response": "MQ==10Mg==10", + "responseHeaders": { + "content-type": "application/xml", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "etag": "\"0x8D77CEE706166CE\"", + "last-modified": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-blob-content-length": "20", + "x-ms-client-request-id": "00244d11-d221-49ac-a0ec-ca282816f87c", + "x-ms-request-id": "84ff3891-a01e-007f-3bd7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678237109446", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3a5e38bd-faee-4e26-997e-f11ff5bdaf1c", + "x-ms-request-id": "84ff38c9-a01e-007f-6fd7-aeae44000000", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container157592678237109446", + "blob": "blob157592678242804877" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_upload_with_progress_report.json b/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_upload_with_progress_report.json new file mode 100644 index 000000000000..eae70187406f --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blockblobclient/recording_upload_with_progress_report.json @@ -0,0 +1,97 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678143108621", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:21 GMT", + "etag": "\"0x8D77CEE6FB8236C\"", + "last-modified": "Mon, 09 Dec 2019 21:26:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2d6c3736-134b-40e2-bdd3-2d9de7fa78e1", + "x-ms-request-id": "84ff3321-a01e-007f-23d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678143108621/blob157592678149609884", + "query": {}, + "requestBody": "randomstring157592678149601807", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "content-md5": "MoI2VYzs2cB2x3bZtAxBog==", + "date": "Mon, 09 Dec 2019 21:26:21 GMT", + "etag": "\"0x8D77CEE6FC15639\"", + "last-modified": "Mon, 09 Dec 2019 21:26:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "dfe94a5e-c9ba-4ed5-be7c-9c4a4f3b8284", + "x-ms-content-crc64": "wXsY1UJnmv0=", + "x-ms-request-id": "84ff3351-a01e-007f-4fd7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678143108621/blob157592678149609884", + "query": {}, + "requestBody": null, + "status": 200, + "response": "randomstring157592678149601807", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "30", + "content-md5": "MoI2VYzs2cB2x3bZtAxBog==", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:26:21 GMT", + "etag": "\"0x8D77CEE6FC15639\"", + "last-modified": "Mon, 09 Dec 2019 21:26:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "b9f99b04-898f-43b3-b2ee-a8471ced4f58", + "x-ms-creation-time": "Mon, 09 Dec 2019 21:26:21 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "84ff3386-a01e-007f-01d7-aeae44000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678143108621", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4ab983de-9420-4596-99cd-82452236fd68", + "x-ms-request-id": "84ff33c9-a01e-007f-40d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container157592678143108621", + "blob": "blob157592678149609884", + "randomstring": "randomstring157592678149601807" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/pageblobclient/recording_uploadpages_with_progress_report.json b/sdk/storage/storage-blob/recordings/browsers/pageblobclient/recording_uploadpages_with_progress_report.json new file mode 100644 index 000000000000..13b81c2aedf8 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/pageblobclient/recording_uploadpages_with_progress_report.json @@ -0,0 +1,192 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73C1B2AE\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b98dc343-dd9a-41e1-935d-1bfc734360cf", + "x-ms-request-id": "84ff51ed-a01e-007f-07d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73CABB23\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5e8de5ef-441c-4086-8825-74a554b9442c", + "x-ms-request-id": "84ff5231-a01e-007f-44d7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": {}, + "requestBody": null, + "status": 200, + "response": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "1024", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73CABB23\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-sequence-number": "0", + "x-ms-blob-type": "PageBlob", + "x-ms-client-request-id": "aa0e5b3c-15d7-48e7-ba7c-1820c0a21693", + "x-ms-creation-time": "Mon, 09 Dec 2019 21:26:28 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "84ff5265-a01e-007f-70d7-aeae44000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": { + "comp": "page" + }, + "requestBody": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73E17D08\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-sequence-number": "0", + "x-ms-client-request-id": "d26b71a4-2efc-4c8f-b0a1-a14649e67656", + "x-ms-content-crc64": "u661BimQ84c=", + "x-ms-request-id": "84ff52c3-a01e-007f-47d7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": { + "comp": "page" + }, + "requestBody": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73E6FC9B\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-sequence-number": "0", + "x-ms-client-request-id": "8589adc3-64bd-4f19-9f31-0405c874ebd8", + "x-ms-content-crc64": "zGf3rvhKPeA=", + "x-ms-request-id": "84ff52e5-a01e-007f-68d7-aeae44000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": {}, + "requestBody": null, + "status": 206, + "response": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "512", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73E6FC9B\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-sequence-number": "0", + "x-ms-blob-type": "PageBlob", + "x-ms-client-request-id": "615fe81c-1a91-4f74-a3a2-aa2e4a76c14a", + "x-ms-creation-time": "Mon, 09 Dec 2019 21:26:28 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "84ff532a-a01e-007f-27d7-aeae44000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027/blob157592678826807059", + "query": {}, + "requestBody": null, + "status": 206, + "response": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "512", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "etag": "\"0x8D77CEE73E6FC9B\"", + "last-modified": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-sequence-number": "0", + "x-ms-blob-type": "PageBlob", + "x-ms-client-request-id": "45bb4224-48a5-4e1a-af2e-8b092643bbfd", + "x-ms-creation-time": "Mon, 09 Dec 2019 21:26:28 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "84ff5374-a01e-007f-6cd7-aeae44000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container157592678820707027", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:26:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "22a85170-9f73-4988-bec3-7da1ffd7c1a3", + "x-ms-request-id": "84ff53ae-a01e-007f-23d7-aeae44000000", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container157592678820707027", + "blob": "blob157592678826807059" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/node/appendblobclient/recording_appendblock_with_progress_report.js b/sdk/storage/storage-blob/recordings/node/appendblobclient/recording_appendblock_with_progress_report.js new file mode 100644 index 000000000000..19b8030510a9 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/appendblobclient/recording_appendblock_with_progress_report.js @@ -0,0 +1,127 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"container":"container157592663509702145","blob":"blob157592663522204231"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592663509702145') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:55 GMT', + 'ETag', + '"0x8D77CEE188A176A"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '3ab5ad49-b01e-0042-66d6-ae1b62000000', + 'x-ms-client-request-id', + '5e137d51-7b18-4def-87f7-a7d9a96362b4', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:23:55 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592663509702145/blob157592663522204231') + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:55 GMT', + 'ETag', + '"0x8D77CEE18A22182"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bd13a9f2-001e-00d8-76d6-ae97a7000000', + 'x-ms-client-request-id', + '53050973-6c0a-4357-a61b-b44771dc1b49', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:23:55 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592663509702145/blob157592663522204231', "Hello World!") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:55 GMT', + 'ETag', + '"0x8D77CEE18A900ED"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bd13aa4c-001e-00d8-3cd6-ae97a7000000', + 'x-ms-client-request-id', + 'de4d56b4-6fa5-470d-b915-b0d98c7cf14f', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + 'peH8Xsgc5QI=', + 'x-ms-blob-append-offset', + '0', + 'x-ms-blob-committed-block-count', + '1', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:23:55 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592663509702145/blob157592663522204231') + .reply(200, "Hello World!", [ 'Content-Length', + '12', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:55 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE18A900ED"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bd13aa8f-001e-00d8-7ad6-ae97a7000000', + 'x-ms-client-request-id', + '4ac4d588-b382-41b6-ad6f-fbf55c1beeba', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:23:55 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'AppendBlob', + 'x-ms-blob-committed-block-count', + '1', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-blob-committed-block-count,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:23:55 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container157592663509702145') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '3ab5adbc-b01e-0042-33d6-ae1b62000000', + 'x-ms-client-request-id', + '75a6f6b0-e1ba-439c-8740-127f61fd3605', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:23:55 GMT' ]); diff --git a/sdk/storage/storage-blob/recordings/node/blobclient/recording_download_with_progress_report.js b/sdk/storage/storage-blob/recordings/node/blobclient/recording_download_with_progress_report.js new file mode 100644 index 000000000000..fec7dd9e535d --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobclient/recording_download_with_progress_report.js @@ -0,0 +1,103 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"container":"container157592663733503219","blob":"blob157592663745900301"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592663733503219') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:57 GMT', + 'ETag', + '"0x8D77CEE19E0442E"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '222f574c-e01e-00d9-7fd6-ae965a000000', + 'x-ms-client-request-id', + '872bfd6a-4408-4627-b34a-7320d10be145', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:23:57 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592663733503219/blob157592663745900301', "Hello World") + .reply(201, "", [ 'Content-Length', + '0', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:57 GMT', + 'ETag', + '"0x8D77CEE19F13A63"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'ae24f44a-501e-0121-5dd6-ae1b12000000', + 'x-ms-client-request-id', + '79ecfc61-68e1-4ccd-ad84-beef1a9447dd', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + 'YeJLfssylmU=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:23:56 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592663733503219/blob157592663745900301') + .reply(200, "Hello World", [ 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:23:57 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE19F13A63"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c2a784d3-401e-00b9-10d6-aed378000000', + 'x-ms-client-request-id', + 'ca418d5a-af53-4bf1-8d5d-579ce09008a5', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:23:57 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,Content-MD5,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:23:56 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container157592663733503219') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '222f578c-e01e-00d9-31d6-ae965a000000', + 'x-ms-client-request-id', + '968abbf9-ef5a-45f0-9f0e-9e5f84fc23d0', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:23:57 GMT' ]); diff --git a/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_stageblock_with_progress_report.js b/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_stageblock_with_progress_report.js new file mode 100644 index 000000000000..5bda05e2c814 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_stageblock_with_progress_report.js @@ -0,0 +1,131 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"container":"container157592665262709328","blob":"blob157592665274204998"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665262709328') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:12 GMT', + 'ETag', + '"0x8D77CEE22FBAACD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '8c855354-f01e-0001-33d7-ae318b000000', + 'x-ms-client-request-id', + '403528b7-4cb5-46d7-94b2-a190ead2bb33', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665262709328/blob157592665274204998', "HelloWorld") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2ffe57e7-301e-007a-2ad7-ae5a3b000000', + 'x-ms-client-request-id', + '33215447-bc71-4ad9-a6b9-0c3832818788', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + '8R2aIe9T07E=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665262709328/blob157592665274204998', "HelloWorld") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2ffe5808-301e-007a-46d7-ae5a3b000000', + 'x-ms-client-request-id', + '769b1511-4971-4db0-879b-fc35d01a6f5b', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + '8R2aIe9T07E=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665262709328/blob157592665274204998', "MQ==Mg==") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:12 GMT', + 'ETag', + '"0x8D77CEE231B5DC1"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2ffe5824-301e-007a-5dd7-ae5a3b000000', + 'x-ms-client-request-id', + 'e179c681-275e-4e37-8960-84dd733dae91', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + 'GFi/o1BSQtU=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592665262709328/blob157592665274204998') + .query(true) + .reply(200, "MQ==10Mg==10", [ 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:12 GMT', + 'ETag', + '"0x8D77CEE231B5DC1"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2ffe5841-301e-007a-75d7-ae5a3b000000', + 'x-ms-client-request-id', + 'bfad6724-9dc6-4610-9ea7-6ce37c7d28fe', + 'x-ms-version', + '2019-02-02', + 'x-ms-blob-content-length', + '20', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-blob-content-length,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container157592665262709328') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '8c8553b2-f01e-0001-09d7-ae318b000000', + 'x-ms-client-request-id', + '017cac2b-87cf-4978-9099-c58b61e861bc', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:12 GMT' ]); diff --git a/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_upload_with_progress_report.js b/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_upload_with_progress_report.js new file mode 100644 index 000000000000..4c8e892786ce --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blockblobclient/recording_upload_with_progress_report.js @@ -0,0 +1,103 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"container":"container157592665127602446","blob":"blob157592665147600158","randomstring":"randomstring157592665147601522"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665127602446') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:11 GMT', + 'ETag', + '"0x8D77CEE222E62DB"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bcf7b22b-001e-00fa-59d6-aef991000000', + 'x-ms-client-request-id', + '3ae0b546-ae3d-4465-9147-37fa69443fba', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:11 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592665127602446/blob157592665147600158', "randomstring157592665147601522") + .reply(201, "", [ 'Content-Length', + '0', + 'Content-MD5', + 'x/EHLw8yNJrur368nG4sNw==', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:11 GMT', + 'ETag', + '"0x8D77CEE224BF478"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e6fa29f0-c01e-0124-4ad6-aeef6d000000', + 'x-ms-client-request-id', + '09069b53-c884-4b0a-b533-91a70f079e63', + 'x-ms-version', + '2019-02-02', + 'x-ms-content-crc64', + 'PxU/7s2wiXk=', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:24:11 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592665127602446/blob157592665147600158') + .reply(200, "randomstring157592665147601522", [ 'Content-Length', + '30', + 'Content-Type', + 'application/octet-stream', + 'Content-MD5', + 'x/EHLw8yNJrur368nG4sNw==', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:11 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE224BF478"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'b29f19ef-701e-00f5-57d6-ae1467000000', + 'x-ms-client-request-id', + 'f2a82c53-7dc9-4f85-92d3-c8786cd4d811', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:24:11 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,Content-MD5,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:24:11 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container157592665127602446') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bcf7b30f-001e-00fa-1bd6-aef991000000', + 'x-ms-client-request-id', + '01af28af-1fad-4a6f-a16e-60aad2ada97d', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:11 GMT' ]); diff --git a/sdk/storage/storage-blob/recordings/node/pageblobclient/recording_uploadpages_with_progress_report.js b/sdk/storage/storage-blob/recordings/node/pageblobclient/recording_uploadpages_with_progress_report.js new file mode 100644 index 000000000000..6bdf67b4f65b --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/pageblobclient/recording_uploadpages_with_progress_report.js @@ -0,0 +1,233 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"container":"container157592666159301045","blob":"blob157592666170408961"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592666159301045') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'ETag', + '"0x8D77CEE2854330B"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '54a1778d-101e-00aa-0bd7-aee699000000', + 'x-ms-client-request-id', + '6623cc4a-44ff-4886-a725-93995d2f487c', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592666159301045/blob157592666170408961') + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'ETag', + '"0x8D77CEE28653206"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a9ab670-301e-0035-12d7-ae9e23000000', + 'x-ms-client-request-id', + 'ab64b4f6-2975-4884-ad1b-f76f5636931f', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592666159301045/blob157592666170408961') + .reply(200, "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", [ 'Content-Length', + '1024', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE28653206"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '34bd6e7f-f01e-010e-4ad7-ae9a28000000', + 'x-ms-client-request-id', + 'ba75a062-658e-4249-ad03-4ef43038219f', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'PageBlob', + 'x-ms-blob-sequence-number', + '0', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-blob-sequence-number,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592666159301045/blob157592666170408961', "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'ETag', + '"0x8D77CEE287C421A"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a9ab6b3-301e-0035-4cd7-ae9e23000000', + 'x-ms-client-request-id', + '957e3755-8a53-4d81-80f7-70d5e5b18d18', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-content-crc64', + 'u661BimQ84c=', + 'x-ms-blob-sequence-number', + '0', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container157592666159301045/blob157592666170408961', "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:22 GMT', + 'ETag', + '"0x8D77CEE2884817D"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a9ab6cd-301e-0035-62d7-ae9e23000000', + 'x-ms-client-request-id', + 'c6bb8865-b0dd-42cb-8be5-c82952320b9e', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-content-crc64', + 'zGf3rvhKPeA=', + 'x-ms-blob-sequence-number', + '0', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592666159301045/blob157592666170408961') + .reply(206, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", [ 'Content-Length', + '512', + 'Content-Type', + 'application/octet-stream', + 'Content-Range', + 'bytes 0-511/1024', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:22 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE2884817D"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a9ab6db-301e-0035-6ed7-ae9e23000000', + 'x-ms-client-request-id', + 'f4ace9f4-4bdd-4c02-b1c1-52cd0ff19664', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'PageBlob', + 'x-ms-blob-sequence-number', + '0', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-blob-sequence-number,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container157592666159301045/blob157592666170408961') + .reply(206, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", [ 'Content-Length', + '512', + 'Content-Type', + 'application/octet-stream', + 'Content-Range', + 'bytes 512-1023/1024', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:24:22 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEE2884817D"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a9ab6f0-301e-0035-80d7-ae9e23000000', + 'x-ms-client-request-id', + '262cb121-3b5d-4f5e-ad14-6abf71fff9b4', + 'x-ms-version', + '2019-02-02', + 'x-ms-creation-time', + 'Mon, 09 Dec 2019 21:24:21 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'PageBlob', + 'x-ms-blob-sequence-number', + '0', + 'x-ms-server-encrypted', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-blob-sequence-number,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container157592666159301045') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '54a17873-101e-00aa-4ad7-aee699000000', + 'x-ms-client-request-id', + 'f0fdca20-12f4-47f9-9bbf-35ff50c3a151', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:24:21 GMT' ]); diff --git a/sdk/storage/storage-blob/src/Clients.ts b/sdk/storage/storage-blob/src/Clients.ts index 4e9e26673b88..dcb47f387fc4 100644 --- a/sdk/storage/storage-blob/src/Clients.ts +++ b/sdk/storage/storage-blob/src/Clients.ts @@ -1125,7 +1125,7 @@ export class BlobClient extends StorageClient { abortSignal: options.abortSignal, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, - onDownloadProgress: isNode ? undefined : options.onProgress, + onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream range: offset === 0 && !count ? undefined : rangeToString({ offset, count }), rangeGetContentMD5: options.rangeGetContentMD5, rangeGetContentCRC64: options.rangeGetContentCrc64, diff --git a/sdk/storage/storage-blob/test/appendblobclient.spec.ts b/sdk/storage/storage-blob/test/appendblobclient.spec.ts index af4d8bd0b9c0..621f609723ef 100644 --- a/sdk/storage/storage-blob/test/appendblobclient.spec.ts +++ b/sdk/storage/storage-blob/test/appendblobclient.spec.ts @@ -76,6 +76,19 @@ describe("AppendBlobClient", () => { assert.equal(downloadResponse.contentLength!, content.length); }); + it("appendBlock with progress report", async () => { + await appendBlobClient.create(); + + const content = "Hello World!"; + await appendBlobClient.appendBlock(content, content.length, { + onProgress: () => {} + }); + + const downloadResponse = await appendBlobClient.download(0); + assert.equal(await bodyToString(downloadResponse, content.length), content); + assert.equal(downloadResponse.contentLength!, content.length); + }); + it("can be created with a sas connection string", async () => { const newClient = new AppendBlobClient( getSASConnectionStringFromEnvironment(), diff --git a/sdk/storage/storage-blob/test/blobclient.spec.ts b/sdk/storage/storage-blob/test/blobclient.spec.ts index e8fcb79abb6c..b9372307ae04 100644 --- a/sdk/storage/storage-blob/test/blobclient.spec.ts +++ b/sdk/storage/storage-blob/test/blobclient.spec.ts @@ -48,6 +48,21 @@ describe("BlobClient", () => { assert.deepStrictEqual(await bodyToString(result, content.length), content); }); + it("download with progress report", async () => { + recorder.skip( + "browser", + "record & playback issue: https://github.com/Azure/azure-sdk-for-js/issues/6477" + ); + let downloadedBytes = 0; + const result = await blobClient.download(0, undefined, { + onProgress: (data) => { + downloadedBytes = data.loadedBytes; + } + }); + assert.deepStrictEqual(await bodyToString(result, content.length), content); + assert.equal(downloadedBytes, content.length); + }); + it("download should not have aborted error after download finishes", async () => { const aborter = new AbortController(); const result = await blobClient.download(0, undefined, { abortSignal: aborter.signal }); diff --git a/sdk/storage/storage-blob/test/blockblobclient.spec.ts b/sdk/storage/storage-blob/test/blockblobclient.spec.ts index ada7923c0a88..60aefcf730ea 100644 --- a/sdk/storage/storage-blob/test/blockblobclient.spec.ts +++ b/sdk/storage/storage-blob/test/blockblobclient.spec.ts @@ -47,6 +47,15 @@ describe("BlockBlobClient", () => { assert.deepStrictEqual(await bodyToString(result, body.length), body); }); + it("upload with progress report", async () => { + const body: string = recorder.getUniqueName("randomstring"); + await blockBlobClient.upload(body, body.length, { + onProgress: () => {} + }); + const result = await blobClient.download(0); + assert.deepStrictEqual(await bodyToString(result, body.length), body); + }); + it("upload with string body and all parameters set", async () => { const body: string = recorder.getUniqueName("randomstring"); const options = { @@ -90,6 +99,23 @@ describe("BlockBlobClient", () => { assert.equal(listResponse.uncommittedBlocks![1].size, body.length); }); + it("stageBlock with progress report", async () => { + const body = "HelloWorld"; + await blockBlobClient.stageBlock(base64encode("1"), body, body.length, { + onProgress: () => {} + }); + await blockBlobClient.stageBlock(base64encode("2"), body, body.length, { + onProgress: () => {} + }); + await blockBlobClient.commitBlockList([base64encode("1"), base64encode("2")]); + const listResponse = await blockBlobClient.getBlockList("committed"); + assert.equal(listResponse.committedBlocks!.length, 2); + assert.equal(listResponse.committedBlocks![0].name, base64encode("1")); + assert.equal(listResponse.committedBlocks![0].size, body.length); + assert.equal(listResponse.committedBlocks![1].name, base64encode("2")); + assert.equal(listResponse.committedBlocks![1].size, body.length); + }); + it("stageBlockFromURL copy source blob as single block", async () => { const body = "HelloWorld"; await blockBlobClient.upload(body, body.length); diff --git a/sdk/storage/storage-blob/test/pageblobclient.spec.ts b/sdk/storage/storage-blob/test/pageblobclient.spec.ts index b227344269ba..bd54315a631d 100644 --- a/sdk/storage/storage-blob/test/pageblobclient.spec.ts +++ b/sdk/storage/storage-blob/test/pageblobclient.spec.ts @@ -107,6 +107,26 @@ describe("PageBlobClient", () => { assert.equal(await bodyToString(page2, 512), "b".repeat(512)); }); + it("uploadPages with progress report", async () => { + await pageBlobClient.create(1024); + + const result = await blobClient.download(0); + assert.equal(await bodyToString(result, 1024), "\u0000".repeat(1024)); + + await pageBlobClient.uploadPages("a".repeat(512), 0, 512, { + onProgress: () => {} + }); + await pageBlobClient.uploadPages("b".repeat(512), 512, 512, { + onProgress: () => {} + }); + + const page1 = await pageBlobClient.download(0, 512); + const page2 = await pageBlobClient.download(512, 512); + + assert.equal(await bodyToString(page1, 512), "a".repeat(512)); + assert.equal(await bodyToString(page2, 512), "b".repeat(512)); + }); + it("clearPages", async () => { await pageBlobClient.create(1024); let result = await blobClient.download(0); diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_download_with_progress_report.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_download_with_progress_report.json new file mode 100644 index 000000000000..a9950d8087ec --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_download_with_progress_report.json @@ -0,0 +1,157 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:13 GMT", + "etag": "\"0x8D77CEC0BC7E477\"", + "last-modified": "Mon, 09 Dec 2019 21:09:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "af29ecdd-da5a-4853-a0ca-07cbcc1533f7", + "x-ms-request-id": "a4393e87-b01a-00e3-35d4-aed5f9000000", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704/dir157592575482901414", + "query": { + "restype": "directory" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:13 GMT", + "etag": "\"0x8D77CEC0BD26538\"", + "last-modified": "Mon, 09 Dec 2019 21:09:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "6c98a37e-bf1a-4736-bc9d-179ba503063c", + "x-ms-file-attributes": "Directory", + "x-ms-file-change-time": "2019-12-09T21:09:14.8678456Z", + "x-ms-file-creation-time": "2019-12-09T21:09:14.8678456Z", + "x-ms-file-id": "13835128424026341376", + "x-ms-file-last-write-time": "2019-12-09T21:09:14.8678456Z", + "x-ms-file-parent-id": "0", + "x-ms-file-permission-key": "15246684120248489204*13496228697838683005", + "x-ms-request-id": "a4393e8a-b01a-00e3-37d4-aed5f9000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704/dir157592575482901414/file157592575491402589", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:14 GMT", + "etag": "\"0x8D77CEC0BE5F1F2\"", + "last-modified": "Mon, 09 Dec 2019 21:09:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8d39477b-e0dc-4b31-a2e8-83acff4d1149", + "x-ms-file-attributes": "Archive", + "x-ms-file-change-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-creation-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-id": "11529285414812647424", + "x-ms-file-last-write-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-parent-id": "13835128424026341376", + "x-ms-file-permission-key": "1435755748577930227*13496228697838683005", + "x-ms-request-id": "a4393e8c-b01a-00e3-39d4-aed5f9000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704/dir157592575482901414/file157592575491402589", + "query": { + "comp": "range" + }, + "requestBody": "Hello World", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "date": "Mon, 09 Dec 2019 21:09:14 GMT", + "etag": "\"0x8D77CEC0BF0CA04\"", + "last-modified": "Mon, 09 Dec 2019 21:09:15 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "555fb60f-ed0e-4935-b0d6-4f90412dfbfe", + "x-ms-request-id": "a4393e8f-b01a-00e3-3cd4-aed5f9000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704/dir157592575482901414/file157592575491402589", + "query": {}, + "requestBody": null, + "status": 200, + "response": "Hello World", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "application/octet-stream", + "date": "Mon, 09 Dec 2019 21:09:14 GMT", + "etag": "\"0x8D77CEC0BF0CA04\"", + "last-modified": "Mon, 09 Dec 2019 21:09:15 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "19e06d34-fc83-4796-a524-bba7bc8e3c94", + "x-ms-file-attributes": "Archive", + "x-ms-file-change-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-creation-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-id": "11529285414812647424", + "x-ms-file-last-write-time": "2019-12-09T21:09:14.9959666Z", + "x-ms-file-parent-id": "13835128424026341376", + "x-ms-file-permission-key": "1435755748577930227*13496228697838683005", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "a4393e92-b01a-00e3-3fd4-aed5f9000000", + "x-ms-server-encrypted": "true", + "x-ms-type": "File", + "x-ms-version": "2019-02-02" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575476801704", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "42131473-0aab-4a5c-9442-185960f5ca1d", + "x-ms-request-id": "a4393e94-b01a-00e3-41d4-aed5f9000000", + "x-ms-version": "2019-02-02" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share157592575476801704", + "dir": "dir157592575482901414", + "file": "file157592575491402589" + }, + "newDate": {} + } +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_uploadrange_with_progress_event.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_uploadrange_with_progress_event.json index d86cb60ff622..577095c17d07 100644 --- a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_uploadrange_with_progress_event.json +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_uploadrange_with_progress_event.json @@ -2,7 +2,7 @@ "recordings": [ { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share157376827752805542", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575139004049", "query": { "restype": "share" }, @@ -10,19 +10,19 @@ "status": 201, "response": "", "responseHeaders": { - "date": "Thu, 14 Nov 2019 21:51:16 GMT", - "last-modified": "Thu, 14 Nov 2019 21:51:17 GMT", + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:10 GMT", + "etag": "\"0x8D77CEC09C494F4\"", + "last-modified": "Mon, 09 Dec 2019 21:09:11 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "etag": "\"0x8D7694CC736545A\"", - "x-ms-request-id": "646c9c1b-a01a-001d-4635-9bbf16000000", - "x-ms-version": "2019-02-02", - "x-ms-client-request-id": "a775a266-3b8b-45de-a6b1-7a1f1ffc7f30", - "content-length": "0" + "x-ms-client-request-id": "debe9649-f250-4e03-923e-691cd374c543", + "x-ms-request-id": "a4393e12-b01a-00e3-4dd4-aed5f9000000", + "x-ms-version": "2019-02-02" } }, { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share157376827752805542/dir157376827770207083", + "url": "https://fakestorageaccount.file.core.windows.net/share157592575139004049/dir157592575145201086", "query": { "restype": "directory" }, @@ -30,30 +30,30 @@ "status": 201, "response": "", "responseHeaders": { - "date": "Thu, 14 Nov 2019 21:51:17 GMT", - "x-ms-file-change-time": "2019-11-14T21:51:17.8698545Z", + "content-length": "0", + "date": "Mon, 09 Dec 2019 21:09:10 GMT", + "etag": "\"0x8D77CEC09CEC499\"", + "last-modified": "Mon, 09 Dec 2019 21:09:11 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b4c8360a-91e4-4432-b272-810739b2b4cc", "x-ms-file-attributes": "Directory", + "x-ms-file-change-time": "2019-12-09T21:09:11.4886297Z", + "x-ms-file-creation-time": "2019-12-09T21:09:11.4886297Z", "x-ms-file-id": "13835128424026341376", - "x-ms-request-server-encrypted": "true", - "x-ms-file-creation-time": "2019-11-14T21:51:17.8698545Z", + "x-ms-file-last-write-time": "2019-12-09T21:09:11.4886297Z", "x-ms-file-parent-id": "0", - "x-ms-file-permission-key": "15292852142319295125*13609941760923454748", - "x-ms-client-request-id": "eb35424a-9c0b-4711-8a6c-80d7b2240a20", - "content-length": "0", - "last-modified": "Thu, 14 Nov 2019 21:51:17 GMT", - "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "etag": "\"0x8D7694CC7523331\"", - "x-ms-request-id": "646c9c1e-a01a-001d-4835-9bbf16000000", - "x-ms-file-last-write-time": "2019-11-14T21:51:17.8698545Z", + "x-ms-file-permission-key": "15246684120248489204*13496228697838683005", + "x-ms-request-id": "a4393e15-b01a-00e3-4fd4-aed5f9000000", + "x-ms-request-server-encrypted": "true", "x-ms-version": "2019-02-02" } } ], "uniqueTestInfo": { "uniqueName": { - "share": "share157376827752805542", - "dir": "dir157376827770207083", - "file": "file157376827788409589" + "share": "share157592575139004049", + "dir": "dir157592575145201086", + "file": "file157592575152004199" }, "newDate": {} } diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_download_with_progress_report.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_download_with_progress_report.js new file mode 100644 index 000000000000..5a975550cdbb --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_download_with_progress_report.js @@ -0,0 +1,183 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"share":"share157592571705709749","dir":"dir157592571719003221","file":"file157592571736706215"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157592571705709749') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:37 GMT', + 'ETag', + '"0x8D77CEBF558BE5B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e8610b85-501a-0061-16d4-ae74a9000000', + 'x-ms-client-request-id', + '3a6104de-50bb-43af-b19f-ff6b6bdbef6e', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:08:36 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157592571705709749/dir157592571719003221') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:37 GMT', + 'ETag', + '"0x8D77CEBF56EC1C2"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'fd4fbd5e-b01a-002f-3cd4-aeb14c000000', + 'x-ms-client-request-id', + 'bbd09f8d-260c-425b-9790-96b7279abe7a', + 'x-ms-version', + '2019-02-02', + 'x-ms-file-change-time', + '2019-12-09T21:08:37.3049794Z', + 'x-ms-file-last-write-time', + '2019-12-09T21:08:37.3049794Z', + 'x-ms-file-creation-time', + '2019-12-09T21:08:37.3049794Z', + 'x-ms-file-permission-key', + '15246684120248489204*13496228697838683005', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:08:36 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157592571705709749/dir157592571719003221/file157592571736706215') + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:37 GMT', + 'ETag', + '"0x8D77CEBF5881C58"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '8bb848f1-b01a-0049-35d4-ae0316000000', + 'x-ms-client-request-id', + 'fb9724de-0e73-41ce-9755-797e43d50e5a', + 'x-ms-version', + '2019-02-02', + 'x-ms-file-change-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-last-write-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-creation-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-permission-key', + '1435755748577930227*13496228697838683005', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '13835093239654252544', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:08:37 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157592571705709749/dir157592571719003221/file157592571736706215', "Hello World") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:37 GMT', + 'ETag', + '"0x8D77CEBF58FE670"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '8bb848f4-b01a-0049-36d4-ae0316000000', + 'x-ms-client-request-id', + '61a819ed-f865-4103-a834-0eb397efc127', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Mon, 09 Dec 2019 21:08:37 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share157592571705709749/dir157592571719003221/file157592571736706215') + .reply(200, "Hello World", [ 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:37 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEBF58FE670"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '8bb848f5-b01a-0049-37d4-ae0316000000', + 'x-ms-client-request-id', + '74a44887-7c12-46f2-923d-e8c132b0a4c9', + 'x-ms-version', + '2019-02-02', + 'x-ms-type', + 'File', + 'x-ms-server-encrypted', + 'true', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-file-change-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-last-write-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-creation-time', + '2019-12-09T21:08:37.4711384Z', + 'x-ms-file-permission-key', + '1435755748577930227*13496228697838683005', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '13835093239654252544', + 'x-ms-file-parent-id', + '13835128424026341376', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-type,x-ms-server-encrypted,x-ms-lease-status,x-ms-lease-state,x-ms-file-change-time,x-ms-file-last-write-time,x-ms-file-creation-time,x-ms-file-permission-key,x-ms-file-attributes,x-ms-file-id,x-ms-file-parent-id,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:08:37 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share157592571705709749') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e8610b88-501a-0061-17d4-ae74a9000000', + 'x-ms-client-request-id', + '848674e2-462c-40a3-9400-3b7088413ccd', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Mon, 09 Dec 2019 21:08:36 GMT' ]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_event.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_event.js index 1436a2fcea81..da47bd015a75 100644 --- a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_event.js +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_event.js @@ -1,53 +1,52 @@ let nock = require('nock'); -module.exports.testInfo = {"share":"share156816839231605427","dir":"dir156816839273906476","file":"file156816839316909187"} +module.exports.testInfo = {"uniqueName":{"share":"share157592571325309446","dir":"dir157592571337909173","file":"file157592571353405656"},"newDate":{}} nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816839231605427') + .put('/share157592571325309446') .query(true) .reply(201, "", [ 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:19:52 GMT', + 'Mon, 09 Dec 2019 21:08:33 GMT', 'ETag', - '"0x8D7365E87A3ACEE"', + '"0x8D77CEBF31342E9"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '5fbd1d4f-c01a-0049-0647-68559c000000', + '263d4aac-f01a-0082-67d4-ae9126000000', 'x-ms-client-request-id', - 'c2a27057-4cf9-4f71-bf4e-92c6259107fe', + '1480dff1-ae29-46b0-8df2-1aa239cdae79', 'x-ms-version', '2019-02-02', 'Date', - 'Wed, 11 Sep 2019 02:19:51 GMT' ]); - + 'Mon, 09 Dec 2019 21:08:32 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816839231605427/dir156816839273906476') + .put('/share157592571325309446/dir157592571337909173') .query(true) .reply(201, "", [ 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:19:53 GMT', + 'Mon, 09 Dec 2019 21:08:33 GMT', 'ETag', - '"0x8D7365E87E51C92"', + '"0x8D77CEBF3299B5F"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'a85a43a0-301a-0018-7647-684b69000000', + '88fd3a8d-b01a-0024-7cd4-aea938000000', 'x-ms-client-request-id', - 'd847a834-2bcb-4965-81ff-d4b7fcf09671', + 'd6a5a21c-a8ce-4d78-a91c-22edf3109ccc', 'x-ms-version', '2019-02-02', 'x-ms-file-change-time', - '2019-09-11T02:19:53.0979474Z', + '2019-12-09T21:08:33.4963551Z', 'x-ms-file-last-write-time', - '2019-09-11T02:19:53.0979474Z', + '2019-12-09T21:08:33.4963551Z', 'x-ms-file-creation-time', - '2019-09-11T02:19:53.0979474Z', + '2019-12-09T21:08:33.4963551Z', 'x-ms-file-permission-key', - '15292852142319295125*13609941760923454748', + '15246684120248489204*13496228697838683005', 'x-ms-file-attributes', 'Directory', 'x-ms-file-id', @@ -57,33 +56,32 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Wed, 11 Sep 2019 02:19:52 GMT' ]); - + 'Mon, 09 Dec 2019 21:08:32 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816839231605427/dir156816839273906476/file156816839316909187') + .put('/share157592571325309446/dir157592571337909173/file157592571353405656') .reply(201, "", [ 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:19:53 GMT', + 'Mon, 09 Dec 2019 21:08:33 GMT', 'ETag', - '"0x8D7365E8825B3C5"', + '"0x8D77CEBF340F9A3"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'ab525481-501a-0008-5b47-687d8f000000', + '49733da7-f01a-0001-6ad4-ae318b000000', 'x-ms-client-request-id', - '774a9f43-a73a-4547-8c50-a937a78b063e', + '1587dc81-e5f2-4de3-a263-8810e9c2566e', 'x-ms-version', '2019-02-02', 'x-ms-file-change-time', - '2019-09-11T02:19:53.5212485Z', + '2019-12-09T21:08:33.6495011Z', 'x-ms-file-last-write-time', - '2019-09-11T02:19:53.5212485Z', + '2019-12-09T21:08:33.6495011Z', 'x-ms-file-creation-time', - '2019-09-11T02:19:53.5212485Z', + '2019-12-09T21:08:33.6495011Z', 'x-ms-file-permission-key', - '1459396823544571282*13609941760923454748', + '1435755748577930227*13496228697838683005', 'x-ms-file-attributes', 'Archive', 'x-ms-file-id', @@ -93,47 +91,93 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Wed, 11 Sep 2019 02:19:52 GMT' ]); - + 'Mon, 09 Dec 2019 21:08:32 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816839231605427/dir156816839273906476/file156816839316909187', "HelloWorld") + .put('/share157592571325309446/dir157592571337909173/file157592571353405656', "HelloWorld") .query(true) .reply(201, "", [ 'Content-Length', '0', 'Content-MD5', 'aOEJ8PQMpyoV4FzCJ4b45g==', 'Last-Modified', - 'Wed, 11 Sep 2019 02:19:53 GMT', + 'Mon, 09 Dec 2019 21:08:33 GMT', 'ETag', - '"0x8D7365E88669922"', + '"0x8D77CEBF347D922"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '1db64136-001a-005f-5547-689402000000', + '49733daa-f01a-0001-6cd4-ae318b000000', 'x-ms-client-request-id', - '18fa83ae-ca93-437d-b5cd-307f3b6e4cf8', + '6e36104c-d8b9-4afb-9110-6cac05ba2552', 'x-ms-version', '2019-02-02', 'x-ms-request-server-encrypted', 'true', 'Date', - 'Wed, 11 Sep 2019 02:19:53 GMT' ]); + 'Mon, 09 Dec 2019 21:08:32 GMT' ]); +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share157592571325309446/dir157592571337909173/file157592571353405656') + .reply(200, "HelloWorld", [ 'Content-Length', + '10', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Mon, 09 Dec 2019 21:08:33 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D77CEBF347D922"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '49733dab-f01a-0001-6dd4-ae318b000000', + 'x-ms-client-request-id', + 'a739c806-374f-4254-aa90-451fe2ae20e8', + 'x-ms-version', + '2019-02-02', + 'x-ms-type', + 'File', + 'x-ms-server-encrypted', + 'true', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-file-change-time', + '2019-12-09T21:08:33.6495011Z', + 'x-ms-file-last-write-time', + '2019-12-09T21:08:33.6495011Z', + 'x-ms-file-creation-time', + '2019-12-09T21:08:33.6495011Z', + 'x-ms-file-permission-key', + '1435755748577930227*13496228697838683005', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '13835093239654252544', + 'x-ms-file-parent-id', + '13835128424026341376', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-type,x-ms-server-encrypted,x-ms-lease-status,x-ms-lease-state,x-ms-file-change-time,x-ms-file-last-write-time,x-ms-file-creation-time,x-ms-file-permission-key,x-ms-file-attributes,x-ms-file-id,x-ms-file-parent-id,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 09 Dec 2019 21:08:32 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/share156816839231605427') + .delete('/share157592571325309446') .query(true) .reply(202, "", [ 'Content-Length', '0', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4b3374bd-001a-0054-6d47-688c76000000', + '263d4ab0-f01a-0082-68d4-ae9126000000', 'x-ms-client-request-id', - 'f2a52acc-b7fe-42a7-9cbc-c95e37514c97', + 'a1314d06-f270-4758-8ec8-0c452d133d2d', 'x-ms-version', '2019-02-02', 'Date', - 'Wed, 11 Sep 2019 02:19:53 GMT' ]); - + 'Mon, 09 Dec 2019 21:08:33 GMT' ]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_report.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_report.js new file mode 100644 index 000000000000..2634ec00cee1 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_uploadrange_with_progress_report.js @@ -0,0 +1,209 @@ +let nock = require('nock'); + +module.exports.testInfo = {"uniqueName":{"share":"share157559087221606101","dir":"dir157559087263706401","file":"file157559087313104693"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157559087221606101') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:52 GMT', + 'ETag', + '"0x8D779E05654E912"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c5216c8b-201a-00a9-3cc9-abe59e000000', + 'x-ms-client-request-id', + '7586c310-b216-45f6-8e95-4bd90ebbdc5c', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Fri, 06 Dec 2019 00:07:51 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157559087221606101/dir157559087263706401') + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:52 GMT', + 'ETag', + '"0x8D779E056A32952"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '90f75fef-c01a-00ec-56c9-ab380f000000', + 'x-ms-client-request-id', + '9bef9bc8-cba3-4835-aa0c-11c6fcf5f000', + 'x-ms-version', + '2019-02-02', + 'x-ms-file-change-time', + '2019-12-06T00:07:52.9383250Z', + 'x-ms-file-last-write-time', + '2019-12-06T00:07:52.9383250Z', + 'x-ms-file-creation-time', + '2019-12-06T00:07:52.9383250Z', + 'x-ms-file-permission-key', + '15246684120248489204*13496228697838683005', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157559087221606101/dir157559087263706401/file157559087313104693') + .reply(201, "", [ 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:53 GMT', + 'ETag', + '"0x8D779E056D1707B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1e0be2c4-201a-0003-71c9-ab3371000000', + 'x-ms-client-request-id', + '4ba1b0ed-b9b4-46d7-a631-5e1492d0f52f', + 'x-ms-version', + '2019-02-02', + 'x-ms-file-change-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-last-write-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-creation-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-permission-key', + '1435755748577930227*13496228697838683005', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '13835093239654252544', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157559087221606101/dir157559087263706401/file157559087313104693', "Hello") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:53 GMT', + 'ETag', + '"0x8D779E056D9AFDB"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1e0be2ca-201a-0003-76c9-ab3371000000', + 'x-ms-client-request-id', + '624b8a35-85dc-4705-8818-330e71604b54', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share157559087221606101/dir157559087263706401/file157559087313104693', "World") + .query(true) + .reply(201, "", [ 'Content-Length', + '0', + 'Content-MD5', + '9aeSTmIehMkoCpon4by39g==', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:53 GMT', + 'ETag', + '"0x8D779E056E300E7"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1e0be2cc-201a-0003-78c9-ab3371000000', + 'x-ms-client-request-id', + '3c5eb264-a21f-4e18-9059-03684fb34bf9', + 'x-ms-version', + '2019-02-02', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share157559087221606101/dir157559087263706401/file157559087313104693') + .reply(206, "HelloWor", [ 'Content-Length', + '8', + 'Content-Type', + 'application/octet-stream', + 'Content-Range', + 'bytes 0-7/10', + 'Last-Modified', + 'Fri, 06 Dec 2019 00:07:53 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D779E056E300E7"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1e0be2ce-201a-0003-7ac9-ab3371000000', + 'x-ms-client-request-id', + '34dddf89-3378-4198-a938-7746c86f6d4a', + 'x-ms-version', + '2019-02-02', + 'x-ms-type', + 'File', + 'x-ms-server-encrypted', + 'true', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-file-change-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-last-write-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-creation-time', + '2019-12-06T00:07:53.2416123Z', + 'x-ms-file-permission-key', + '1435755748577930227*13496228697838683005', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '13835093239654252544', + 'x-ms-file-parent-id', + '13835128424026341376', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-type,x-ms-server-encrypted,x-ms-lease-status,x-ms-lease-state,x-ms-file-change-time,x-ms-file-last-write-time,x-ms-file-creation-time,x-ms-file-permission-key,x-ms-file-attributes,x-ms-file-id,x-ms-file-parent-id,Content-Range,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share157559087221606101') + .query(true) + .reply(202, "", [ 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c5216c8f-201a-00a9-3dc9-abe59e000000', + 'x-ms-client-request-id', + 'ef3b5b57-0024-4ef4-8c2a-dcb546bc3a3f', + 'x-ms-version', + '2019-02-02', + 'Date', + 'Fri, 06 Dec 2019 00:07:52 GMT' ]); diff --git a/sdk/storage/storage-file-share/src/ShareFileClient.ts b/sdk/storage/storage-file-share/src/ShareFileClient.ts index 8863372f1efd..e69cf01821c8 100644 --- a/sdk/storage/storage-file-share/src/ShareFileClient.ts +++ b/sdk/storage/storage-file-share/src/ShareFileClient.ts @@ -970,7 +970,7 @@ export class ShareFileClient extends StorageClient { const downloadFullFile = offset === 0 && !count; const res = await this.context.download({ abortSignal: options.abortSignal, - onDownloadProgress: !isNode ? options.onProgress : undefined, + onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream range: downloadFullFile ? undefined : rangeToString({ offset, count }), rangeGetContentMD5: options.rangeGetContentMD5, spanOptions diff --git a/sdk/storage/storage-file-share/test/fileclient.spec.ts b/sdk/storage/storage-file-share/test/fileclient.spec.ts index 094e0caa712d..71e56e45599f 100644 --- a/sdk/storage/storage-file-share/test/fileclient.spec.ts +++ b/sdk/storage/storage-file-share/test/fileclient.spec.ts @@ -365,7 +365,10 @@ describe("FileClient", () => { }); it("uploadRange with progress event", async () => { - recorder.skip(undefined, "Nock issue: https://github.com/Azure/azure-sdk-for-js/issues/5229"); + recorder.skip( + "browser", + "record & playback issue: https://github.com/Azure/azure-sdk-for-js/issues/6476" + ); await fileClient.create(10); let progressUpdated = false; await fileClient.uploadRange("HelloWorld", 0, 10, { @@ -373,7 +376,10 @@ describe("FileClient", () => { progressUpdated = true; } }); - assert.deepStrictEqual(progressUpdated, true); + assert.equal(progressUpdated, true); + + const response = await fileClient.download(0); + assert.deepStrictEqual(await bodyToString(response), "HelloWorld"); }); it("clearRange", async () => { @@ -423,6 +429,15 @@ describe("FileClient", () => { assert.deepStrictEqual(await bodyToString(result, 1), content[0]); }); + it("download with progress report", async () => { + await fileClient.create(content.length); + await fileClient.uploadRange(content, 0, content.length); + const result = await fileClient.download(0, undefined, { + onProgress: () => {} + }); + assert.deepStrictEqual(await bodyToString(result), content); + }); + it("download partial content", async () => { await fileClient.create(10); await fileClient.uploadRange("HelloWorld", 0, 10); From 3a810992fe520ce9ef96ec57e2e6d9da9126edcd Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 08:23:48 -0800 Subject: [PATCH 13/32] [event-hubs] Better error handling and reporting (#6465) Prior to this change we couldn't tell the difference between "storage is failing for some reason" and "we're just losing to other processors that are attempting to claim partitions". Now an empty list of ownerships is okay and just indicates that we should do nothing this time around. Fixes #6444 minus the the change to exit the processing loop. --- sdk/eventhub/event-hubs/changelog.md | 5 + sdk/eventhub/event-hubs/package.json | 2 +- sdk/eventhub/event-hubs/src/eventProcessor.ts | 16 +- .../event-hubs/src/partitionProcessor.ts | 9 +- sdk/eventhub/event-hubs/src/partitionPump.ts | 4 +- sdk/eventhub/event-hubs/src/pumpManager.ts | 33 +++- sdk/eventhub/event-hubs/src/util/constants.ts | 2 +- .../event-hubs/test/eventProcessor.spec.ts | 167 +++++++++++++++++- .../changelog.md | 5 + .../package.json | 4 +- .../src/blobCheckpointStore.ts | 16 +- ...r.spec.ts => blob-checkpointstore.spec.ts} | 64 ++++++- 12 files changed, 301 insertions(+), 26 deletions(-) rename sdk/eventhub/eventhubs-checkpointstore-blob/test/{blob-partition-manager.spec.ts => blob-checkpointstore.spec.ts} (85%) diff --git a/sdk/eventhub/event-hubs/changelog.md b/sdk/eventhub/event-hubs/changelog.md index 0bca2e62590a..ab61d421508a 100644 --- a/sdk/eventhub/event-hubs/changelog.md +++ b/sdk/eventhub/event-hubs/changelog.md @@ -1,3 +1,8 @@ +### 5.0.0-preview.8 + +- Fixed potential issues with claims being mismanaged when subscriptions terminate. +- Improved reporting of errors that occur when attempting to claim partitions from CheckpointStores. + ### 2019-12-03 5.0.0-preview.7 - Improves load-balancing capabilities to reduce the frequency that partitions are claimed by other running diff --git a/sdk/eventhub/event-hubs/package.json b/sdk/eventhub/event-hubs/package.json index b211d18fe6cb..8c12e0b2e335 100644 --- a/sdk/eventhub/event-hubs/package.json +++ b/sdk/eventhub/event-hubs/package.json @@ -1,7 +1,7 @@ { "name": "@azure/event-hubs", "sdk-type": "client", - "version": "5.0.0-preview.7", + "version": "5.0.0-preview.8", "description": "Azure Event Hubs SDK for JS.", "author": "Microsoft Corporation", "license": "MIT", diff --git a/sdk/eventhub/event-hubs/src/eventProcessor.ts b/sdk/eventhub/event-hubs/src/eventProcessor.ts index 41bd69f689be..a63d4cb3f1b7 100644 --- a/sdk/eventhub/event-hubs/src/eventProcessor.ts +++ b/sdk/eventhub/event-hubs/src/eventProcessor.ts @@ -4,7 +4,7 @@ import uuid from "uuid/v4"; import { EventHubClient } from "./impl/eventHubClient"; import { EventPosition } from "./eventPosition"; -import { PumpManager } from "./pumpManager"; +import { PumpManager, PumpManagerImpl } from "./pumpManager"; import { AbortController, AbortSignalLike } from "@azure/abort-controller"; import * as log from "./log"; import { FairPartitionLoadBalancer, PartitionLoadBalancer } from "./partitionLoadBalancer"; @@ -258,7 +258,7 @@ export class EventProcessor { this._consumerGroup = consumerGroup; this._eventHubClient = eventHubClient; this._processorOptions = options; - this._pumpManager = options.pumpManager || new PumpManager(this._id, this._processorOptions); + this._pumpManager = options.pumpManager || new PumpManagerImpl(this._id, this._processorOptions); const inactiveTimeLimitInMS = options.inactiveTimeLimitInMs || this._inactiveTimeLimitInMs; this._partitionLoadBalancer = options.partitionLoadBalancer || @@ -305,9 +305,11 @@ export class EventProcessor { ); try { const claimedOwnerships = await this._checkpointStore.claimOwnership([ownershipRequest]); - // since we only claim one ownership at a time, check the array length and throw + + // can happen if the partition was claimed out from underneath us - we shouldn't + // attempt to spin up a processor. if (!claimedOwnerships.length) { - throw new Error(`Failed to claim ownership of partition ${ownershipRequest.partitionId}`); + return; } log.partitionLoadBalancer( @@ -498,8 +500,6 @@ export class EventProcessor { * */ async stop(): Promise { - await this.abandonPartitionOwnerships(); - log.eventProcessor(`[${this._id}] Stopping an EventProcessor.`); if (this._abortController) { // cancel the event processor loop @@ -519,6 +519,8 @@ export class EventProcessor { } finally { log.eventProcessor(`[${this._id}] EventProcessor stopped.`); } + + await this.abandonPartitionOwnerships(); } private async abandonPartitionOwnerships() { @@ -528,7 +530,7 @@ export class EventProcessor { for (const ownership of ourOwnerships) { ownership.ownerId = ""; } - this._checkpointStore.claimOwnership(ourOwnerships); + return this._checkpointStore.claimOwnership(ourOwnerships); } } diff --git a/sdk/eventhub/event-hubs/src/partitionProcessor.ts b/sdk/eventhub/event-hubs/src/partitionProcessor.ts index db3587e53d7d..cd0dea310fa8 100644 --- a/sdk/eventhub/event-hubs/src/partitionProcessor.ts +++ b/sdk/eventhub/event-hubs/src/partitionProcessor.ts @@ -6,7 +6,8 @@ import { InitializationContext, BasicPartitionProperties } from "./eventHubConsumerClientModels"; -import { EventPosition } from "."; +import { EventPosition } from "./eventPosition"; +import * as log from "./log"; /** * A checkpoint is meant to represent the last successfully processed event by the user from a particular @@ -176,7 +177,11 @@ export class PartitionProcessor implements InitializationContext { */ async processError(error: Error): Promise { if (this._eventHandlers.processError) { - await this._eventHandlers.processError(error, this); + try { + await this._eventHandlers.processError(error, this); + } catch (err) { + log.partitionPump(`Error thrown from user's processError handler : ${err}`); + } } } diff --git a/sdk/eventhub/event-hubs/src/partitionPump.ts b/sdk/eventhub/event-hubs/src/partitionPump.ts index ac79c7414021..6cd522e46fb8 100644 --- a/sdk/eventhub/event-hubs/src/partitionPump.ts +++ b/sdk/eventhub/event-hubs/src/partitionPump.ts @@ -42,8 +42,9 @@ export class PartitionPump { let userRequestedDefaultPosition: EventPosition | undefined; try { userRequestedDefaultPosition = await this._partitionProcessor.initialize(); - } catch { + } catch (err) { // swallow the error from the user-defined code + this._partitionProcessor.processError(err); } const startingPosition = getStartingPosition( @@ -137,6 +138,7 @@ export class PartitionPump { await this._partitionProcessor.close(reason); } catch (err) { log.error("An error occurred while closing the receiver.", err); + this._partitionProcessor.processError(err); throw err; } } diff --git a/sdk/eventhub/event-hubs/src/pumpManager.ts b/sdk/eventhub/event-hubs/src/pumpManager.ts index 2f1ccede1c39..415a2e1e8878 100644 --- a/sdk/eventhub/event-hubs/src/pumpManager.ts +++ b/sdk/eventhub/event-hubs/src/pumpManager.ts @@ -13,8 +13,39 @@ import * as log from "./log"; * It also starts a PartitionPump when it is created, and stops a * PartitionPump when it is removed. * @ignore + * @internal */ -export class PumpManager { +export interface PumpManager { + /** + * Creates and starts a PartitionPump. + * @param eventHubClient The EventHubClient to forward to the PartitionPump. + * @param initialEventPosition The EventPosition to forward to the PartitionPump. + * @param partitionProcessor The PartitionProcessor to forward to the PartitionPump. + * @param abortSignal Used to cancel pump creation. + * @ignore + */ + createPump( + eventHubClient: EventHubClient, + initialEventPosition: EventPosition | undefined, + partitionProcessor: PartitionProcessor + ): Promise; + + /** + * Stops all PartitionPumps and removes them from the internal map. + * @param reason The reason for removing the pump. + * @ignore + */ + removeAllPumps(reason: CloseReason): Promise; +} + +/** + * The PumpManager handles the creation and removal of PartitionPumps. + * It also starts a PartitionPump when it is created, and stops a + * PartitionPump when it is removed. + * @ignore + * @internal + */ +export class PumpManagerImpl implements PumpManager { private readonly _eventProcessorName: string; private readonly _options: FullEventProcessorOptions; private _partitionIdToPumps: { diff --git a/sdk/eventhub/event-hubs/src/util/constants.ts b/sdk/eventhub/event-hubs/src/util/constants.ts index 7be16bda7e84..58c3648d514e 100644 --- a/sdk/eventhub/event-hubs/src/util/constants.ts +++ b/sdk/eventhub/event-hubs/src/util/constants.ts @@ -6,5 +6,5 @@ */ export const packageJsonInfo = { name: "@azure/event-hubs", - version: "5.0.0-preview.7" + version: "5.0.0-preview.8" }; diff --git a/sdk/eventhub/event-hubs/test/eventProcessor.spec.ts b/sdk/eventhub/event-hubs/test/eventProcessor.spec.ts index 5ded87805b92..d3f4184b72e4 100644 --- a/sdk/eventhub/event-hubs/test/eventProcessor.spec.ts +++ b/sdk/eventhub/event-hubs/test/eventProcessor.spec.ts @@ -15,7 +15,7 @@ import { LastEnqueuedEventProperties, SubscriptionEventHandlers, EventPosition, - CheckpointStore, + CheckpointStore } from "../src"; import { EventHubClient } from "../src/impl/eventHubClient"; import { EnvVarKeys, getEnvVars, loopUntil } from "./utils/testUtils"; @@ -34,7 +34,6 @@ import { GreedyPartitionLoadBalancer } from "../src/partitionLoadBalancer"; import { AbortError } from "@azure/abort-controller"; import { FakeSubscriptionEventHandlers } from './utils/fakeSubscriptionEventHandlers'; import sinon from 'sinon'; -import { PumpManager } from '../src/pumpManager'; const env = getEnvVars(); describe("Event Processor", function(): void { @@ -188,6 +187,63 @@ describe("Event Processor", function(): void { }); }); + it("if we fail to claim partitions we don't start up new processors", async () => { + const checkpointStore = { + claimOwnershipCalled: false, + + // the important thing is that the EventProcessor won't be able to claim + // any partitions, causing it to go down the "I tried but failed" path. + async claimOwnership(_: PartitionOwnership[]): Promise { + checkpointStore.claimOwnershipCalled = true; + return []; + }, + + // (these aren't used for this test) + async listOwnership(): Promise { return []; }, + async updateCheckpoint(): Promise { }, + async listCheckpoints(): Promise { return []; } + }; + + const pumpManager = { + createPumpCalled: false, + + async createPump() { + pumpManager.createPumpCalled = true; + }, + + async removeAllPumps() { } + } + + const eventProcessor = new EventProcessor( + EventHubClient.defaultConsumerGroupName, + client, + { + processEvents: async () => { }, + processError: async () => { }, + }, + checkpointStore, + { + ...defaultOptions, + pumpManager: pumpManager + } + ); + + await eventProcessor['_claimOwnership']({ + consumerGroup: "cgname", + eventHubName: "ehname", + fullyQualifiedNamespace: "fqdn", + ownerId: "owner", + partitionId: "0" + }); + + // when we fail to claim a partition we should _definitely_ + // not attempt to start a pump. + pumpManager.createPumpCalled.should.be.false; + + // we'll attempt to claim a partition (but won't succeed) + checkpointStore.claimOwnershipCalled.should.be.true; + }); + it("abandoned claims are treated as unowned claims", async () => { const commonFields = { fullyQualifiedNamespace: "irrelevant namespace", @@ -215,13 +271,14 @@ describe("Event Processor", function(): void { sinon.replaceGetter(fakeEventHubClient, 'eventHubName', () => commonFields.eventHubName); sinon.replaceGetter(fakeEventHubClient, 'fullyQualifiedNamespace', () => commonFields.fullyQualifiedNamespace); - const fakePumpManager = sinon.createStubInstance(PumpManager); - const ep = new EventProcessor(commonFields.consumerGroup, fakeEventHubClient as any, handlers, checkpointStore, { maxBatchSize: 1, loopIntervalInMs: 1, maxWaitTimeInSeconds: 1, - pumpManager: fakePumpManager as any + pumpManager: { + async createPump() { }, + async removeAllPumps(): Promise { } + } }); // allow three iterations through the loop - one for each partition that @@ -270,6 +327,106 @@ describe("Event Processor", function(): void { }); }); + it("claimOwnership throws and is reported to the user", async () => { + const errors = []; + + const faultyCheckpointStore: CheckpointStore = { + listOwnership: async () => [], + claimOwnership: async () => { + throw new Error("Some random failure!"); + }, + updateCheckpoint: async () => {}, + listCheckpoints: async () => [] + }; + + const eventProcessor = new EventProcessor( + EventHubClient.defaultConsumerGroupName, + client, + { + processEvents: async () => {}, + processError: async (err, _) => { + errors.push(err); + } + }, + faultyCheckpointStore, + { + ...defaultOptions, + partitionLoadBalancer: new GreedyPartitionLoadBalancer(["0"]) + } + ); + + // claimOwnership() calls that fail in the runloop of eventProcessor + // will get directed to the user's processError handler. + eventProcessor.start(); + + try { + await loopUntil({ + name: "waiting for checkpoint store errors to show up", + timeBetweenRunsMs: 1000, + maxTimes: 30, + until: async () => errors.length !== 0 + }); + + errors.length.should.equal(1); + } finally { + // this will also fail - we "abandon" all claimed partitions at + // when a processor is stopped (which requires us to claim them + // with an empty owner ID). + // + // Note that this one gets thrown directly from stop(), rather + // than reporting to processError() since we have a direct + // point of contact with the user. + await eventProcessor.stop().should.be.rejectedWith(/Some random failure!/); + } + }); + + it("errors thrown from the user's handlers are reported to processError()", async () => { + const errors = new Set(); + + const eventProcessor = new EventProcessor( + EventHubClient.defaultConsumerGroupName, + client, + { + processClose: async () => { throw new Error("processClose() error") }, + processEvents: async () => { throw new Error("processEvents() error"); }, + processInitialize: async () => { throw new Error("processInitialize() error") }, + processError: async (err, _) => { + errors.add(err); + throw new Error("These are logged but ignored"); + } + }, + new InMemoryCheckpointStore(), + { + ...defaultOptions, + partitionLoadBalancer: new GreedyPartitionLoadBalancer(["0"]) + } + ); + + // errors that occur within the user's own event handlers will get + // routed to their processError() handler + eventProcessor.start(); + + try { + await loopUntil({ + name: "waiting for errors thrown from user's handlers", + timeBetweenRunsMs: 1000, + maxTimes: 30, + until: async () => errors.size >= 3 + }); + + const messages = [...errors].map(e => e.message); + messages.sort(); + + messages.should.deep.equal([ + "processClose() error", + "processEvents() error", + "processInitialize() error" + ]); + } finally { + await eventProcessor.stop(); + } + }); + it("should expose an id #RunnableInBrowser", async function(): Promise { const processor = new EventProcessor( EventHubClient.defaultConsumerGroupName, diff --git a/sdk/eventhub/eventhubs-checkpointstore-blob/changelog.md b/sdk/eventhub/eventhubs-checkpointstore-blob/changelog.md index f19f6d6dc54d..9a914394d4b6 100644 --- a/sdk/eventhub/eventhubs-checkpointstore-blob/changelog.md +++ b/sdk/eventhub/eventhubs-checkpointstore-blob/changelog.md @@ -1,3 +1,8 @@ +### 1.0.0-preview.6 + +- `claimOwnership()` will throw on underlying issues with storage, rather than + failing silently. + ### 2019-12-03 - 1.0.0-preview.5 - Updated to use the latest version of the `@azure/event-hubs` package. diff --git a/sdk/eventhub/eventhubs-checkpointstore-blob/package.json b/sdk/eventhub/eventhubs-checkpointstore-blob/package.json index 486dc7ac5f8d..35a090546617 100644 --- a/sdk/eventhub/eventhubs-checkpointstore-blob/package.json +++ b/sdk/eventhub/eventhubs-checkpointstore-blob/package.json @@ -1,7 +1,7 @@ { "name": "@azure/eventhubs-checkpointstore-blob", "sdk-type": "client", - "version": "1.0.0-preview.5", + "version": "1.0.0-preview.6", "description": "An Azure Storage Blob solution to store checkpoints when using Event Hubs.", "author": "Microsoft Corporation", "license": "MIT", @@ -63,7 +63,7 @@ "unit-test": "npm run unit-test:node && npm run unit-test:browser" }, "dependencies": { - "@azure/event-hubs": "5.0.0-preview.7", + "@azure/event-hubs": "5.0.0-preview.8", "@azure/storage-blob": "^12.0.0", "debug": "^4.1.1", "events": "^3.0.0", diff --git a/sdk/eventhub/eventhubs-checkpointstore-blob/src/blobCheckpointStore.ts b/sdk/eventhub/eventhubs-checkpointstore-blob/src/blobCheckpointStore.ts index 8dbbf2f6a50c..5a105f16cd8c 100644 --- a/sdk/eventhub/eventhubs-checkpointstore-blob/src/blobCheckpointStore.ts +++ b/sdk/eventhub/eventhubs-checkpointstore-blob/src/blobCheckpointStore.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { CheckpointStore, PartitionOwnership, Checkpoint } from "@azure/event-hubs"; -import { ContainerClient, Metadata } from "@azure/storage-blob"; +import { ContainerClient, Metadata, RestError } from "@azure/storage-blob"; import * as log from "./log"; import { throwTypeErrorIfParameterMissing } from "./util/error"; @@ -107,12 +107,22 @@ export class BlobCheckpointStore implements CheckpointStore { `LastModifiedTime: ${ownership.lastModifiedTimeInMs}, ETag: ${ownership.etag}` ); } catch (err) { - // NOTE: there is some ordinary contention that can occur as different consumers battle over - // ownership. So the catching (and _only_ logging, not rethrowing) of this error is intentional. + const restError = err as RestError; + + if (restError.statusCode === 412) { + // etag failures (precondition not met) aren't fatal errors. They happen + // as multiple consumers attempt to claim the same partition (first one wins) + // and losers get this error. + log.blobCheckpointStore(`[${ownership.ownerId}] Did not claim partition ${ownership.partitionId}. Another processor has already claimed it.`); + continue; + } + log.error( `Error occurred while claiming ownership for partition: ${ownership.partitionId}`, err ); + + throw err; } } return partitionOwnershipArray; diff --git a/sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-partition-manager.spec.ts b/sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-checkpointstore.spec.ts similarity index 85% rename from sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-partition-manager.spec.ts rename to sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-checkpointstore.spec.ts index 85399bebe91e..2bad74e16ba6 100644 --- a/sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-partition-manager.spec.ts +++ b/sdk/eventhub/eventhubs-checkpointstore-blob/test/blob-checkpointstore.spec.ts @@ -11,13 +11,14 @@ import debugModule from "debug"; const debug = debugModule("azure:event-hubs:partitionPump"); import { EnvVarKeys, getEnvVars } from "./utils/testUtils"; import { BlobCheckpointStore } from "../src"; -import { ContainerClient } from "@azure/storage-blob"; -import { PartitionOwnership, Checkpoint } from "@azure/event-hubs"; +import { ContainerClient, RestError } from "@azure/storage-blob"; +import { PartitionOwnership, Checkpoint, EventHubConsumerClient } from "@azure/event-hubs"; import { Guid } from "guid-typescript"; import { parseIntOrThrow } from "../src/blobCheckpointStore"; +import { fail } from 'assert'; const env = getEnvVars(); -describe("Blob Partition Manager", function(): void { +describe("Blob Checkpoint Store", function(): void { const service = { storageConnectionString: env[EnvVarKeys.STORAGE_CONNECTION_STRING] }; @@ -51,6 +52,63 @@ describe("Blob Partition Manager", function(): void { should.equal(listOwnership.length, 0); }); + // these errors happen when we have multiple consumers starting up + // at the same time and load balancing amongst themselves. This is a + // normal thing and shouldn't be reported to the user. + it("claimOwnership ignores errors about etags", async () => { + const checkpointStore = new BlobCheckpointStore(containerClient); + + const originalClaimedOwnerships = await checkpointStore.claimOwnership([{ + partitionId: "0", + consumerGroup: EventHubConsumerClient.defaultConsumerGroupName, + fullyQualifiedNamespace: "fqdn", + eventHubName: "ehname", + ownerId: "me" + }]); + + const originalETag = originalClaimedOwnerships[0] && originalClaimedOwnerships[0].etag; + + const newClaimedOwnerships = await checkpointStore.claimOwnership(originalClaimedOwnerships); + newClaimedOwnerships.length.should.equal(1); + + newClaimedOwnerships[0]!.etag!.should.not.equal(originalETag); + + // we've now invalidated the previous ownership's etag so using the old etag will + // fail. + const shouldNotThrowButNothingWillClaim = await checkpointStore.claimOwnership([{ + partitionId: "0", + consumerGroup: EventHubConsumerClient.defaultConsumerGroupName, + fullyQualifiedNamespace: "fqdn", + eventHubName: "ehname", + ownerId: "me", + etag: originalETag + }]); + + shouldNotThrowButNothingWillClaim.length.should.equal(0); + }); + + it("claimOwnership will throw if the error is NOT an outdated etag", async () => { + const checkpointStore = new BlobCheckpointStore(containerClient); + + // now let's induce a bad failure (removing the container) + await containerClient.delete(); + + try { + await checkpointStore.claimOwnership([{ + partitionId: "0", + consumerGroup: EventHubConsumerClient.defaultConsumerGroupName, + fullyQualifiedNamespace: "fqdn", + eventHubName: "ehname", + ownerId: "me" + }]); + fail("Should have thrown an error - this isn't a normal claim collision issue"); + } catch (err) { + (err instanceof RestError).should.be.ok; + // 404 because the container is missing (since we deleted it up above) + (err as RestError).statusCode!.should.equal(404); + } + }); + it("claimOwnership call should succeed, if it has been called for the first time", async function(): Promise< void > { From 94b5d23d3055a8ff7191e4d319ed2d766190014d Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Tue, 10 Dec 2019 11:35:26 -0800 Subject: [PATCH 14/32] [Core-http] Move getDefaultProxySettings into proxyPolicy (#6478) * [Core-http] Move getDefaultProxySettings into proxyPolicy so that libraries that don't use the PipelineOptions or createDefaultRequestPolicyFactories from core-http can use this behavior without duplicating code. --- sdk/core/core-http/lib/policies/proxyPolicy.ts | 3 +++ sdk/core/core-http/lib/serviceClient.ts | 12 +++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sdk/core/core-http/lib/policies/proxyPolicy.ts b/sdk/core/core-http/lib/policies/proxyPolicy.ts index 3fe443946194..6d6924ea4046 100644 --- a/sdk/core/core-http/lib/policies/proxyPolicy.ts +++ b/sdk/core/core-http/lib/policies/proxyPolicy.ts @@ -47,6 +47,9 @@ export function getDefaultProxySettings(proxyUrl?: string): ProxySettings | unde } export function proxyPolicy(proxySettings?: ProxySettings): RequestPolicyFactory { + if (!proxySettings) { + proxySettings = getDefaultProxySettings(); + } return { create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => { return new ProxyPolicy(nextPolicy, options, proxySettings!); diff --git a/sdk/core/core-http/lib/serviceClient.ts b/sdk/core/core-http/lib/serviceClient.ts index 2100351a5ec7..9e0410def135 100644 --- a/sdk/core/core-http/lib/serviceClient.ts +++ b/sdk/core/core-http/lib/serviceClient.ts @@ -44,7 +44,7 @@ import { stringifyXML } from "./util/xml"; import { RequestOptionsBase, RequestPrepareOptions, WebResource } from "./webResource"; import { OperationResponse } from "./operationResponse"; import { ServiceCallback, isNode } from "./util/utils"; -import { proxyPolicy, getDefaultProxySettings } from "./policies/proxyPolicy"; +import { proxyPolicy } from "./policies/proxyPolicy"; import { throttlingRetryPolicy } from "./policies/throttlingRetryPolicy"; import { ServiceClientCredentials } from "./credentials/serviceClientCredentials"; import { signingPolicy } from "./policies/signingPolicy"; @@ -618,9 +618,8 @@ function createDefaultRequestPolicyFactories( factories.push(deserializationPolicy(options.deserializationContentTypes)); - const proxySettings = options.proxySettings || getDefaultProxySettings(); - if (proxySettings) { - factories.push(proxyPolicy(proxySettings)); + if (isNode) { + factories.push(proxyPolicy(options.proxySettings)); } factories.push(logPolicy({ logger: logger.info })); @@ -664,9 +663,8 @@ export function createPipelineFromOptions( ...pipelineOptions.redirectOptions }; - const proxySettings = pipelineOptions.proxyOptions || getDefaultProxySettings(); - if (isNode && proxySettings) { - requestPolicyFactories.push(proxyPolicy(proxySettings)); + if (isNode) { + requestPolicyFactories.push(proxyPolicy(pipelineOptions.proxyOptions)); } const deserializationOptions = { From 27d9cb1165e12c055ca61a505a9b1c2c7d15701b Mon Sep 17 00:00:00 2001 From: chradek <51000525+chradek@users.noreply.github.com> Date: Tue, 10 Dec 2019 13:35:41 -0800 Subject: [PATCH 15/32] [core-amqp] adds support for idle timeout and additional logging (#6492) * [core-amqp] adds logging around dns.resolve in checkNetworkConnection * [core-amqp] adds support for idle timeout check * updates pnpm lock file --- common/config/rush/pnpm-lock.yaml | 631 +++++++++--------- sdk/core/core-amqp/changelog.md | 7 +- sdk/core/core-amqp/package.json | 10 +- sdk/core/core-amqp/rollup.base.config.js | 2 +- .../core-amqp/src/ConnectionContextBase.ts | 1 + sdk/core/core-amqp/src/retry.ts | 21 +- .../util/checkNetworkConnection.browser.ts | 11 + .../src/util/checkNetworkConnection.ts | 34 + sdk/core/core-amqp/src/util/constants.ts | 1 + sdk/eventhub/testhub/package.json | 2 +- sdk/servicebus/service-bus/package.json | 2 +- 11 files changed, 392 insertions(+), 330 deletions(-) create mode 100644 sdk/core/core-amqp/src/util/checkNetworkConnection.browser.ts create mode 100644 sdk/core/core-amqp/src/util/checkNetworkConnection.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 53939cbc535f..633cbfda95ea 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -86,6 +86,29 @@ packages: dev: false resolution: integrity: sha512-e0nNyP0O802YMb4jq0nsVduIBHRWtmX/AtiWMCDI1f0KtcEmNRPfbP8DxU6iNgwnV09qy3EfaRfSY0vMsYs5cg== + /@azure/core-amqp/1.0.0-preview.6_rhea-promise@1.0.0: + dependencies: + '@azure/abort-controller': 1.0.1 + '@azure/core-auth': 1.0.2 + '@types/async-lock': 1.1.1 + '@types/is-buffer': 2.0.0 + async-lock: 1.2.2 + buffer: 5.4.3 + debug: 4.1.1 + events: 3.0.0 + is-buffer: 2.0.4 + jssha: 2.3.1 + process: 0.11.10 + rhea-promise: 1.0.0 + stream-browserify: 2.0.2 + tslib: 1.10.0 + url: 0.11.0 + util: 0.12.1 + dev: false + peerDependencies: + rhea-promise: ^1.0.0 + resolution: + integrity: sha512-H/VglmkegQPLpycNBMSk2R1pD++StqJUiRUJxzg/VAj26khtOyXlJmTjScTNqflJNgrRvP3YYLw8ZHYtli8eAw== /@azure/core-arm/1.0.0-preview.7: dependencies: '@azure/core-http': 1.0.2 @@ -130,9 +153,9 @@ packages: dev: false resolution: integrity: sha512-pkFCw6OiJrpR+aH1VQe6DYm3fK2KWCC5Jf3m/Pv1RxF08M1Xm08RCyQ5Qe0YyW5L16yYT2nnV48krVhYZ6SGFA== - /@azure/eslint-plugin-azure-sdk/2.0.1_d70227464f3da19960f35606e3defe4f: + /@azure/eslint-plugin-azure-sdk/2.0.1_941bfbd66607e40eaf4ff1b6e0744479: dependencies: - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 eslint: 6.7.2 fast-levenshtein: 2.0.6 glob: 7.1.6 @@ -350,19 +373,19 @@ packages: node: '>=8.0.0' resolution: integrity: sha512-GtwNB6BNDdsIPAYEdpp3JnOGO/3AJxjPvny53s3HERBdXSJTGQw8IRhiaTEX0b3w9P8+FwFZde4k+qkjn67aVw== - /@rollup/plugin-json/4.0.0_rollup@1.27.8: + /@rollup/plugin-json/4.0.0_rollup@1.27.9: dependencies: - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 dev: false peerDependencies: rollup: ^1.20.0 resolution: integrity: sha512-Z65CtEVWv40+ri4CvmswyhtuUtki9yP5p0UJN/GyCKKyU4jRuDS9CG0ZuV7/XuS7zGkoajyE7E4XBEaC4GW62A== - /@rollup/plugin-replace/2.2.1_rollup@1.27.8: + /@rollup/plugin-replace/2.2.1_rollup@1.27.9: dependencies: magic-string: 0.25.4 - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 dev: false peerDependencies: @@ -413,7 +436,7 @@ packages: /@types/body-parser/1.17.1: dependencies: '@types/connect': 3.4.32 - '@types/node': 12.12.14 + '@types/node': 12.12.16 dev: false resolution: integrity: sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w== @@ -439,7 +462,7 @@ packages: integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== /@types/connect/3.4.32: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 dev: false resolution: integrity: sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== @@ -477,7 +500,7 @@ packages: integrity: sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA== /@types/express-serve-static-core/4.17.0: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 '@types/range-parser': 1.2.3 dev: false resolution: @@ -547,7 +570,7 @@ packages: integrity: sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== /@types/memory-fs/0.3.2: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 dev: false resolution: integrity: sha512-j5AcZo7dbMxHoOimcHEIh0JZe5e1b8q8AqGSpZJrYc7xOgCIP79cIjTdx5jSDLtySnQDwkDTqwlC7Xw7uXw7qg== @@ -579,10 +602,10 @@ packages: dev: false resolution: integrity: sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ== - /@types/node/12.12.14: + /@types/node/12.12.16: dev: false resolution: - integrity: sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA== + integrity: sha512-vRuMyoOr5yfNf8QWxXegOjeyjpWJxFePzHzmBOIzDIzo+rSqF94RW0PkS6y4T2+VjAWLXHWrfbIJY3E3aS7lUw== /@types/node/8.10.54: dev: false resolution: @@ -609,7 +632,7 @@ packages: integrity: sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== /@types/resolve/0.0.8: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 dev: false resolution: integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== @@ -642,7 +665,7 @@ packages: integrity: sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ== /@types/tunnel/0.0.0: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 dev: false resolution: integrity: sha512-FGDp0iBRiBdPjOgjJmn1NH0KDLN+Z8fRmo+9J7XGBhubq1DPrGrbmG4UTlGzrpbCpesMqD0sWkzi27EYkOMHyg== @@ -679,7 +702,7 @@ packages: integrity: sha512-DzNJJ6ah/6t1n8sfAgQyEbZ/OMmFcF9j9P3aesnm7G6/iBFR/qiGin8K89J0RmaWIBzhTMdDg3I5PmKmSv7N9w== /@types/webpack-sources/0.1.5: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 '@types/source-list-map': 0.1.2 source-map: 0.6.1 dev: false @@ -718,9 +741,9 @@ packages: dev: false resolution: integrity: sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== - /@typescript-eslint/eslint-plugin-tslint/2.10.0_9ce81f026c1274914d7c1e8dc2a5e3ee: + /@typescript-eslint/eslint-plugin-tslint/2.11.0_9ce81f026c1274914d7c1e8dc2a5e3ee: dependencies: - '@typescript-eslint/experimental-utils': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/experimental-utils': 2.11.0_eslint@6.7.2+typescript@3.6.4 eslint: 6.7.2 lodash.memoize: 4.1.2 tslint: 5.20.1_typescript@3.6.4 @@ -733,11 +756,11 @@ packages: tslint: ^5.0.0 typescript: '*' resolution: - integrity: sha512-Bcw49dqC1My/cUg+0l7Ao5gn4hm6nyrKkacoLOa3C+08t8YdMshCec6FTUijHORAISWoG1RRmCGS+OHeO39fvA== - /@typescript-eslint/eslint-plugin/2.10.0_b3521696dde82c63983c202fc0d4064a: + integrity: sha512-mZ2HqY3ZoC32mFB2LjN/XanP/Op2aylVWpv+qmTjbtoVl7ZkuDLZKoqoJ7KHVchE77/pw9YDDz9EG49ee5veSQ== + /@typescript-eslint/eslint-plugin/2.11.0_f7075e6e0f0ded741b43d31cdfc430d3: dependencies: - '@typescript-eslint/experimental-utils': 2.10.0_eslint@6.7.2+typescript@3.6.4 - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/experimental-utils': 2.11.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 eslint: 6.7.2 eslint-utils: 1.4.3 functional-red-black-tree: 1.0.1 @@ -755,11 +778,11 @@ packages: typescript: optional: true resolution: - integrity: sha512-rT51fNLW0u3fnDGnAHVC5nu+Das+y2CpW10yqvf6/j5xbuUV3FxA3mBaIbM24CXODXjbgUznNb4Kg9XZOUxKAw== - /@typescript-eslint/experimental-utils/2.10.0_eslint@6.7.2+typescript@3.6.4: + integrity: sha512-G2HHA1vpMN0EEbUuWubiCCfd0R3a30BB+UdvnFkxwZIxYEGOrWEXDv8tBFO9f44CWc47Xv9lLM3VSn4ORLI2bA== + /@typescript-eslint/experimental-utils/2.11.0_eslint@6.7.2+typescript@3.6.4: dependencies: '@types/json-schema': 7.0.3 - '@typescript-eslint/typescript-estree': 2.10.0_typescript@3.6.4 + '@typescript-eslint/typescript-estree': 2.11.0_typescript@3.6.4 eslint: 6.7.2 eslint-scope: 5.0.0 dev: false @@ -769,12 +792,12 @@ packages: eslint: '*' typescript: '*' resolution: - integrity: sha512-FZhWq6hWWZBP76aZ7bkrfzTMP31CCefVIImrwP3giPLcoXocmLTmr92NLZxuIcTL4GTEOE33jQMWy9PwelL+yQ== - /@typescript-eslint/parser/2.10.0_eslint@6.7.2+typescript@3.6.4: + integrity: sha512-YxcA/y0ZJaCc/fB/MClhcDxHI0nOBB7v2/WxBju2cOTanX7jO9ttQq6Fy4yW9UaY5bPd9xL3cun3lDVqk67sPQ== + /@typescript-eslint/parser/2.11.0_eslint@6.7.2+typescript@3.6.4: dependencies: '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.10.0_eslint@6.7.2+typescript@3.6.4 - '@typescript-eslint/typescript-estree': 2.10.0_typescript@3.6.4 + '@typescript-eslint/experimental-utils': 2.11.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/typescript-estree': 2.11.0_typescript@3.6.4 eslint: 6.7.2 eslint-visitor-keys: 1.1.0 dev: false @@ -784,8 +807,8 @@ packages: eslint: ^5.0.0 || ^6.0.0 typescript: '*' resolution: - integrity: sha512-wQNiBokcP5ZsTuB+i4BlmVWq6o+oAhd8en2eSm/EE9m7BgZUIfEeYFd6z3S+T7bgNuloeiHA1/cevvbBDLr98g== - /@typescript-eslint/typescript-estree/2.10.0_typescript@3.6.4: + integrity: sha512-DyGXeqhb3moMioEFZIHIp7oXBBh7dEfPTzGrlyP0Mi9ScCra4SWEGs3kPd18mG7Sy9Wy8z88zmrw5tSGL6r/6A== + /@typescript-eslint/typescript-estree/2.11.0_typescript@3.6.4: dependencies: debug: 4.1.1 eslint-visitor-keys: 1.1.0 @@ -804,7 +827,7 @@ packages: typescript: optional: true resolution: - integrity: sha512-oOYnplddQNm/LGVkqbkAwx4TIBuuZ36cAQq9v3nFIU9FmhemHuVzAesMSXNQDdAzCa5bFgCrfD3JWhYVKlRN2g== + integrity: sha512-HGY4+d4MagO6cKMcKfIKaTMxcAv7dEVnji2Zi+vi5VV8uWAM631KjAB5GxFcexMYrwKT0EekRiiGK1/Sd7VFGA== /@webassemblyjs/ast/1.8.5: dependencies: '@webassemblyjs/helper-module-context': 1.8.5 @@ -1795,7 +1818,7 @@ packages: dependencies: babel-core: 6.26.3 babel-runtime: 6.26.0 - core-js: 2.6.10 + core-js: 2.6.11 home-or-tmp: 2.0.0 lodash: 4.17.15 mkdirp: 0.5.1 @@ -1805,7 +1828,7 @@ packages: integrity: sha1-btAhFz4vy0htestFxgCahW9kcHE= /babel-runtime/6.26.0: dependencies: - core-js: 2.6.10 + core-js: 2.6.11 regenerator-runtime: 0.11.1 dev: false resolution: @@ -2343,7 +2366,7 @@ packages: integrity: sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== /chrome-launcher/0.11.2: dependencies: - '@types/node': 12.12.14 + '@types/node': 12.12.16 is-wsl: 2.1.1 lighthouse-logger: 1.2.0 mkdirp: 0.5.1 @@ -2613,17 +2636,17 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - /core-js/2.6.10: - deprecated: 'core-js@<3.0 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.' + /core-js/2.6.11: + deprecated: 'core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.' dev: false requiresBuild: true resolution: - integrity: sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA== - /core-js/3.4.7: + integrity: sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + /core-js/3.4.8: dev: false requiresBuild: true resolution: - integrity: sha512-qaPVGw30J1wQ0GR3GvoPqlGf9GZfKKF4kFC7kiHlcsPTqH3txrs9crCp3ZiMAXuSenhz89Jnl4GZs/67S5VOSg== + integrity: sha512-b+BBmCZmVgho8KnBUOXpvlqEMguko+0P+kXCwD4vIprsXC6ht1qgPxtb1OK6XgSlrySF71wkwBQ0Hv695bk9gQ== /core-util-is/1.0.2: dev: false resolution: @@ -3645,7 +3668,7 @@ packages: /fetch-mock/8.0.1_node-fetch@2.6.0: dependencies: babel-runtime: 6.26.0 - core-js: 3.4.7 + core-js: 3.4.8 glob-to-regexp: 0.4.1 lodash.isequal: 4.5.0 node-fetch: 2.6.0 @@ -4170,7 +4193,7 @@ packages: node: '>=0.4.7' hasBin: true optionalDependencies: - uglify-js: 3.7.1 + uglify-js: 3.7.2 resolution: integrity: sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== /har-schema/2.0.0: @@ -5258,11 +5281,11 @@ packages: requirejs: ^2.1.0 resolution: integrity: sha1-/driy4fX68FvsCIok1ZNf+5Xh5g= - /karma-rollup-preprocessor/7.0.2_rollup@1.27.8: + /karma-rollup-preprocessor/7.0.2_rollup@1.27.9: dependencies: chokidar: 3.3.0 debounce: 1.2.0 - rollup: 1.27.8 + rollup: 1.27.9 dev: false engines: node: '>= 8.0.0' @@ -7504,13 +7527,13 @@ packages: dev: false resolution: integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - /rollup-plugin-commonjs/10.1.0_rollup@1.27.8: + /rollup-plugin-commonjs/10.1.0_rollup@1.27.9: dependencies: estree-walker: 0.6.1 is-reference: 1.1.4 magic-string: 0.25.4 resolve: 1.13.1 - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 dev: false peerDependencies: @@ -7546,13 +7569,13 @@ packages: dev: false resolution: integrity: sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g== - /rollup-plugin-node-resolve/5.2.0_rollup@1.27.8: + /rollup-plugin-node-resolve/5.2.0_rollup@1.27.9: dependencies: '@types/resolve': 0.0.8 builtin-modules: 3.1.0 is-module: 1.0.0 resolve: 1.13.1 - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 dev: false peerDependencies: @@ -7563,9 +7586,9 @@ packages: dev: false resolution: integrity: sha512-rZqFD43y4U9nSqVq3iyWBiDwmBQJY8Txi04yI9jTKD3xcl7CbFjh1qRpQshUB3sONLubDzm7vJiwB+1MEGv67w== - /rollup-plugin-sourcemaps/0.4.2_rollup@1.27.8: + /rollup-plugin-sourcemaps/0.4.2_rollup@1.27.9: dependencies: - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 source-map-resolve: 0.5.2 dev: false @@ -7576,11 +7599,11 @@ packages: rollup: '>=0.31.2' resolution: integrity: sha1-YhJaqUCHqt97g+9N+vYptHMTXoc= - /rollup-plugin-terser/5.1.2_rollup@1.27.8: + /rollup-plugin-terser/5.1.2_rollup@1.27.9: dependencies: '@babel/code-frame': 7.5.5 jest-worker: 24.9.0 - rollup: 1.27.8 + rollup: 1.27.9 rollup-pluginutils: 2.8.2 serialize-javascript: 1.9.1 terser: 4.4.2 @@ -7589,25 +7612,25 @@ packages: rollup: '>=0.66.0 <2' resolution: integrity: sha512-sWKBCOS+vUkRtHtEiJPAf+WnBqk/C402fBD9AVHxSIXMqjsY7MnYWKYEUqGixtr0c8+1DjzUEPlNgOYQPVrS1g== - /rollup-plugin-uglify/6.0.3_rollup@1.27.8: + /rollup-plugin-uglify/6.0.3_rollup@1.27.9: dependencies: '@babel/code-frame': 7.5.5 jest-worker: 24.9.0 - rollup: 1.27.8 + rollup: 1.27.9 serialize-javascript: 1.9.1 - uglify-js: 3.7.1 + uglify-js: 3.7.2 dev: false peerDependencies: rollup: '>=0.66.0 <2' resolution: integrity: sha512-PIv3CfhZJlOG8C85N0GX+uK09TPggmAS6Nk6fpp2ELzDAV5VUhNzOURDU2j7+MwuRr0zq9IZttUTADc/jH8Gkg== - /rollup-plugin-visualizer/3.3.0_rollup@1.27.8: + /rollup-plugin-visualizer/3.3.0_rollup@1.27.9: dependencies: mkdirp: 0.5.1 nanoid: 2.1.7 open: 6.4.0 pupa: 2.0.1 - rollup: 1.27.8 + rollup: 1.27.9 source-map: 0.7.3 yargs: 15.0.2 dev: false @@ -7624,7 +7647,7 @@ packages: dev: false resolution: integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== - /rollup/1.27.8: + /rollup/1.27.9: dependencies: '@types/estree': 0.0.40 '@types/node': 8.10.59 @@ -7632,7 +7655,7 @@ packages: dev: false hasBin: true resolution: - integrity: sha512-EVoEV5rAWl+5clnGznt1KY8PeVkzVQh/R0d2s3gHEkN7gfoyC4JmvIVuCtPbYE8NM5Ep/g+nAmvKXBjzaqTsHA== + integrity: sha512-8AfW4cJTPZfG6EXWwT/ujL4owUsDI1Xl8J1t+hvK4wDX81F5I4IbwP9gvGbHzxnV19fnU4rRABZQwZSX9J402Q== /run-async/2.3.0: dependencies: is-promise: 2.1.0 @@ -7736,10 +7759,10 @@ packages: dev: false resolution: integrity: sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A== - /serialize-javascript/2.1.1: + /serialize-javascript/2.1.2: dev: false resolution: - integrity: sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== + integrity: sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== /serve-static/1.14.1: dependencies: encodeurl: 1.0.2 @@ -8440,7 +8463,7 @@ packages: find-cache-dir: 2.1.0 is-wsl: 1.1.0 schema-utils: 1.0.0 - serialize-javascript: 2.1.1 + serialize-javascript: 2.1.2 source-map: 0.6.1 terser: 4.4.2 webpack: 4.41.2_webpack@4.41.2 @@ -8825,7 +8848,7 @@ packages: node: '>= 8' resolution: integrity: sha512-z5AWKqQDz7igl9WkUuafx8cEm4MPVQGMpbWE+3lwVOaq+U4UoLKBMnpFQWh/4fqQ3bGysXpOstMxy2OOzHezyw== - /typedoc/0.15.3: + /typedoc/0.15.4: dependencies: '@types/minimatch': 3.0.3 fs-extra: 8.1.0 @@ -8843,7 +8866,7 @@ packages: node: '>= 6.0.0' hasBin: true resolution: - integrity: sha512-RGX+dgnm9fyg5KHj81/ZhMiee0FfvJnjBXedhedhMWlrtM4YRv3pn8sYCWRt5TMi1Jli3/JG224pbFo3/3uaGw== + integrity: sha512-XzrV8sM44j4nXGSKt99VOkFCPGLUH9DHGGvcgZJbvqdSG7/iR3HztNjpsLyTu1nybZLLjcClLRuWJDO3icXzYA== /typescript/3.6.4: dev: false engines: @@ -8858,7 +8881,7 @@ packages: hasBin: true resolution: integrity: sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw== - /uglify-js/3.7.1: + /uglify-js/3.7.2: dependencies: commander: 2.20.3 source-map: 0.6.1 @@ -8867,7 +8890,7 @@ packages: node: '>=0.8.0' hasBin: true resolution: - integrity: sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g== + integrity: sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== /ultron/1.1.1: dev: false resolution: @@ -9495,11 +9518,11 @@ packages: 'file:projects/abort-controller.tgz': dependencies: '@microsoft/api-extractor': 7.7.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 delay: 4.3.0 @@ -9525,12 +9548,12 @@ packages: nyc: 14.1.1 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 @@ -9544,10 +9567,13 @@ packages: dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 + '@types/chai': 4.2.6 '@types/mocha': 5.2.7 '@types/node': 8.10.59 + '@types/sinon': 7.5.1 assert: 1.5.0 + chai: 4.2.0 dotenv: 8.2.0 eslint: 6.7.2 eslint-config-prettier: 6.7.0_eslint@6.7.2 @@ -9561,27 +9587,28 @@ packages: nyc: 14.1.1 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + sinon: 7.5.0 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 dev: false name: '@rush-temp/app-configuration' resolution: - integrity: sha512-KT+Iq4VO0udmNMX3aSs95zDmkAOjAXPCMQnZBGGZJE8kuTSJu5ooI/ZUZtupEH/Rg0J8Z4ZMe6eH50I5FLUEww== + integrity: sha512-JR1ms9VsVh2vVhBcpQ41/N/nb8RTDCo/Nsnvm7NjEK9BwrXnyobVA7dYoJvAmc7re7gJ8/Q7rNXwGTPSxf/xbg== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/async-lock': 1.1.1 '@types/chai': 4.2.6 '@types/chai-as-promised': 7.1.2 @@ -9591,8 +9618,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/sinon': 7.5.1 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 async-lock: 1.2.2 buffer: 5.4.3 @@ -9622,15 +9649,15 @@ packages: rhea: 1.0.15 rhea-promise: 1.0.0 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-inject: 3.0.2 rollup-plugin-multi-entry: 2.1.0 rollup-plugin-node-globals: 1.4.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 sinon: 7.5.0 stream-browserify: 2.0.2 ts-node: 8.5.4_typescript@3.6.4 @@ -9642,7 +9669,7 @@ packages: dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-C3k0o+aknv0OvsMgN3lgDNqrePHNsZqPlsFSHEIiJXSVj/OqzTbBSQkrg5elg5tsMpmMTX4TdXI7o+LnG6dq8w== + integrity: sha512-BsX1EW+uzq8OLaq4FZshkR/tEWRvjNhrLATVk+dRodY64B4mbXT6jONqzb94AT8tglH30+Xg5//cQgZTH3z5yQ== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -9650,8 +9677,8 @@ packages: '@types/chai': 4.2.6 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 chai: 4.2.0 eslint: 6.7.2 eslint-config-prettier: 6.7.0_eslint@6.7.2 @@ -9664,15 +9691,15 @@ packages: npm-run-all: 4.1.5 nyc: 14.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 shx: 0.3.2 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 yarn: 1.21.0 dev: false name: '@rush-temp/core-arm' @@ -9683,8 +9710,8 @@ packages: 'file:projects/core-asynciterator-polyfill.tgz': dependencies: '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 eslint: 6.7.2 eslint-config-prettier: 6.7.0_eslint@6.7.2 eslint-plugin-no-null: 1.0.2_eslint@6.7.2 @@ -9700,15 +9727,15 @@ packages: version: 0.0.0 'file:projects/core-auth.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 eslint: 6.7.2 @@ -9722,13 +9749,13 @@ packages: mocha-multi: 1.1.3_mocha@6.2.2 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 tslib: 1.10.0 typescript: 3.6.4 util: 0.12.1 @@ -9740,10 +9767,10 @@ packages: version: 0.0.0 'file:projects/core-http.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@azure/logger-js': 1.3.2 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 '@types/chai': 4.2.6 '@types/express': 4.17.2 '@types/glob': 7.1.1 @@ -9758,8 +9785,8 @@ packages: '@types/webpack': 4.41.0 '@types/webpack-dev-middleware': 2.0.3 '@types/xml2js': 0.4.5 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 babel-runtime: 6.26.0 chai: 4.2.0 eslint: 6.7.2 @@ -9775,7 +9802,7 @@ packages: karma-chai: 0.1.0_chai@4.2.0+karma@4.4.1 karma-chrome-launcher: 3.1.0 karma-mocha: 1.3.0 - karma-rollup-preprocessor: 7.0.2_rollup@1.27.8 + karma-rollup-preprocessor: 7.0.2_rollup@1.27.9 karma-sourcemap-loader: 0.3.7 karma-typescript-es6-transform: 4.1.1 karma-webpack: 4.0.2_webpack@4.41.2 @@ -9791,12 +9818,12 @@ packages: puppeteer: 2.0.0 regenerator-runtime: 0.13.3 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 shx: 0.3.2 sinon: 7.5.0 terser: 4.4.2 @@ -9806,7 +9833,7 @@ packages: tslib: 1.10.0 tunnel: 0.0.6 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 uuid: 3.3.3 webpack: 4.41.2_webpack@4.41.2 webpack-cli: 3.3.10_webpack@4.41.2 @@ -9825,12 +9852,12 @@ packages: '@azure/core-arm': 1.0.0-preview.7 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 eslint: 6.7.2 @@ -9859,19 +9886,19 @@ packages: nyc: 14.1.1 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 shx: 0.3.2 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 yarn: 1.21.0 dev: false name: '@rush-temp/core-lro' @@ -9882,8 +9909,8 @@ packages: 'file:projects/core-paging.tgz': dependencies: '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 eslint: 6.7.2 eslint-config-prettier: 6.7.0_eslint@6.7.2 eslint-plugin-no-null: 1.0.2_eslint@6.7.2 @@ -9899,16 +9926,16 @@ packages: version: 0.0.0 'file:projects/core-tracing.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opencensus/web-types': 0.0.7 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 eslint: 6.7.2 @@ -9922,13 +9949,13 @@ packages: mocha-multi: 1.1.3_mocha@6.2.2 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 tslib: 1.10.0 typescript: 3.6.4 util: 0.12.1 @@ -9940,9 +9967,9 @@ packages: version: 0.0.0 'file:projects/cosmos.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 '@types/debug': 4.1.5 '@types/fast-json-stable-stringify': 2.0.0 '@types/mocha': 5.2.7 @@ -9954,9 +9981,9 @@ packages: '@types/tunnel': 0.0.1 '@types/underscore': 1.9.4 '@types/uuid': 3.4.6 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/eslint-plugin-tslint': 2.10.0_9ce81f026c1274914d7c1e8dc2a5e3ee - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/eslint-plugin-tslint': 2.11.0_9ce81f026c1274914d7c1e8dc2a5e3ee + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 cross-env: 6.0.3 debug: 4.1.1 dotenv: 8.2.0 @@ -9988,7 +10015,7 @@ packages: proxy-agent: 3.1.1 requirejs: 2.3.6 rimraf: 3.0.0 - rollup: 1.27.8 + rollup: 1.27.9 rollup-plugin-local-resolve: 1.0.7 rollup-plugin-multi-entry: 2.1.0 semaphore: 1.1.0 @@ -9999,7 +10026,7 @@ packages: tslib: 1.10.0 tslint: 5.20.1_typescript@3.6.4 tslint-config-prettier: 1.18.0 - typedoc: 0.15.3 + typedoc: 0.15.4 typescript: 3.6.4 uuid: 3.3.3 webpack: 4.41.2_webpack@4.41.2 @@ -10011,11 +10038,12 @@ packages: version: 0.0.0 'file:projects/event-hubs.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/core-amqp': 1.0.0-preview.6_rhea-promise@1.0.0 + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/async-lock': 1.1.1 '@types/chai': 4.2.6 '@types/chai-as-promised': 7.1.2 @@ -10027,8 +10055,8 @@ packages: '@types/sinon': 7.5.1 '@types/uuid': 3.4.6 '@types/ws': 6.0.4 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 async-lock: 1.2.2 buffer: 5.4.3 @@ -10066,14 +10094,14 @@ packages: puppeteer: 2.0.0 rhea-promise: 1.0.0 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-inject: 3.0.2 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 sinon: 7.5.0 ts-mocha: 6.0.0_mocha@6.2.2 ts-node: 8.5.4_typescript@3.6.4 @@ -10084,17 +10112,17 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-LFd1b9scPYEme/xthxSXniQTvumnsDVK+W6/buXTtuh7L/owlXXknbbJR56ajxvdOmWMayWUQSW+ng0FgnAAbA== + integrity: sha512-V7lQ6nh67y8MBg11mF3iA5VfchcUZwnLFvilKiwl5AtwdzmXFpTtWv1CkJhWLRBZS+hTM9tKQFKoAjHEuCeMNg== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@azure/event-hubs': 2.1.3 '@azure/ms-rest-nodeauth': 0.9.3 '@microsoft/api-extractor': 7.7.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/async-lock': 1.1.1 '@types/chai': 4.2.6 '@types/chai-as-promised': 7.1.2 @@ -10104,8 +10132,8 @@ packages: '@types/node': 8.10.59 '@types/uuid': 3.4.6 '@types/ws': 6.0.4 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 async-lock: 1.2.2 azure-storage: 2.10.3 chai: 4.2.0 @@ -10127,12 +10155,12 @@ packages: path-browserify: 1.0.0 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-uglify: 6.0.3_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-uglify: 6.0.3_rollup@1.27.9 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 @@ -10147,16 +10175,16 @@ packages: 'file:projects/eventhubs-checkpointstore-blob.tgz': dependencies: '@microsoft/api-extractor': 7.7.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/chai-as-promised': 7.1.2 '@types/chai-string': 1.4.2 '@types/debug': 4.1.5 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 chai-as-promised: 7.1.1_chai@4.2.0 @@ -10188,15 +10216,15 @@ packages: mocha-multi: 1.1.3_mocha@6.2.2 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-inject: 3.0.2 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 @@ -10211,16 +10239,16 @@ packages: dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/express': 4.17.2 '@types/jws': 3.2.1 '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/qs': 6.9.0 '@types/uuid': 3.4.6 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 eslint: 6.7.2 @@ -10247,13 +10275,13 @@ packages: puppeteer: 2.0.0 qs: 6.9.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 tslib: 1.10.0 typescript: 3.6.4 util: 0.12.1 @@ -10266,17 +10294,17 @@ packages: version: 0.0.0 'file:projects/keyvault-certificates.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 cross-env: 6.0.3 @@ -10308,18 +10336,18 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 url: 0.11.0 dev: false name: '@rush-temp/keyvault-certificates' @@ -10329,17 +10357,17 @@ packages: version: 0.0.0 'file:projects/keyvault-keys.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 cross-env: 6.0.3 @@ -10371,18 +10399,18 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 url: 0.11.0 dev: false name: '@rush-temp/keyvault-keys' @@ -10392,17 +10420,17 @@ packages: version: 0.0.0 'file:projects/keyvault-secrets.tgz': dependencies: - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 cross-env: 6.0.3 @@ -10434,18 +10462,18 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 tslib: 1.10.0 typescript: 3.6.4 - uglify-js: 3.7.1 + uglify-js: 3.7.2 url: 0.11.0 dev: false name: '@rush-temp/keyvault-secrets' @@ -10456,13 +10484,13 @@ packages: 'file:projects/logger.tgz': dependencies: '@microsoft/api-extractor': 7.7.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/chai': 4.2.6 '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/sinon': 7.5.1 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 chai: 4.2.0 cross-env: 6.0.3 @@ -10491,12 +10519,12 @@ packages: prettier: 1.19.1 puppeteer: 2.0.0 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 sinon: 7.5.0 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 @@ -10511,12 +10539,12 @@ packages: dependencies: '@azure/amqp-common': 1.0.0-preview.8_rhea-promise@0.1.15 '@azure/arm-servicebus': 3.2.0 - '@azure/eslint-plugin-azure-sdk': 2.0.1_d70227464f3da19960f35606e3defe4f + '@azure/eslint-plugin-azure-sdk': 2.0.1_941bfbd66607e40eaf4ff1b6e0744479 '@azure/ms-rest-nodeauth': 0.9.3 '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/async-lock': 1.1.1 '@types/chai': 4.2.6 '@types/chai-as-promised': 7.1.2 @@ -10526,8 +10554,8 @@ packages: '@types/mocha': 5.2.7 '@types/node': 8.10.59 '@types/ws': 6.0.4 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 buffer: 5.4.3 chai: 4.2.0 @@ -10568,14 +10596,14 @@ packages: rhea: 1.0.15 rhea-promise: 0.1.15 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-inject: 3.0.2 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 typescript: 3.6.4 @@ -10583,21 +10611,21 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-v9JQLOn0+S//dIlZWY84RHP0umc+qt7wppf2TKW9jP6dmuWwI0TzNkD9xVID6yGwPBAdTmIFphV+XhN+CWetog== + integrity: sha512-txAzZJSshDRxNPixPpjnpTz35Q+twuk0BXb0oaHOlDV2sH5T6wCxR7LM9Fy73GWqmEd15ZV7KBUOiV8IOK+Tqg== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/nise': 1.4.0 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 dotenv: 8.2.0 @@ -10634,14 +10662,14 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 @@ -10657,7 +10685,7 @@ packages: dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/dotenv': 6.1.1 '@types/execa': 0.9.0 '@types/fs-extra': 8.0.1 @@ -10666,8 +10694,8 @@ packages: '@types/nock': 10.0.3 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 dotenv: 8.2.0 @@ -10704,14 +10732,14 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 @@ -10720,21 +10748,21 @@ packages: dev: false name: '@rush-temp/storage-file-datalake' resolution: - integrity: sha512-rWmLhRxEdLrPZqWrB5YHLPiF1cfWNAw7aSiarogGH3+NM/NMmkIHVxjvNPo7MNsXBK8+9UsRuDmW83nhhE2ffQ== + integrity: sha512-bjhgD3vgXO9DxGo0tuPVP6UeqPIfhxWCA9zhlddcGjdYqhyq0IyPIPf+Wt6TI4z3Ko74Lm2JKKFRnOzqmvRMeA== tarball: 'file:projects/storage-file-datalake.tgz' version: 0.0.0 'file:projects/storage-file-share.tgz': dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/nise': 1.4.0 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 dotenv: 8.2.0 @@ -10771,14 +10799,14 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 @@ -10794,14 +10822,14 @@ packages: dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/nise': 1.4.0 '@types/node': 8.10.59 '@types/query-string': 6.2.0 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 dotenv: 8.2.0 @@ -10837,14 +10865,14 @@ packages: puppeteer: 2.0.0 query-string: 5.1.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 source-map-support: 0.5.16 ts-node: 8.5.4_typescript@3.6.4 tslib: 1.10.0 @@ -10860,12 +10888,12 @@ packages: dependencies: '@microsoft/api-extractor': 7.7.0 '@opentelemetry/types': 0.2.0 - '@rollup/plugin-json': 4.0.0_rollup@1.27.8 - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-json': 4.0.0_rollup@1.27.9 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/mocha': 5.2.7 '@types/node': 8.10.59 - '@typescript-eslint/eslint-plugin': 2.10.0_b3521696dde82c63983c202fc0d4064a - '@typescript-eslint/parser': 2.10.0_eslint@6.7.2+typescript@3.6.4 + '@typescript-eslint/eslint-plugin': 2.11.0_f7075e6e0f0ded741b43d31cdfc430d3 + '@typescript-eslint/parser': 2.11.0_eslint@6.7.2+typescript@3.6.4 assert: 1.5.0 cross-env: 6.0.3 eslint: 6.7.2 @@ -10891,13 +10919,13 @@ packages: mocha-multi: 1.1.3_mocha@6.2.2 prettier: 1.19.1 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 tslib: 1.10.0 typescript: 3.6.4 util: 0.12.1 @@ -10909,7 +10937,7 @@ packages: version: 0.0.0 'file:projects/test-utils-recorder.tgz': dependencies: - '@rollup/plugin-replace': 2.2.1_rollup@1.27.8 + '@rollup/plugin-replace': 2.2.1_rollup@1.27.9 '@types/fs-extra': 8.0.1 '@types/mocha': 5.2.7 '@types/nise': 1.4.0 @@ -10917,14 +10945,14 @@ packages: nise: 1.5.2 nock: 11.7.0 rimraf: 3.0.0 - rollup: 1.27.8 - rollup-plugin-commonjs: 10.1.0_rollup@1.27.8 + rollup: 1.27.9 + rollup-plugin-commonjs: 10.1.0_rollup@1.27.9 rollup-plugin-multi-entry: 2.1.0 - rollup-plugin-node-resolve: 5.2.0_rollup@1.27.8 + rollup-plugin-node-resolve: 5.2.0_rollup@1.27.9 rollup-plugin-shim: 1.0.0 - rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.8 - rollup-plugin-terser: 5.1.2_rollup@1.27.8 - rollup-plugin-visualizer: 3.3.0_rollup@1.27.8 + rollup-plugin-sourcemaps: 0.4.2_rollup@1.27.9 + rollup-plugin-terser: 5.1.2_rollup@1.27.9 + rollup-plugin-visualizer: 3.3.0_rollup@1.27.9 tslib: 1.10.0 typescript: 3.6.4 dev: false @@ -10951,9 +10979,10 @@ packages: dev: false name: '@rush-temp/testhub' resolution: - integrity: sha512-9jr74sQhEUbO70fTRMEExmTQIenZst4iKtAemjCJ5fXqyGHH/TciZN9OuzFdO2XxyG4m41OpXDenzcmI7HyM4w== + integrity: sha512-LY0h0mQWnJEsZYRn5NE7U1FYrDeA8DAGqU9sl7DuJg8yRDOeyyHI8wHs0dJK8ByRzIdDZv7bWmTvGMVPGQPojw== tarball: 'file:projects/testhub.tgz' version: 0.0.0 +registry: '' specifiers: '@rush-temp/abort-controller': 'file:./projects/abort-controller.tgz' '@rush-temp/app-configuration': 'file:./projects/app-configuration.tgz' diff --git a/sdk/core/core-amqp/changelog.md b/sdk/core/core-amqp/changelog.md index 0a337b83dd96..c7e9d15596ba 100644 --- a/sdk/core/core-amqp/changelog.md +++ b/sdk/core/core-amqp/changelog.md @@ -1,6 +1,11 @@ +## 1.0.0-preview.7 - TBD + +- Improved detection of when an established socket is no longer receiving data from the service. +- Added logging around the network connectivity check. + ## 1.0.0-preview.6 - 3rd December, 2019 -* Treat ETIMEOUT error from dns.resolve as network disconnected. +- Treat ETIMEOUT error from dns.resolve as network disconnected. ## 1.0.0-preview.5 - 29th October, 2019 diff --git a/sdk/core/core-amqp/package.json b/sdk/core/core-amqp/package.json index c38501f1e2a5..87f58b92ceec 100644 --- a/sdk/core/core-amqp/package.json +++ b/sdk/core/core-amqp/package.json @@ -1,7 +1,7 @@ { "name": "@azure/core-amqp", "sdk-type": "client", - "version": "1.0.0-preview.6", + "version": "1.0.0-preview.7", "description": "Common library for amqp based azure sdks like @azure/event-hubs.", "author": "Microsoft Corporation", "license": "MIT", @@ -9,6 +9,7 @@ "module": "./dist-esm/src/index.js", "types": "./typings/src/index.d.ts", "browser": { + "./dist-esm/src/util/checkNetworkConnection.js": "./dist-esm/src/util/checkNetworkConnection.browser.js", "./dist/index.js": "./browser/index.js", "buffer": "buffer", "stream": "stream-browserify" @@ -66,14 +67,13 @@ "is-buffer": "^2.0.3", "jssha": "^2.3.1", "process": "^0.11.10", + "rhea": "^1.0.15", + "rhea-promise": "^1.0.0", "stream-browserify": "^2.0.2", "tslib": "^1.9.3", "url": "^0.11.0", "util": "^0.12.1" }, - "peerDependencies": { - "rhea-promise": "^1.0.0" - }, "devDependencies": { "@azure/eslint-plugin-azure-sdk": "^2.0.1", "@azure/identity": "^1.0.0", @@ -107,8 +107,6 @@ "nyc": "^14.0.0", "prettier": "^1.16.4", "puppeteer": "^2.0.0", - "rhea": "^1.0.4", - "rhea-promise": "^1.0.0", "rimraf": "^3.0.0", "rollup": "^1.16.3", "rollup-plugin-commonjs": "^10.0.0", diff --git a/sdk/core/core-amqp/rollup.base.config.js b/sdk/core/core-amqp/rollup.base.config.js index 1042ee42436d..912aa7b7c85e 100644 --- a/sdk/core/core-amqp/rollup.base.config.js +++ b/sdk/core/core-amqp/rollup.base.config.js @@ -14,7 +14,7 @@ import shim from "rollup-plugin-shim"; import json from "@rollup/plugin-json"; const pkg = require("./package.json"); -const depNames = Object.keys(pkg.dependencies).concat(Object.keys(pkg.peerDependencies)); +const depNames = Object.keys(pkg.dependencies); const input = "dist-esm/src/index.js"; const production = process.env.NODE_ENV === "production"; diff --git a/sdk/core/core-amqp/src/ConnectionContextBase.ts b/sdk/core/core-amqp/src/ConnectionContextBase.ts index f095693dff6d..2abfc503bd6c 100644 --- a/sdk/core/core-amqp/src/ConnectionContextBase.ts +++ b/sdk/core/core-amqp/src/ConnectionContextBase.ts @@ -156,6 +156,7 @@ export module ConnectionContextBase { platform: `(${os.arch()}-${os.type()}-${os.release()})`, framework: `Node/${process.version}` }, + idle_time_out: Constants.defaultConnectionIdleTimeoutInMs, operationTimeoutInSeconds: parameters.operationTimeoutInMs ? parameters.operationTimeoutInMs / 1000 : undefined diff --git a/sdk/core/core-amqp/src/retry.ts b/sdk/core/core-amqp/src/retry.ts index f6c3129bc334..c5dadaae3bb9 100644 --- a/sdk/core/core-amqp/src/retry.ts +++ b/sdk/core/core-amqp/src/retry.ts @@ -2,15 +2,15 @@ // Licensed under the MIT License. import { translate, MessagingError } from "./errors"; -import { delay, isNode } from "./util/utils"; +import { delay } from "./util/utils"; import * as log from "./log"; import { defaultMaxRetries, defaultDelayBetweenOperationRetriesInMs, defaultMaxDelayForExponentialRetryInMs } from "./util/constants"; -import { resolve } from "dns"; import { AbortSignalLike } from "@azure/abort-controller"; +import { checkNetworkConnection } from "./util/checkNetworkConnection"; /** * Determines whether the object is a Delivery object. @@ -139,23 +139,6 @@ function validateRetryConfig(config: RetryConfig): void { } } -async function checkNetworkConnection(host: string): Promise { - if (isNode) { - return new Promise((res) => { - resolve(host, function(err: any): void { - // List of possible DNS error codes: https://nodejs.org/dist/latest-v12.x/docs/api/dns.html#dns_error_codes - if (err && (err.code === "ECONNREFUSED" || err.code === "ETIMEOUT")) { - res(false); - } else { - res(true); - } - }); - }); - } else { - return window.navigator.onLine; - } -} - /** * Every operation is attempted at least once. Additional attempts are made if the previous attempt failed * with a retryable error. The number of additional attempts is governed by the `maxRetries` property provided diff --git a/sdk/core/core-amqp/src/util/checkNetworkConnection.browser.ts b/sdk/core/core-amqp/src/util/checkNetworkConnection.browser.ts new file mode 100644 index 000000000000..8bcf6d0cdbaa --- /dev/null +++ b/sdk/core/core-amqp/src/util/checkNetworkConnection.browser.ts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/** + * Checks whether a network connection is detected. + * @ignore + * @internal + */ +export function checkNetworkConnection(): Promise { + return Promise.resolve(window.navigator.onLine); +} diff --git a/sdk/core/core-amqp/src/util/checkNetworkConnection.ts b/sdk/core/core-amqp/src/util/checkNetworkConnection.ts new file mode 100644 index 000000000000..266223e2523b --- /dev/null +++ b/sdk/core/core-amqp/src/util/checkNetworkConnection.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { resolve, CONNREFUSED, TIMEOUT } from "dns"; +import { retry as logRetry } from "../log"; + +/** + * Checks whether a network connection is detected. + * @ignore + * @internal + */ +export function checkNetworkConnection(host: string): Promise { + return new Promise((res) => { + logRetry("Calling dns.resolve to determine network connection status."); + resolve(host, function(err: any): void { + if (err) { + logRetry( + "Error thrown from dns.resolve in network connection check: '%s', %O", + err.code || err.name, + err + ); + // List of possible DNS error codes: https://nodejs.org/dist/latest-v12.x/docs/api/dns.html#dns_error_codes + // Only when dns.resolve returns an error we expect to see when the network is down, resolve as 'false'. + if (err.code === CONNREFUSED || err.code === TIMEOUT) { + return res(false); + } + } else { + logRetry("Successfully resolved host via dns.resolve in network connection check."); + } + + return res(true); + }); + }); +} diff --git a/sdk/core/core-amqp/src/util/constants.ts b/sdk/core/core-amqp/src/util/constants.ts index da36c98c80a7..07cc619cd815 100644 --- a/sdk/core/core-amqp/src/util/constants.ts +++ b/sdk/core/core-amqp/src/util/constants.ts @@ -51,6 +51,7 @@ export const senderError = "sender_error"; export const sessionError = "session_error"; export const connectionError = "connection_error"; export const defaultOperationTimeoutInMs = 60000; +export const defaultConnectionIdleTimeoutInMs = 60000; export const managementRequestKey = "managementRequest"; export const negotiateCbsKey = "negotiateCbs"; export const negotiateClaim = "negotiateClaim"; diff --git a/sdk/eventhub/testhub/package.json b/sdk/eventhub/testhub/package.json index 500b318a956f..fc1c6b5d06cc 100644 --- a/sdk/eventhub/testhub/package.json +++ b/sdk/eventhub/testhub/package.json @@ -41,7 +41,7 @@ "async-lock": "^1.1.3", "death": "^1.1.0", "debug": "^4.1.1", - "rhea": "^1.0.4", + "rhea": "^1.0.15", "rimraf": "^3.0.0", "tslib": "^1.9.3", "typescript": "~3.6.4", diff --git a/sdk/servicebus/service-bus/package.json b/sdk/servicebus/service-bus/package.json index 8e4fa529b39a..ee16ff468e65 100644 --- a/sdk/servicebus/service-bus/package.json +++ b/sdk/servicebus/service-bus/package.json @@ -79,7 +79,7 @@ "is-buffer": "^2.0.3", "long": "^4.0.0", "process": "^0.11.10", - "rhea": "^1.0.4", + "rhea": "^1.0.15", "rhea-promise": "^0.1.15", "tslib": "^1.9.3" }, From 887e83af9625be3d4c092e5704d485395598a08a Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 14:07:52 -0800 Subject: [PATCH 16/32] [event-hubs] Updating samples folder to make it a standalone project (#6413) Updating samples folder to make it a standalone project * Makes it simpler for users to just download the entire folder, npm install and run. * Makes it more effective for us as a testing tool since we can use it to test whatever is published. --- sdk/eventhub/event-hubs/samples/README.md | 43 ++++++---------- sdk/eventhub/event-hubs/samples/package.json | 41 +++++++++++++++ .../event-hubs/samples/receiveEvents.ts | 25 +++++----- .../receiveEventsUsingCheckpointStore.ts | 38 +++++++------- sdk/eventhub/event-hubs/samples/runsamples.ts | 30 +++++++++++ sdk/eventhub/event-hubs/samples/sample.env | 28 +++++++++++ .../event-hubs/samples/sampleHelpers.ts | 42 ++++++++++++++++ sdk/eventhub/event-hubs/samples/sendEvents.ts | 50 ++++++++++++++----- sdk/eventhub/event-hubs/samples/tsconfig.json | 34 ++++++++++--- .../event-hubs/samples/useWithIotHub.ts | 13 ++--- .../event-hubs/samples/usingAadAuth.ts | 19 ++++--- sdk/eventhub/event-hubs/samples/websockets.ts | 17 ++++--- 12 files changed, 280 insertions(+), 100 deletions(-) create mode 100644 sdk/eventhub/event-hubs/samples/package.json create mode 100644 sdk/eventhub/event-hubs/samples/runsamples.ts create mode 100644 sdk/eventhub/event-hubs/samples/sample.env create mode 100644 sdk/eventhub/event-hubs/samples/sampleHelpers.ts diff --git a/sdk/eventhub/event-hubs/samples/README.md b/sdk/eventhub/event-hubs/samples/README.md index 0f466d761ebe..51a4f7c7e89f 100644 --- a/sdk/eventhub/event-hubs/samples/README.md +++ b/sdk/eventhub/event-hubs/samples/README.md @@ -6,7 +6,7 @@ The samples in this folder are for version 5.0.0 and above of this library. If y Run the below in your samples folder to install the npm package for Event Hubs library. ```bash -npm install @azure/event-hubs@next +npm install ``` ## Get connection string & Event Hubs name @@ -20,35 +20,22 @@ npm install @azure/event-hubs@next Before running a sample, update it with the connection string and the Event Hub name you have noted above. -## Running a sample +## Running samples -Start by copying the sample into a npm project. -```bash -mkdir event-hubs-samples -cd event-hubs-samples -npm init -# copy sample into this directory -``` +1. Copy this folder to your machine. +2. Install dependencies for the samples project. + + ```bash + npm install + ``` -If you don't have Typescript installed, then use `npm` to install it first. -```bash -npm install -g typescript -``` - -Install the `@azure/event-hubs@next` package into your project, as well as any other dependencies you might need. -```bash -npm install --save @azure/event-hubs@next -``` - -One way to run Typescript samples is to use `ts-node`. To install `ts-node`, run the below in your sample folder -```bash -npm install ts-node -``` - -Use `ts-node` to run the sample copied previously. -```bash -ts-node sample.ts -``` +3. Rename the `sample.env` file to `.env` +4. Open the `.env` file in a text editor and fill in values related to the + sample you'd like to run. +5. Run the samples: + ```bash + npm run samples + ``` ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Feventhub%2Fevent-hubs%2Fsamples%2FREADME.png) diff --git a/sdk/eventhub/event-hubs/samples/package.json b/sdk/eventhub/event-hubs/samples/package.json new file mode 100644 index 000000000000..4de5e6eb2503 --- /dev/null +++ b/sdk/eventhub/event-hubs/samples/package.json @@ -0,0 +1,41 @@ +{ + "name": "azure-event-hubs-samples", + "private": true, + "version": "1.0.0", + "description": "The samples in this folder are for version 5.0.0 and above of this library. If you are using version 2.1.0 or lower, then please use [samples for v2.1.0](https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples) instead", + "main": "dist-esm/runsamples.js", + "scripts": { + "samples": "ts-node ./runsamples.ts", + "build": "tsc -p ." + }, + "keywords": [ + "Azure", + "EventHubs", + "CheckpointStore", + "Node.js", + "TypeScript" + ], + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Azure/azure-sdk-for-js/issues" + }, + "homepage": "https://github.com/Azure/azure-sdk-for-js#readme", + "devDependencies": { + "ts-node": "^8.5.4", + "typescript": "^3.7.2", + "@types/node": "^12.12.17" + }, + "dependencies": { + "@azure/core-amqp": "next", + "@azure/event-hubs": "next", + "@azure/eventhubs-checkpointstore-blob": "next", + "@types/dotenv": "^8.2.0", + "@types/ws": "^6.0.4", + "dotenv": "^8.2.0", + "https-proxy-agent": "^3.0.1", + "rhea-promise": "^1.0.0", + "tslib": "^1.9.3", + "ws": "^7.2.0" + } +} diff --git a/sdk/eventhub/event-hubs/samples/receiveEvents.ts b/sdk/eventhub/event-hubs/samples/receiveEvents.ts index 0b66f5ab1c5c..c59593498caf 100644 --- a/sdk/eventhub/event-hubs/samples/receiveEvents.ts +++ b/sdk/eventhub/event-hubs/samples/receiveEvents.ts @@ -12,15 +12,18 @@ https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples instead. */ +import { runSample, cleanupAfterWaiting } from './sampleHelpers'; import { EventHubConsumerClient } from "@azure/event-hubs"; -const connectionString = ""; -const eventHubName = ""; -const consumerGroup = ""; +const connectionString = process.env["EVENTHUB_CONNECTION_STRING"] || ""; +const eventHubName = process.env["EVENTHUB_NAME"] || ""; +const consumerGroup = process.env["CONSUMER_GROUP_NAME"] || ""; -async function main() { +export async function main() { + console.log(`Running receiveEvents sample`); + const consumerClient = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName); const subscription = consumerClient.subscribe({ @@ -37,16 +40,12 @@ async function main() { } }); - // after 30 seconds, stop processing - await new Promise((resolve) => { - setTimeout(async () => { + await cleanupAfterWaiting(async () => { await subscription.close(); await consumerClient.close(); - resolve(); - }, 30000); - }); + }, 30); + + console.log(`Exiting receiveEvents sample`); } -main().catch((err) => { - console.log("Error occurred: ", err); -}); +runSample(main); \ No newline at end of file diff --git a/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts b/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts index 22e6efe9433d..ff93f54de9d3 100644 --- a/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts +++ b/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts @@ -16,6 +16,7 @@ https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples instead. */ +import { runSample, cleanupAfterWaiting } from './sampleHelpers'; import { EventHubConsumerClient, CheckpointStore, } from "@azure/event-hubs"; @@ -23,24 +24,25 @@ import { import { ContainerClient } from "@azure/storage-blob"; import { BlobCheckpointStore } from "@azure/eventhubs-checkpointstore-blob"; -const connectionString = ""; -const eventHubName = ""; -const storageConnectionString = ""; -const containerName = ""; -const consumerGroup = ""; +const connectionString = process.env["EVENTHUB_CONNECTION_STRING"] || ""; +const eventHubName = process.env["EVENTHUB_NAME"] || ""; +const consumerGroup = process.env["CONSUMER_GROUP_NAME"] || ""; +const storageConnectionString = process.env["STORAGE_CONNECTION_STRING"] || ""; +const containerName = process.env["STORAGE_CONTAINER_NAME"] || ""; + +export async function main() { + console.log(`Running receiveEventsUsingCheckpointStore sample`); -async function main() { // this client will be used by our eventhubs-checkpointstore-blob, which // persists any checkpoints from this session in Azure Storage const containerClient = new ContainerClient(storageConnectionString, containerName); - if (!containerClient.exists()) { + if (!(await containerClient.exists())) { await containerClient.create(); } const checkpointStore : CheckpointStore = new BlobCheckpointStore(containerClient); - const consumerClient = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName, checkpointStore); const subscription = consumerClient.subscribe({ @@ -58,7 +60,7 @@ async function main() { }; console.log( - `Successfully checkpointed event with sequence number: ${events[events.length - 1].sequenceNumber} from partition: 'partitionContext.partitionId'` + `Successfully checkpointed event with sequence number: ${events[events.length - 1].sequenceNumber} from partition: '${context.partitionId}'` ); }, processError: async (err, context) => { @@ -68,15 +70,13 @@ async function main() { ); // after 30 seconds, stop processing - await new Promise((resolve) => { - setTimeout(async () => { - await subscription.close(); - await consumerClient.close(); - resolve(); - }, 30000); - }); + await cleanupAfterWaiting(async () => { + await subscription.close(); + await consumerClient.close(); + }, 30); + + console.log(`Exiting receiveEventsUsingCheckpointStore sample`); } -main().catch((err) => { - console.log("Error occurred: ", err); -}); +runSample(main); + diff --git a/sdk/eventhub/event-hubs/samples/runsamples.ts b/sdk/eventhub/event-hubs/samples/runsamples.ts new file mode 100644 index 000000000000..6ca9ecba1a69 --- /dev/null +++ b/sdk/eventhub/event-hubs/samples/runsamples.ts @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as dotenv from "dotenv"; + +dotenv.config(); + +// don't have the samples execute - we'll run them manually in `main` below +process.env["DO_NOT_EXECUTE_SAMPLE"] = "1"; + +import { main as sendEventsMain } from "./sendEvents"; +import { main as receiveEventsMain } from "./receiveEvents"; +import { main as receiveEventsUsingCheckpointStoreMain } from "./receiveEventsUsingCheckpointStore"; +import { main as useWithIotHubMain } from "./useWithIotHub"; +import { main as usingAadAuthMain } from "./usingAadAuth"; +import { main as websocketsMain } from "./websockets"; + +async function main() { + await sendEventsMain(); + await receiveEventsMain(); + await receiveEventsUsingCheckpointStoreMain(); + await useWithIotHubMain(); + await usingAadAuthMain(); + await websocketsMain(); +} + +main().catch(err => { + console.log(err); + process.exit(1); +}) \ No newline at end of file diff --git a/sdk/eventhub/event-hubs/samples/sample.env b/sdk/eventhub/event-hubs/samples/sample.env new file mode 100644 index 000000000000..f63b3f16055f --- /dev/null +++ b/sdk/eventhub/event-hubs/samples/sample.env @@ -0,0 +1,28 @@ +# Used in most samples +EVENTHUB_CONNECTION_STRING= +EVENTHUB_NAME= +EVENTHUB_FQDN=.servicebus.windows.net +CONSUMER_GROUP_NAME= + +# Used in the receiveEventsUsingCheckpointStore.ts sample +STORAGE_CONTAINER_NAME= + +# Used in the useWithIotHub.ts sample +IOTHUB_CONNECTION_STRING= + +# Used in the usingAadAuth.ts sample +# Setup : +# Please ensure that your Azure Event Hubs resource is in US East, US East 2, or West Europe +# region. AAD Role Based Access Control is not supported in other regions yet. +# Register a new application in AAD and assign the "Azure Event Hubs Data Owner (Preview)" role to it +# - See https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app +# to register a new application in the Azure Active Directory. +# - Note down the CLIENT_ID and TENANT_ID from the above step. +# - In the "Certificates & Secrets" tab, create a secret and note that down. +# - In the Azure portal, go to your Even Hubs resource and click on the Access control (IAM) +# tab. Here, assign the "Azure Event Hubs Data Owner (Preview)" role to the registered application. +# - For more information on Event Hubs RBAC setup, learn more at +# https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-role-based-access-control) +AZURE_CLIENT_ID= +AZURE_TENANT_ID= +AZURE_CLIENT_SECRET= diff --git a/sdk/eventhub/event-hubs/samples/sampleHelpers.ts b/sdk/eventhub/event-hubs/samples/sampleHelpers.ts new file mode 100644 index 000000000000..026b409979a0 --- /dev/null +++ b/sdk/eventhub/event-hubs/samples/sampleHelpers.ts @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as dotenv from "dotenv"; + +// initialize using the .env file in the current folder +dotenv.config(); + +/** + * Runs the async sample function, exiting if needed if it fails. + * @param main The 'main' function for the sample. + */ +export function runSample(main: () => Promise) { + if (process.env["DO_NOT_EXECUTE_SAMPLE"]) { + return Promise.resolve(); + } + + return main().catch((err) => { + console.log("Error occurred: ", err); + process.exit(1); + }); +} + +/** + * Runs your cleanupFn after waiting for `timeToWaitInSeconds` seconds + * @param cleanupFn Cleanup function to run. + * @param timeToWaitInSeconds Seconds to wait. + */ +export function cleanupAfterWaiting(cleanupFn: () => Promise, timeToWaitInSeconds: number): Promise { + return new Promise((resolve, reject) => { + console.log(`Waiting for ${timeToWaitInSeconds} seconds...`) + + setTimeout(async () => { + try { + await cleanupFn(); + resolve(); + } catch (err) { + reject(err); + } + }, timeToWaitInSeconds * 1000); + }); +} \ No newline at end of file diff --git a/sdk/eventhub/event-hubs/samples/sendEvents.ts b/sdk/eventhub/event-hubs/samples/sendEvents.ts index a9ce6c98895b..99ffafb8487c 100644 --- a/sdk/eventhub/event-hubs/samples/sendEvents.ts +++ b/sdk/eventhub/event-hubs/samples/sendEvents.ts @@ -9,16 +9,22 @@ https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples instead. */ +import { runSample } from './sampleHelpers'; import { EventHubProducerClient } from "@azure/event-hubs"; // Define connection string and related Event Hubs entity name here -const connectionString = ""; -const eventHubName = ""; +const connectionString = process.env["EVENTHUB_CONNECTION_STRING"] || ""; +const eventHubName = process.env["EVENTHUB_NAME"] || ""; + +export async function main(): Promise { + console.log(`Running sendEvents sample`); -async function main(): Promise { const producer = new EventHubProducerClient(connectionString, eventHubName); console.log("Creating and sending a batch of events..."); + + const eventsToSend = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]; + try { // By not specifying a partition ID or a partition key we allow the server to choose // which partition will accept this message. @@ -30,28 +36,46 @@ async function main(): Promise { // If you would like more control you can pass either a `partitionKey` or a `partitionId` // into the createBatch() `options` parameter which will allow you full control over the // destination. - const batch = await producer.createBatch(); + let batch = await producer.createBatch(); // add events to our batch - for (let index = 0; index < 10; index++) { + for (const event of eventsToSend) { // messages can fail to be added to the batch if they exceed the maximum size configured for // the EventHub. - const isAdded = batch.tryAdd({ body: "Sent along with 9 other events using batch" }); + const isAdded = batch.tryAdd({ body: event }); if (!isAdded) { - console.log(`Unable to add event ${index} to the batch`); - break; + if (batch.count === 0) { + // if we can't add it and the batch is empty that means the message we're trying to send + // is too large, even when it would be the _only_ message in the batch. + // + // To fix this you'll need to potentially split the message up across multiple batches or + // skip it. In this example, we'll skip the message. + console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); + continue; + } + + // otherwise this just signals a good spot to send our batch + console.log(`Batch is full - sending ${batch.count} messages as a single batch.`) + await producer.sendBatch(batch); + + // and create a new one to house the next set of messages + batch = await producer.createBatch(); + continue; } } - - await producer.sendBatch(batch); + + // send any remaining messages, if any. + if (batch.count > 0) { + console.log(`Sending remaining ${batch.count} messages as a single batch.`) + await producer.sendBatch(batch); + } } catch (err) { console.log("Error when creating & sending a batch of events: ", err); } await producer.close(); + console.log(`Exiting sendEvents sample`); } -main().catch((err) => { - console.log("Error occurred: ", err); -}); +runSample(main); diff --git a/sdk/eventhub/event-hubs/samples/tsconfig.json b/sdk/eventhub/event-hubs/samples/tsconfig.json index 9b753039b6f1..04c0208e238a 100644 --- a/sdk/eventhub/event-hubs/samples/tsconfig.json +++ b/sdk/eventhub/event-hubs/samples/tsconfig.json @@ -1,13 +1,35 @@ { - "extends": "../tsconfig.json", "compilerOptions": { - "module": "commonjs" + /* Basic Options */ + "target": "es2016" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "declaration": true /* Generates corresponding '.d.ts' file. */, + "declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */, + "sourceMap": true /* Generates corresponding '.map' file. */, + "outDir": "./dist-esm" /* Redirect output structure to the directory. */, + "declarationDir": "./typings" /* Output directory for generated declaration files.*/, + "importHelpers": true /* Import emit helpers from 'tslib'. */, + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, + /* Additional Checks */ + "noUnusedLocals": true /* Report errors on unused locals. */, + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + /* Experimental Options */ + "forceConsistentCasingInFileNames": true, + /* Other options */ + "newLine": "LF" /* Use the specified end of line sequence to be used when emitting files: "crlf" (windows) or "lf" (unix).”*/, + "allowJs": false /* Don't allow JavaScript files to be compiled.*/, + "resolveJsonModule": true }, "include": [ - "**/*.ts" + "*.ts" ], "exclude": [ - "../node_modules", - "../typings/**" + "./node_modules", + "./typings/**" ] -} +} \ No newline at end of file diff --git a/sdk/eventhub/event-hubs/samples/useWithIotHub.ts b/sdk/eventhub/event-hubs/samples/useWithIotHub.ts index 329823d59b8b..184b2c8b3161 100644 --- a/sdk/eventhub/event-hubs/samples/useWithIotHub.ts +++ b/sdk/eventhub/event-hubs/samples/useWithIotHub.ts @@ -4,23 +4,24 @@ This sample demonstrates how to use the EventHubClient with an IotHub instance */ +import { runSample } from './sampleHelpers'; import { EventHubConsumerClient } from "@azure/event-hubs"; // Define IoT Hub Event Hubs-compatible connection string here. // To find the correct connection string to use, visit: // https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-read-builtin -const connectionString = ""; -const consumerGroup = ""; +const connectionString = process.env["IOTHUB_CONNECTION_STRING"] || ""; +const consumerGroup = process.env["CONSUMER_GROUP_NAME"] || ""; -async function main(): Promise { +export async function main(): Promise { + console.log(`Running useWithIotHub sample`); const client = new EventHubConsumerClient(consumerGroup, connectionString); /* Refer to other samples, and place your code here to receive events using the above client. Please note that send operations are not supported when this client is used against an IotHub instance */ await client.close(); + console.log(`Exiting useWithIotHub sample`); } -main().catch((err) => { - console.log("Error occurred: ", err); -}); +runSample(main); diff --git a/sdk/eventhub/event-hubs/samples/usingAadAuth.ts b/sdk/eventhub/event-hubs/samples/usingAadAuth.ts index a3c2b148c983..0a3650f737c1 100644 --- a/sdk/eventhub/event-hubs/samples/usingAadAuth.ts +++ b/sdk/eventhub/event-hubs/samples/usingAadAuth.ts @@ -22,26 +22,29 @@ Note: If you are using version 2.1.0 or lower of @azure/event-hubs library, then please use the samples at https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples instead. */ +import { runSample } from './sampleHelpers'; import { EventHubConsumerClient } from "@azure/event-hubs"; import { DefaultAzureCredential } from "@azure/identity"; // Define Event Hubs Endpoint and related entity name here here -const evenHubsEndpoint = ""; // .servicebus.windows.net -const eventHubName = ""; -const consumerGroup = ""; +const eventHubsFullyQualifiedName = process.env["EVENTHUB_FQDN"] || ""; // .servicebus.windows.net +const eventHubName = process.env["EVENTHUB_NAME"] || ""; +const consumerGroup = process.env["CONSUMER_GROUP_NAME"] || ""; // Define AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET of your AAD application in your environment -async function main(): Promise { +export async function main(): Promise { + console.log(`Running usingAadAuth sample`); + const credential = new DefaultAzureCredential(); - const client = new EventHubConsumerClient(consumerGroup, evenHubsEndpoint, eventHubName, credential); + const client = new EventHubConsumerClient(consumerGroup, eventHubsFullyQualifiedName, eventHubName, credential); /* Refer to other samples, and place your code here to send/receive events */ await client.close(); + + console.log(`Exiting usingAadAuth sample`); } -main().catch((err) => { - console.log("error: ", err); -}); +runSample(main); diff --git a/sdk/eventhub/event-hubs/samples/websockets.ts b/sdk/eventhub/event-hubs/samples/websockets.ts index 6337b889dbc1..3ed73262f86a 100644 --- a/sdk/eventhub/event-hubs/samples/websockets.ts +++ b/sdk/eventhub/event-hubs/samples/websockets.ts @@ -14,15 +14,16 @@ https://github.com/Azure/azure-sdk-for-js/tree/%40azure/event-hubs_2.1.0/sdk/eventhub/event-hubs/samples instead. */ +import { runSample } from './sampleHelpers'; import { EventHubConsumerClient } from "@azure/event-hubs"; import WebSocket from "ws"; const url = require("url"); const httpsProxyAgent = require("https-proxy-agent"); // Define connection string and related Event Hubs entity name here -const connectionString = ""; -const eventHubName = ""; -const consumerGroup = ""; +const connectionString = process.env["EVENTHUB_CONNECTION_STRING"] || ""; +const eventHubName = process.env["EVENTHUB_NAME"] || ""; +const consumerGroup = process.env["CONSUMER_GROUP_NAME"] || ""; // Create an instance of the `HttpsProxyAgent` class with the proxy server information like // proxy url, username and password @@ -31,7 +32,9 @@ const urlParts = url.parse("http://localhost:3128"); urlParts.auth = "username:password"; // Skip this if proxy server does not need authentication. const proxyAgent = new httpsProxyAgent(urlParts); -async function main(): Promise { +export async function main(): Promise { + console.log(`Running websockets sample`); + const client = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName, { webSocketOptions: { webSocket: WebSocket, @@ -42,8 +45,8 @@ async function main(): Promise { Refer to other samples, and place your code here to send/receive events */ await client.close(); + + console.log(`Exiting websockets sample`); } -main().catch(err => { - console.log("error: ", err); -}); +runSample(main); From 39f6a4427da556b1e5e8617ffc2166c3b96e20d8 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 10 Dec 2019 14:23:59 -0800 Subject: [PATCH 17/32] Adding example for EventProcessorHost => EventHubConsumerClient migration --- event hubs migration guide.md | 59 ++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 7c70d784a899..bee0dd06bb6e 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -94,7 +94,7 @@ for (const event of eventsToSend) { // if we can't add it and the batch is empty that means the message we're trying to send // is too large, even when it would be the _only_ message in the batch. // - // To fix this you'll need to potentially split the message up across multiple batches or + // To fix this you'll need to split the message up across multiple batches or // skip it. In this example, we'll skip the message. console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); continue; @@ -116,3 +116,60 @@ if (batch.count > 0) { await producer.sendBatch(batch); } ``` + +### Migrating code from `EventProcessorHost` to `EventHubConsumerClient` for receiving events + +In V2, `EventProcessorHost` allowed you to start receiving events, delivered via callbacks. + +In V5, `EventHubConsumerClient` allows you to do the same with `subscribe()` and the +`SubscriptionEventHandlers` interface. + +So in V2: +```typescript +const eph = EventProcessorHost.createFromConnectionString( + EventProcessorHost.createHostName(ephName), + storageConnectionString, + storageContainerName, + ehConnectionString, + { + eventHubPath: eventHubName, + onEphError: (error: any) => { + console.log("[%s] Error: %O", ephName, error); + } + } +); + +const onMessage: OnReceivedMessage = async (context: PartitionContext, event: EventData) => { } + +const onError: OnReceivedError = (error: any) => { + console.log("[%s] Received Error: %O", ephName, error); +}; + +await eph.start(onMessage, onError); +``` + +And in V5: +```typescript +import { EventHubConsumerClient, CheckpointStore } from "@azure/event-hubs"; +import { ContainerClient } from "@azure/storage-blob"; +import { BlobCheckpointStore } from "@azure/eventhubs-checkpointstore-blob"; + +const containerClient = new ContainerClient(storageConnectionString, storageContainerName); +const checkpointStore : CheckpointStore = new BlobCheckpointStore(containerClient); +const eventHubConsumerClient = new EventHubConsumerClient("$Default", ehConnectionString, eventHubName); + +const subscription = eventHubConsumerClient.subscribe( + partitionId, { + // In V5 we deliver messages in batches, rather than a single message + // at a time. + processEvents: (messages, context) => {}, + + // Prior to V5 errors were handled by separate callbacks depending + // on where they were thrown. + // + // In V5 you only need a single error handler for all of those cases. + processError: onErrorHandler +}); + +await subscription.close(); +``` \ No newline at end of file From 339ba8ce2e32f6ece50cdb4448066037bb7be1c3 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 10 Dec 2019 14:59:26 -0800 Subject: [PATCH 18/32] * Don't use $Default anywhere if we can avoid it. Guide the user choose a consumer group name. * Give the document a bit more structure, including a TOC for the inline migration samples. --- event hubs migration guide.md | 48 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index bee0dd06bb6e..3ea930e6570f 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -1,21 +1,53 @@ # Migration Guide (EventHubs v2 to v5) -## Class changes +This document is intended for users that are familiar with EventHubs V2 (`@azure/event-hubs@2.x.x`) and wish +to migrate their application to EventHubs V5. -`EventHubClient` has been split into two clients - `EventHubProducerClient` (for sending -messages) and `EventHubConsumerClient` (for receiving messages). +For a more general introduction to Event Hubs, see the [readme.md](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/README.md) +for the @azure/event-hubs package. -`EventProcessorHost`'s functionality has been merged into `EventHubConsumerClient`. +## General changes + +In the interest of simplifying the API surface we've made two distinct +clients, rather than having a single `EventHubClient`: +* [EventHubProducerClient](https://docs.microsoft.com/en-us/javascript/api/@azure/event-hubs/eventhubproducerclient?view=azure-node-preview) + for sending messages. +* [EventHubConsumerClient](https://docs.microsoft.com/en-us/javascript/api/@azure/event-hubs/eventhubconsumerclient?view=azure-node-preview) + for receiving messages. + +We've also merged the functionality from `EventProcessorHost` into +`EventHubConsumerClient`, allowing `EventHubConsumerClient` to be the single +point of entry for receiving of any type within Event Hubs. + + +### Construction | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| -| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [All](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/) | +| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts), [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | `EventHubClient.createFromAadTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) + + +### Receiving events (subscribe) + +| In v2 | Equivalent in v5 | Sample | +|------------------------------------------------|------------------------------------------------------------------|--------| | `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | `EventProcessorHost` | `new EventHubConsumerClient(with checkpointStore)` | [receiveEventsUsingCheckpointStore](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts) | + +### Sending events + +| In v2 | Equivalent in v5 | Sample | +|------------------------------------------------|------------------------------------------------------------------|--------| | `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +## Migration samples + +* [Receiving events](#migrating-code-from-`eventhubclient`-to-`eventhubconsumerclient`-for-receiving-events) +* [Receiving events with checkpointing](#migrating-code-from-`eventprocessorhost`-to-`eventhubconsumerclient`-for-receiving-events) +* [Sending events](#migrating-code-from-`eventhubclient`-to-`eventhubproducerclient`-for-sending-events) + ### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events In V2, event handlers were passed as positional arguments to `receive`. @@ -28,7 +60,7 @@ For example, this code which receives from a partition in V2: const client = EventHubClient.createFromConnectionString(connectionString); const rcvHandler = client.receive(partitionId, onMessageHandler, onErrorHandler, { eventPosition: EventPosition.fromStart(), - consumerGroup: "$Default" + consumerGroup: consumerGroupName }); await rcvHandler.stop(); ``` @@ -36,7 +68,7 @@ await rcvHandler.stop(); Becomes this in V5: ```typescript -const eventHubConsumerClient = new EventHubConsumerClient("$Default", connectionString); +const eventHubConsumerClient = new EventHubConsumerClient(consumerGroupName, connectionString); const subscription = eventHubConsumerClient.subscribe( partitionId, { @@ -156,7 +188,7 @@ import { BlobCheckpointStore } from "@azure/eventhubs-checkpointstore-blob"; const containerClient = new ContainerClient(storageConnectionString, storageContainerName); const checkpointStore : CheckpointStore = new BlobCheckpointStore(containerClient); -const eventHubConsumerClient = new EventHubConsumerClient("$Default", ehConnectionString, eventHubName); +const eventHubConsumerClient = new EventHubConsumerClient(consumerGroupName, ehConnectionString, eventHubName); const subscription = eventHubConsumerClient.subscribe( partitionId, { From 7fe7deab28ce08f06373f9ea5d8cbd857a7d9eea Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:45:00 -0800 Subject: [PATCH 19/32] There were two packages, not one. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 3ea930e6570f..af2ecd6ed41e 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -1,6 +1,6 @@ # Migration Guide (EventHubs v2 to v5) -This document is intended for users that are familiar with EventHubs V2 (`@azure/event-hubs@2.x.x`) and wish +This document is intended for users that are familiar with EventHubs V2 (`@azure/event-hubs@2.x.x` & `@azure/event-processor-host@2.x.x`) and wish to migrate their application to EventHubs V5. For a more general introduction to Event Hubs, see the [readme.md](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/README.md) @@ -204,4 +204,4 @@ const subscription = eventHubConsumerClient.subscribe( }); await subscription.close(); -``` \ No newline at end of file +``` From 20492ab68e044d4bc3f7673b02f9bd9258ac3ea4 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:46:53 -0800 Subject: [PATCH 20/32] Document the multiple types of message receiving we can handle. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index af2ecd6ed41e..b1b246c0345a 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -17,7 +17,7 @@ clients, rather than having a single `EventHubClient`: We've also merged the functionality from `EventProcessorHost` into `EventHubConsumerClient`, allowing `EventHubConsumerClient` to be the single -point of entry for receiving of any type within Event Hubs. +point of entry for receiving of any type (from single partition, all partitions, or with load balancing and checkpointing features) within Event Hubs. ### Construction From 78138d40e4834344df694f959ff595bb0cdab46a Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:47:09 -0800 Subject: [PATCH 21/32] We only construct clients, not empires. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index b1b246c0345a..7e01902b4a09 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -20,7 +20,7 @@ We've also merged the functionality from `EventProcessorHost` into point of entry for receiving of any type (from single partition, all partitions, or with load balancing and checkpointing features) within Event Hubs. -### Construction +### Client constructors | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| From 8992aeeaba29885443bcd329a99059d377359a5d Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:47:41 -0800 Subject: [PATCH 22/32] It's a function. Be proud of it and call it theoretically in the table. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 7e01902b4a09..0cb2d3a30bdf 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -24,7 +24,7 @@ point of entry for receiving of any type (from single partition, all partitions, | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| -| `EventHubClient.createFromConnectionString` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts), [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| `EventHubClient.createFromConnectionString()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts), [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | `EventHubClient.createFromAadTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) From 58bdcb15fc4271d22900ff10460f9e14fd33c420 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:48:11 -0800 Subject: [PATCH 23/32] Parens. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 0cb2d3a30bdf..3af858b19565 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -25,7 +25,7 @@ point of entry for receiving of any type (from single partition, all partitions, | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| | `EventHubClient.createFromConnectionString()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts), [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | -| `EventHubClient.createFromAadTokenCredentials` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) +| `EventHubClient.createFromAadTokenCredentials()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) ### Receiving events (subscribe) From 07fb17cb4cac9c83051727bbc309a41ba2029444 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 16:49:30 -0800 Subject: [PATCH 24/32] Removed! Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 3af858b19565..d7140e168ba5 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -28,7 +28,7 @@ point of entry for receiving of any type (from single partition, all partitions, | `EventHubClient.createFromAadTokenCredentials()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) -### Receiving events (subscribe) +### Receiving events | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| From b6286da0f9aafcb82bc4e4ab19fb2fa68e5cd204 Mon Sep 17 00:00:00 2001 From: "Richard Park (WDG/ES)" Date: Tue, 10 Dec 2019 16:57:21 -0800 Subject: [PATCH 25/32] Updated with in-person feedback --- event hubs migration guide.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index d7140e168ba5..bf0999d882d2 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -32,15 +32,14 @@ point of entry for receiving of any type (from single partition, all partitions, | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| -| `EventHubClient.receive` | `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventHubClient.receiveBatch` | Removed in favor of `EventHubConsumerClient.subscribe` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | -| `EventProcessorHost` | `new EventHubConsumerClient(with checkpointStore)` | [receiveEventsUsingCheckpointStore](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts) | +| `EventHubClient.receive()` and `EventHubClient.receiveBatch()` | `EventHubConsumerClient.subscribe()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | +| `EventProcessorHost.createFromConnectionString()` | `new EventHubConsumerClient(..., checkpointStore)` | [receiveEventsUsingCheckpointStore](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts) | ### Sending events | In v2 | Equivalent in v5 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| -| `EventHubClient.send` | `EventHubConsumerClient.sendBatch` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | +| `EventHubClient.send()` | `EventHubConsumerClient.sendBatch()` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | ## Migration samples From de2de90f55bc53b84bf4cda8ae49b1037db79595 Mon Sep 17 00:00:00 2001 From: "Richard Park (WDG/ES)" Date: Tue, 10 Dec 2019 17:02:01 -0800 Subject: [PATCH 26/32] Remove backtick from the toc links --- event hubs migration guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index bf0999d882d2..6fb9af24e1ee 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -43,9 +43,9 @@ point of entry for receiving of any type (from single partition, all partitions, ## Migration samples -* [Receiving events](#migrating-code-from-`eventhubclient`-to-`eventhubconsumerclient`-for-receiving-events) -* [Receiving events with checkpointing](#migrating-code-from-`eventprocessorhost`-to-`eventhubconsumerclient`-for-receiving-events) -* [Sending events](#migrating-code-from-`eventhubclient`-to-`eventhubproducerclient`-for-sending-events) +* [Receiving events](#migrating-code-from-eventhubclient-to-eventhubconsumerclient-for-receiving-events) +* [Receiving events with checkpointing](#migrating-code-from-eventprocessorhost-to-eventhubconsumerclient-for-receiving-events) +* [Sending events](#migrating-code-from-eventhubclient-to-eventhubproducerclient-for-sending-events) ### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events From 55e8480304dcaeddc3deb9ea9190350fc0cabd6b Mon Sep 17 00:00:00 2001 From: "Richard Park (WDG/ES)" Date: Tue, 10 Dec 2019 17:05:28 -0800 Subject: [PATCH 27/32] send example was incorrect (should have been sendBatch) --- event hubs migration guide.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 6fb9af24e1ee..864648c38514 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -99,10 +99,9 @@ const eventsToSend = [ ]; const client = EventHubClient.createFromConnectionString(connectionString); -console.log(`Sending event: ${eventData.body}`); // Would fail if the total size of events exceed the max size supported by the library. -await client.send(eventsToSend, partitionId); +await client.sendBatch(eventsToSend, partitionId); ``` In V5: From de034b96c2dde45b880db8c5a25760be42968e0e Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:08:20 -0800 Subject: [PATCH 28/32] The user is in control of the batch size... Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index 6fb9af24e1ee..50e4e61f848d 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -192,7 +192,7 @@ const eventHubConsumerClient = new EventHubConsumerClient(consumerGroupName, ehC const subscription = eventHubConsumerClient.subscribe( partitionId, { // In V5 we deliver messages in batches, rather than a single message - // at a time. + // at a time. You can control the batch size via the options passed to the client. processEvents: (messages, context) => {}, // Prior to V5 errors were handled by separate callbacks depending From 8e74f244842a92349c8e90043a87c55477e53529 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:10:30 -0800 Subject: [PATCH 29/32] Let's assume they're already full events and not just data. Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index c186bddff88b..b288d890c25c 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -117,7 +117,7 @@ let batch = await producer.createBatch(); for (const event of eventsToSend) { // messages can fail to be added to the batch if they exceed the maximum size configured for // the EventHub. - const isAdded = batch.tryAdd({ body: event }); + const isAdded = batch.tryAdd(event); if (!isAdded) { if (batch.count === 0) { From bb92f68c76ceccf9133ff60c13044855fb2a7115 Mon Sep 17 00:00:00 2001 From: "Richard Park (WDG/ES)" Date: Tue, 10 Dec 2019 17:29:25 -0800 Subject: [PATCH 30/32] Tenatitively fixing sample --- event hubs migration guide.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index c186bddff88b..b29d913727a5 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -114,18 +114,18 @@ const eventsToSend = [ let batch = await producer.createBatch(); -for (const event of eventsToSend) { +for (let i = 0; i < eventsToSend.length; ++i) { // messages can fail to be added to the batch if they exceed the maximum size configured for // the EventHub. - const isAdded = batch.tryAdd({ body: event }); + const isAdded = batch.tryAdd(eventsToSend[i]); if (!isAdded) { if (batch.count === 0) { - // if we can't add it and the batch is empty that means the message we're trying to send + // If we can't add it and the batch is empty that means the message we're trying to send // is too large, even when it would be the _only_ message in the batch. // - // To fix this you'll need to split the message up across multiple batches or - // skip it. In this example, we'll skip the message. + // At this point you'll need to decide if you're okay with skipping this message entirely + // or find some way to shrink it. console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); continue; } @@ -136,6 +136,9 @@ for (const event of eventsToSend) { // and create a new one to house the next set of messages batch = await producer.createBatch(); + + // we'll retry adding this message + --i; continue; } } From 96d7a5bcf8055a4f6476cf610abd9e2d81408d4a Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 10 Dec 2019 17:35:14 -0800 Subject: [PATCH 31/32] Advertise the goodness that was EPH and that is now part of the EventHubConsumerClient Co-Authored-By: Ramya Rao --- event hubs migration guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event hubs migration guide.md b/event hubs migration guide.md index b29d913727a5..a4c7db40a172 100644 --- a/event hubs migration guide.md +++ b/event hubs migration guide.md @@ -152,7 +152,7 @@ if (batch.count > 0) { ### Migrating code from `EventProcessorHost` to `EventHubConsumerClient` for receiving events -In V2, `EventProcessorHost` allowed you to start receiving events, delivered via callbacks. +In V2, `EventProcessorHost` allowed you to balance the load between multiple instances of your program when receiving events. In V5, `EventHubConsumerClient` allows you to do the same with `subscribe()` and the `SubscriptionEventHandlers` interface. From 0db9b43e4e4f856cd8c68982a25e6a87f9a692c3 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 10 Dec 2019 20:05:39 -0800 Subject: [PATCH 32/32] * Make sample a bit more interesting by allowing them to specify the max batch size. * Added in some more console output to better illustrate the control flow. * Move migration guide to its final location. --- .../eventhub/event-hubs/migrationguide.md | 44 ++++++------ sdk/eventhub/event-hubs/samples/sendEvents.ts | 67 +++++++++++++------ 2 files changed, 70 insertions(+), 41 deletions(-) rename event hubs migration guide.md => sdk/eventhub/event-hubs/migrationguide.md (90%) diff --git a/event hubs migration guide.md b/sdk/eventhub/event-hubs/migrationguide.md similarity index 90% rename from event hubs migration guide.md rename to sdk/eventhub/event-hubs/migrationguide.md index a4c7db40a172..636ce7827fc2 100644 --- a/event hubs migration guide.md +++ b/sdk/eventhub/event-hubs/migrationguide.md @@ -113,34 +113,36 @@ const eventsToSend = [ ]; let batch = await producer.createBatch(); +let i = 0; -for (let i = 0; i < eventsToSend.length; ++i) { +while (i < eventsToSend.length) { // messages can fail to be added to the batch if they exceed the maximum size configured for // the EventHub. const isAdded = batch.tryAdd(eventsToSend[i]); - - if (!isAdded) { - if (batch.count === 0) { - // If we can't add it and the batch is empty that means the message we're trying to send - // is too large, even when it would be the _only_ message in the batch. - // - // At this point you'll need to decide if you're okay with skipping this message entirely - // or find some way to shrink it. - console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); - continue; - } - - // otherwise this just signals a good spot to send our batch - console.log(`Batch is full - sending ${batch.count} messages as a single batch.`) - await producer.sendBatch(batch); - // and create a new one to house the next set of messages - batch = await producer.createBatch(); - - // we'll retry adding this message - --i; + if (isAdded) { + console.log(`Added eventsToSend[${i}]`); + ++i; + continue; + } + + if (batch.count === 0) { + // If we can't add it and the batch is empty that means the message we're trying to send + // is too large, even when it would be the _only_ message in the batch. + // + // At this point you'll need to decide if you're okay with skipping this message entirely + // or find some way to shrink it. + console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); + ++i; continue; } + + // otherwise this just signals a good spot to send our batch + console.log(`Batch is full - sending ${batch.count} messages as a single batch.`); + await producer.sendBatch(batch); + + // and create a new one to house the next set of messages + batch = await producer.createBatch(); } // send any remaining messages, if any. diff --git a/sdk/eventhub/event-hubs/samples/sendEvents.ts b/sdk/eventhub/event-hubs/samples/sendEvents.ts index 99ffafb8487c..b767da1f839c 100644 --- a/sdk/eventhub/event-hubs/samples/sendEvents.ts +++ b/sdk/eventhub/event-hubs/samples/sendEvents.ts @@ -36,39 +36,66 @@ export async function main(): Promise { // If you would like more control you can pass either a `partitionKey` or a `partitionId` // into the createBatch() `options` parameter which will allow you full control over the // destination. - let batch = await producer.createBatch(); + const batchOptions = { + // The maxSizeInBytes lets you manually control the size of the batch. + // if this is not set we will get the maximum batch size from Event Hubs. + // + // For this sample you can change the batch size to see how different parts + // of the sample handle batching. In production we recommend using the default + // and not specifying a maximum size. + // + // maxSizeInBytes: 200 + }; + + let batch = await producer.createBatch(batchOptions); + + let numEventsSent = 0; // add events to our batch - for (const event of eventsToSend) { + let i = 0; + + while (i < eventsToSend.length) { // messages can fail to be added to the batch if they exceed the maximum size configured for // the EventHub. - const isAdded = batch.tryAdd({ body: event }); + const isAdded = batch.tryAdd({ body: eventsToSend[i] }); + + if (isAdded) { + console.log(`Added eventsToSend[${i}]`); + ++i; + continue; + } - if (!isAdded) { - if (batch.count === 0) { - // if we can't add it and the batch is empty that means the message we're trying to send - // is too large, even when it would be the _only_ message in the batch. - // - // To fix this you'll need to potentially split the message up across multiple batches or - // skip it. In this example, we'll skip the message. - console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); - continue; - } - - // otherwise this just signals a good spot to send our batch - console.log(`Batch is full - sending ${batch.count} messages as a single batch.`) - await producer.sendBatch(batch); - - // and create a new one to house the next set of messages - batch = await producer.createBatch(); + if (batch.count === 0) { + // If we can't add it and the batch is empty that means the message we're trying to send + // is too large, even when it would be the _only_ message in the batch. + // + // At this point you'll need to decide if you're okay with skipping this message entirely + // or find some way to shrink it. + console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); + ++i; continue; } + + // otherwise this just signals a good spot to send our batch + console.log(`Batch is full - sending ${batch.count} messages as a single batch.`); + await producer.sendBatch(batch); + numEventsSent += batch.count; + + // and create a new one to house the next set of messages + batch = await producer.createBatch(batchOptions); } // send any remaining messages, if any. if (batch.count > 0) { console.log(`Sending remaining ${batch.count} messages as a single batch.`) await producer.sendBatch(batch); + numEventsSent += batch.count; + } + + console.log(`Sent ${numEventsSent} events`); + + if (numEventsSent !== eventsToSend.length) { + throw new Error(`Not all messages were sent (${numEventsSent}/${eventsToSend.length})`); } } catch (err) { console.log("Error when creating & sending a batch of events: ", err);