diff --git a/sdk/eventhub/eventhubs-checkpointstore-blob/package.json b/sdk/eventhub/eventhubs-checkpointstore-blob/package.json index a657b648b022..26b81c5cd067 100644 --- a/sdk/eventhub/eventhubs-checkpointstore-blob/package.json +++ b/sdk/eventhub/eventhubs-checkpointstore-blob/package.json @@ -61,7 +61,7 @@ "dependencies": { "@azure/event-hubs": "^5.0.0", "@azure/logger": "^1.0.0", - "@azure/storage-blob": "^12.2.0", + "@azure/storage-blob": "^12.3.0-beta.1", "events": "^3.0.0", "tslib": "^2.0.0" }, diff --git a/sdk/storage/storage-blob-changefeed/README.md b/sdk/storage/storage-blob-changefeed/README.md index 97d4763c40b8..027ec45e58a4 100644 --- a/sdk/storage/storage-blob-changefeed/README.md +++ b/sdk/storage/storage-blob-changefeed/README.md @@ -1,6 +1,6 @@ # Azure Storage Blob Change Feed client library for JavaScript -> Server Version: 2019-12-12 +> Server Version: 2019-12-12 or later. The change feed provides an ordered, guaranteed, durable, immutable, read-only transaction log of all the changes that occur to blobs and blob metadata in your storage account. Client applications can read these logs at any time. The change feed enables you to build efficient and scalable solutions that process change events that occur in your Blob Storage account at a low cost. diff --git a/sdk/storage/storage-blob-changefeed/package.json b/sdk/storage/storage-blob-changefeed/package.json index 639266e976d1..d756bb794dac 100644 --- a/sdk/storage/storage-blob-changefeed/package.json +++ b/sdk/storage/storage-blob-changefeed/package.json @@ -95,7 +95,7 @@ ] }, "dependencies": { - "@azure/storage-blob": "^12.2.0", + "@azure/storage-blob": "^12.3.0-beta.1", "@azure/abort-controller": "^1.0.0", "@azure/core-http": "^1.1.6", "@azure/core-lro": "^1.0.2", diff --git a/sdk/storage/storage-blob/CHANGELOG.md b/sdk/storage/storage-blob/CHANGELOG.md index c8b028ecfd46..611d56554142 100644 --- a/sdk/storage/storage-blob/CHANGELOG.md +++ b/sdk/storage/storage-blob/CHANGELOG.md @@ -1,7 +1,11 @@ # Release History -## 12.2.2 (Unreleased) +## 12.3.0-beta.1 (2020-10-13) +- Updated Azure Storage Service API version to 2020-02-10. +- Added support for Blob Last Access Time tracking. +- Added support for Blob Query Arrow output format. +- Added support for Container Soft Delete. ## 12.2.1 (2020-09-17) diff --git a/sdk/storage/storage-blob/karma.conf.js b/sdk/storage/storage-blob/karma.conf.js index 36b4fbda909a..0c0125680a59 100644 --- a/sdk/storage/storage-blob/karma.conf.js +++ b/sdk/storage/storage-blob/karma.conf.js @@ -67,7 +67,9 @@ module.exports = function(config) { "ENCRYPTION_SCOPE_1", "ENCRYPTION_SCOPE_2", "ORS_DEST_ACCOUNT_NAME", - "ORS_DEST_ACCOUNT_SAS" + "ORS_DEST_ACCOUNT_SAS", + "SOFT_DELETE_ACCOUNT_NAME", + "SOFT_DELETE_ACCOUNT_SAS" ], // test results reporter to use diff --git a/sdk/storage/storage-blob/package.json b/sdk/storage/storage-blob/package.json index fd59abc5b10e..97071d20ba2d 100644 --- a/sdk/storage/storage-blob/package.json +++ b/sdk/storage/storage-blob/package.json @@ -1,7 +1,7 @@ { "name": "@azure/storage-blob", "sdk-type": "client", - "version": "12.2.2", + "version": "12.3.0-beta.1", "description": "Microsoft Azure Storage SDK for JavaScript - Blob", "main": "./dist/index.js", "module": "./dist-esm/storage-blob/src/index.js", @@ -32,7 +32,7 @@ }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", - "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.2.1 --use=@microsoft.azure/autorest.typescript@5.0.1", + "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.3.0-beta.1 --use=@microsoft.azure/autorest.typescript@5.0.1", "build:es6": "tsc -p tsconfig.json", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", diff --git a/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_create_append_blob_should_work_with_tags.json b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_create_append_blob_should_work_with_tags.json index c2ca7adb7ea7..dc7325c47ee6 100644 --- a/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_create_append_blob_should_work_with_tags.json +++ b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_create_append_blob_should_work_with_tags.json @@ -1,128 +1,112 @@ { - "recordings": [ - { - "method": "PUT", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596", - "query": { - "restype": "container" - }, - "requestBody": null, - "status": 201, - "response": "", - "responseHeaders": { - "content-length": "0", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "etag": "\"0x8D810800E57E396\"", - "last-modified": "Sun, 14 Jun 2020 16:29:05 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "3638240f-b7a3-429a-a9b2-ba7a04315ac8", - "x-ms-request-id": "1ae6a46c-c01e-0009-6968-420873000000", - "x-ms-version": "2019-12-12" - } - }, - { - "method": "PUT", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596/blob159215214554005971", - "query": {}, - "requestBody": "Hello World", - "status": 201, - "response": "", - "responseHeaders": { - "content-length": "0", - "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "etag": "\"0x8D810800E5B493D\"", - "last-modified": "Sun, 14 Jun 2020 16:29:05 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "9c008653-9ead-4ae0-a85a-173d2d614658", - "x-ms-content-crc64": "YeJLfssylmU=", - "x-ms-request-id": "1ae6a47e-c01e-0009-7868-420873000000", - "x-ms-request-server-encrypted": "true", - "x-ms-version": "2019-12-12", - "x-ms-version-id": "2020-06-14T16:29:05.5647037Z" - } - }, - { - "method": "DELETE", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596/blob159215214554005971", - "query": {}, - "requestBody": null, - "status": 202, - "response": "", - "responseHeaders": { - "content-length": "0", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "b3354f08-1ca7-4cd5-a635-9d4ecc330644", - "x-ms-delete-type-permanent": "false", - "x-ms-request-id": "1ae6a491-c01e-0009-0b68-420873000000", - "x-ms-version": "2019-12-12" - } - }, - { - "method": "PUT", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596/blob159215214554005971", - "query": {}, - "requestBody": null, - "status": 201, - "response": "", - "responseHeaders": { - "content-length": "0", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "etag": "\"0x8D810800E624F61\"", - "last-modified": "Sun, 14 Jun 2020 16:29:05 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "d1a4bb14-c88d-453d-aedc-11c3cdb3bd13", - "x-ms-request-id": "1ae6a499-c01e-0009-1368-420873000000", - "x-ms-request-server-encrypted": "true", - "x-ms-version": "2019-12-12", - "x-ms-version-id": "2020-06-14T16:29:05.6107361Z" - } - }, - { - "method": "GET", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596/blob159215214554005971", - "query": { - "comp": "tags" - }, - "requestBody": null, - "status": 200, - "response": "\ntag1val1tag2val2", - "responseHeaders": { - "content-length": "162", - "content-type": "application/xml", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "aec7fefc-7641-4f71-98f8-6b1dd5c5b38a", - "x-ms-request-id": "1ae6a4a8-c01e-0009-2268-420873000000", - "x-ms-version": "2019-12-12" - } - }, - { - "method": "DELETE", - "url": "https://fakestorageaccount.blob.core.windows.net/container159215214551806596", - "query": { - "restype": "container" - }, - "requestBody": null, - "status": 202, - "response": "", - "responseHeaders": { - "content-length": "0", - "date": "Sun, 14 Jun 2020 16:29:04 GMT", - "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "4fef5df9-5b85-4eea-a5ab-2b008fafe9bd", - "x-ms-request-id": "1ae6a4b1-c01e-0009-2b68-420873000000", - "x-ms-version": "2019-12-12" - } - } - ], - "uniqueTestInfo": { - "uniqueName": { - "container": "container159215214551806596", - "blob": "blob159215214554005971" - }, - "newDate": {} + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258675791209317", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 13 Oct 2020 10:59:19 GMT", + "etag": "\"0x8D86F6708D65ECE\"", + "last-modified": "Tue, 13 Oct 2020 10:59:19 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f0bd6e7f-84d5-46f1-8f98-89557e6859a7", + "x-ms-request-id": "f31510ab-201e-0003-0f4f-a12bd5000000", + "x-ms-version": "2020-02-10" + } }, - "hash": "3448881c36f419bc94b581ee37224655" -} + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258675791209317/blob160258675949705978", + "query": {}, + "requestBody": "Hello World", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "date": "Tue, 13 Oct 2020 10:59:19 GMT", + "etag": "\"0x8D86F670931D368\"", + "last-modified": "Tue, 13 Oct 2020 10:59:19 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "450e785d-10d3-4696-ad3a-2dcb7c953fed", + "x-ms-content-crc64": "YeJLfssylmU=", + "x-ms-request-id": "f31510c2-201e-0003-254f-a12bd5000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2020-02-10", + "x-ms-version-id": "2020-10-13T10:59:19.9500136Z" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258675791209317/apendBlob160258676008800186", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 13 Oct 2020 10:59:20 GMT", + "etag": "\"0x8D86F67098C11C3\"", + "last-modified": "Tue, 13 Oct 2020 10:59:20 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1f05ac1c-1c65-47fb-a965-7699867cc9e6", + "x-ms-request-id": "f31510d9-201e-0003-374f-a12bd5000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2020-02-10", + "x-ms-version-id": "2020-10-13T10:59:20.5414339Z" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258675791209317/apendBlob160258676008800186", + "query": { + "comp": "tags" + }, + "requestBody": null, + "status": 200, + "response": "\ntag1val1tag2val2", + "responseHeaders": { + "content-length": "162", + "content-type": "application/xml", + "date": "Tue, 13 Oct 2020 10:59:20 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9b1e59e0-6c42-4a25-9e45-ce0124115458", + "x-ms-request-id": "f31510e0-201e-0003-3e4f-a12bd5000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258675791209317", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 13 Oct 2020 10:59:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0b8be035-b96f-41f2-b2d7-34d9f5b952d1", + "x-ms-request-id": "f31510ec-201e-0003-464f-a12bd5000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container160258675791209317", + "blob": "blob160258675949705978", + "apendBlob": "apendBlob160258676008800186" + }, + "newDate": {} + }, + "hash": "f2b9dc8cfb8716ccc2d9f44b07f815c4" +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_lastaccessed_returned.json b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_lastaccessed_returned.json new file mode 100644 index 000000000000..b42681e5cf1a --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blobclient/recording_lastaccessed_returned.json @@ -0,0 +1,153 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 13 Oct 2020 10:59:21 GMT", + "etag": "\"0x8D86F670A996EC9\"", + "last-modified": "Tue, 13 Oct 2020 10:59:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "53c39fb5-b2ce-4c7e-96f0-ab5aafd741a8", + "x-ms-request-id": "f315110a-201e-0003-604f-a12bd5000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961/blob160258676244100095", + "query": {}, + "requestBody": "Hello World", + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "date": "Tue, 13 Oct 2020 10:59:22 GMT", + "etag": "\"0x8D86F670AF1AF8E\"", + "last-modified": "Tue, 13 Oct 2020 10:59:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "04c5f291-295c-49dd-b6bf-09f6b9c3b7a2", + "x-ms-content-crc64": "YeJLfssylmU=", + "x-ms-request-id": "f3151115-201e-0003-6a4f-a12bd5000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2020-02-10", + "x-ms-version-id": "2020-10-13T10:59:22.8851086Z" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961/blob160258676244100095", + "query": {}, + "requestBody": null, + "status": 200, + "response": "Hello World", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "content-type": "application/octet-stream", + "date": "Tue, 13 Oct 2020 10:59:23 GMT", + "etag": "\"0x8D86F670AF1AF8E\"", + "last-modified": "Tue, 13 Oct 2020 10:59:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "a3a9ede7-01c0-4ffc-9a59-e3e4b8e23475", + "x-ms-creation-time": "Tue, 13 Oct 2020 10:59:22 GMT", + "x-ms-is-current-version": "true", + "x-ms-last-access-time": "Tue, 13 Oct 2020 10:59:22 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "f3151124-201e-0003-744f-a12bd5000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2020-02-10", + "x-ms-version-id": "2020-10-13T10:59:22.8851086Z" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961/blob160258676244100095", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "content-type": "application/octet-stream", + "date": "Tue, 13 Oct 2020 10:59:23 GMT", + "etag": "\"0x8D86F670AF1AF8E\"", + "last-modified": "Tue, 13 Oct 2020 10:59:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "c5d8e171-f7b6-49e7-9818-214f850b0d0b", + "x-ms-creation-time": "Tue, 13 Oct 2020 10:59:22 GMT", + "x-ms-is-current-version": "true", + "x-ms-last-access-time": "Tue, 13 Oct 2020 10:59:23 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "f315113b-201e-0003-054f-a12bd5000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2020-02-10", + "x-ms-version-id": "2020-10-13T10:59:22.8851086Z" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961", + "query": { + "prefix": "blob160258676244100095", + "restype": "container", + "comp": "list" + }, + "requestBody": null, + "status": 200, + "response": "blob160258676244100095blob1602586762441000952020-10-13T10:59:22.8851086ZtrueTue, 13 Oct 2020 10:59:22 GMTTue, 13 Oct 2020 10:59:22 GMT0x8D86F670AF1AF8E11application/octet-streamsQqNsWTgdUEFt6mb5y4/5Q==Tue, 13 Oct 2020 10:59:23 GMTBlockBlobHottrueunlockedavailabletrue", + "responseHeaders": { + "content-type": "application/xml", + "date": "Tue, 13 Oct 2020 10:59:24 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "e430d15f-0fe4-4394-a635-da053b058fd7", + "x-ms-request-id": "f3151147-201e-0003-104f-a12bd5000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container160258676186503961", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 13 Oct 2020 10:59:24 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "bace8a2b-1a63-4d9d-aef6-532b61c3c08d", + "x-ms-request-id": "f3151158-201e-0003-214f-a12bd5000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container160258676186503961", + "blob": "blob160258676244100095" + }, + "newDate": {} + }, + "hash": "283bc4f8ed68a454b2f51eff55349ad8" +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container.json b/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container.json new file mode 100644 index 000000000000..9a29399a9caf --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container.json @@ -0,0 +1,88 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160126300203004421", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:16:42 GMT", + "etag": "\"0x8D8635CECF434C8\"", + "last-modified": "Mon, 28 Sep 2020 03:16:43 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "7c0f0296-e5ba-4378-94f8-0cd26bf48431", + "x-ms-request-id": "d3d39dc9-a01e-009c-5b45-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container160126300203004421", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:16:43 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "7972156d-5f50-4114-9931-567d33ca93f5", + "x-ms-request-id": "d3d39e17-a01e-009c-1c45-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/", + "query": { + "include": "deleted", + "comp": "list" + }, + "requestBody": null, + "status": 200, + "response": "container160126084293406905true01D69540C360196EMon, 28 Sep 2020 02:40:44 GMT\"0x8D86357E5D6E2D3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:40:44 GMT6container160126106381401561true01D6954159845195Mon, 28 Sep 2020 02:44:56 GMT\"0x8D863587BFB5C7E\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:45:17 GMT6container160126138854301057Mon, 28 Sep 2020 02:52:20 GMT\"0x8D8635984BFED93\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126156070606689true01D695426F2D1935Mon, 28 Sep 2020 02:52:41 GMT\"0x8D8635991A3D4C3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:52:42 GMT7container160126163636303463Mon, 28 Sep 2020 02:54:29 GMT\"0x8D86359D1773488\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126189495206143Mon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6B7F32AC\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126192762308290true01D695434939B1EDMon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6BB07DB9\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:58:48 GMT7container160126192762308290true01D695435B799FC5Mon, 28 Sep 2020 02:59:18 GMT\"0x8D8635A7DEFF0A5\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:59:18 GMT7container160126214436904243true01D69543CB1B180EMon, 28 Sep 2020 03:02:25 GMT\"0x8D8635AED911531\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:02:26 GMT7container160126287722103166Mon, 28 Sep 2020 03:15:09 GMT\"0x8D8635CB50497D2\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126300203004421true01D69545CA7E7E9CMon, 28 Sep 2020 03:16:43 GMT\"0x8D8635CECF434C8\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:16:44 GMT7newcontainer160126234811800748Mon, 28 Sep 2020 03:05:48 GMT\"0x8D8635B66537475\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248509809420Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB7F89648\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248544608083Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB82D9242\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126294120807116Mon, 28 Sep 2020 03:15:41 GMT\"0x8D8635CC7D518BB\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "responseHeaders": { + "content-type": "application/xml", + "date": "Mon, 28 Sep 2020 03:17:14 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "a3d9a31b-2880-449f-ad69-ae53b649ef29", + "x-ms-request-id": "d3d3c833-a01e-009c-3c45-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160126300203004421", + "query": { + "restype": "container", + "comp": "undelete" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:17:15 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b42ba986-c9c4-4f04-815a-f56eb374bbb1", + "x-ms-request-id": "d3d3c89e-a01e-009c-1845-95c3c0000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container160126300203004421" + }, + "newDate": {} + }, + "hash": "7d59403e2123de9b95b525b56a0cda54" +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container_to_a_new_name.json b/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container_to_a_new_name.json new file mode 100644 index 000000000000..d2997081c366 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/browsers/blobserviceclient/recording_restore_container_to_a_new_name.json @@ -0,0 +1,89 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/container160126303601800919", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:17:16 GMT", + "etag": "\"0x8D8635D0084A53B\"", + "last-modified": "Mon, 28 Sep 2020 03:17:16 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "ec494d63-76f5-4b2b-88ec-f61edfed2ce1", + "x-ms-request-id": "d3d3c929-a01e-009c-1645-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/container160126303601800919", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:17:17 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "712f2145-b924-42c4-8a07-0aea0e1df047", + "x-ms-request-id": "d3d3c98f-a01e-009c-6a45-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.blob.core.windows.net/", + "query": { + "include": "deleted", + "comp": "list" + }, + "requestBody": null, + "status": 200, + "response": "container160126084293406905true01D69540C360196EMon, 28 Sep 2020 02:40:44 GMT\"0x8D86357E5D6E2D3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:40:44 GMT6container160126106381401561true01D6954159845195Mon, 28 Sep 2020 02:44:56 GMT\"0x8D863587BFB5C7E\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:45:17 GMT6container160126138854301057Mon, 28 Sep 2020 02:52:20 GMT\"0x8D8635984BFED93\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126156070606689true01D695426F2D1935Mon, 28 Sep 2020 02:52:41 GMT\"0x8D8635991A3D4C3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:52:42 GMT7container160126163636303463Mon, 28 Sep 2020 02:54:29 GMT\"0x8D86359D1773488\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126189495206143Mon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6B7F32AC\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126192762308290true01D695434939B1EDMon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6BB07DB9\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:58:48 GMT7container160126192762308290true01D695435B799FC5Mon, 28 Sep 2020 02:59:18 GMT\"0x8D8635A7DEFF0A5\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:59:18 GMT7container160126214436904243true01D69543CB1B180EMon, 28 Sep 2020 03:02:25 GMT\"0x8D8635AED911531\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:02:26 GMT7container160126287722103166Mon, 28 Sep 2020 03:15:09 GMT\"0x8D8635CB50497D2\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126300203004421Mon, 28 Sep 2020 03:17:15 GMT\"0x8D8635D00226D98\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126303601800919true01D69545DE0DBF4DMon, 28 Sep 2020 03:17:16 GMT\"0x8D8635D0084A53B\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:17:17 GMT7newcontainer160126234811800748Mon, 28 Sep 2020 03:05:48 GMT\"0x8D8635B66537475\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248509809420Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB7F89648\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248544608083Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB82D9242\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126294120807116Mon, 28 Sep 2020 03:15:41 GMT\"0x8D8635CC7D518BB\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "responseHeaders": { + "content-type": "application/xml", + "date": "Mon, 28 Sep 2020 03:17:47 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "2ed4e528-ffe1-4c70-8630-ef20d593bdd4", + "x-ms-request-id": "d3d3df0a-a01e-009c-2845-95c3c0000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/newcontainer160126306811600750", + "query": { + "restype": "container", + "comp": "undelete" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Mon, 28 Sep 2020 03:17:48 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1b79c00c-fb02-4ad4-a65e-7724075ef673", + "x-ms-request-id": "d3d3df98-a01e-009c-2045-95c3c0000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "container": "container160126303601800919", + "newcontainer": "newcontainer160126306811600750" + }, + "newDate": {} + }, + "hash": "abb379982ab8a7e39f634206938e3b53" +} \ No newline at end of file diff --git a/sdk/storage/storage-blob/recordings/node/blobclient/recording_lastaccessed_returned.js b/sdk/storage/storage-blob/recordings/node/blobclient/recording_lastaccessed_returned.js new file mode 100644 index 000000000000..44894d8c8d9e --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobclient/recording_lastaccessed_returned.js @@ -0,0 +1,196 @@ +let nock = require('nock'); + +module.exports.hash = "554a9260d6af406d03e8b94e399b0b50"; + +module.exports.testInfo = {"uniqueName":{"container":"container160248070036307761","blob":"blob160248070171605025"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160248070036307761') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'ETag', + '"0x8D86E70197A483F"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be4576a-901e-0016-5558-a03c66000000', + 'x-ms-client-request-id', + '70237b34-ae1c-4f71-a825-fbe844fe537a', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 12 Oct 2020 05:31:41 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160248070036307761/blob160248070171605025', "Hello World") + .reply(201, "", [ + 'Content-Length', + '0', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'ETag', + '"0x8D86E7019AAC2FD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be45779-901e-0016-5958-a03c66000000', + 'x-ms-client-request-id', + '68e00b27-3a66-40cf-ad47-5447a9d90c7e', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'YeJLfssylmU=', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-version-id', + '2020-10-12T05:31:41.8939133Z', + 'Date', + 'Mon, 12 Oct 2020 05:31:41 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container160248070036307761/blob160248070171605025') + .reply(200, "Hello World", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D86E7019AAC2FD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be45781-901e-0016-6058-a03c66000000', + 'x-ms-client-request-id', + '4eea2cca-8a7f-4734-a27e-667b7fc3e456', + 'x-ms-version', + '2020-02-10', + 'x-ms-version-id', + '2020-10-12T05:31:41.8939133Z', + 'x-ms-is-current-version', + 'true', + 'x-ms-creation-time', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-last-access-time', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-version-id,x-ms-is-current-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,x-ms-last-access-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 12 Oct 2020 05:31:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/container160248070036307761/blob160248070171605025') + .reply(200, "", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D86E7019AAC2FD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be45789-901e-0016-6658-a03c66000000', + 'x-ms-client-request-id', + 'cc753c9e-80ce-4212-bbaa-aec051ec1cb9', + 'x-ms-version', + '2020-02-10', + 'x-ms-version-id', + '2020-10-12T05:31:41.8939133Z', + 'x-ms-is-current-version', + 'true', + 'x-ms-creation-time', + 'Mon, 12 Oct 2020 05:31:41 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + 'true', + 'x-ms-last-access-time', + 'Mon, 12 Oct 2020 05:31:42 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-version-id,x-ms-is-current-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,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,x-ms-last-access-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 12 Oct 2020 05:31:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/container160248070036307761') + .query(true) + .reply(200, "blob160248070171605025blob1602480701716050252020-10-12T05:31:41.8939133ZtrueMon, 12 Oct 2020 05:31:41 GMTMon, 12 Oct 2020 05:31:41 GMT0x8D86E7019AAC2FD11application/octet-streamsQqNsWTgdUEFt6mb5y4/5Q==Mon, 12 Oct 2020 05:31:42 GMTBlockBlobHottrueunlockedavailabletrue", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be45792-901e-0016-6d58-a03c66000000', + 'x-ms-client-request-id', + 'e6f76fa9-fe57-4fb5-a12f-c7f0cfdde992', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 12 Oct 2020 05:31:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160248070036307761') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6be4579b-901e-0016-7458-a03c66000000', + 'x-ms-client-request-id', + '834ad9e6-c56f-4681-8c2a-6876d8fd5a82', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 12 Oct 2020 05:31:43 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations.js b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations.js new file mode 100644 index 000000000000..c413bec53011 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations.js @@ -0,0 +1,123 @@ +let nock = require('nock'); + +module.exports.hash = "e29af77e299520ce36fecae9203c86a0"; + +module.exports.testInfo = {"uniqueName":{"container":"container160084451581307559","blob":"blob160084451748308902"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160084451581307559') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:01:57 GMT', + 'ETag', + '"0x8D85F8E8FAC3266"', + 'x-ms-request-id', + 'ff7752d8-501e-0005-2177-91eaf9000000', + 'x-ms-client-request-id', + 'c6105029-9e60-4acf-81e0-3d9eb4c8b8ba', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Wed, 23 Sep 2020 07:01:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160084451581307559/blob160084451748308902', "Hello World") + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:01:57 GMT', + 'ETag', + '"0x8D85F8E8FD825FA"', + 'x-ms-request-id', + 'ff7752dc-501e-0005-2277-91eaf9000000', + 'x-ms-client-request-id', + 'ae929343-963f-4594-a532-341e47cc78a7', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'YeJLfssylmU=', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Wed, 23 Sep 2020 07:01:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160084451581307559/blob160084451748308902', "100,200,300,400\n150,250,350,450\n") + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'v9C7YWQTetukQaGSOQcgRQ==', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:01:57 GMT', + 'ETag', + '"0x8D85F8E9003549C"', + 'x-ms-request-id', + 'ff7752dd-501e-0005-2377-91eaf9000000', + 'x-ms-client-request-id', + '1b596356-6e7b-465c-9ee8-c15725386c19', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'gema9E3+zEY=', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Wed, 23 Sep 2020 07:01:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/container160084451581307559/blob160084451748308902', "SQLselect * from BlobStoragearrowdecimalname42") + .query(true) + .reply(200, Buffer.from("4f626a0102166176726f2e736368656d61be1e5b0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e726573756c7444617461222c0a2020202022646f63223a2022486f6c647320726573756c74206461746120696e2074686520666f726d61742073706563696669656420666f72207468697320717565727920284353562c204a534f4e2c206574632e292e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202264617461222c0a20202020202020202274797065223a20226279746573220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e6572726f72222c0a2020202022646f63223a2022416e206572726f722074686174206f63637572726564207768696c652070726f63657373696e67207468652071756572792e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022666174616c222c0a20202020202020202274797065223a2022626f6f6c65616e222c0a202020202020202022646f63223a2022496620747275652c2074686973206572726f722070726576656e747320667572746865722071756572792070726f63657373696e672e20204d6f726520726573756c742064617461206d61792062652072657475726e65642c20627574207468657265206973206e6f2067756172616e746565207468617420616c6c206f6620746865206f726967696e616c20646174612077696c6c2062652070726f6365737365642e202049662066616c73652c2074686973206572726f7220646f6573206e6f742070726576656e7420667572746865722071756572792070726f63657373696e672e220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226e616d65222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a2022546865206e616d65206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226465736372697074696f6e222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a202241206465736372697074696f6e206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022706f736974696f6e222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520626c6f62206f666673657420617420776869636820746865206572726f72206f63637572726564220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e70726f6772657373222c0a2020202022646f63223a2022496e666f726d6174696f6e2061626f7574207468652070726f6772657373206f6620746865207175657279222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202262797465735363616e6e6564222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a2022546865206e756d626572206f6620627974657320746861742068617665206265656e207363616e6e6564220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e656e64222c0a2020202022646f63223a202253656e74206173207468652066696e616c206d657373616765206f662074686520726573706f6e73652c20696e6469636174696e67207468617420616c6c20726573756c74732068617665206265656e2073656e742e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d0a5d0a00ede8894823947843a9db686b39a1f2ae028604008004ffffffff800000001000000000000a000c000600050008000a000000000103000c000000080008000000040008000000040000000100000014000000100014000800060007000c000000100010000000000001072400000014000000040000000000000008000c0004000800080000000400000002000000040000006e616d650000000000000000ffffffff700000001000000000000a000e000600050008000a000000000303001000000000000a000c000000040008000a0000003000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000ede8894823947843a9db686b39a1f2ae02040000ede8894823947843a9db686b39a1f2ae028e01020116436c69656e744572726f726e4e756d626572206f6620636f6c756d6e7320696e2074686520726f7720646f6573206e6f74206d617463682074686520736368656d612e00ede8894823947843a9db686b39a1f2ae0206044040ede8894823947843a9db686b39a1f2ae02040640ede8894823947843a9db686b39a1f2ae", "hex"), [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'avro/binary', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:01:57 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D85F8E9003549C"', + 'x-ms-creation-time', + 'Wed, 23 Sep 2020 07:01:57 GMT', + 'x-ms-lease-state', + 'available', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-request-id', + 'ff7752de-501e-0005-2477-91eaf9000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3d3df40b-b46c-4834-9cc2-92acf74c1dd1', + 'Date', + 'Wed, 23 Sep 2020 07:01:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160084451581307559') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'x-ms-request-id', + 'ff7752df-501e-0005-2577-91eaf9000000', + 'x-ms-client-request-id', + 'dd172217-6cf1-4bb8-82c1-2f17bceecefc', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Wed, 23 Sep 2020 07:01:58 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations_for_timestampms.js b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations_for_timestampms.js new file mode 100644 index 000000000000..b94b3e8afb01 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_arrow_output_configurations_for_timestampms.js @@ -0,0 +1,123 @@ +let nock = require('nock'); + +module.exports.hash = "6dcc9746edd52180ffb83408ed333065"; + +module.exports.testInfo = {"uniqueName":{"container":"container160126471904604167","blob":"blob160126472072205618"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126471904604167') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:45:20 GMT', + 'ETag', + '"0x8D86360EC5038AA"', + 'x-ms-request-id', + '953eed2d-101e-0001-2549-950155000000', + 'x-ms-client-request-id', + '1de26084-09a0-4c10-8095-e322e79e6358', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:45:20 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126471904604167/blob160126472072205618', "Hello World") + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:45:20 GMT', + 'ETag', + '"0x8D86360EC7FF71D"', + 'x-ms-request-id', + '953eed31-101e-0001-2649-950155000000', + 'x-ms-client-request-id', + 'a1be0774-3c6c-4a3f-a34a-7a5105af80e4', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'YeJLfssylmU=', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Mon, 28 Sep 2020 03:45:20 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126471904604167/blob160126472072205618', "100,200,300,400\n150,250,350,450\n") + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'v9C7YWQTetukQaGSOQcgRQ==', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:45:21 GMT', + 'ETag', + '"0x8D86360ECB02EFC"', + 'x-ms-request-id', + '953eed32-101e-0001-2749-950155000000', + 'x-ms-client-request-id', + '94752325-c8e4-41ac-9924-461ecff2b9a8', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'gema9E3+zEY=', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Mon, 28 Sep 2020 03:45:20 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/container160126471904604167/blob160126472072205618', "SQLselect * from BlobStoragearrowtimestamp[ms]") + .query(true) + .reply(200, Buffer.from("4f626a0102166176726f2e736368656d61be1e5b0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e726573756c7444617461222c0a2020202022646f63223a2022486f6c647320726573756c74206461746120696e2074686520666f726d61742073706563696669656420666f72207468697320717565727920284353562c204a534f4e2c206574632e292e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202264617461222c0a20202020202020202274797065223a20226279746573220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e6572726f72222c0a2020202022646f63223a2022416e206572726f722074686174206f63637572726564207768696c652070726f63657373696e67207468652071756572792e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022666174616c222c0a20202020202020202274797065223a2022626f6f6c65616e222c0a202020202020202022646f63223a2022496620747275652c2074686973206572726f722070726576656e747320667572746865722071756572792070726f63657373696e672e20204d6f726520726573756c742064617461206d61792062652072657475726e65642c20627574207468657265206973206e6f2067756172616e746565207468617420616c6c206f6620746865206f726967696e616c20646174612077696c6c2062652070726f6365737365642e202049662066616c73652c2074686973206572726f7220646f6573206e6f742070726576656e7420667572746865722071756572792070726f63657373696e672e220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226e616d65222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a2022546865206e616d65206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226465736372697074696f6e222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a202241206465736372697074696f6e206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022706f736974696f6e222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520626c6f62206f666673657420617420776869636820746865206572726f72206f63637572726564220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e70726f6772657373222c0a2020202022646f63223a2022496e666f726d6174696f6e2061626f7574207468652070726f6772657373206f6620746865207175657279222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202262797465735363616e6e6564222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a2022546865206e756d626572206f6620627974657320746861742068617665206265656e207363616e6e6564220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e656e64222c0a2020202022646f63223a202253656e74206173207468652066696e616c206d657373616765206f662074686520726573706f6e73652c20696e6469636174696e67207468617420616c6c20726573756c74732068617665206265656e2073656e742e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d0a5d0a00c8de5ff1a9bfc040bace30a29b8861d102f60300f003ffffffff780000001000000000000a000c000600050008000a000000000103000c000000080008000000040008000000040000000100000014000000100014000800060007000c0000001000100000000000010a2000000014000000040000000000000000000600080006000600000000000100010000003100000000000000ffffffff700000001000000000000a000e000600050008000a000000000303001000000000000a000c000000040008000a0000003000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000c8de5ff1a9bfc040bace30a29b8861d102040000c8de5ff1a9bfc040bace30a29b8861d1028e01020116436c69656e744572726f726e4e756d626572206f6620636f6c756d6e7320696e2074686520726f7720646f6573206e6f74206d617463682074686520736368656d612e00c8de5ff1a9bfc040bace30a29b8861d10206044040c8de5ff1a9bfc040bace30a29b8861d102040640c8de5ff1a9bfc040bace30a29b8861d1", "hex"), [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'avro/binary', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:45:21 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D86360ECB02EFC"', + 'x-ms-creation-time', + 'Mon, 28 Sep 2020 03:45:20 GMT', + 'x-ms-lease-state', + 'available', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-request-id', + '953eed33-101e-0001-2849-950155000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '259e9e32-cca4-403d-b912-59aeb9522db9', + 'Date', + 'Mon, 28 Sep 2020 03:45:21 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160126471904604167') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'x-ms-request-id', + '4e5a5f6e-901e-0002-4e49-95f235000000', + 'x-ms-client-request-id', + '8521c0d3-c4f6-4417-82ab-29dee21f9340', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:45:22 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_conditional_tags.js b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_conditional_tags.js index 47dd2ad8fc01..c3961327f18c 100644 --- a/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_conditional_tags.js +++ b/sdk/storage/storage-blob/recordings/node/blobclient_nodejs_only/recording_query_should_work_with_conditional_tags.js @@ -1,62 +1,153 @@ let nock = require('nock'); -module.exports.hash = "35241ca13b2f0a4e39ac34a5c3703e44"; +module.exports.hash = "a3bb3d95026d53671b051ff1dbc68bc3"; -module.exports.testInfo = {"uniqueName":{"container":"container159549714446502477","blob":"blob159549714476903821"},"newDate":{}} +module.exports.testInfo = {"uniqueName":{"container":"container160231128647507275","blob":"blob160231128993209131"},"newDate":{}} nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container159549714446502477') + .put('/container160231128647507275') .query(true) .reply(201, "", [ 'Content-Length', '0', 'Last-Modified', - 'Thu, 23 Jul 2020 09:39:03 GMT', + 'Sat, 10 Oct 2020 06:28:09 GMT', 'ETag', - '"0x8D82EEC3C7D3E44"', + '"0x8D86CE5A82C7E31"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4bd01901-a01e-0020-3bd5-603607000000', + 'c2ea3acf-101e-000a-4cce-9ee917000000', 'x-ms-client-request-id', - '47ba7d87-1be4-49d1-9e7d-729c83f34cea', + '888c9721-f32b-436f-af73-3212c214b69a', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'Date', - 'Thu, 23 Jul 2020 09:39:03 GMT' + 'Sat, 10 Oct 2020 06:28:09 GMT' ]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container159549714446502477/blob159549714476903821', "Hello World") + .put('/container160231128647507275/blob160231128993209131', "Hello World") .reply(201, "", [ 'Content-Length', '0', 'Content-MD5', 'sQqNsWTgdUEFt6mb5y4/5Q==', 'Last-Modified', - 'Thu, 23 Jul 2020 09:39:03 GMT', + 'Sat, 10 Oct 2020 06:28:10 GMT', 'ETag', - '"0x8D82EEC3CAACDC0"', + '"0x8D86CE5A85F355F"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4bd0191b-a01e-0020-4cd5-603607000000', + 'c2ea3aea-101e-000a-60ce-9ee917000000', 'x-ms-client-request-id', - '8a480dc9-a495-462d-a8f9-376158b7f63d', + 'a67e344f-019b-4ded-9200-28331d0b1002', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'x-ms-content-crc64', 'YeJLfssylmU=', 'x-ms-request-server-encrypted', 'true', 'x-ms-version-id', - '2020-07-23T09:39:03.7911488Z', + '2020-10-10T06:28:10.1047647Z', 'Date', - 'Thu, 23 Jul 2020 09:39:03 GMT' + 'Sat, 10 Oct 2020 06:28:09 GMT' ]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/container159549714446502477') + .put('/container160231128647507275/blob160231128993209131', "100,200,300,400\n150,250,350,450\n") + .reply(201, "", [ + 'Content-Length', + '0', + 'Content-MD5', + 'v9C7YWQTetukQaGSOQcgRQ==', + 'Last-Modified', + 'Sat, 10 Oct 2020 06:28:10 GMT', + 'ETag', + '"0x8D86CE5A88ED98B"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c2ea3af6-101e-000a-68ce-9ee917000000', + 'x-ms-client-request-id', + 'e29665de-124e-4d79-a6a8-02603a0a2ad4', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'gema9E3+zEY=', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-version-id', + '2020-10-10T06:28:10.4179867Z', + 'Date', + 'Sat, 10 Oct 2020 06:28:10 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/container160231128647507275/blob160231128993209131', "SQLselect * from BlobStorage") + .query(true) + .reply(412, "\nConditionNotMetThe condition specified using HTTP conditional header(s) is not met.\nRequestId:c2ea3b02-101e-000a-72ce-9ee917000000\nTime:2020-10-10T06:28:10.8701764Z", [ + 'Content-Length', + '253', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-error-code', + 'ConditionNotMet', + 'x-ms-request-id', + 'c2ea3b02-101e-000a-72ce-9ee917000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'e39e1ad3-29f9-42ea-8596-79055ce9f35e', + 'Date', + 'Sat, 10 Oct 2020 06:28:10 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/container160231128647507275/blob160231128993209131', "SQLselect * from BlobStorage") + .query(true) + .reply(200, Buffer.from("4f626a0102166176726f2e736368656d61be1e5b0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e726573756c7444617461222c0a2020202022646f63223a2022486f6c647320726573756c74206461746120696e2074686520666f726d61742073706563696669656420666f72207468697320717565727920284353562c204a534f4e2c206574632e292e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202264617461222c0a20202020202020202274797065223a20226279746573220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e6572726f72222c0a2020202022646f63223a2022416e206572726f722074686174206f63637572726564207768696c652070726f63657373696e67207468652071756572792e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022666174616c222c0a20202020202020202274797065223a2022626f6f6c65616e222c0a202020202020202022646f63223a2022496620747275652c2074686973206572726f722070726576656e747320667572746865722071756572792070726f63657373696e672e20204d6f726520726573756c742064617461206d61792062652072657475726e65642c20627574207468657265206973206e6f2067756172616e746565207468617420616c6c206f6620746865206f726967696e616c20646174612077696c6c2062652070726f6365737365642e202049662066616c73652c2074686973206572726f7220646f6573206e6f742070726576656e7420667572746865722071756572792070726f63657373696e672e220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226e616d65222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a2022546865206e616d65206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226465736372697074696f6e222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a202241206465736372697074696f6e206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022706f736974696f6e222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520626c6f62206f666673657420617420776869636820746865206572726f72206f63637572726564220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e70726f6772657373222c0a2020202022646f63223a2022496e666f726d6174696f6e2061626f7574207468652070726f6772657373206f6620746865207175657279222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202262797465735363616e6e6564222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a2022546865206e756d626572206f6620627974657320746861742068617665206265656e207363616e6e6564220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e656e64222c0a2020202022646f63223a202253656e74206173207468652066696e616c206d657373616765206f662074686520726573706f6e73652c20696e6469636174696e67207468617420616c6c20726573756c74732068617665206265656e2073656e742e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d0a5d0a00f6f0565630435444a3385adf0c234b58024400403130302c3230302c3330302c3430300a3135302c3235302c3335302c3435300af6f0565630435444a3385adf0c234b580206044040f6f0565630435444a3385adf0c234b5802040640f6f0565630435444a3385adf0c234b58", "hex"), [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'avro/binary', + 'Last-Modified', + 'Sat, 10 Oct 2020 06:28:10 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D86CE5A88ED98B"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-creation-time', + 'Sat, 10 Oct 2020 06:28:10 GMT', + 'x-ms-lease-state', + 'available', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-version-id', + '2020-10-10T06:28:10.4179867Z', + 'x-ms-is-current-version', + 'true', + 'x-ms-request-id', + 'c2ea3b22-101e-000a-0cce-9ee917000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3c88599d-74ee-4d72-8a7e-6a70c4949155', + 'Date', + 'Sat, 10 Oct 2020 06:28:11 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160231128647507275') .query(true) .reply(202, "", [ 'Content-Length', @@ -64,11 +155,11 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4bd0192d-a01e-0020-58d5-603607000000', + 'c2ea3b6e-101e-000a-3bce-9ee917000000', 'x-ms-client-request-id', - 'd1882594-78ea-4b35-9b06-2fdf08723138', + '6146a5f7-41a5-44a1-9b66-0288507886c3', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'Date', - 'Thu, 23 Jul 2020 09:39:03 GMT' + 'Sat, 10 Oct 2020 06:28:12 GMT' ]); diff --git a/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container.js b/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container.js new file mode 100644 index 000000000000..9f719d617fb1 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container.js @@ -0,0 +1,87 @@ +let nock = require('nock'); + +module.exports.hash = "1a05718a0ff21b8797d5b152061afbea"; + +module.exports.testInfo = {"uniqueName":{"container":"container160126287722103166"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126287722103166') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:14:38 GMT', + 'ETag', + '"0x8D8635CA25BAEF0"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6bbe3-e01e-0024-0145-959806000000', + 'x-ms-client-request-id', + '2360d180-02e7-4905-ad11-755ff7bc749f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:14:37 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160126287722103166') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6bc0a-e01e-0024-1e45-959806000000', + 'x-ms-client-request-id', + 'c56253b3-3ac8-4eb6-a6a2-05b1b0b68dfd', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:14:38 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/') + .query(true) + .reply(200, "container160126084293406905true01D69540C360196EMon, 28 Sep 2020 02:40:44 GMT\"0x8D86357E5D6E2D3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:40:44 GMT6container160126106381401561true01D6954159845195Mon, 28 Sep 2020 02:44:56 GMT\"0x8D863587BFB5C7E\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:45:17 GMT7container160126138854301057Mon, 28 Sep 2020 02:52:20 GMT\"0x8D8635984BFED93\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126156070606689true01D695426F2D1935Mon, 28 Sep 2020 02:52:41 GMT\"0x8D8635991A3D4C3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:52:42 GMT7container160126163636303463Mon, 28 Sep 2020 02:54:29 GMT\"0x8D86359D1773488\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126189495206143Mon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6B7F32AC\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126192762308290true01D695434939B1EDMon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6BB07DB9\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:58:48 GMT7container160126192762308290true01D695435B799FC5Mon, 28 Sep 2020 02:59:18 GMT\"0x8D8635A7DEFF0A5\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:59:18 GMT7container160126214436904243true01D69543CB1B180EMon, 28 Sep 2020 03:02:25 GMT\"0x8D8635AED911531\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:02:26 GMT7container160126287722103166true01D695457FE6286FMon, 28 Sep 2020 03:14:38 GMT\"0x8D8635CA25BAEF0\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:14:38 GMT7newcontainer160126234811800748Mon, 28 Sep 2020 03:05:48 GMT\"0x8D8635B66537475\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248509809420Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB7F89648\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248544608083Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB82D9242\"unlockedavailable$account-encryption-keyfalsefalsefalse", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6d002-e01e-0024-4c45-959806000000', + 'x-ms-client-request-id', + 'e670009f-9c91-47e9-ae52-18e3663c0c14', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 28 Sep 2020 03:15:08 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126287722103166') + .query(true) + .reply(201, "", [ + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6d05e-e01e-0024-1d45-959806000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3a90c421-d61a-47ba-af6b-2b88ad37b77d', + 'Date', + 'Mon, 28 Sep 2020 03:15:09 GMT', + 'Content-Length', + '0' +]); diff --git a/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container_to_a_new_name.js b/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container_to_a_new_name.js new file mode 100644 index 000000000000..6ea93ac38201 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/blobserviceclient/recording_restore_container_to_a_new_name.js @@ -0,0 +1,87 @@ +let nock = require('nock'); + +module.exports.hash = "5bfeb55e47a68f2fc0cd9636c26ca427"; + +module.exports.testInfo = {"uniqueName":{"container":"container160126290998402953","newcontainer":"newcontainer160126294120807116"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160126290998402953') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Mon, 28 Sep 2020 03:15:10 GMT', + 'ETag', + '"0x8D8635CB538BE26"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6d09a-e01e-0024-4e45-959806000000', + 'x-ms-client-request-id', + 'd41f9461-ec86-457f-a59c-d8e160ee0f32', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:15:09 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160126290998402953') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6d0eb-e01e-0024-1945-959806000000', + 'x-ms-client-request-id', + '76bb088d-9d9a-413b-a6d2-c83beaace12e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 03:15:09 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .get('/') + .query(true) + .reply(200, "container160126084293406905true01D69540C360196EMon, 28 Sep 2020 02:40:44 GMT\"0x8D86357E5D6E2D3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:40:44 GMT6container160126106381401561true01D6954159845195Mon, 28 Sep 2020 02:44:56 GMT\"0x8D863587BFB5C7E\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:45:17 GMT7container160126138854301057Mon, 28 Sep 2020 02:52:20 GMT\"0x8D8635984BFED93\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126156070606689true01D695426F2D1935Mon, 28 Sep 2020 02:52:41 GMT\"0x8D8635991A3D4C3\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:52:42 GMT7container160126163636303463Mon, 28 Sep 2020 02:54:29 GMT\"0x8D86359D1773488\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126189495206143Mon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6B7F32AC\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126192762308290true01D695434939B1EDMon, 28 Sep 2020 02:58:47 GMT\"0x8D8635A6BB07DB9\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:58:48 GMT7container160126192762308290true01D695435B799FC5Mon, 28 Sep 2020 02:59:18 GMT\"0x8D8635A7DEFF0A5\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 02:59:18 GMT7container160126214436904243true01D69543CB1B180EMon, 28 Sep 2020 03:02:25 GMT\"0x8D8635AED911531\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:02:26 GMT7container160126287722103166Mon, 28 Sep 2020 03:15:09 GMT\"0x8D8635CB50497D2\"unlockedavailable$account-encryption-keyfalsefalsefalsecontainer160126290998402953true01D6954592C1FDF6Mon, 28 Sep 2020 03:15:10 GMT\"0x8D8635CB538BE26\"unlockedexpired$account-encryption-keyfalsefalsefalseMon, 28 Sep 2020 03:15:10 GMT7newcontainer160126234811800748Mon, 28 Sep 2020 03:05:48 GMT\"0x8D8635B66537475\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248509809420Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB7F89648\"unlockedavailable$account-encryption-keyfalsefalsefalsenewcontainer160126248544608083Mon, 28 Sep 2020 03:08:05 GMT\"0x8D8635BB82D9242\"unlockedavailable$account-encryption-keyfalsefalsefalse", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6f2ad-e01e-0024-7945-959806000000', + 'x-ms-client-request-id', + '1bad920a-73b3-4dee-809b-849d257e0a1e', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 28 Sep 2020 03:15:40 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/newcontainer160126294120807116') + .query(true) + .reply(201, "", [ + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'bbe6f33e-e01e-0024-7f45-959806000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1d198345-d9bb-4447-b270-79afa8f7d6e0', + 'Date', + 'Mon, 28 Sep 2020 03:15:40 GMT', + 'Content-Length', + '0' +]); diff --git a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob.js b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob.js index 072293b3700a..b4c3a006b8c4 100644 --- a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob.js +++ b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob.js @@ -1,73 +1,114 @@ let nock = require('nock'); -module.exports.testInfo = {"now":"2019-09-11T02:25:52.739Z","tmr":"2019-09-11T02:25:52.739Z","container":"container156816875324700414","blob":"blob156816875367207681"} +module.exports.hash = "4dd736c0146c2e8d3e14ef02e0b8fe19"; + +module.exports.testInfo = {"uniqueName":{"container":"container160258359833805473","blob":"blob160258359862402571"},"newDate":{"now":"2020-10-13T10:06:37.598Z","tmr":"2020-10-13T10:06:37.598Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzI5NywibmJmIjoxNjAyNTgzMjk3LCJleHAiOjE2MDI2Njk5OTcsImFpbyI6IkUyUmdZUGpDcnFiMHJ2TFgxOWZtRGJ1ME9IZzBBUT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJ1VXFQSnpUNVZrZUhjbWpKY2tNREFBIiwidmVyIjoiMS4wIn0.NiVOq6v527qlu3bv3_IaW1n9SdfNIF_vd19nxyUDobYGfKEixxpG9z_u5imn-w5gp0DfhYEkWaILy_u-sSg-uTp9L0MicQ8WWEnVYm9UAGOhoi3GSkDCmr2Im-7H5fKMziaLluqMSjkRnNNmw6d0RzC6xJoMKyYWEpX4IZxMVYF2mCIhVRIe3k3pHVXT6apU03-chbwhjsVVDaMfA6NBY84sFRJYVAH9ORp10KTidhaR9y0BqTt-r24wGPy0GaPRectGaJbLPFak2LTScx0ev7PRgNEiEVbCArVOox0egPC89UEgXMEhcrKgSo5ZhzrCSNgt0-rzeo9M-IFwp-aa1Q"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '278f4ab9-f934-4756-8772-68c972430300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AuiEYUa7F-tDoPpi7qpYXv900ISJAQAAAC1zF9cOAAAA; expires=Thu, 12-Nov-2020 10:06:38 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:06:37 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-09-11T01:25:52Z2019-09-12T02:25:52Z") + .post('/', "2020-10-13T09:06:37Z2020-10-14T10:06:37Z") .query(true) - .reply(200, "f27c2809-dfd7-4dbc-b5ed-b8b3b934133572f988bf-86f1-41af-91ab-2d7cd011db472019-09-11T01:25:52Z2019-09-12T02:25:52Zb2019-02-02hqY/U2XC1kOyEmo+ZmbM+3tIMpmDZselDd5RwskV4hY=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:06:37Z2020-10-14T10:06:37Zb2020-02-10pE9JqmX24mK5QH/NKgeCMtYAyjkxQ1ggkwfRmcz7vAw=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '8fec2faa-b01e-0009-3b48-687c72000000', + '12d9c5f6-601e-002d-4a48-a179c2000000', 'x-ms-client-request-id', - 'ac030ea9-54bb-4c57-8096-63954aa2cd32', + '0040906f-8e4b-4350-8373-2cb2be344b22', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:52 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:37 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875324700414') + .put('/container160258359833805473') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:53 GMT', + 'Tue, 13 Oct 2020 10:06:38 GMT', 'ETag', - '"0x8D7365F5EC589A0"', + '"0x8D86F5FACD140D1"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'fbedf712-701e-001f-3f48-68bdec000000', + '12d9c602-601e-002d-5248-a179c2000000', 'x-ms-client-request-id', - 'b48ef270-6dfc-4bef-90ce-fcd01f86e321', + 'af92bdee-a0ad-4a86-8e12-c6485eb4c48d', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:53 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:37 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875324700414/blob156816875367207681') - .reply(201, "", [ 'Content-Length', + .put('/container160258359833805473/blob160258359862402571') + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:54 GMT', + 'Tue, 13 Oct 2020 10:06:38 GMT', 'ETag', - '"0x8D7365F5F059B37"', + '"0x8D86F5FACFD9AC2"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'be46570b-201e-0007-4c48-689079000000', + '12d9c60b-601e-002d-5848-a179c2000000', 'x-ms-client-request-id', - '184d0e26-0f60-44bc-bf85-c02388286103', + '39da8265-8c00-410f-9f50-c5ab4d5f4a73', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-request-server-encrypted', 'true', + 'x-ms-version-id', + '2020-10-13T10:06:38.7802818Z', 'Date', - 'Wed, 11 Sep 2019 02:25:53 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:38 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .head('/container156816875324700414/blob156816875367207681') + .head('/container160258359833805473/blob160258359862402571') .query(true) - .reply(200, [], [ 'Cache-Control', + .reply(200, [], [ + 'Cache-Control', 'cache-control-override', 'Content-Length', '1024', @@ -78,23 +119,25 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Content-Language', 'content-language-override', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:54 GMT', + 'Tue, 13 Oct 2020 10:06:38 GMT', 'Accept-Ranges', 'bytes', 'ETag', - '"0x8D7365F5F059B37"', + '"0x8D86F5FACFD9AC2"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '7a372f6e-301e-003a-1148-68255f000000', + '12d9c629-601e-002d-6b48-a179c2000000', 'x-ms-client-request-id', - 'cc9a9614-40eb-457d-84bf-86044fb4dc5b', + '0708ddba-9c83-43d3-9891-684141b4e876', 'x-ms-version', - '2019-02-02', - 'x-ms-tag-count', - '0', + '2020-02-10', + 'x-ms-version-id', + '2020-10-13T10:06:38.7802818Z', + 'x-ms-is-current-version', + 'true', 'x-ms-creation-time', - 'Wed, 11 Sep 2019 02:25:54 GMT', + 'Tue, 13 Oct 2020 10:06:38 GMT', 'x-ms-lease-status', 'unlocked', 'x-ms-lease-state', @@ -107,31 +150,28 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'content-disposition-override', 'x-ms-server-encrypted', 'true', - 'x-ms-access-tier', - 'Cool', - 'x-ms-access-tier-inferred', - 'true', 'Access-Control-Expose-Headers', - 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-tag-count,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,Cache-Control,Content-Disposition,Content-Encoding,Content-Language,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-version-id,x-ms-is-current-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,Cache-Control,Content-Disposition,Content-Encoding,Content-Language,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:25:54 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:38 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/container156816875324700414') + .delete('/container160258359833805473') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'af58df1a-501e-0008-3d48-687d8f000000', + '12d9c635-601e-002d-7548-a179c2000000', 'x-ms-client-request-id', - '859be13a-cfcf-462c-83d5-539fefda6fa3', + '7e3e3c72-e1c4-4786-98d6-18262ab8a376', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:54 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:38 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_snapshot.js b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_snapshot.js index 67bfb84d08c3..41b27d220c49 100644 --- a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_snapshot.js +++ b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_snapshot.js @@ -1,98 +1,142 @@ let nock = require('nock'); -module.exports.testInfo = {"now":"2019-09-11T02:25:55.007Z","tmr":"2019-09-11T02:25:55.007Z","container":"container156816875550904052","blob":"blob156816875593106676"} +module.exports.hash = "3b306e0dbe654c15df49dd0c3ca1d177"; + +module.exports.testInfo = {"uniqueName":{"container":"container160258360024207047","blob":"blob160258360052609781"},"newDate":{"now":"2020-10-13T10:06:39.490Z","tmr":"2020-10-13T10:06:39.490Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzI5OSwibmJmIjoxNjAyNTgzMjk5LCJleHAiOjE2MDI2Njk5OTksImFpbyI6IkUyUmdZTERqVmc1NjRCcWhhYlpXK3RUcmJZWTJBQT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJFU0RzSXZnZzJrQ0VEWENURENZREFBIiwidmVyIjoiMS4wIn0.F15c63d7bZahRpel-4k2dAGx279ehjAhTGhY78bRw1sIBpjH-IcOY23ZeynUT2Q958JeHfXk2FMAmynxUbAaHVGFJx4rp-6-1rrQ4F57uhGKVQMkEwpIkMijEQ4kefYHUYYyuMhTI7rYfuWUDFkgTRkcGHh0TYlIlOS-yoF2O7Wb4OIiZoPrZeDS41ylDYU4farqhPpmLueIBrWr107Vm9RCbEpx5fR8OVUq8flEO5m6Qzgcz2066JHNDp33ZKatNSkVj0UIklwoPzNQoslVe3ne2dFF4EsqchNjam6t2xVdqTtGYvpkiOAsTsj2v6NtiJlA9miAc2ioQn8kemLBlA"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '22ec2011-20f8-40da-840d-70930c260300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=Ato6duSMdw1BnT8_rEQbOWZ00ISJAQAAAC9zF9cOAAAA; expires=Thu, 12-Nov-2020 10:06:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:06:39 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-09-11T01:25:55Z2019-09-12T02:25:55Z") + .post('/', "2020-10-13T09:06:39Z2020-10-14T10:06:39Z") .query(true) - .reply(200, "f27c2809-dfd7-4dbc-b5ed-b8b3b934133572f988bf-86f1-41af-91ab-2d7cd011db472019-09-11T01:25:55Z2019-09-12T02:25:55Zb2019-02-02N9/Xz1De2vslllh4212SglhEg+yEp1Z0ME4VrnNQl7c=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:06:39Z2020-10-14T10:06:39Zb2020-02-10qyO2Fbb+hypzmtYXilzghvJsY70OloarL+hzEriW5kk=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4849f6ec-201e-0048-5c48-685461000000', + '12d9c653-601e-002d-0f48-a179c2000000', 'x-ms-client-request-id', - '9383e084-943e-4cde-a2ae-0a9feb3363b2', + '5664c334-4bae-444e-9881-b05bb23695c0', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:54 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:39 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875550904052') + .put('/container160258360024207047') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:55 GMT', + 'Tue, 13 Oct 2020 10:06:40 GMT', 'ETag', - '"0x8D7365F601E24B1"', + '"0x8D86F5FADF3AEDE"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'd653b685-a01e-0034-6848-68c954000000', + '12d9c65a-601e-002d-1548-a179c2000000', 'x-ms-client-request-id', - '7d8da79a-6feb-4c32-bfa7-3da2decf42da', + '2fa2ae3f-df56-4d4e-890a-4785c07be4c0', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:55 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:39 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875550904052/blob156816875593106676') - .reply(201, "", [ 'Content-Length', + .put('/container160258360024207047/blob160258360052609781') + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:56 GMT', + 'Tue, 13 Oct 2020 10:06:40 GMT', 'ETag', - '"0x8D7365F605E6496"', + '"0x8D86F5FAE1F1E4F"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '25d8c36c-101e-002d-5e48-68e53c000000', + '12d9c662-601e-002d-1b48-a179c2000000', 'x-ms-client-request-id', - '184bd643-77a2-46f3-a397-b7759e2b1d87', + '4f668a6b-59af-42b3-ad76-101662a11e41', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-request-server-encrypted', 'true', + 'x-ms-version-id', + '2020-10-13T10:06:40.6776399Z', 'Date', - 'Wed, 11 Sep 2019 02:25:55 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:40 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875550904052/blob156816875593106676') + .put('/container160258360024207047/blob160258360052609781') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:56 GMT', + 'Tue, 13 Oct 2020 10:06:40 GMT', 'ETag', - '"0x8D7365F605E6496"', + '"0x8D86F5FAE1F1E4F"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '86b7cdf1-c01e-0049-4c48-68559c000000', + '12d9c66c-601e-002d-2548-a179c2000000', 'x-ms-client-request-id', - '168804f5-d398-44b1-baa4-a607c6f26d7f', + '4d5f618f-c25b-46ae-b3a6-3a8cbf70651b', 'x-ms-version', - '2019-02-02', + '2020-02-10', + 'x-ms-version-id', + '2020-10-13T10:06:40.9688452Z', 'x-ms-snapshot', - '2019-09-11T02:25:56.6989363Z', + '2020-10-13T10:06:40.9678452Z', 'x-ms-request-server-encrypted', 'false', 'Date', - 'Wed, 11 Sep 2019 02:25:56 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:40 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .head('/container156816875550904052/blob156816875593106676') + .head('/container160258360024207047/blob160258360052609781') .query(true) - .reply(200, [], [ 'Cache-Control', + .reply(200, [], [ + 'Cache-Control', 'cache-control-override', 'Content-Length', '1024', @@ -103,25 +147,21 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Content-Language', 'content-language-override', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:56 GMT', + 'Tue, 13 Oct 2020 10:06:40 GMT', 'Accept-Ranges', 'bytes', 'ETag', - '"0x8D7365F605E6496"', + '"0x8D86F5FAE1F1E4F"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'ed193b36-f01e-0005-1d48-689283000000', + '12d9c674-601e-002d-2d48-a179c2000000', 'x-ms-client-request-id', - '96236c8e-3e25-4bb0-b8e1-52d389bccede', + 'a87f964d-3d6a-4957-8384-8098675618cf', 'x-ms-version', - '2019-02-02', - 'x-ms-snapshot', - '2019-09-11T02:25:56.6989363Z', - 'x-ms-tag-count', - '0', + '2020-02-10', 'x-ms-creation-time', - 'Wed, 11 Sep 2019 02:25:56 GMT', + 'Tue, 13 Oct 2020 10:06:40 GMT', 'x-ms-blob-type', 'PageBlob', 'x-ms-blob-sequence-number', @@ -130,31 +170,28 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'content-disposition-override', 'x-ms-server-encrypted', 'true', - 'x-ms-access-tier', - 'Cool', - 'x-ms-access-tier-inferred', - 'true', 'Access-Control-Expose-Headers', - 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-snapshot,x-ms-tag-count,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-blob-type,x-ms-blob-sequence-number,Cache-Control,Content-Disposition,Content-Encoding,Content-Language,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-blob-type,x-ms-blob-sequence-number,Cache-Control,Content-Disposition,Content-Encoding,Content-Language,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:25:56 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:40 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/container156816875550904052') + .delete('/container160258360024207047') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '52e9b241-801e-0028-0748-681143000000', + '12d9c67d-601e-002d-3448-a179c2000000', 'x-ms-client-request-id', - '4328cdc3-df7a-4dc1-9ca7-30c1b5793336', + 'cd1deccb-77a9-4a2a-a67d-1eadc51dd996', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:57 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:40 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_version_delete.js b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_version_delete.js new file mode 100644 index 000000000000..7b48b8676324 --- /dev/null +++ b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_blob_version_delete.js @@ -0,0 +1,200 @@ +let nock = require('nock'); + +module.exports.hash = "f48afc31ecf8135871b78c61c64a42ff"; + +module.exports.testInfo = {"uniqueName":{"container":"container160258360169304951","blob":"blob160258360197803631"},"newDate":{"now":"2020-10-13T10:06:42.548Z","tmr":"2020-10-13T10:06:42.548Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160258360169304951') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:06:41 GMT', + 'ETag', + '"0x8D86F5FAED13EE5"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c68a-601e-002d-3f48-a179c2000000', + 'x-ms-client-request-id', + '40e3adc4-dbe8-42f1-b799-ad39fdec8a2e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:06:41 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160258360169304951/blob160258360197803631', "Hello World") + .reply(201, "", [ + 'Content-Length', + '0', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:06:42 GMT', + 'ETag', + '"0x8D86F5FAEFCD5AE"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c695-601e-002d-4948-a179c2000000', + 'x-ms-client-request-id', + '0e994334-0cc1-47d6-9a58-69bbaf7b2bfa', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'YeJLfssylmU=', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-version-id', + '2020-10-13T10:06:42.1306798Z', + 'Date', + 'Tue, 13 Oct 2020 10:06:41 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/container160258360169304951/blob160258360197803631') + .reply(201, "", [ + 'Content-Length', + '0', + 'Content-MD5', + '1B2M2Y8AsgTpgAmY7PhCfg==', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:06:42 GMT', + 'ETag', + '"0x8D86F5FAF28334C"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c6a0-601e-002d-5248-a179c2000000', + 'x-ms-client-request-id', + 'ea75103d-0e49-4857-8465-212cda76444f', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-crc64', + 'AAAAAAAAAAA=', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-version-id', + '2020-10-13T10:06:42.4158812Z', + 'Date', + 'Tue, 13 Oct 2020 10:06:41 GMT' +]); + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzMwMiwibmJmIjoxNjAyNTgzMzAyLCJleHAiOjE2MDI2NzAwMDIsImFpbyI6IkUyUmdZSWh1WEpNWnUzREQ3Yzl2TjY1ditOYXlHZ0E9IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJDQkRud19GZWxVYTUyYU90bVFZREFBIiwidmVyIjoiMS4wIn0.LSGiuWgAhDMxI8nH7rkr3lioGX_znbVoirvJhV3bB2LrROfFYcK3Rh4GX9XivmR29DzzNmVEh9E2MDgJekQltC1nl8C2dI9TwytLmQY3QruUmhJDY49Fpk5kLSiyFU8JHwSfafuw0-9yg6lTCtaFijfw8wSw6UmguojE_0dDQpx9rfsevMbfLikjTgngKBlzU-9JrF2ij7BrzsE1CdMqiAvz0wMbeU7wNubhnyFS0ztNeLgIERZ7T90H9UPgg0vnq58413Bx9ScefLMsvc9Yt-jcEacYHJcBfMFMMXC7Ggqbm3Cm0VjxnkjfN5d8dT6K4zzwf_iNFJ-xomrd_ix2Bw"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1318', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'c3e71008-5ef1-4695-b9d9-a3ad99060300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=Ava0SdkBQOVFnbye4SUfmoJ00ISJAQAAADJzF9cOAAAA; expires=Thu, 12-Nov-2020 10:06:42 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:06:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/', "2020-10-13T10:01:42Z2020-10-14T10:06:42Z") + .query(true) + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T10:01:42Z2020-10-14T10:06:42Zb2020-02-10Bwuwf457ctdtVCO4+PmcHUN1h4CrH6aUv8UrasHcJ0U=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c6bc-601e-002d-6d48-a179c2000000', + 'x-ms-client-request-id', + '8b45cddb-86cb-4523-b6be-52c08eab6d77', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:06:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160258360169304951/blob160258360197803631') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c6c0-601e-002d-7148-a179c2000000', + 'x-ms-client-request-id', + 'fcc2e3b0-91fd-42e1-a3ee-7c0f78e14d26', + 'x-ms-version', + '2020-02-10', + 'x-ms-delete-type-permanent', + 'false', + 'Date', + 'Tue, 13 Oct 2020 10:06:42 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/container160258360169304951/blob160258360197803631') + .query(true) + .reply(404, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c6cc-601e-002d-7c48-a179c2000000', + 'x-ms-client-request-id', + '05abaa3f-508f-46b0-8912-46f2cc505502', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'BlobNotFound', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-error-code,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Tue, 13 Oct 2020 10:06:43 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/container160258360169304951') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '12d9c6d3-601e-002d-0148-a179c2000000', + 'x-ms-client-request-id', + '1f17289d-45d5-4b87-b305-b47417c8c6d0', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:06:43 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_all_configurations.js b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_all_configurations.js index 7f321055b8d6..3f6b18f3b90f 100644 --- a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_all_configurations.js +++ b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_all_configurations.js @@ -1,83 +1,122 @@ let nock = require('nock'); -module.exports.testInfo = {"now":"2019-09-11T02:25:48.559Z","tmr":"2019-09-11T02:25:48.559Z","container":"container156816874945701355"} +module.exports.hash = "209dd93b01f0a4f09ea58ad8f79a8df9"; + +module.exports.testInfo = {"uniqueName":{"container":"container160258359458802685"},"newDate":{"now":"2020-10-13T10:06:32.882Z","tmr":"2020-10-13T10:06:32.882Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzI5MywibmJmIjoxNjAyNTgzMjkzLCJleHAiOjE2MDI2Njk5OTMsImFpbyI6IkUyUmdZRkE4V05yT1VMYlEyeUZBcE50OFV2TUdBQT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiI4OXNsLW9tX2kwaWw5VmJkazJnREFBIiwidmVyIjoiMS4wIn0.TNgnCUmQkGiE6S6ITKavyawjE2qEobLVvVYt0BWClVfN9WfXPkqKw_8ao01vCOklvCX3tgEsKHxnz8diobJXCy5tuUkndv--5YoP_cSJC1t7XkACTS4f5QkT39NGXOzvjYKMUs66bd2w75sRhiDYIZaKVmk2xF2xSa-vy0Zl63hNpir0J-xYkgOv4_OlFkxAdF1uAmu_nDeBoOF-Krunncwp9EPSjhp3Dx_HWveOeqngSq6kqHNNGqqPaTBYWE_yE9FE5-0KSSz3YwIktEegzZ2-_GTmZxzCivbxM6fOnigxGqR7-FRqYPEpb3D_Q-aUq0t5lG2kYxOExjqKkR9YVg"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'fa25dbf3-bf89-488b-a5f5-56dd93680300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AhuQkqzdmI1Aj6WUV_WToLh00ISJAQAAAChzF9cOAAAA; expires=Thu, 12-Nov-2020 10:06:33 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:06:33 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-09-11T01:25:48Z2019-09-12T02:25:48Z") + .post('/', "2020-10-13T09:06:32Z2020-10-14T10:06:32Z") .query(true) - .reply(200, "f27c2809-dfd7-4dbc-b5ed-b8b3b934133572f988bf-86f1-41af-91ab-2d7cd011db472019-09-11T01:25:48Z2019-09-12T02:25:48Zb2019-02-02cY7gYZN2XsFbkbcsMCRzh4tMtLFS8pMZZ/9Csh6QLbk=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:06:32Z2020-10-14T10:06:32Zb2020-02-10FQCuFbOZ/5DtsXgiO6py17X2cMP98cJ8nrJkj1JmZc0=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'd254a8cb-501e-0003-5648-6865fb000000', + '12d9c570-601e-002d-5b48-a179c2000000', 'x-ms-client-request-id', - 'e0ab9d62-2c68-4ff1-85c0-062b1cc895ea', + '5759edcf-476d-4ffd-b140-23738ee28074', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:49 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:33 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816874945701355') + .put('/container160258359458802685') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:49 GMT', + 'Tue, 13 Oct 2020 10:06:34 GMT', 'ETag', - '"0x8D7365F5C81FE79"', + '"0x8D86F5FAA95DC8E"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '84b980b5-401e-0017-4048-68a69f000000', + '12d9c586-601e-002d-6f48-a179c2000000', 'x-ms-client-request-id', - 'd3ea8b58-6fa3-4fe2-96fa-68c4fa8cd6ec', + '88b8bcf3-78f0-4b2e-9d0c-a5132a0b2443', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:49 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:34 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .get('/container156816874945701355') + .get('/container160258359458802685') .query(true) - .reply(200, "", [ 'Transfer-Encoding', + .reply(200, "", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '409350fe-f01e-0027-0a48-68fcb5000000', + '12d9c596-601e-002d-7b48-a179c2000000', 'x-ms-client-request-id', - '70a40051-1160-4d66-a490-b6eb658f14f3', + '5e315aa6-f9ef-471b-ac0c-43e9d9429220', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Access-Control-Expose-Headers', 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:25:49 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:34 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/container156816874945701355') + .delete('/container160258359458802685') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '2bc3cfb3-e01e-0038-1848-6827a5000000', + '12d9c5b3-601e-002d-1148-a179c2000000', 'x-ms-client-request-id', - '85ddae5f-6d85-4e9f-ae92-e1ef6b09d102', + '25623e98-2567-4375-aaae-eb228980080f', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:50 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:35 GMT' +]); diff --git a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_minimum_parameters.js b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_minimum_parameters.js index f7c7e965a1f4..7bed1bcfa97c 100644 --- a/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_minimum_parameters.js +++ b/sdk/storage/storage-blob/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_container_with_minimum_parameters.js @@ -1,83 +1,122 @@ let nock = require('nock'); -module.exports.testInfo = {"now":"2019-09-11T02:25:50.847Z","tmr":"2019-09-11T02:25:50.847Z","container":"container156816875142302139"} +module.exports.hash = "5c45c034633ef927b271c27527735d9b"; + +module.exports.testInfo = {"uniqueName":{"container":"container160258359673708257"},"newDate":{"now":"2020-10-13T10:06:35.980Z","tmr":"2020-10-13T10:06:35.980Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzI5NiwibmJmIjoxNjAyNTgzMjk2LCJleHAiOjE2MDI2Njk5OTYsImFpbyI6IkUyUmdZRkE4V05yT1VMYlEyeUZBcE50OFV2TUdBQT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJTcjlzY1lWbU9FYUNBVUsyMFdNREFBIiwidmVyIjoiMS4wIn0.pdSpuC2aEbgZNs5oN72PQIQ9ZoPiWlCTnS4k9MC0PCZp6tHZgkc5vVPcEbjLY5Iv7HZw7bgrVgEVw9Mh8kxlutqXsOsmDrudMVVZbeyf3S6rBW4cXKyqfigDgObUFq4OX2bCosMBw9eKip1aVmjICzJDWwCRKKS0pWN22h8FrU5XELGG3zEfW5eaAh8Ad_f9hIZZ7CUM1SmBCyzf9ykBjxcQ9DuoVmLJE9tWwSGbl2WGqO2TJHEwlodZNLY7mXu_DKLO6p-Y2jlho5w2QFLpq3xnNDu4X2wtVrjbyTJwadcP3z9oCEVuOt-a2RRzsPoPNG09CItqiMQg2OkH876Zew"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1318', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '716cbf4a-6685-4638-8201-42b6d1630300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AjMQ5a788ytDu8lFnFLviRB00ISJAQAAACxzF9cOAAAA; expires=Thu, 12-Nov-2020 10:06:36 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:06:35 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-09-11T01:25:50Z2019-09-12T02:25:50Z") + .post('/', "2020-10-13T09:06:35Z2020-10-14T10:06:35Z") .query(true) - .reply(200, "f27c2809-dfd7-4dbc-b5ed-b8b3b934133572f988bf-86f1-41af-91ab-2d7cd011db472019-09-11T01:25:50Z2019-09-12T02:25:50Zb2019-02-02pGs10MkrH+wkU8AdPq1yPqONmDnuqCZUZhcR3OIiQ7A=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:06:35Z2020-10-14T10:06:35Zb2020-02-10jpVWs5qOQ6MJmrr3S6bCtlYqOeju2ZKmRtDAjVbJdO0=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '49249512-901e-0015-4048-68a465000000', + '12d9c5d2-601e-002d-2d48-a179c2000000', 'x-ms-client-request-id', - '66f9710e-a584-4b04-8222-c24deccc69dd', + '39749911-55ba-4ce8-aa57-35768997d366', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:51 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:35 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/container156816875142302139') + .put('/container160258359673708257') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:25:51 GMT', + 'Tue, 13 Oct 2020 10:06:36 GMT', 'ETag', - '"0x8D7365F5DAE0D10"', + '"0x8D86F5FABDCC938"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'ed193294-f01e-0005-3a48-689283000000', + '12d9c5d5-601e-002d-3048-a179c2000000', 'x-ms-client-request-id', - '2e69cb38-02bf-4ff3-bb2f-99077f2453c0', + '15c8bca8-449f-44e6-82b8-e3b08ca4ccdd', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:51 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:36 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .get('/container156816875142302139') + .get('/container160258359673708257') .query(true) - .reply(200, "", [ 'Transfer-Encoding', + .reply(200, "", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '8bb9fc1c-601e-000b-0848-687e88000000', + '12d9c5dd-601e-002d-3548-a179c2000000', 'x-ms-client-request-id', - '13697b20-533e-4e99-9234-48a357a7b47c', + 'efe7ccee-7a1b-460b-9464-c07102c7453e', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Access-Control-Expose-Headers', 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:25:51 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:36 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/container156816875142302139') + .delete('/container160258359673708257') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'eba22c9f-d01e-003b-4d48-6824a2000000', + '12d9c5e6-601e-002d-3c48-a179c2000000', 'x-ms-client-request-id', - '858498d1-0d6c-4933-bffb-014444d6e76e', + '1b7bb074-2458-479e-ab5b-3e88c800c474', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:25:52 GMT' ]); - + 'Tue, 13 Oct 2020 10:06:36 GMT' +]); diff --git a/sdk/storage/storage-blob/review/storage-blob.api.md b/sdk/storage/storage-blob/review/storage-blob.api.md index 7d6a8079b1c1..6348bb28591d 100644 --- a/sdk/storage/storage-blob/review/storage-blob.api.md +++ b/sdk/storage/storage-blob/review/storage-blob.api.md @@ -527,6 +527,7 @@ export interface BlobDownloadHeaders { etag?: string; isSealed?: boolean; isServerEncrypted?: boolean; + lastAccessed?: Date; lastModified?: Date; leaseDuration?: LeaseDurationType; leaseState?: LeaseStateType; @@ -654,6 +655,7 @@ export interface BlobGetPropertiesHeaders { isIncrementalCopy?: boolean; isSealed?: boolean; isServerEncrypted?: boolean; + lastAccessed?: Date; lastModified?: Date; leaseDuration?: LeaseDurationType; leaseState?: LeaseStateType; @@ -868,6 +870,8 @@ export interface BlobProperties { // (undocumented) isSealed?: boolean; // (undocumented) + lastAccessedOn?: Date; + // (undocumented) lastModified: Date; leaseDuration?: LeaseDurationType; leaseState?: LeaseStateType; @@ -881,6 +885,23 @@ export interface BlobProperties { tagCount?: number; } +// @public +export interface BlobQueryArrowConfiguration { + kind: "arrow"; + schema: BlobQueryArrowField[]; +} + +// @public +export interface BlobQueryArrowField { + name?: string; + precision?: number; + scale?: number; + type: BlobQueryArrowFieldType; +} + +// @public +export type BlobQueryArrowFieldType = "int64" | "bool" | "timestamp[ms]" | "string" | "double" | "decimal"; + // @public export interface BlobQueryCsvTextConfiguration { columnSeparator?: string; @@ -1024,6 +1045,10 @@ export class BlobServiceClient extends StorageClient { getUserDelegationKey(startsOn: Date, expiresOn: Date, options?: ServiceGetUserDelegationKeyOptions): Promise; listContainers(options?: ServiceListContainersOptions): PagedAsyncIterableIterator; setProperties(properties: BlobServiceProperties, options?: ServiceSetPropertiesOptions): Promise; + undeleteContainer(deletedContainerName: string, deletedContainerVersion: string, options?: ServiceUndeleteContainerOptions): Promise<{ + containerClient: ContainerClient; + containerUndeleteResponse: ContainerUndeleteResponse; + }>; } // @public @@ -1355,7 +1380,7 @@ export interface BlockBlobQueryOptions extends CommonOptions { inputTextConfiguration?: BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration; onError?: (error: BlobQueryError) => void; onProgress?: (progress: TransferProgressEvent) => void; - outputTextConfiguration?: BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration; + outputTextConfiguration?: BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration | BlobQueryArrowConfiguration; } // @public @@ -1873,6 +1898,23 @@ export type ContainerSetMetadataResponse = ContainerSetMetadataHeaders & { }; }; +// @public +export interface ContainerUndeleteHeaders { + clientRequestId?: string; + date?: Date; + // (undocumented) + errorCode?: string; + requestId?: string; + version?: string; +} + +// @public +export type ContainerUndeleteResponse = ContainerUndeleteHeaders & { + _response: coreHttp.HttpResponse & { + parsedHeaders: ContainerUndeleteHeaders; + }; +}; + // @public export type CopyPollerBlobClient = Pick & { startCopyFromURL(copySource: string, options?: BlobStartCopyFromURLOptions): Promise; @@ -2725,6 +2767,7 @@ export type ServiceGetUserDelegationKeyResponse = UserDelegationKey & ServiceGet // @public export interface ServiceListContainersOptions extends CommonOptions { abortSignal?: AbortSignalLike; + includeDeleted?: boolean; includeMetadata?: boolean; prefix?: string; } @@ -2793,6 +2836,12 @@ export type ServiceSubmitBatchResponseModel = ServiceSubmitBatchHeaders & { }; }; +// @public +export interface ServiceUndeleteContainerOptions extends CommonOptions { + abortSignal?: AbortSignalLike; + destinationContainerName?: string; +} + // @public export interface SignedIdentifier { accessPolicy: { diff --git a/sdk/storage/storage-blob/sample.env b/sdk/storage/storage-blob/sample.env index 99294db65c63..4757365fc4d0 100644 --- a/sdk/storage/storage-blob/sample.env +++ b/sdk/storage/storage-blob/sample.env @@ -21,4 +21,10 @@ AZURE_CLIENT_SECRET= # Our tests assume that TEST_MODE is "playback" by default. You can # change it to "record" to generate new recordings, or "live" to bypass the recorder entirely. -# TEST_MODE=playback \ No newline at end of file +# TEST_MODE=playback + +# Optional, used for testing container soft delete. +SOFT_DELETE_ACCOUNT_NAME= +SOFT_DELETE_ACCOUNT_KEY= +SOFT_DELETE_STORAGE_CONNECTION_STRING= +SOFT_DELETE_ACCOUNT_SAS= diff --git a/sdk/storage/storage-blob/src/BlobDownloadResponse.ts b/sdk/storage/storage-blob/src/BlobDownloadResponse.ts index 88ffdb662741..c88dd35bcb50 100644 --- a/sdk/storage/storage-blob/src/BlobDownloadResponse.ts +++ b/sdk/storage/storage-blob/src/BlobDownloadResponse.ts @@ -388,6 +388,18 @@ export class BlobDownloadResponse implements BlobDownloadResponseParsed { return this.originalResponse.lastModified; } + /** + * Returns the UTC date and time generated by the service that indicates the time at which the blob was + * last read or written to. + * + * @readonly + * @type {(Date | undefined)} + * @memberof BlobDownloadResponse + */ + public get lastAccessed(): Date | undefined { + return this.originalResponse.lastAccessed; + } + /** * A name-value pair * to associate with a file storage object. diff --git a/sdk/storage/storage-blob/src/BlobSASSignatureValues.ts b/sdk/storage/storage-blob/src/BlobSASSignatureValues.ts index 5bcd0e00d71c..5e1a19576f83 100644 --- a/sdk/storage/storage-blob/src/BlobSASSignatureValues.ts +++ b/sdk/storage/storage-blob/src/BlobSASSignatureValues.ts @@ -311,10 +311,18 @@ export function generateBlobSASQueryParameters( if (sharedKeyCredential !== undefined) { return generateBlobSASQueryParameters20181109(blobSASSignatureValues, sharedKeyCredential); } else { - return generateBlobSASQueryParametersUDK20181109( - blobSASSignatureValues, - userDelegationKeyCredential! - ); + // Version 2020-02-10 delegation SAS signature construction includes preauthorizedAgentObjectId, agentObjectId, correlationId. + if (version >= "2020-02-10") { + return generateBlobSASQueryParametersUDK20200210( + blobSASSignatureValues, + userDelegationKeyCredential! + ); + } else { + return generateBlobSASQueryParametersUDK20181109( + blobSASSignatureValues, + userDelegationKeyCredential! + ); + } } } @@ -352,6 +360,8 @@ function generateBlobSASQueryParameters20150405( blobSASSignatureValues: BlobSASSignatureValues, sharedKeyCredential: StorageSharedKeyCredential ): SASQueryParameters { + blobSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill(blobSASSignatureValues); + if ( !blobSASSignatureValues.identifier && !blobSASSignatureValues.permissions && @@ -362,38 +372,13 @@ function generateBlobSASQueryParameters20150405( ); } - const version = blobSASSignatureValues.version ? blobSASSignatureValues.version : SERVICE_VERSION; let resource: string = "c"; - let verifiedPermissions: string | undefined; - - if (blobSASSignatureValues.snapshotTime) { - throw RangeError("'version' must be >= '2018-11-09' when provided 'snapshotTime'."); - } - - if (blobSASSignatureValues.versionId) { - throw RangeError("'version' must be >= '2019-10-10' when provided 'versionId'."); - } - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.deleteVersion && - version < "2019-10-10" - ) { - throw RangeError("'version' must be >= '2019-10-10' when provided 'x' permission."); - } - - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.tag && - version < "2019-12-12" - ) { - throw RangeError("'version' must be >= '2019-12-12' when provided 't' permission."); - } - if (blobSASSignatureValues.blobName) { resource = "b"; } // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (blobSASSignatureValues.permissions) { if (blobSASSignatureValues.blobName) { verifiedPermissions = BlobSASPermissions.parse( @@ -423,7 +408,7 @@ function generateBlobSASQueryParameters20150405( blobSASSignatureValues.identifier, blobSASSignatureValues.ipRange ? ipRangeToString(blobSASSignatureValues.ipRange) : "", blobSASSignatureValues.protocol ? blobSASSignatureValues.protocol : "", - version, + blobSASSignatureValues.version, blobSASSignatureValues.cacheControl ? blobSASSignatureValues.cacheControl : "", blobSASSignatureValues.contentDisposition ? blobSASSignatureValues.contentDisposition : "", blobSASSignatureValues.contentEncoding ? blobSASSignatureValues.contentEncoding : "", @@ -434,7 +419,7 @@ function generateBlobSASQueryParameters20150405( const signature = sharedKeyCredential.computeHMACSHA256(stringToSign); return new SASQueryParameters( - version, + blobSASSignatureValues.version!, signature, verifiedPermissions, undefined, @@ -474,6 +459,8 @@ function generateBlobSASQueryParameters20181109( blobSASSignatureValues: BlobSASSignatureValues, sharedKeyCredential: StorageSharedKeyCredential ): SASQueryParameters { + blobSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill(blobSASSignatureValues); + if ( !blobSASSignatureValues.identifier && !blobSASSignatureValues.permissions && @@ -484,37 +471,7 @@ function generateBlobSASQueryParameters20181109( ); } - const version = blobSASSignatureValues.version ? blobSASSignatureValues.version : SERVICE_VERSION; let resource: string = "c"; - let verifiedPermissions: string | undefined; - - if (blobSASSignatureValues.versionId && version < "2019-10-10") { - throw RangeError("'version' must be >= '2019-10-10' when provided 'versionId'."); - } - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.deleteVersion && - version < "2019-10-10" - ) { - throw RangeError("'version' must be >= '2019-10-10' when provided 'x' permission."); - } - - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.tag && - version < "2019-12-12" - ) { - throw RangeError("'version' must be >= '2019-12-12' when provided 't' permission."); - } - - if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.snapshotTime) { - throw RangeError("Must provide 'blobName' when provided 'snapshotTime'."); - } - - if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.versionId) { - throw RangeError("Must provide 'blobName' when provided 'versionId'."); - } - let timestamp = blobSASSignatureValues.snapshotTime; if (blobSASSignatureValues.blobName) { resource = "b"; @@ -527,6 +484,7 @@ function generateBlobSASQueryParameters20181109( } // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (blobSASSignatureValues.permissions) { if (blobSASSignatureValues.blobName) { verifiedPermissions = BlobSASPermissions.parse( @@ -556,7 +514,7 @@ function generateBlobSASQueryParameters20181109( blobSASSignatureValues.identifier, blobSASSignatureValues.ipRange ? ipRangeToString(blobSASSignatureValues.ipRange) : "", blobSASSignatureValues.protocol ? blobSASSignatureValues.protocol : "", - version, + blobSASSignatureValues.version, resource, timestamp, blobSASSignatureValues.cacheControl ? blobSASSignatureValues.cacheControl : "", @@ -569,7 +527,7 @@ function generateBlobSASQueryParameters20181109( const signature = sharedKeyCredential.computeHMACSHA256(stringToSign); return new SASQueryParameters( - version, + blobSASSignatureValues.version!, signature, verifiedPermissions, undefined, @@ -595,7 +553,7 @@ function generateBlobSASQueryParameters20181109( * Creates an instance of SASQueryParameters. * * Only accepts required settings needed to create a SAS. For optional settings please - * set corresponding properties directly, such as permissions, startsOn and identifier. + * set corresponding properties directly, such as permissions, startsOn. * * WARNING: identifier will be ignored, permissions and expiresOn are required. * @@ -607,44 +565,128 @@ function generateBlobSASQueryParametersUDK20181109( blobSASSignatureValues: BlobSASSignatureValues, userDelegationKeyCredential: UserDelegationKeyCredential ): SASQueryParameters { + blobSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill(blobSASSignatureValues); + + // Stored access policies are not supported for a user delegation SAS. if (!blobSASSignatureValues.permissions || !blobSASSignatureValues.expiresOn) { throw new RangeError( "Must provide 'permissions' and 'expiresOn' for Blob SAS generation when generating user delegation SAS." ); } - const version = blobSASSignatureValues.version ? blobSASSignatureValues.version : SERVICE_VERSION; - - if (blobSASSignatureValues.versionId && version < "2019-10-10") { - throw RangeError("'version' must be >= '2019-10-10' when provided 'versionId'."); - } - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.deleteVersion && - version < "2019-10-10" - ) { - throw RangeError("'version' must be >= '2019-10-10' when provided 'x' permission."); + let resource: string = "c"; + let timestamp = blobSASSignatureValues.snapshotTime; + if (blobSASSignatureValues.blobName) { + resource = "b"; + if (blobSASSignatureValues.snapshotTime) { + resource = "bs"; + } else if (blobSASSignatureValues.versionId) { + resource = "bv"; + timestamp = blobSASSignatureValues.versionId; + } } - if ( - blobSASSignatureValues.permissions && - blobSASSignatureValues.permissions.tag && - version < "2019-12-12" - ) { - throw RangeError("'version' must be >= '2019-12-12' when provided 't' permission."); + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; + if (blobSASSignatureValues.permissions) { + if (blobSASSignatureValues.blobName) { + verifiedPermissions = BlobSASPermissions.parse( + blobSASSignatureValues.permissions.toString() + ).toString(); + } else { + verifiedPermissions = ContainerSASPermissions.parse( + blobSASSignatureValues.permissions.toString() + ).toString(); + } } - let resource: string = "c"; - let verifiedPermissions: string | undefined; + // Signature is generated on the un-url-encoded values. + const stringToSign = [ + verifiedPermissions ? verifiedPermissions : "", + blobSASSignatureValues.startsOn + ? truncatedISO8061Date(blobSASSignatureValues.startsOn, false) + : "", + blobSASSignatureValues.expiresOn + ? truncatedISO8061Date(blobSASSignatureValues.expiresOn, false) + : "", + getCanonicalName( + userDelegationKeyCredential.accountName, + blobSASSignatureValues.containerName, + blobSASSignatureValues.blobName + ), + userDelegationKeyCredential.userDelegationKey.signedObjectId, + userDelegationKeyCredential.userDelegationKey.signedTenantId, + userDelegationKeyCredential.userDelegationKey.signedStartsOn + ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedStartsOn, false) + : "", + userDelegationKeyCredential.userDelegationKey.signedExpiresOn + ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedExpiresOn, false) + : "", + userDelegationKeyCredential.userDelegationKey.signedService, + userDelegationKeyCredential.userDelegationKey.signedVersion, + blobSASSignatureValues.ipRange ? ipRangeToString(blobSASSignatureValues.ipRange) : "", + blobSASSignatureValues.protocol ? blobSASSignatureValues.protocol : "", + blobSASSignatureValues.version, + resource, + timestamp, + blobSASSignatureValues.cacheControl, + blobSASSignatureValues.contentDisposition, + blobSASSignatureValues.contentEncoding, + blobSASSignatureValues.contentLanguage, + blobSASSignatureValues.contentType + ].join("\n"); - if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.snapshotTime) { - throw RangeError("Must provide 'blobName' when provided 'snapshotTime'."); - } + const signature = userDelegationKeyCredential.computeHMACSHA256(stringToSign); + return new SASQueryParameters( + blobSASSignatureValues.version!, + signature, + verifiedPermissions, + undefined, + undefined, + blobSASSignatureValues.protocol, + blobSASSignatureValues.startsOn, + blobSASSignatureValues.expiresOn, + blobSASSignatureValues.ipRange, + blobSASSignatureValues.identifier, + resource, + blobSASSignatureValues.cacheControl, + blobSASSignatureValues.contentDisposition, + blobSASSignatureValues.contentEncoding, + blobSASSignatureValues.contentLanguage, + blobSASSignatureValues.contentType, + userDelegationKeyCredential.userDelegationKey + ); +} - if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.versionId) { - throw RangeError("Must provide 'blobName' when provided 'versionId'."); +/** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * IMPLEMENTATION FOR API VERSION FROM 2020-02-10. + * + * Creates an instance of SASQueryParameters. + * + * Only accepts required settings needed to create a SAS. For optional settings please + * set corresponding properties directly, such as permissions, startsOn. + * + * WARNING: identifier will be ignored, permissions and expiresOn are required. + * + * @param {BlobSASSignatureValues} blobSASSignatureValues + * @param {UserDelegationKeyCredential} userDelegationKeyCredential + * @returns {SASQueryParameters} + */ +function generateBlobSASQueryParametersUDK20200210( + blobSASSignatureValues: BlobSASSignatureValues, + userDelegationKeyCredential: UserDelegationKeyCredential +): SASQueryParameters { + blobSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill(blobSASSignatureValues); + + // Stored access policies are not supported for a user delegation SAS. + if (!blobSASSignatureValues.permissions || !blobSASSignatureValues.expiresOn) { + throw new RangeError( + "Must provide 'permissions' and 'expiresOn' for Blob SAS generation when generating user delegation SAS." + ); } + let resource: string = "c"; let timestamp = blobSASSignatureValues.snapshotTime; if (blobSASSignatureValues.blobName) { resource = "b"; @@ -657,6 +699,7 @@ function generateBlobSASQueryParametersUDK20181109( } // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (blobSASSignatureValues.permissions) { if (blobSASSignatureValues.blobName) { verifiedPermissions = BlobSASPermissions.parse( @@ -693,9 +736,12 @@ function generateBlobSASQueryParametersUDK20181109( : "", userDelegationKeyCredential.userDelegationKey.signedService, userDelegationKeyCredential.userDelegationKey.signedVersion, + undefined, // preauthorizedAgentObjectId + undefined, // agentObjectId + undefined, // correlationId blobSASSignatureValues.ipRange ? ipRangeToString(blobSASSignatureValues.ipRange) : "", blobSASSignatureValues.protocol ? blobSASSignatureValues.protocol : "", - version, + blobSASSignatureValues.version, resource, timestamp, blobSASSignatureValues.cacheControl, @@ -706,9 +752,8 @@ function generateBlobSASQueryParametersUDK20181109( ].join("\n"); const signature = userDelegationKeyCredential.computeHMACSHA256(stringToSign); - return new SASQueryParameters( - version, + blobSASSignatureValues.version!, signature, verifiedPermissions, undefined, @@ -737,3 +782,41 @@ function getCanonicalName(accountName: string, containerName: string, blobName?: } return elements.join(""); } + +function SASSignatureValuesSanityCheckAndAutofill( + blobSASSignatureValues: BlobSASSignatureValues +): BlobSASSignatureValues { + const version = blobSASSignatureValues.version ? blobSASSignatureValues.version : SERVICE_VERSION; + if (blobSASSignatureValues.snapshotTime && version < "2018-11-09") { + throw RangeError("'version' must be >= '2018-11-09' when providing 'snapshotTime'."); + } + if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.snapshotTime) { + throw RangeError("Must provide 'blobName' when providing 'snapshotTime'."); + } + + if (blobSASSignatureValues.versionId && version < "2019-10-10") { + throw RangeError("'version' must be >= '2019-10-10' when providing 'versionId'."); + } + if (blobSASSignatureValues.blobName === undefined && blobSASSignatureValues.versionId) { + throw RangeError("Must provide 'blobName' when providing 'versionId'."); + } + + if ( + blobSASSignatureValues.permissions && + blobSASSignatureValues.permissions.deleteVersion && + version < "2019-10-10" + ) { + throw RangeError("'version' must be >= '2019-10-10' when providing 'x' permission."); + } + + if ( + blobSASSignatureValues.permissions && + blobSASSignatureValues.permissions.tag && + version < "2019-12-12" + ) { + throw RangeError("'version' must be >= '2019-12-12' when providing 't' permission."); + } + + blobSASSignatureValues.version = version; + return blobSASSignatureValues; +} diff --git a/sdk/storage/storage-blob/src/BlobServiceClient.ts b/sdk/storage/storage-blob/src/BlobServiceClient.ts index c82d612a11d8..4b23c429c95d 100644 --- a/sdk/storage/storage-blob/src/BlobServiceClient.ts +++ b/sdk/storage/storage-blob/src/BlobServiceClient.ts @@ -23,9 +23,10 @@ import { ListContainersIncludeType, UserDelegationKeyModel, ServiceFindBlobsByTagsSegmentResponse, - FilterBlobItem + FilterBlobItem, + ContainerUndeleteResponse } from "./generatedModels"; -import { Service } from "./generated/src/operations"; +import { Container, Service } from "./generated/src/operations"; import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; import { ContainerClient, ContainerCreateOptions, ContainerDeleteMethodOptions } from "./Clients"; import { appendToURLPath, extractConnectionStringParts } from "./utils/utils.common"; @@ -213,6 +214,14 @@ export interface ServiceListContainersOptions extends CommonOptions { * should be returned as part of the response body. */ includeMetadata?: boolean; + + /** + * Specifies whether soft deleted containers should be included in the response. + * + * @type {boolean} + * @memberof ServiceListContainersOptions + */ + includeDeleted?: boolean; } /** @@ -313,6 +322,31 @@ export declare type ServiceGetUserDelegationKeyResponse = UserDelegationKey & }; }; +/** + * Options to configure {@link BlobServiceClient.undeleteContainer} operation. + * + * @export + * @interface ServiceUndeleteContainerOptions + */ +export interface ServiceUndeleteContainerOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ServiceUndeleteContainerOptions + */ + abortSignal?: AbortSignalLike; + /** + * Optional. Specifies the new name of the restored container. + * Will use its original name if this is not specified. + * + * @type {string} + * @memberof ServiceUndeleteContainerOptions + */ + destinationContainerName?: string; +} + /** * A BlobServiceClient represents a Client to the Azure Storage Blob service allowing you * to manipulate blob containers. @@ -538,6 +572,51 @@ export class BlobServiceClient extends StorageClient { } } + /** + * Restore a previously deleted Blob container. + * This API is only functional if Container Soft Delete is enabled for the storage account associated with the container. + * + * @param {string} deletedContainerName Name of the previously deleted container. + * @param {string} deletedContainerVersion Version of the previously deleted container, used to uniquely identify the deleted container. + * @returns {Promise} Container deletion response. + * @memberof BlobServiceClient + */ + public async undeleteContainer( + deletedContainerName: string, + deletedContainerVersion: string, + options: ServiceUndeleteContainerOptions = {} + ): Promise<{ + containerClient: ContainerClient; + containerUndeleteResponse: ContainerUndeleteResponse; + }> { + const { span, spanOptions } = createSpan( + "BlobServiceClient-undeleteContainer", + options.tracingOptions + ); + try { + const containerClient = this.getContainerClient( + options.destinationContainerName || deletedContainerName + ); + // Hack to access a protected member. + const containerContext = new Container(containerClient["storageClientContext"]); + const containerUndeleteResponse = await containerContext.restore({ + deletedContainerName, + deletedContainerVersion, + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { containerClient, containerUndeleteResponse }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + /** * Gets the properties of a storage account’s Blob service, including properties * for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. @@ -1071,10 +1150,19 @@ export class BlobServiceClient extends StorageClient { if (options.prefix === "") { options.prefix = undefined; } + + const include: ListContainersIncludeType[] = []; + if (options.includeDeleted) { + include.push("deleted"); + } + if (options.includeMetadata) { + include.push("metadata"); + } + // AsyncIterableIterator to iterate over containers const listSegmentOptions: ServiceListContainersSegmentOptions = { ...options, - ...(options.includeMetadata ? { include: "metadata" } : {}) + ...(include.length > 0 ? { include } : {}) }; const iter = this.listItems(listSegmentOptions); diff --git a/sdk/storage/storage-blob/src/Clients.ts b/sdk/storage/storage-blob/src/Clients.ts index 691574528bde..38f9731f3246 100644 --- a/sdk/storage/storage-blob/src/Clients.ts +++ b/sdk/storage/storage-blob/src/Clients.ts @@ -102,7 +102,8 @@ import { TagConditions, MatchConditions, ModificationConditions, - ModifiedAccessConditions + ModifiedAccessConditions, + BlobQueryArrowField } from "./models"; import { PageBlobGetPageRangesDiffResponse, @@ -3307,6 +3308,30 @@ export interface BlobQueryCsvTextConfiguration { hasHeaders?: boolean; } +/** + * Options to query blob with Apache Arrow format. Only valid for {@link BlockBlobQueryOptions.outputTextConfiguration}. + * + * @export + * @interface BlobQueryArrowConfiguration + */ +export interface BlobQueryArrowConfiguration { + /** + * Kind. + * + * @type {"arrow"} + * @memberof BlobQueryArrowConfiguration + */ + kind: "arrow"; + + /** + * List of {@link BlobQueryArrowField} describing the schema of the data. + * + * @type {BlobQueryArrowField[]} + * @memberof BlobQueryArrowConfiguration + */ + schema: BlobQueryArrowField[]; +} + /** * Options to configure {@link BlockBlobClient.query} operation. * @@ -3332,10 +3357,13 @@ export interface BlockBlobQueryOptions extends CommonOptions { /** * Configurations for the query output. * - * @type {BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration} + * @type {BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration| BlobQueryArrowConfiguration} * @memberof BlockBlobQueryOptions */ - outputTextConfiguration?: BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration; + outputTextConfiguration?: + | BlobQueryJsonTextConfiguration + | BlobQueryCsvTextConfiguration + | BlobQueryArrowConfiguration; /** * Callback to receive events on the progress of query operation. * diff --git a/sdk/storage/storage-blob/src/generated/src/models/blobMappers.ts b/sdk/storage/storage-blob/src/generated/src/models/blobMappers.ts index 00356c263890..6155de6204df 100644 --- a/sdk/storage/storage-blob/src/generated/src/models/blobMappers.ts +++ b/sdk/storage/storage-blob/src/generated/src/models/blobMappers.ts @@ -7,6 +7,8 @@ */ export { + ArrowConfiguration, + ArrowField, BlobAbortCopyFromURLHeaders, BlobAcquireLeaseHeaders, BlobBreakLeaseHeaders, diff --git a/sdk/storage/storage-blob/src/generated/src/models/index.ts b/sdk/storage/storage-blob/src/generated/src/models/index.ts index f54c9b83bc3d..d0aca286eb05 100644 --- a/sdk/storage/storage-blob/src/generated/src/models/index.ts +++ b/sdk/storage/storage-blob/src/generated/src/models/index.ts @@ -185,6 +185,7 @@ export interface BlobPropertiesInternal { * Possible values include: 'High', 'Standard' */ rehydratePriority?: RehydratePriority; + lastAccessedOn?: Date; } /** @@ -374,6 +375,23 @@ export interface JsonTextConfiguration { recordSeparator: string; } +/** + * field of an arrow schema + */ +export interface ArrowField { + type: string; + name?: string; + precision?: number; + scale?: number; +} + +/** + * arrow configuration + */ +export interface ArrowConfiguration { + schema: ArrowField[]; +} + /** * An enumeration of containers */ @@ -542,11 +560,12 @@ export interface PageList { */ export interface QueryFormat { /** - * Possible values include: 'delimited', 'json' + * Possible values include: 'delimited', 'json', 'arrow' */ type?: QueryFormatType; delimitedTextConfiguration?: DelimitedTextConfiguration; jsonTextConfiguration?: JsonTextConfiguration; + arrowConfiguration?: ArrowConfiguration; } /** @@ -1195,12 +1214,12 @@ export interface ContainerRestoreOptionalParams extends coreHttp.RequestOptionsB */ requestId?: string; /** - * Optional. Version 2019-12-12 and laster. Specifies the name of the deleted container to + * Optional. Version 2019-12-12 and later. Specifies the name of the deleted container to * restore. */ deletedContainerName?: string; /** - * Optional. Version 2019-12-12 and laster. Specifies the version of the deleted container to + * Optional. Version 2019-12-12 and later. Specifies the version of the deleted container to * restore. */ deletedContainerVersion?: string; @@ -4526,6 +4545,11 @@ export interface BlobDownloadHeaders { * If this blob has been sealed */ isSealed?: boolean; + /** + * UTC date/time value generated by the service that indicates the time at which the blob was + * last read or written to + */ + lastAccessed?: Date; /** * If the request is to read a specified range and the x-ms-range-get-content-crc64 is set to * true, then the request returns a crc64 for the range, as long as the range size is less than @@ -4771,6 +4795,11 @@ export interface BlobGetPropertiesHeaders { * rehydrate. Possible values include: 'High', 'Standard' */ rehydratePriority?: RehydratePriority; + /** + * UTC date/time value generated by the service that indicates the time at which the blob was + * last read or written to + */ + lastAccessed?: Date; errorCode?: string; } @@ -6892,10 +6921,11 @@ export type RehydratePriority = 'High' | 'Standard'; * 'OperationTimedOut', 'OutOfRangeInput', 'OutOfRangeQueryParameterValue', 'RequestBodyTooLarge', * 'ResourceTypeMismatch', 'RequestUrlFailedToParse', 'ResourceAlreadyExists', 'ResourceNotFound', * 'ServerBusy', 'UnsupportedHeader', 'UnsupportedXmlNode', 'UnsupportedQueryParameter', - * 'UnsupportedHttpVerb', 'AppendPositionConditionNotMet', 'BlobAlreadyExists', 'BlobNotFound', - * 'BlobOverwritten', 'BlobTierInadequateForContentLength', 'BlockCountExceedsLimit', - * 'BlockListTooLong', 'CannotChangeToLowerTier', 'CannotVerifyCopySource', - * 'ContainerAlreadyExists', 'ContainerBeingDeleted', 'ContainerDisabled', 'ContainerNotFound', + * 'UnsupportedHttpVerb', 'AppendPositionConditionNotMet', 'BlobAlreadyExists', + * 'BlobImmutableDueToPolicy', 'BlobNotFound', 'BlobOverwritten', + * 'BlobTierInadequateForContentLength', 'BlockCountExceedsLimit', 'BlockListTooLong', + * 'CannotChangeToLowerTier', 'CannotVerifyCopySource', 'ContainerAlreadyExists', + * 'ContainerBeingDeleted', 'ContainerDisabled', 'ContainerNotFound', * 'ContentLengthLargerThanTierLimit', 'CopyAcrossAccountsNotSupported', 'CopyIdMismatch', * 'FeatureVersionMismatch', 'IncrementalCopyBlobMismatch', * 'IncrementalCopyOfEralierVersionSnapshotNotAllowed', 'IncrementalCopySourceMustBeSnapshot', @@ -6920,7 +6950,7 @@ export type RehydratePriority = 'High' | 'Standard'; * @readonly * @enum {string} */ -export type StorageErrorCode = 'AccountAlreadyExists' | 'AccountBeingCreated' | 'AccountIsDisabled' | 'AuthenticationFailed' | 'AuthorizationFailure' | 'ConditionHeadersNotSupported' | 'ConditionNotMet' | 'EmptyMetadataKey' | 'InsufficientAccountPermissions' | 'InternalError' | 'InvalidAuthenticationInfo' | 'InvalidHeaderValue' | 'InvalidHttpVerb' | 'InvalidInput' | 'InvalidMd5' | 'InvalidMetadata' | 'InvalidQueryParameterValue' | 'InvalidRange' | 'InvalidResourceName' | 'InvalidUri' | 'InvalidXmlDocument' | 'InvalidXmlNodeValue' | 'Md5Mismatch' | 'MetadataTooLarge' | 'MissingContentLengthHeader' | 'MissingRequiredQueryParameter' | 'MissingRequiredHeader' | 'MissingRequiredXmlNode' | 'MultipleConditionHeadersNotSupported' | 'OperationTimedOut' | 'OutOfRangeInput' | 'OutOfRangeQueryParameterValue' | 'RequestBodyTooLarge' | 'ResourceTypeMismatch' | 'RequestUrlFailedToParse' | 'ResourceAlreadyExists' | 'ResourceNotFound' | 'ServerBusy' | 'UnsupportedHeader' | 'UnsupportedXmlNode' | 'UnsupportedQueryParameter' | 'UnsupportedHttpVerb' | 'AppendPositionConditionNotMet' | 'BlobAlreadyExists' | 'BlobNotFound' | 'BlobOverwritten' | 'BlobTierInadequateForContentLength' | 'BlockCountExceedsLimit' | 'BlockListTooLong' | 'CannotChangeToLowerTier' | 'CannotVerifyCopySource' | 'ContainerAlreadyExists' | 'ContainerBeingDeleted' | 'ContainerDisabled' | 'ContainerNotFound' | 'ContentLengthLargerThanTierLimit' | 'CopyAcrossAccountsNotSupported' | 'CopyIdMismatch' | 'FeatureVersionMismatch' | 'IncrementalCopyBlobMismatch' | 'IncrementalCopyOfEralierVersionSnapshotNotAllowed' | 'IncrementalCopySourceMustBeSnapshot' | 'InfiniteLeaseDurationRequired' | 'InvalidBlobOrBlock' | 'InvalidBlobTier' | 'InvalidBlobType' | 'InvalidBlockId' | 'InvalidBlockList' | 'InvalidOperation' | 'InvalidPageRange' | 'InvalidSourceBlobType' | 'InvalidSourceBlobUrl' | 'InvalidVersionForPageBlobOperation' | 'LeaseAlreadyPresent' | 'LeaseAlreadyBroken' | 'LeaseIdMismatchWithBlobOperation' | 'LeaseIdMismatchWithContainerOperation' | 'LeaseIdMismatchWithLeaseOperation' | 'LeaseIdMissing' | 'LeaseIsBreakingAndCannotBeAcquired' | 'LeaseIsBreakingAndCannotBeChanged' | 'LeaseIsBrokenAndCannotBeRenewed' | 'LeaseLost' | 'LeaseNotPresentWithBlobOperation' | 'LeaseNotPresentWithContainerOperation' | 'LeaseNotPresentWithLeaseOperation' | 'MaxBlobSizeConditionNotMet' | 'NoAuthenticationInformation' | 'NoPendingCopyOperation' | 'OperationNotAllowedOnIncrementalCopyBlob' | 'PendingCopyOperation' | 'PreviousSnapshotCannotBeNewer' | 'PreviousSnapshotNotFound' | 'PreviousSnapshotOperationNotSupported' | 'SequenceNumberConditionNotMet' | 'SequenceNumberIncrementTooLarge' | 'SnapshotCountExceeded' | 'SnaphotOperationRateExceeded' | 'SnapshotsPresent' | 'SourceConditionNotMet' | 'SystemInUse' | 'TargetConditionNotMet' | 'UnauthorizedBlobOverwrite' | 'BlobBeingRehydrated' | 'BlobArchived' | 'BlobNotArchived' | 'AuthorizationSourceIPMismatch' | 'AuthorizationProtocolMismatch' | 'AuthorizationPermissionMismatch' | 'AuthorizationServiceMismatch' | 'AuthorizationResourceTypeMismatch'; +export type StorageErrorCode = 'AccountAlreadyExists' | 'AccountBeingCreated' | 'AccountIsDisabled' | 'AuthenticationFailed' | 'AuthorizationFailure' | 'ConditionHeadersNotSupported' | 'ConditionNotMet' | 'EmptyMetadataKey' | 'InsufficientAccountPermissions' | 'InternalError' | 'InvalidAuthenticationInfo' | 'InvalidHeaderValue' | 'InvalidHttpVerb' | 'InvalidInput' | 'InvalidMd5' | 'InvalidMetadata' | 'InvalidQueryParameterValue' | 'InvalidRange' | 'InvalidResourceName' | 'InvalidUri' | 'InvalidXmlDocument' | 'InvalidXmlNodeValue' | 'Md5Mismatch' | 'MetadataTooLarge' | 'MissingContentLengthHeader' | 'MissingRequiredQueryParameter' | 'MissingRequiredHeader' | 'MissingRequiredXmlNode' | 'MultipleConditionHeadersNotSupported' | 'OperationTimedOut' | 'OutOfRangeInput' | 'OutOfRangeQueryParameterValue' | 'RequestBodyTooLarge' | 'ResourceTypeMismatch' | 'RequestUrlFailedToParse' | 'ResourceAlreadyExists' | 'ResourceNotFound' | 'ServerBusy' | 'UnsupportedHeader' | 'UnsupportedXmlNode' | 'UnsupportedQueryParameter' | 'UnsupportedHttpVerb' | 'AppendPositionConditionNotMet' | 'BlobAlreadyExists' | 'BlobImmutableDueToPolicy' | 'BlobNotFound' | 'BlobOverwritten' | 'BlobTierInadequateForContentLength' | 'BlockCountExceedsLimit' | 'BlockListTooLong' | 'CannotChangeToLowerTier' | 'CannotVerifyCopySource' | 'ContainerAlreadyExists' | 'ContainerBeingDeleted' | 'ContainerDisabled' | 'ContainerNotFound' | 'ContentLengthLargerThanTierLimit' | 'CopyAcrossAccountsNotSupported' | 'CopyIdMismatch' | 'FeatureVersionMismatch' | 'IncrementalCopyBlobMismatch' | 'IncrementalCopyOfEralierVersionSnapshotNotAllowed' | 'IncrementalCopySourceMustBeSnapshot' | 'InfiniteLeaseDurationRequired' | 'InvalidBlobOrBlock' | 'InvalidBlobTier' | 'InvalidBlobType' | 'InvalidBlockId' | 'InvalidBlockList' | 'InvalidOperation' | 'InvalidPageRange' | 'InvalidSourceBlobType' | 'InvalidSourceBlobUrl' | 'InvalidVersionForPageBlobOperation' | 'LeaseAlreadyPresent' | 'LeaseAlreadyBroken' | 'LeaseIdMismatchWithBlobOperation' | 'LeaseIdMismatchWithContainerOperation' | 'LeaseIdMismatchWithLeaseOperation' | 'LeaseIdMissing' | 'LeaseIsBreakingAndCannotBeAcquired' | 'LeaseIsBreakingAndCannotBeChanged' | 'LeaseIsBrokenAndCannotBeRenewed' | 'LeaseLost' | 'LeaseNotPresentWithBlobOperation' | 'LeaseNotPresentWithContainerOperation' | 'LeaseNotPresentWithLeaseOperation' | 'MaxBlobSizeConditionNotMet' | 'NoAuthenticationInformation' | 'NoPendingCopyOperation' | 'OperationNotAllowedOnIncrementalCopyBlob' | 'PendingCopyOperation' | 'PreviousSnapshotCannotBeNewer' | 'PreviousSnapshotNotFound' | 'PreviousSnapshotOperationNotSupported' | 'SequenceNumberConditionNotMet' | 'SequenceNumberIncrementTooLarge' | 'SnapshotCountExceeded' | 'SnaphotOperationRateExceeded' | 'SnapshotsPresent' | 'SourceConditionNotMet' | 'SystemInUse' | 'TargetConditionNotMet' | 'UnauthorizedBlobOverwrite' | 'BlobBeingRehydrated' | 'BlobArchived' | 'BlobNotArchived' | 'AuthorizationSourceIPMismatch' | 'AuthorizationProtocolMismatch' | 'AuthorizationPermissionMismatch' | 'AuthorizationServiceMismatch' | 'AuthorizationResourceTypeMismatch'; /** * Defines values for GeoReplicationStatusType. @@ -6932,11 +6962,11 @@ export type GeoReplicationStatusType = 'live' | 'bootstrap' | 'unavailable'; /** * Defines values for QueryFormatType. - * Possible values include: 'delimited', 'json' + * Possible values include: 'delimited', 'json', 'arrow' * @readonly * @enum {string} */ -export type QueryFormatType = 'delimited' | 'json'; +export type QueryFormatType = 'delimited' | 'json' | 'arrow'; /** * Defines values for BlobExpiryOptions. diff --git a/sdk/storage/storage-blob/src/generated/src/models/mappers.ts b/sdk/storage/storage-blob/src/generated/src/models/mappers.ts index 634991b2c184..3eb90408bb81 100644 --- a/sdk/storage/storage-blob/src/generated/src/models/mappers.ts +++ b/sdk/storage/storage-blob/src/generated/src/models/mappers.ts @@ -477,6 +477,13 @@ export const BlobPropertiesInternal: coreHttp.CompositeMapper = { type: { name: "String" } + }, + lastAccessedOn: { + xmlName: "LastAccessTime", + serializedName: "LastAccessTime", + type: { + name: "DateTimeRfc1123" + } } } } @@ -1198,6 +1205,72 @@ export const JsonTextConfiguration: coreHttp.CompositeMapper = { } }; +export const ArrowField: coreHttp.CompositeMapper = { + xmlName: "Field", + serializedName: "ArrowField", + type: { + name: "Composite", + className: "ArrowField", + modelProperties: { + type: { + xmlName: "Type", + required: true, + serializedName: "Type", + type: { + name: "String" + } + }, + name: { + xmlName: "Name", + serializedName: "Name", + type: { + name: "String" + } + }, + precision: { + xmlName: "Precision", + serializedName: "Precision", + type: { + name: "Number" + } + }, + scale: { + xmlName: "Scale", + serializedName: "Scale", + type: { + name: "Number" + } + } + } + } +}; + +export const ArrowConfiguration: coreHttp.CompositeMapper = { + serializedName: "ArrowConfiguration", + type: { + name: "Composite", + className: "ArrowConfiguration", + modelProperties: { + schema: { + xmlIsWrapped: true, + xmlName: "Schema", + xmlElementName: "Field", + required: true, + serializedName: "Schema", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ArrowField" + } + } + } + } + } + } +}; + export const ListContainersSegmentResponse: coreHttp.CompositeMapper = { xmlName: "EnumerationResults", serializedName: "ListContainersSegmentResponse", @@ -1649,7 +1722,8 @@ export const QueryFormat: coreHttp.CompositeMapper = { name: "Enum", allowedValues: [ "delimited", - "json" + "json", + "arrow" ] } }, @@ -1668,6 +1742,14 @@ export const QueryFormat: coreHttp.CompositeMapper = { name: "Composite", className: "JsonTextConfiguration" } + }, + arrowConfiguration: { + xmlName: "ArrowConfiguration", + serializedName: "ArrowConfiguration", + type: { + name: "Composite", + className: "ArrowConfiguration" + } } } } @@ -3902,6 +3984,12 @@ export const BlobDownloadHeaders: coreHttp.CompositeMapper = { name: "Boolean" } }, + lastAccessed: { + serializedName: "x-ms-last-access-time", + type: { + name: "DateTimeRfc1123" + } + }, contentCrc64: { serializedName: "x-ms-content-crc64", type: { @@ -4232,6 +4320,12 @@ export const BlobGetPropertiesHeaders: coreHttp.CompositeMapper = { name: "String" } }, + lastAccessed: { + serializedName: "x-ms-last-access-time", + type: { + name: "DateTimeRfc1123" + } + }, errorCode: { serializedName: "x-ms-error-code", type: { diff --git a/sdk/storage/storage-blob/src/generated/src/models/parameters.ts b/sdk/storage/storage-blob/src/generated/src/models/parameters.ts index c985e05682ff..d7985b887061 100644 --- a/sdk/storage/storage-blob/src/generated/src/models/parameters.ts +++ b/sdk/storage/storage-blob/src/generated/src/models/parameters.ts @@ -1680,7 +1680,7 @@ export const version: coreHttp.OperationParameter = { required: true, isConstant: true, serializedName: "x-ms-version", - defaultValue: '2019-12-12', + defaultValue: '2020-02-10', type: { name: "String" } diff --git a/sdk/storage/storage-blob/src/generated/src/storageClientContext.ts b/sdk/storage/storage-blob/src/generated/src/storageClientContext.ts index 16d58c043472..6710606071bb 100644 --- a/sdk/storage/storage-blob/src/generated/src/storageClientContext.ts +++ b/sdk/storage/storage-blob/src/generated/src/storageClientContext.ts @@ -11,7 +11,7 @@ import * as coreHttp from "@azure/core-http"; const packageName = "azure-storage-blob"; -const packageVersion = "12.2.1"; +const packageVersion = "12.3.0-beta.1"; export class StorageClientContext extends coreHttp.ServiceClient { url: string; @@ -39,7 +39,7 @@ export class StorageClientContext extends coreHttp.ServiceClient { super(undefined, options); - this.version = "2019-12-12"; + this.version = '2020-02-10'; this.baseUri = "{url}"; this.requestContentType = "application/json; charset=utf-8"; this.url = url; diff --git a/sdk/storage/storage-blob/src/generatedModels.ts b/sdk/storage/storage-blob/src/generatedModels.ts index a913e22c4b85..7e7150767ab9 100644 --- a/sdk/storage/storage-blob/src/generatedModels.ts +++ b/sdk/storage/storage-blob/src/generatedModels.ts @@ -146,5 +146,7 @@ export { ServiceFilterBlobsResponse as ServiceFindBlobsByTagsSegmentResponse, FilterBlobItem, BlobQueryHeaders, - BlobQueryResponse as BlobQueryResponseModel + BlobQueryResponse as BlobQueryResponseModel, + ContainerRestoreResponse as ContainerUndeleteResponse, + ContainerRestoreHeaders as ContainerUndeleteHeaders } from "./generated/src/models"; diff --git a/sdk/storage/storage-blob/src/index.ts b/sdk/storage/storage-blob/src/index.ts index 2a8bb0beab25..109e19a3d10d 100644 --- a/sdk/storage/storage-blob/src/index.ts +++ b/sdk/storage/storage-blob/src/index.ts @@ -29,7 +29,9 @@ export { BlobDownloadResponseParsed, ObjectReplicationPolicy, ObjectReplicationRule, - ObjectReplicationStatus + ObjectReplicationStatus, + BlobQueryArrowField, + BlobQueryArrowFieldType } from "./models"; export * from "./Pipeline"; export * from "./policies/AnonymousCredentialPolicy"; diff --git a/sdk/storage/storage-blob/src/models.ts b/sdk/storage/storage-blob/src/models.ts index b2b7de3fd1c0..6c48ea86425a 100644 --- a/sdk/storage/storage-blob/src/models.ts +++ b/sdk/storage/storage-blob/src/models.ts @@ -223,6 +223,9 @@ export interface ObjectReplicationRule { * This is used when retrieving the Object Replication Properties on the source blob. The policy id for the * destination blob is set in ObjectReplicationDestinationPolicyId of the respective method responses * (e.g. {@link BlobProperties.ObjectReplicationDestinationPolicyId}. + * + * @export + * @interface ObjectReplicationPolicy */ export interface ObjectReplicationPolicy { /** @@ -236,7 +239,7 @@ export interface ObjectReplicationPolicy { /** * The Rule ID(s) and respective Replication Status(s) that are under the Policy ID. * - * @type {string} + * @type {ObjectReplicationRule[]} * @memberof ObjectReplicationPolicy */ rules: ObjectReplicationRule[]; @@ -265,3 +268,54 @@ export interface BlobDownloadResponseParsed extends BlobDownloadResponseModel { */ objectReplicationDestinationPolicyId?: string; } + +/** + * The type of a {@link BlobQueryArrowField}. + */ +export type BlobQueryArrowFieldType = + | "int64" + | "bool" + | "timestamp[ms]" + | "string" + | "double" + | "decimal"; + +/** + * Describe a field in {@link BlobQueryArrowConfiguration}. + * + * @export + * @interface BlobQueryArrowField + */ +export interface BlobQueryArrowField { + /** + * The type of the field. + * + * @type {BlobQueryArrowFieldType} + * @memberof BlobQueryArrowField + */ + type: BlobQueryArrowFieldType; + + /** + * The name of the field. + * + * @type {string} + * @memberof BlobQueryArrowField + */ + name?: string; + + /** + * The precision of the field. Required if type is "decimal". + * + * @type {number} + * @memberof BlobQueryArrowField + */ + precision?: number; + + /** + * The scale of the field. Required if type is is "decimal". + * + * @type {number} + * @memberof BlobQueryArrowField + */ + scale?: number; +} diff --git a/sdk/storage/storage-blob/src/utils/constants.ts b/sdk/storage/storage-blob/src/utils/constants.ts index ca397e83dffb..e20f8c57f035 100644 --- a/sdk/storage/storage-blob/src/utils/constants.ts +++ b/sdk/storage/storage-blob/src/utils/constants.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export const SDK_VERSION: string = "12.2.2"; -export const SERVICE_VERSION: string = "2019-12-12"; +export const SDK_VERSION: string = "12.3.0-beta.1"; +export const SERVICE_VERSION: string = "2020-02-10"; export const BLOCK_BLOB_MAX_UPLOAD_BLOB_BYTES: number = 256 * 1024 * 1024; // 256MB export const BLOCK_BLOB_MAX_STAGE_BLOCK_BYTES: number = 4000 * 1024 * 1024; // 4000MB diff --git a/sdk/storage/storage-blob/src/utils/utils.common.ts b/sdk/storage/storage-blob/src/utils/utils.common.ts index 86fb0a15b251..395e84ccd055 100644 --- a/sdk/storage/storage-blob/src/utils/utils.common.ts +++ b/sdk/storage/storage-blob/src/utils/utils.common.ts @@ -4,7 +4,11 @@ import { AbortSignalLike } from "@azure/abort-controller"; import { HttpHeaders, isNode, URLBuilder } from "@azure/core-http"; -import { BlobQueryCsvTextConfiguration, BlobQueryJsonTextConfiguration } from "../Clients"; +import { + BlobQueryArrowConfiguration, + BlobQueryCsvTextConfiguration, + BlobQueryJsonTextConfiguration +} from "../Clients"; import { QuerySerialization, BlobTags } from "../generated/src/models"; import { DevelopmentConnectionString, HeaderConstants, URLConstants } from "./constants"; import { @@ -650,11 +654,14 @@ export function toTags(tags?: BlobTags): Tags | undefined { * Convert BlobQueryTextConfiguration to QuerySerialization type. * * @export - * @param {(BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration)} [textConfiguration] + * @param {(BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration | BlobQueryArrowConfiguration)} [textConfiguration] * @returns {(QuerySerialization | undefined)} */ export function toQuerySerialization( - textConfiguration?: BlobQueryJsonTextConfiguration | BlobQueryCsvTextConfiguration + textConfiguration?: + | BlobQueryJsonTextConfiguration + | BlobQueryCsvTextConfiguration + | BlobQueryArrowConfiguration ): QuerySerialization | undefined { if (textConfiguration === undefined) { return undefined; @@ -683,6 +690,16 @@ export function toQuerySerialization( } } }; + case "arrow": + return { + format: { + type: "arrow", + arrowConfiguration: { + schema: textConfiguration.schema + } + } + }; + default: throw Error("Invalid BlobQueryTextConfiguration."); } diff --git a/sdk/storage/storage-blob/src/utils/utils.node.ts b/sdk/storage/storage-blob/src/utils/utils.node.ts index ed67cbade40d..ddd5897dc480 100644 --- a/sdk/storage/storage-blob/src/utils/utils.node.ts +++ b/sdk/storage/storage-blob/src/utils/utils.node.ts @@ -107,6 +107,30 @@ export async function streamToBuffer2( }); } +/** + * Reads a readable stream into a buffer. + * + * @export + * @param {NodeJS.ReadableStream} stream A Node.js Readable stream + * @param {string} [encoding] Encoding of the Readable stream + * @returns {Promise} with the count of bytes read. + */ +export async function streamToBuffer3( + readableStream: NodeJS.ReadableStream, + encoding?: string +): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + readableStream.on("data", (data: Buffer | string) => { + chunks.push(data instanceof Buffer ? data : Buffer.from(data, encoding)); + }); + readableStream.on("end", () => { + resolve(Buffer.concat(chunks)); + }); + readableStream.on("error", reject); + }); +} + /** * ONLY AVAILABLE IN NODE.JS RUNTIME. * diff --git a/sdk/storage/storage-blob/swagger/README.md b/sdk/storage/storage-blob/swagger/README.md index ad173321949d..004a1403654d 100644 --- a/sdk/storage/storage-blob/swagger/README.md +++ b/sdk/storage/storage-blob/swagger/README.md @@ -12,7 +12,7 @@ enable-xml: true generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../src/generated -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.BlobStorage/preview/2019-12-12/blob.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.BlobStorage/preview/2020-02-10/blob.json model-date-time-as-string: true optional-response-headers: true ``` @@ -350,7 +350,6 @@ directive: transform: > $.Start["x-ms-client-name"] = "startsOn"; $.Expiry["x-ms-client-name"] = "expiresOn"; - ``` ### Rename KeyInfo start -> startsOn @@ -362,10 +361,9 @@ directive: transform: > $.Start["x-ms-client-name"] = "startsOn"; $.Expiry["x-ms-client-name"] = "expiresOn"; - ``` -### Un-group encryptionScope +### Un-group encryptionScope ```yaml directive: @@ -376,7 +374,6 @@ directive: if (grouping) { delete $["x-ms-parameter-grouping"]; } - ``` ### Rename ContainerCpkScopeInfo -> ContainerEncryptionScope @@ -391,7 +388,6 @@ directive: where: $.parameters.DenyEncryptionScopeOverride transform: > $["x-ms-parameter-grouping"]["name"] = "container-encryption-scope"; - ``` ### Use string union instead of string for RehydratePriority in getProperties @@ -405,8 +401,7 @@ directive: $["enum"] = ["High", "Standard"]; $["x-ms-enum"] = {}; $["x-ms-enum"]["name"] = "RehydratePriority"; - $["x-ms-enum"]["modelAsString"] = true; - + $["x-ms-enum"]["modelAsString"] = true; ``` ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fstorage%2Fstorage-blob%2Fswagger%2FREADME.png) diff --git a/sdk/storage/storage-blob/test/blobclient.spec.ts b/sdk/storage/storage-blob/test/blobclient.spec.ts index 9e32fff8cb9a..6c393cc02190 100644 --- a/sdk/storage/storage-blob/test/blobclient.spec.ts +++ b/sdk/storage/storage-blob/test/blobclient.spec.ts @@ -55,11 +55,6 @@ describe("BlobClient", () => { }); it("Set blob tags should work", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const tags = { tag1: "val1", tag2: "val2" @@ -85,11 +80,6 @@ describe("BlobClient", () => { }); it("Get blob tags should work with a snapshot", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const tags = { tag1: "val1", tag2: "val2" @@ -104,11 +94,6 @@ describe("BlobClient", () => { }); it("Create block blob should work with tags", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - await blockBlobClient.delete(); const tags = { @@ -122,11 +107,6 @@ describe("BlobClient", () => { }); it("Create append blob should work with tags", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const tags = { tag1: "val1", tag2: "val2" @@ -141,11 +121,6 @@ describe("BlobClient", () => { }); it("Create page blob should work with tags", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const tags = { tag1: "val1", tag2: "val2" @@ -348,6 +323,8 @@ describe("BlobClient", () => { result3.segment.blobItems![0].properties.accessTier = result3.segment.blobItems![1].properties.accessTier = undefined; // tslint:disable-next-line:max-line-length result3.segment.blobItems![0].properties.accessTierInferred = result3.segment.blobItems![1].properties.accessTierInferred = undefined; + // tslint:disable-next-line:max-line-length + result3.segment.blobItems![0].properties.lastAccessedOn = result3.segment.blobItems![1].properties.lastAccessedOn = undefined; assert.deepStrictEqual( result3.segment.blobItems![0].properties, @@ -828,6 +805,25 @@ describe("BlobClient", () => { await checkRehydratePriority("Standard"); }); + it("lastAccessed returned", async function() { + if (isLiveMode()) { + // Skipped for now as it's not working in live tests pipeline. + this.skip(); + } + const downloadRes = await blockBlobClient.download(); + assert.ok(downloadRes.lastAccessed); + + const getPropertiesRes = await blockBlobClient.getProperties(); + assert.ok(getPropertiesRes.lastAccessed); + + for await (const blobItem of containerClient.listBlobsFlat({ prefix: blobName })) { + if (blobItem.name === blobName) { + assert.ok(blobItem.properties.lastAccessedOn); + break; + } + } + }); + describe("conditional tags", () => { const tags = { tag1: "val1", @@ -838,10 +834,6 @@ describe("BlobClient", () => { const tagConditionUnmet = { tagConditions: "tag1 = 'val2'" }; beforeEach(async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } await blobClient.setTags(tags); }); diff --git a/sdk/storage/storage-blob/test/blobserviceclient.spec.ts b/sdk/storage/storage-blob/test/blobserviceclient.spec.ts index 39350c1dc0f9..ec115032ae1b 100644 --- a/sdk/storage/storage-blob/test/blobserviceclient.spec.ts +++ b/sdk/storage/storage-blob/test/blobserviceclient.spec.ts @@ -5,6 +5,7 @@ import { BlobServiceClient } from "../src"; import { getAlternateBSU, getBSU, + getGenericBSU, getSASConnectionStringFromEnvironment, getTokenBSU, recorderEnvSetup, @@ -12,7 +13,6 @@ import { } from "./utils"; import { record, delay, Recorder } from "@azure/test-utils-recorder"; import { Tags } from "../src/models"; -import { isNode } from "@azure/core-http"; dotenv.config(); describe("BlobServiceClient", () => { @@ -471,11 +471,6 @@ describe("BlobServiceClient", () => { }); it("Find blob by tags should work", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const blobServiceClient = getBSU(); const containerName = recorder.getUniqueName("container1"); @@ -561,4 +556,74 @@ describe("BlobServiceClient", () => { assert.equal(staticWebsite?.errorDocument404Path, errorDocument404Path); assert.equal(staticWebsite?.defaultIndexDocumentPath, defaultIndexDocumentPath); }); + + it("restore container", async function() { + let blobServiceClient: BlobServiceClient; + try { + blobServiceClient = getGenericBSU("SOFT_DELETE_"); + } catch (err) { + this.skip(); + } + + const containerName = recorder.getUniqueName("container"); + const containerClient = blobServiceClient.getContainerClient(containerName); + + await containerClient.create(); + await containerClient.delete(); + + await delay(30 * 1000); + + for await (const containerItem of blobServiceClient.listContainers({ includeDeleted: true })) { + if (containerItem.deleted && containerItem.name === containerName) { + // check list container response + assert.ok(containerItem.version); + assert.ok(containerItem.properties.deletedOn); + assert.ok(containerItem.properties.remainingRetentionDays); + + const restoreRes = await blobServiceClient.undeleteContainer( + containerName, + containerItem.version! + ); + assert.equal(restoreRes.containerClient.containerName, containerName); + break; + } + } + }); + + it("restore container to a new name", async function() { + let blobServiceClient: BlobServiceClient; + try { + blobServiceClient = getGenericBSU("SOFT_DELETE_"); + } catch (err) { + this.skip(); + } + + const containerName = recorder.getUniqueName("container"); + const containerClient = blobServiceClient.getContainerClient(containerName); + + await containerClient.create(); + await containerClient.delete(); + await delay(30 * 1000); + + for await (const containerItem of blobServiceClient.listContainers({ includeDeleted: true })) { + if (containerItem.deleted && containerItem.name === containerName) { + // check list container response + assert.ok(containerItem.version); + assert.ok(containerItem.properties.deletedOn); + assert.ok(containerItem.properties.remainingRetentionDays); + + const newContainerName = recorder.getUniqueName("newcontainer"); + const restoreRes2 = await blobServiceClient.undeleteContainer( + containerName, + containerItem.version!, + { + destinationContainerName: newContainerName + } + ); + assert.equal(restoreRes2.containerClient.containerName, newContainerName); + + break; + } + } + }); }); diff --git a/sdk/storage/storage-blob/test/blobversioning.spec.ts b/sdk/storage/storage-blob/test/blobversioning.spec.ts index a1a40e3c1e37..5a1ee1d5c6b1 100644 --- a/sdk/storage/storage-blob/test/blobversioning.spec.ts +++ b/sdk/storage/storage-blob/test/blobversioning.spec.ts @@ -130,11 +130,6 @@ describe("Blob versioning", () => { }); it("delete a version", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); await blobVersionClient.delete(); @@ -146,11 +141,6 @@ describe("Blob versioning", () => { }); it("deleteBlobs should work for batch delete", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - recorder.skip( undefined, "UUID is randomly generated within the SDK and used in the HTTP request and cannot be preserved." @@ -212,11 +202,6 @@ describe("Blob versioning", () => { }); it("deleting root blob with versionId should fail", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - await containerClient.deleteBlob(blobName, { versionId: uploadRes.versionId }); @@ -250,11 +235,6 @@ describe("Blob versioning", () => { }); it("deleting a blob that has snapshots needs deleteSnapshots option", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const result = await blobClient.createSnapshot(); assert.ok(result.snapshot); @@ -267,7 +247,7 @@ describe("Blob versioning", () => { } assert.ok(exceptionCaught); - blobClient.delete({ deleteSnapshots: "include" }); + await blobClient.delete({ deleteSnapshots: "include" }); const snapshotExists = await blobClient.withSnapshot(result.snapshot!).exists(); assert.ok(!snapshotExists); const rootExists = await blobClient.exists(); @@ -310,11 +290,6 @@ describe("Blob versioning", () => { }); it("promote a version: as the copy source", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); await blobVersionClient.getProperties(); @@ -382,11 +357,6 @@ describe("Blob versioning", () => { }); it("undelete a soft-deleted version", async function() { - if (!isNode) { - // SAS in test pipeline need to support the new permission. - this.skip(); - } - let properties = await blobServiceClient.getProperties(); if (!properties.deleteRetentionPolicy!.enabled) { await blobServiceClient.setProperties({ diff --git a/sdk/storage/storage-blob/test/browser/highlevel.browser.spec.ts b/sdk/storage/storage-blob/test/browser/highlevel.browser.spec.ts index bbac66a0438a..4858c59b0e58 100644 --- a/sdk/storage/storage-blob/test/browser/highlevel.browser.spec.ts +++ b/sdk/storage/storage-blob/test/browser/highlevel.browser.spec.ts @@ -154,8 +154,7 @@ describe("Highlevel", () => { assert.equal(uploadedString, downloadedString); }); - // SAS in test pipeline need to support the new permission. - it.skip("uploadBrowserDataToBlockBlob should work with tags", async function() { + it("uploadBrowserDataToBlockBlob should work with tags", async function() { recorder.skip("browser", "Temp file - recorder doesn't support saving the file"); const tags = { diff --git a/sdk/storage/storage-blob/test/node/blobclient.spec.ts b/sdk/storage/storage-blob/test/node/blobclient.spec.ts index 0e0ffddd1e83..c6544f42c142 100644 --- a/sdk/storage/storage-blob/test/node/blobclient.spec.ts +++ b/sdk/storage/storage-blob/test/node/blobclient.spec.ts @@ -26,6 +26,7 @@ import { } from "../utils"; import { assertClientUsesTokenCredential } from "../utils/assert"; import { readStreamToLocalFileWithLogs } from "../utils/testutils.node"; +import { streamToBuffer3 } from "../../src/utils/utils.node"; dotenv.config(); @@ -363,7 +364,6 @@ describe("BlobClient Node.js only", () => { }); it("query should work with conditional tags", async function() { - recorder.skip(undefined, "TODO: figure out why quick query do not work with recording"); const csvContent = "100,200,300,400\n150,250,350,450\n"; await blockBlobClient.upload(csvContent, csvContent.length, { tags: { tag: "val" } }); @@ -643,4 +643,43 @@ describe("BlobClient Node.js only", () => { }); assert.deepStrictEqual(await bodyToString(response), jsonContent); }); + + it("query should work with arrow output configurations", async function() { + const csvContent = "100,200,300,400\n150,250,350,450\n"; + await blockBlobClient.upload(csvContent, csvContent.length); + + const response = await blockBlobClient.query("select * from BlobStorage", { + outputTextConfiguration: { + kind: "arrow", + schema: [ + { + type: "decimal", + name: "name", + precision: 4, + scale: 2 + } + ] + } + }); + assert.equal( + (await streamToBuffer3(response.readableStreamBody!)).toString("hex"), + "ffffffff800000001000000000000a000c000600050008000a000000000103000c000000080008000000040008000000040000000100000014000000100014000800060007000c000000100010000000000001072400000014000000040000000000000008000c0004000800080000000400000002000000040000006e616d650000000000000000ffffffff700000001000000000000a000e000600050008000a000000000303001000000000000a000c000000040008000a0000003000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000" + ); + }); + + it("query should work with arrow output configurations for timestamp[ms]", async function() { + const csvContent = "100,200,300,400\n150,250,350,450\n"; + await blockBlobClient.upload(csvContent, csvContent.length); + + await blockBlobClient.query("select * from BlobStorage", { + outputTextConfiguration: { + kind: "arrow", + schema: [ + { + type: "timestamp[ms]" + } + ] + } + }); + }); }); diff --git a/sdk/storage/storage-blob/test/node/sas.spec.ts b/sdk/storage/storage-blob/test/node/sas.spec.ts index 709ebf8f3eae..c09ec5518bc1 100644 --- a/sdk/storage/storage-blob/test/node/sas.spec.ts +++ b/sdk/storage/storage-blob/test/node/sas.spec.ts @@ -18,7 +18,7 @@ import { Tags } from "../../src"; import { SASProtocol } from "../../src/SASQueryParameters"; -import { getBSU, getTokenBSU, recorderEnvSetup, sleep } from "../utils"; +import { getBSU, getTokenBSUWithDefaultCredential, recorderEnvSetup, sleep } from "../utils"; import { delay, record } from "@azure/test-utils-recorder"; import { SERVICE_VERSION } from "../../src/utils/constants"; @@ -667,11 +667,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for container with all configurations", async function() { - // Try to get BlobServiceClient object with TokenCredential - // when ACCOUNT_TOKEN environment variable is set + // Try to get BlobServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let blobServiceClientWithToken: BlobServiceClient | undefined; try { - blobServiceClientWithToken = getTokenBSU(); + blobServiceClientWithToken = getTokenBSUWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -725,11 +725,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for container with minimum parameters", async function() { - // Try to get BlobServiceClient object with TokenCredential - // when ACCOUNT_TOKEN environment variable is set + // Try to get BlobServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let blobServiceClientWithToken: BlobServiceClient | undefined; try { - blobServiceClientWithToken = getTokenBSU(); + blobServiceClientWithToken = getTokenBSUWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -779,11 +779,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for blob", async function() { - // Try to get blobServiceClient object with TokenCredential - // when ACCOUNT_TOKEN environment variable is set + // Try to get blobServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let blobServiceClientWithToken: BlobServiceClient | undefined; try { - blobServiceClientWithToken = getTokenBSU(); + blobServiceClientWithToken = getTokenBSUWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -848,11 +848,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for blob snapshot", async function() { - // Try to get blobServiceClient object with TokenCredential - // when ACCOUNT_TOKEN environment variable is set + // Try to get blobServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let blobServiceClientWithToken: BlobServiceClient | undefined; try { - blobServiceClientWithToken = getTokenBSU(); + blobServiceClientWithToken = getTokenBSUWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -1005,12 +1005,12 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { await containerClient.delete(); }); - it.skip("GenerateUserDelegationSAS should work for blob version delete", async function() { - // Try to get blobServiceClient object with TokenCredential - // when ACCOUNT_TOKEN environment variable is set + it("GenerateUserDelegationSAS should work for blob version delete", async function() { + // Try to get blobServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let blobServiceClientWithToken: BlobServiceClient | undefined; try { - blobServiceClientWithToken = getTokenBSU(); + blobServiceClientWithToken = getTokenBSUWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -1051,7 +1051,8 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { ipRange: { start: "0.0.0.0", end: "255.255.255.255" }, permissions: BlobSASPermissions.parse("racwdx"), protocol: SASProtocol.HttpsAndHttp, - versionId: uploadRes.versionId + versionId: uploadRes.versionId, + version: "2019-12-12" }, userDelegationKey, accountName diff --git a/sdk/storage/storage-blob/test/utils/index.ts b/sdk/storage/storage-blob/test/utils/index.ts index 746073b6f457..0a13368eb0bb 100644 --- a/sdk/storage/storage-blob/test/utils/index.ts +++ b/sdk/storage/storage-blob/test/utils/index.ts @@ -18,6 +18,7 @@ import { import { extractConnectionStringParts } from "../../src/utils/utils.common"; import { TokenCredential } from "@azure/core-http"; import { env } from "@azure/test-utils-recorder"; +import { DefaultAzureCredential } from "@azure/identity"; dotenv.config(); @@ -98,6 +99,25 @@ export function getTokenBSU(): BlobServiceClient { return new BlobServiceClient(blobPrimaryURL, pipeline); } +export function getTokenBSUWithDefaultCredential( + pipelineOptions: StoragePipelineOptions = {}, + accountType: string = "", + accountNameSuffix: string = "" +): BlobServiceClient { + const accountNameEnvVar = `${accountType}ACCOUNT_NAME`; + let accountName = process.env[accountNameEnvVar]; + if (!accountName || accountName === "") { + throw new Error(`${accountNameEnvVar} environment variables not specified.`); + } + + const credential = new DefaultAzureCredential(); + const pipeline = newPipeline(credential, { + ...pipelineOptions + }); + const blobPrimaryURL = `https://${accountName}${accountNameSuffix}.blob.core.windows.net/`; + return new BlobServiceClient(blobPrimaryURL, pipeline); +} + export function getBSU(pipelineOptions: StoragePipelineOptions = {}): BlobServiceClient { return getGenericBSU("", undefined, pipelineOptions); } diff --git a/sdk/storage/storage-blob/test/utils/testutils.common.ts b/sdk/storage/storage-blob/test/utils/testutils.common.ts index c93bc94402e9..2459713652bf 100644 --- a/sdk/storage/storage-blob/test/utils/testutils.common.ts +++ b/sdk/storage/storage-blob/test/utils/testutils.common.ts @@ -22,6 +22,9 @@ export const recorderEnvSetup: RecorderEnvironmentSetup = { // Comment following line to skip user delegation key/SAS related cases in record and play // which depends on this environment variable ACCOUNT_TOKEN: `${mockAccountKey}`, + AZURE_CLIENT_ID: `${mockAccountKey}`, + AZURE_TENANT_ID: `${mockAccountKey}`, + AZURE_CLIENT_SECRET: `${mockAccountKey}`, MD_ACCOUNT_NAME: `${mockMDAccountName}`, MD_ACCOUNT_KEY: `${mockAccountKey}`, MD_ACCOUNT_SAS: `${mockAccountKey}`, @@ -31,7 +34,11 @@ export const recorderEnvSetup: RecorderEnvironmentSetup = { ORS_DEST_ACCOUNT_NAME: `${mockAccountName1}`, ORS_DEST_ACCOUNT_KEY: `${mockAccountKey}`, ORS_DEST_ACCOUNT_SAS: `${mockAccountKey}`, - ORS_DEST_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockAccountName1};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net` + ORS_DEST_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockAccountName1};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net`, + SOFT_DELETE_ACCOUNT_NAME: `${mockAccountName}`, + SOFT_DELETE_ACCOUNT_KEY: `${mockAccountKey}`, + SOFT_DELETE_ACCOUNT_SAS: `${mockAccountKey}`, + SOFT_DELETE_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockAccountName};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net` }, customizationsOnRecordings: [ // Used in record mode diff --git a/sdk/storage/storage-blob/tests.yml b/sdk/storage/storage-blob/tests.yml index 12d911a20a77..6426f6c29b74 100644 --- a/sdk/storage/storage-blob/tests.yml +++ b/sdk/storage/storage-blob/tests.yml @@ -7,7 +7,8 @@ extends: ResourceServiceDirectory: storage TimeoutInMinutes: 90 ResourceGroupLocation: canadacentral - ArmTemplateParameters: '@{ enableVersioning = $true }' + SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources-preview) + ArmTemplateParameters: "@{ enableVersioning = $true }" EnvVars: AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) diff --git a/sdk/storage/storage-file-datalake/CHANGELOG.md b/sdk/storage/storage-file-datalake/CHANGELOG.md index 8d130f56bc9e..0dd39efe0446 100644 --- a/sdk/storage/storage-file-datalake/CHANGELOG.md +++ b/sdk/storage/storage-file-datalake/CHANGELOG.md @@ -1,7 +1,11 @@ # Release History -## 12.1.2 (Unreleased) +## 12.2.0-beta.1 (2020-10-13) +- Updated Azure Storage Service API version to 2020-02-10. +- Added support for Directory SAS. +- Added support for File Set Expiry. +- Added support to set access control list recursively. ## 12.1.1 (2020-09-17) diff --git a/sdk/storage/storage-file-datalake/package.json b/sdk/storage/storage-file-datalake/package.json index 5d55d042b768..125daafa1a06 100644 --- a/sdk/storage/storage-file-datalake/package.json +++ b/sdk/storage/storage-file-datalake/package.json @@ -1,6 +1,6 @@ { "name": "@azure/storage-file-datalake", - "version": "12.1.2", + "version": "12.2.0-beta.1", "description": "Microsoft Azure Storage SDK for JavaScript - DataLake", "sdk-type": "client", "main": "./dist/index.js", @@ -102,7 +102,7 @@ "@azure/core-paging": "^1.1.1", "@azure/core-tracing": "1.0.0-preview.9", "@azure/logger": "^1.0.0", - "@azure/storage-blob": "^12.2.0", + "@azure/storage-blob": "^12.3.0-beta.1", "events": "^3.0.0", "tslib": "^2.0.0" }, diff --git a/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__absolute.json b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__absolute.json new file mode 100644 index 000000000000..0635cb65463c --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__absolute.json @@ -0,0 +1,179 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159352498324300178", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:43 GMT", + "etag": "\"0x8D81CFC71F20962\"", + "last-modified": "Tue, 30 Jun 2020 13:49:44 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b0232c97-ad4f-4fb1-97b3-42cd96e37b0d", + "x-ms-request-id": "86fbebe0-e01e-0016-5ce5-4ed37e000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": { + "resource": "file" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:45 GMT", + "etag": "\"0x8D81CFC72E7C74C\"", + "last-modified": "Tue, 30 Jun 2020 13:49:45 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9b74d411-8793-416a-83e8-9f69c72277b8", + "x-ms-request-id": "abbf6b9b-001f-000e-2fe5-4e0c19000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": { + "position": "0", + "action": "append" + }, + "requestBody": "Hello World", + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:46 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "268e0f3b-b8e0-4dec-b64d-c89b88a6062d", + "x-ms-request-id": "abbf6b9e-001f-000e-31e5-4e0c19000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": { + "position": "11", + "action": "flush" + }, + "requestBody": "", + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:46 GMT", + "etag": "\"0x8D81CFC73979C8F\"", + "last-modified": "Tue, 30 Jun 2020 13:49:46 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "28047e9b-0cdb-46ba-96f2-2029308e31fe", + "x-ms-request-id": "abbf6ba0-001f-000e-33e5-4e0c19000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:47 GMT", + "etag": "\"0x8D81CFC73979C8F\"", + "last-modified": "Tue, 30 Jun 2020 13:49:46 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "af048384-e07f-4c98-8774-d1944912610a", + "x-ms-request-id": "86fbeca0-e01e-0016-79e5-4ed37e000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "text/plain;charset=UTF-8", + "date": "Tue, 30 Jun 2020 13:49:47 GMT", + "etag": "\"0x8D81CFC73979C8F\"", + "last-modified": "Tue, 30 Jun 2020 13:49:46 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "eba765f2-34c2-482b-90ac-f44d8952bc01", + "x-ms-creation-time": "Tue, 30 Jun 2020 13:49:45 GMT", + "x-ms-expiry-time": "Tue, 30 Jun 2020 13:49:52 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "86fbeccc-e01e-0016-18e5-4ed37e000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159352498324300178/file159352498487800651", + "query": {}, + "requestBody": null, + "status": 404, + "response": "", + "responseHeaders": { + "date": "Tue, 30 Jun 2020 13:49:53 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "7b2fa34b-52be-46d8-b31f-73b616cd7516", + "x-ms-error-code": "BlobNotFound", + "x-ms-request-id": "86fbee46-e01e-0016-4ce5-4ed37e000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159352498324300178", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 30 Jun 2020 13:49:53 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "19b96757-2e1c-406e-84a7-0d7086500351", + "x-ms-request-id": "86fbee65-e01e-0016-66e5-4ed37e000000", + "x-ms-version": "2019-12-12" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "filesystem": "filesystem159352498324300178", + "file": "file159352498487800651" + }, + "newDate": { + "now": "2020-06-30T13:49:47.617Z" + } + }, + "hash": "c7bd60afc7b99e8133f2a601c5f613e8" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__neverexpire.json b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__neverexpire.json new file mode 100644 index 000000000000..1568edbf97b8 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__neverexpire.json @@ -0,0 +1,159 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159239956833708016", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:49 GMT", + "etag": "\"0x8D812C022C2586D\"", + "last-modified": "Wed, 17 Jun 2020 13:12:49 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "838e0ace-c89c-4548-891b-af02661fd427", + "x-ms-request-id": "21918a50-c01e-0063-1ba9-44b852000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159239956833708016/file159239957007507452", + "query": { + "resource": "file" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:50 GMT", + "etag": "\"0x8D812C023B4A8A3\"", + "last-modified": "Wed, 17 Jun 2020 13:12:51 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "bc8508df-4d74-4161-bafc-08b70fc4b15c", + "x-ms-request-id": "f3d5a31e-101f-0002-2ba9-449b11000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159239956833708016/file159239957007507452", + "query": { + "position": "0", + "action": "append" + }, + "requestBody": "Hello World", + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:51 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "a652f82a-6d78-4328-a6fe-94e7da120872", + "x-ms-request-id": "f3d5a320-101f-0002-2da9-449b11000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159239956833708016/file159239957007507452", + "query": { + "position": "11", + "action": "flush" + }, + "requestBody": "", + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:51 GMT", + "etag": "\"0x8D812C02465CAE5\"", + "last-modified": "Wed, 17 Jun 2020 13:12:52 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "07a6fc49-5fad-464f-bcf6-b0f279bb0a88", + "x-ms-request-id": "f3d5a322-101f-0002-2fa9-449b11000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159239956833708016/file159239957007507452", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:53 GMT", + "etag": "\"0x8D812C02465CAE5\"", + "last-modified": "Wed, 17 Jun 2020 13:12:52 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c2bf3445-ae98-470c-a10c-beb27c18bafb", + "x-ms-request-id": "6ba7a955-e01e-0029-01a9-441bdd000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159239956833708016/file159239957007507452", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "text/plain;charset=UTF-8", + "date": "Wed, 17 Jun 2020 13:12:54 GMT", + "etag": "\"0x8D812C02465CAE5\"", + "last-modified": "Wed, 17 Jun 2020 13:12:52 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "eac4a0aa-32e8-4edb-bce8-9ab7027e82a8", + "x-ms-creation-time": "Wed, 17 Jun 2020 13:12:51 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "6ba7a99d-e01e-0029-3ba9-441bdd000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159239956833708016", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 17 Jun 2020 13:12:54 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1114e467-b86f-4ab6-bde1-9eb2acb1dd4d", + "x-ms-request-id": "6ba7aa08-e01e-0029-18a9-441bdd000000", + "x-ms-version": "2019-12-12" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "filesystem": "filesystem159239956833708016", + "file": "file159239957007507452" + }, + "newDate": {} + }, + "hash": "c6d159241838e22eddeb2accb80cf720" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__override.json b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__override.json new file mode 100644 index 000000000000..3a31a8908534 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__override.json @@ -0,0 +1,207 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:26 GMT", + "etag": "\"0x8D818256BA3F6B3\"", + "last-modified": "Wed, 24 Jun 2020 10:00:27 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "284e6770-2358-4c68-8b14-10791c5794a9", + "x-ms-request-id": "7b699a1f-501e-0013-5a0e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": { + "resource": "file" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:26 GMT", + "etag": "\"0x8D818256BFD652E\"", + "last-modified": "Wed, 24 Jun 2020 10:00:27 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "80c2d50c-3c97-47d7-ac7d-0948e02d9392", + "x-ms-request-id": "2a2870f9-b01f-0034-210e-4a1661000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": { + "position": "0", + "action": "append" + }, + "requestBody": "Hello World", + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:27 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "51a4f743-9bdc-47e8-ac64-15459a2bcffb", + "x-ms-request-id": "2a2870fe-b01f-0034-250e-4a1661000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": { + "position": "11", + "action": "flush" + }, + "requestBody": "", + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:28 GMT", + "etag": "\"0x8D818256CAC30A7\"", + "last-modified": "Wed, 24 Jun 2020 10:00:28 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "79b7e151-9ac2-423c-b1de-1752aafc999c", + "x-ms-request-id": "2a287101-b01f-0034-280e-4a1661000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:28 GMT", + "etag": "\"0x8D818256CAC30A7\"", + "last-modified": "Wed, 24 Jun 2020 10:00:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b479d931-6e13-430d-9be6-60ff9f42b9ea", + "x-ms-request-id": "7b699a4d-501e-0013-7f0e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "text/plain;charset=UTF-8", + "date": "Wed, 24 Jun 2020 10:00:29 GMT", + "etag": "\"0x8D818256CAC30A7\"", + "last-modified": "Wed, 24 Jun 2020 10:00:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "e477113f-0b4c-4b86-8e5d-96ce34c3cf2b", + "x-ms-creation-time": "Wed, 24 Jun 2020 10:00:27 GMT", + "x-ms-expiry-time": "Wed, 24 Jun 2020 11:00:27 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "7b699a5d-501e-0013-070e-4a01a5000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:29 GMT", + "etag": "\"0x8D818256CAC30A7\"", + "last-modified": "Wed, 24 Jun 2020 10:00:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "79f76f62-d229-4e84-87d3-7ea8fe925080", + "x-ms-request-id": "7b699a6d-501e-0013-120e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611/file159299282745900163", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "text/plain;charset=UTF-8", + "date": "Wed, 24 Jun 2020 10:00:29 GMT", + "etag": "\"0x8D818256CAC30A7\"", + "last-modified": "Wed, 24 Jun 2020 10:00:28 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "cabc72df-422f-4bdb-b375-9ef1f1d9ae09", + "x-ms-creation-time": "Wed, 24 Jun 2020 10:00:27 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "7b699a91-501e-0013-320e-4a01a5000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282687904611", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:30 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "18720132-86c0-4183-921f-f21725174dd5", + "x-ms-request-id": "7b699aa6-501e-0013-430e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "filesystem": "filesystem159299282687904611", + "file": "file159299282745900163" + }, + "newDate": {} + }, + "hash": "481cec3f9359747a3e79454241767795" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetocreation.json b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetocreation.json new file mode 100644 index 000000000000..84519eaf02cb --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetocreation.json @@ -0,0 +1,160 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282283600351", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:22 GMT", + "etag": "\"0x8D81825693B674E\"", + "last-modified": "Wed, 24 Jun 2020 10:00:23 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1738b4fc-5a96-4118-b22e-599bddc02274", + "x-ms-request-id": "7b69993c-501e-0013-140e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282283600351/file159299282341904059", + "query": { + "resource": "file" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:22 GMT", + "etag": "\"0x8D818256994D24E\"", + "last-modified": "Wed, 24 Jun 2020 10:00:23 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "267684a6-91ca-4e19-9971-483d58ae73f8", + "x-ms-request-id": "2a2870c3-b01f-0034-6d0e-4a1661000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282283600351/file159299282341904059", + "query": { + "position": "0", + "action": "append" + }, + "requestBody": "Hello World", + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:23 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9379f59d-1d90-4138-9068-13e12aab467c", + "x-ms-request-id": "2a2870c5-b01f-0034-6f0e-4a1661000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299282283600351/file159299282341904059", + "query": { + "position": "11", + "action": "flush" + }, + "requestBody": "", + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:23 GMT", + "etag": "\"0x8D818256A41F7EB\"", + "last-modified": "Wed, 24 Jun 2020 10:00:24 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d4ec5275-19ce-40d0-9fa1-9f4b1e041184", + "x-ms-request-id": "2a2870e3-b01f-0034-0d0e-4a1661000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282283600351/file159299282341904059", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:24 GMT", + "etag": "\"0x8D818256A41F7EB\"", + "last-modified": "Wed, 24 Jun 2020 10:00:24 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1e8b9979-d442-4abc-8e68-457d76762fcc", + "x-ms-request-id": "7b6999bb-501e-0013-7e0e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282283600351/file159299282341904059", + "query": {}, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "accept-ranges": "bytes", + "content-length": "11", + "content-type": "text/plain;charset=UTF-8", + "date": "Wed, 24 Jun 2020 10:00:25 GMT", + "etag": "\"0x8D818256A41F7EB\"", + "last-modified": "Wed, 24 Jun 2020 10:00:24 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "5cec842e-89ae-4692-9479-aa07735aab1f", + "x-ms-creation-time": "Wed, 24 Jun 2020 10:00:23 GMT", + "x-ms-expiry-time": "Wed, 24 Jun 2020 11:00:23 GMT", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "7b6999de-501e-0013-1e0e-4a01a5000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299282283600351", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:25 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "534826a1-815c-4e23-9c06-63eb04787cb3", + "x-ms-request-id": "7b699a01-501e-0013-3e0e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "filesystem": "filesystem159299282283600351", + "file": "file159299282341904059" + }, + "newDate": {} + }, + "hash": "201798d7335e3eb29b47567fb4b9c17c" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetonow.json b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetonow.json new file mode 100644 index 000000000000..792bb767fb1b --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/browsers/datalakepathclient/recording_set_expiry__relativetonow.json @@ -0,0 +1,149 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299281555203886", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:16 GMT", + "etag": "\"0x8D81825658CF317\"", + "last-modified": "Wed, 24 Jun 2020 10:00:16 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "aef775b7-7512-4c5d-b230-181d79ac815b", + "x-ms-request-id": "7b699848-501e-0013-420e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299281555203886/file159299281729603669", + "query": { + "resource": "file" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:17 GMT", + "etag": "\"0x8D8182566872C7E\"", + "last-modified": "Wed, 24 Jun 2020 10:00:18 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "89d244c1-145b-4006-b1f0-45fdaa0751c5", + "x-ms-request-id": "2a28708a-b01f-0034-350e-4a1661000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299281555203886/file159299281729603669", + "query": { + "position": "0", + "action": "append" + }, + "requestBody": "Hello World", + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:18 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "ee4d1524-bd5a-46e7-8152-57b887eab692", + "x-ms-request-id": "2a28708e-b01f-0034-390e-4a1661000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PATCH", + "url": "https://fakestorageaccount.dfs.core.windows.net/filesystem159299281555203886/file159299281729603669", + "query": { + "position": "11", + "action": "flush" + }, + "requestBody": "", + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:18 GMT", + "etag": "\"0x8D818256736A9F3\"", + "last-modified": "Wed, 24 Jun 2020 10:00:19 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9b2f0792-defb-4ba0-8087-af4c1fcdf6aa", + "x-ms-request-id": "2a287091-b01f-0034-3c0e-4a1661000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299281555203886/file159299281729603669", + "query": { + "comp": "expiry" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:19 GMT", + "etag": "\"0x8D818256736A9F3\"", + "last-modified": "Wed, 24 Jun 2020 10:00:19 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "a590a4c7-7459-4da1-bebb-67c7b4e7508a", + "x-ms-request-id": "7b6998b7-501e-0013-1c0e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "HEAD", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299281555203886/file159299281729603669", + "query": {}, + "requestBody": null, + "status": 404, + "response": "", + "responseHeaders": { + "date": "Wed, 24 Jun 2020 10:00:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "af0a4934-6669-49d6-ac52-a77af454a844", + "x-ms-error-code": "BlobNotFound", + "x-ms-request-id": "7b6998f5-501e-0013-570e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.blob.core.windows.net/filesystem159299281555203886", + "query": { + "restype": "container" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Wed, 24 Jun 2020 10:00:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "58a23de7-6823-457c-8aa6-1538b80b3749", + "x-ms-request-id": "7b699919-501e-0013-750e-4a01a5000000", + "x-ms-version": "2019-12-12" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "filesystem": "filesystem159299281555203886", + "file": "file159299281729603669" + }, + "newDate": {} + }, + "hash": "c0da3264e322f03bf5b03f643ca889cf" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__absolute.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__absolute.js new file mode 100644 index 000000000000..40010cb3d69d --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__absolute.js @@ -0,0 +1,201 @@ +let nock = require('nock'); + +module.exports.hash = "42ea6f8cd24d4b0d44ffa4ddf236bf54"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159352492035906829","file":"file159352492196002191"},"newDate":{"now":"2020-06-30T13:48:43.836Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159352492035906829') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 30 Jun 2020 13:48:41 GMT', + 'ETag', + '"0x8D81CFC4C618ABE"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e0bc4ebc-201e-006b-19e5-4ea25d000000', + 'x-ms-client-request-id', + '5a185975-5ccc-4798-8c9d-a4a24c8d81c0', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Tue, 30 Jun 2020 13:48:40 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159352492035906829/file159352492196002191') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 30 Jun 2020 13:48:42 GMT', + 'ETag', + '"0x8D81CFC4D3A1C4B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '7da89b3e-a01f-0028-24e5-4e4401000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '37091797-e064-4645-b3b5-52208ea00020', + 'Date', + 'Tue, 30 Jun 2020 13:48:42 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159352492035906829/file159352492196002191', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '7da89b40-a01f-0028-25e5-4e4401000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '4732a7ac-1c45-4333-9b4f-7a209c4aca62', + 'Date', + 'Tue, 30 Jun 2020 13:48:42 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159352492035906829/file159352492196002191') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 30 Jun 2020 13:48:43 GMT', + 'ETag', + '"0x8D81CFC4D9386C4"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '7da89b42-a01f-0028-26e5-4e4401000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'e7f455bd-2059-48d8-8d97-a80c99cb9aee', + 'Date', + 'Tue, 30 Jun 2020 13:48:43 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159352492035906829/file159352492196002191') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 30 Jun 2020 13:48:43 GMT', + 'ETag', + '"0x8D81CFC4D9386C4"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e0bc4f2d-201e-006b-6fe5-4ea25d000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '906a8309-f807-4cc5-9042-ffb24a2bfcfe', + 'Date', + 'Tue, 30 Jun 2020 13:48:43 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159352492035906829/file159352492196002191') + .reply(200, "", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Tue, 30 Jun 2020 13:48:43 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D81CFC4D9386C4"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e0bc4f3b-201e-006b-7ae5-4ea25d000000', + 'x-ms-client-request-id', + '124b715a-dd1f-4b80-9da3-9d80039becab', + 'x-ms-version', + '2019-12-12', + 'x-ms-creation-time', + 'Tue, 30 Jun 2020 13:48:42 GMT', + 'x-ms-expiry-time', + 'Tue, 30 Jun 2020 13:48:48 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + '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-expiry-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Tue, 30 Jun 2020 13:48:43 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159352492035906829/file159352492196002191') + .reply(404, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e0bc504b-201e-006b-58e5-4ea25d000000', + 'x-ms-client-request-id', + '8e7659fb-a4a0-4117-9022-1c32706231f2', + 'x-ms-version', + '2019-12-12', + 'x-ms-error-code', + 'BlobNotFound', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-error-code,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Tue, 30 Jun 2020 13:48:48 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159352492035906829') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e0bc5055-201e-006b-5ee5-4ea25d000000', + 'x-ms-client-request-id', + '645421a7-c602-4e6e-900d-df247bccd167', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Tue, 30 Jun 2020 13:48:49 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__neverexpire.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__neverexpire.js new file mode 100644 index 000000000000..d07bfc57eb8d --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__neverexpire.js @@ -0,0 +1,190 @@ +let nock = require('nock'); + +module.exports.hash = "4a4fed79044d292913f1861b636c5f4a"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159239943150501028","file":"file159239943296504342"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159239943150501028') + .query(true) + .reply(201, "", [ + 'content-length', + '0', + 'last-modified', + 'Wed, 17 Jun 2020 13:10:32 GMT', + 'etag', + '"0x8D812BFD107142D"', + 'server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4a588ac5-c01e-005c-4ea8-4470f1000000', + 'x-ms-client-request-id', + '944452a5-b237-40bf-8b1c-7d2cbc4608e8', + 'x-ms-version', + '2019-12-12', + 'date', + 'Wed, 17 Jun 2020 13:10:31 GMT', + 'connection', + 'close' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159239943150501028/file159239943296504342') + .query(true) + .reply(201, "", [ + 'last-modified', + 'Wed, 17 Jun 2020 13:10:34 GMT', + 'etag', + '"0x8D812BFD1D625F7"', + 'server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '727808fc-701f-0004-11a8-44a8ae000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '057a4301-1bb1-464c-b546-923313169e84', + 'date', + 'Wed, 17 Jun 2020 13:10:33 GMT', + 'connection', + 'close', + 'content-length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159239943150501028/file159239943296504342', "Hello World") + .query(true) + .reply(202, "", [ + 'server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '23bb3cc3-801f-0010-42a8-44e0c1000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '702a8037-ec33-46b3-a726-b7d7609cf734', + 'date', + 'Wed, 17 Jun 2020 13:10:35 GMT', + 'connection', + 'close', + 'content-length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159239943150501028/file159239943296504342') + .query(true) + .reply(200, "", [ + 'last-modified', + 'Wed, 17 Jun 2020 13:10:36 GMT', + 'etag', + '"0x8D812BFD351E306"', + 'server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '326cc5a0-601f-0045-34a8-44f04a000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '92cb20a5-bf65-4dfb-b06d-6c5eb91bf2ba', + 'date', + 'Wed, 17 Jun 2020 13:10:35 GMT', + 'connection', + 'close', + 'content-length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159239943150501028/file159239943296504342') + .query(true) + .reply(200, "", [ + 'last-modified', + 'Wed, 17 Jun 2020 13:10:36 GMT', + 'etag', + '"0x8D812BFD351E306"', + 'server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'b997c7b7-501e-003c-54a8-440c6e000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '3565e493-9d75-488b-a896-2b0b7dd28a4e', + 'date', + 'Wed, 17 Jun 2020 13:10:37 GMT', + 'connection', + 'close', + 'content-length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159239943150501028/file159239943296504342') + .reply(200, "", [ + 'content-length', + '11', + 'content-type', + 'application/octet-stream', + 'last-modified', + 'Wed, 17 Jun 2020 13:10:36 GMT', + 'accept-ranges', + 'bytes', + 'etag', + '"0x8D812BFD351E306"', + 'server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'a4226320-801e-003f-7aa8-44ed0a000000', + 'x-ms-client-request-id', + '3b1fdbb9-6c0a-47dc-ab91-8c247c686aca', + 'x-ms-version', + '2019-12-12', + 'x-ms-creation-time', + 'Wed, 17 Jun 2020 13:10:34 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + '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-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'access-control-allow-origin', + '*', + 'date', + 'Wed, 17 Jun 2020 13:10:38 GMT', + 'connection', + 'close' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159239943150501028') + .query(true) + .reply(202, "", [ + 'content-length', + '0', + 'server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'a0ab7cbe-201e-0036-08a8-44a8d9000000', + 'x-ms-client-request-id', + '9663c928-6d37-42f5-aeb4-8188214cb0da', + 'x-ms-version', + '2019-12-12', + 'date', + 'Wed, 17 Jun 2020 13:10:39 GMT', + 'connection', + 'close' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__override.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__override.js new file mode 100644 index 000000000000..e380cd71bac1 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__override.js @@ -0,0 +1,243 @@ +let nock = require('nock'); + +module.exports.hash = "49ae201267dbd16bc5c2949dfdee3daa"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159299255423504608","file":"file159299255462704152"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255423504608') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'ETag', + '"0x8D81824C8FC84C9"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03b8d-a01e-0007-7a0d-4a49ca000000', + 'x-ms-client-request-id', + '8399bc23-b69d-46ad-b4ff-5b656ec741d2', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:53 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255423504608/file159299255462704152') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'ETag', + '"0x8D81824C93ABDDE"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6f8e5650-501f-0003-790d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'adcc7919-125e-40d9-9909-47bdc889e0f7', + 'Date', + 'Wed, 24 Jun 2020 09:55:53 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299255423504608/file159299255462704152', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '6f8e565e-501f-0003-070d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'e01417a4-e8a8-404c-9d3a-89b44b517fc8', + 'Date', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299255423504608/file159299255462704152') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'ETag', + '"0x8D81824C9C67EF8"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '6f8e566c-501f-0003-130d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'dd4bb946-c11c-4652-b9ca-1dc2a54f644f', + 'Date', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255423504608/file159299255462704152') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'ETag', + '"0x8D81824C9C67EF8"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03c15-a01e-0007-6a0d-4a49ca000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'fd6a7cd3-2b10-43ff-9f3d-d1240d306701', + 'Date', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159299255423504608/file159299255462704152') + .reply(200, "", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D81824C9C67EF8"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03c41-a01e-0007-110d-4a49ca000000', + 'x-ms-client-request-id', + '5ea0a817-c9e0-4207-89d5-a3c6cda5de44', + 'x-ms-version', + '2019-12-12', + 'x-ms-creation-time', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'x-ms-expiry-time', + 'Wed, 24 Jun 2020 10:55:54 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + '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-expiry-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Wed, 24 Jun 2020 09:55:56 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255423504608/file159299255462704152') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'ETag', + '"0x8D81824C9C67EF8"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03c79-a01e-0007-450d-4a49ca000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '9e2e5751-679d-438b-8385-ca4642b86e2c', + 'Date', + 'Wed, 24 Jun 2020 09:55:56 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159299255423504608/file159299255462704152') + .reply(200, "", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:55 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D81824C9C67EF8"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03c96-a01e-0007-590d-4a49ca000000', + 'x-ms-client-request-id', + 'a07246d0-d412-4b73-b304-c966648ecb76', + 'x-ms-version', + '2019-12-12', + 'x-ms-creation-time', + 'Wed, 24 Jun 2020 09:55:54 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + '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-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Wed, 24 Jun 2020 09:55:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159299255423504608') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03cc6-a01e-0007-040d-4a49ca000000', + 'x-ms-client-request-id', + '2a8fb699-f327-427d-9825-d807836519b8', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:57 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetocreation.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetocreation.js new file mode 100644 index 000000000000..e865460d650f --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetocreation.js @@ -0,0 +1,178 @@ +let nock = require('nock'); + +module.exports.hash = "1b61a967d608c729ba89903bf69e5ff8"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159299255097900923","file":"file159299255140603883"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255097900923') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:50 GMT', + 'ETag', + '"0x8D81824C70679AD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03a72-a01e-0007-1c0d-4a49ca000000', + 'x-ms-client-request-id', + '87942801-834d-4d1f-8168-6b7e993594f0', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:50 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255097900923/file159299255140603883') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:51 GMT', + 'ETag', + '"0x8D81824C75D6C43"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6f8e5601-501f-0003-2b0d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'caee113c-8d02-4cc7-833c-c4cbbf67e0ec', + 'Date', + 'Wed, 24 Jun 2020 09:55:50 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299255097900923/file159299255140603883', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '6f8e5602-501f-0003-2c0d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '0a5cbc12-2ae2-4560-94b9-4719100e4629', + 'Date', + 'Wed, 24 Jun 2020 09:55:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299255097900923/file159299255140603883') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:52 GMT', + 'ETag', + '"0x8D81824C7DF53B3"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '6f8e5603-501f-0003-2d0d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'ce07f92e-cc8f-438e-a833-a236bf4e6884', + 'Date', + 'Wed, 24 Jun 2020 09:55:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299255097900923/file159299255140603883') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:52 GMT', + 'ETag', + '"0x8D81824C7DF53B3"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03b36-a01e-0007-2e0d-4a49ca000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '51df929b-5e32-437d-9527-01dc9348ed23', + 'Date', + 'Wed, 24 Jun 2020 09:55:52 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159299255097900923/file159299255140603883') + .reply(200, "", [ + 'Content-Length', + '11', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:52 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D81824C7DF53B3"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03b52-a01e-0007-460d-4a49ca000000', + 'x-ms-client-request-id', + '9b880212-c59d-4477-81f8-0d942e429cc9', + 'x-ms-version', + '2019-12-12', + 'x-ms-creation-time', + 'Wed, 24 Jun 2020 09:55:51 GMT', + 'x-ms-expiry-time', + 'Wed, 24 Jun 2020 10:55:51 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + '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-expiry-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Wed, 24 Jun 2020 09:55:52 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159299255097900923') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03b74-a01e-0007-640d-4a49ca000000', + 'x-ms-client-request-id', + 'c5ae678f-e7d5-4063-9dcb-ac65af589cdc', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:53 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetonow.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetonow.js new file mode 100644 index 000000000000..cb1edc154d60 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient/recording_set_expiry__relativetonow.js @@ -0,0 +1,156 @@ +let nock = require('nock'); + +module.exports.hash = "de1ed5242bebc0c085f969ddc1486386"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159299254439403398","file":"file159299254594100472"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299254439403398') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:45 GMT', + 'ETag', + '"0x8D81824C3C7C8D7"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e038c9-a01e-0007-490d-4a49ca000000', + 'x-ms-client-request-id', + 'd5ee2979-c506-412f-93ae-75c0e7cf0024', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:45 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299254439403398/file159299254594100472') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:47 GMT', + 'ETag', + '"0x8D81824C4B7A0DF"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '6f8e55b5-501f-0003-690d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '8ede6eeb-edc0-416e-a9c9-c7460d70a766', + 'Date', + 'Wed, 24 Jun 2020 09:55:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299254439403398/file159299254594100472', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '6f8e55bb-501f-0003-6f0d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '9c370921-6e24-4587-93bb-9fe701baa41e', + 'Date', + 'Wed, 24 Jun 2020 09:55:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159299254439403398/file159299254594100472') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:48 GMT', + 'ETag', + '"0x8D81824C5576AFC"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '6f8e55c3-501f-0003-700d-4ac4cd000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '7d6cab88-2231-487b-b040-b512fa3c0e7c', + 'Date', + 'Wed, 24 Jun 2020 09:55:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159299254439403398/file159299254594100472') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 09:55:48 GMT', + 'ETag', + '"0x8D81824C5576AFC"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e039d8-a01e-0007-1f0d-4a49ca000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'a9331e1b-818a-41c7-b8cb-1f2e6355e02e', + 'Date', + 'Wed, 24 Jun 2020 09:55:48 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem159299254439403398/file159299254594100472') + .reply(404, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03a3a-a01e-0007-6f0d-4a49ca000000', + 'x-ms-client-request-id', + 'bd867b0d-504a-4d8f-bac4-6acf493f478a', + 'x-ms-version', + '2019-12-12', + 'x-ms-error-code', + 'BlobNotFound', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-error-code,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Wed, 24 Jun 2020 09:55:49 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159299254439403398') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '00e03a5e-a01e-0007-0b0d-4a49ca000000', + 'x-ms-client-request-id', + 'f953a6a0-8863-4f31-823c-4cd1328dfa90', + 'x-ms-version', + '2019-12-12', + 'Date', + 'Wed, 24 Jun 2020 09:55:50 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_nodejs_only/recording_quick_query_should_work_with_arrow_output_configuration.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_nodejs_only/recording_quick_query_should_work_with_arrow_output_configuration.js new file mode 100644 index 000000000000..46972661dd2e --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_nodejs_only/recording_quick_query_should_work_with_arrow_output_configuration.js @@ -0,0 +1,193 @@ +let nock = require('nock'); + +module.exports.hash = "5d698c75689d843c8dc3544d7ca6d674"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160084667955801065","file":"file160084668061309353"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160084667955801065') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:00 GMT', + 'ETag', + '"0x8D85F93990039E1"', + 'x-ms-request-id', + 'ff775b84-501e-0005-277c-91eaf9000000', + 'x-ms-client-request-id', + 'bcc444f1-1b4b-423b-b675-ffaed21ae2e1', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Wed, 23 Sep 2020 07:38:00 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160084667955801065/file160084668061309353') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'ETag', + '"0x8D85F939996BD58"', + 'x-ms-request-id', + '51b9d5bf-801f-0008-457c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '52fb17bc-9218-4700-b9a0-51280c043c71', + 'Date', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160084667955801065/file160084668061309353', "Hello World") + .query(true) + .reply(202, "", [ + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '51b9d5c0-801f-0008-467c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd7ce3602-64ba-419e-ae00-f0db9a5c9dd7', + 'Date', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160084667955801065/file160084668061309353') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'ETag', + '"0x8D85F9399E32F9A"', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '51b9d5c1-801f-0008-477c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '8d500751-7371-44ac-a85a-0b047fcea14f', + 'Date', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160084667955801065/file1600846680613093532') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:02 GMT', + 'ETag', + '"0x8D85F939A0843F0"', + 'x-ms-request-id', + '51b9d5c2-801f-0008-487c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'a7335df3-c7c7-4620-90f1-64d4b905f209', + 'Date', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160084667955801065/file1600846680613093532', "100,200,300,400\n150,250,350,450\n") + .query(true) + .reply(202, "", [ + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '51b9d5c3-801f-0008-497c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '4c2ca286-fc1b-4038-ade1-a9bd8555ac48', + 'Date', + 'Wed, 23 Sep 2020 07:38:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160084667955801065/file1600846680613093532') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:02 GMT', + 'ETag', + '"0x8D85F939A548F3E"', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '51b9d5c4-801f-0008-4a7c-91d877000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'c6fca687-c9a8-4dad-98d4-662808b8fa99', + 'Date', + 'Wed, 23 Sep 2020 07:38:02 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/filesystem160084667955801065/file1600846680613093532', "SQLselect * from BlobStoragearrowdecimalname42") + .query(true) + .reply(200, Buffer.from("4f626a0102166176726f2e736368656d61be1e5b0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e726573756c7444617461222c0a2020202022646f63223a2022486f6c647320726573756c74206461746120696e2074686520666f726d61742073706563696669656420666f72207468697320717565727920284353562c204a534f4e2c206574632e292e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202264617461222c0a20202020202020202274797065223a20226279746573220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e6572726f72222c0a2020202022646f63223a2022416e206572726f722074686174206f63637572726564207768696c652070726f63657373696e67207468652071756572792e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022666174616c222c0a20202020202020202274797065223a2022626f6f6c65616e222c0a202020202020202022646f63223a2022496620747275652c2074686973206572726f722070726576656e747320667572746865722071756572792070726f63657373696e672e20204d6f726520726573756c742064617461206d61792062652072657475726e65642c20627574207468657265206973206e6f2067756172616e746565207468617420616c6c206f6620746865206f726967696e616c20646174612077696c6c2062652070726f6365737365642e202049662066616c73652c2074686973206572726f7220646f6573206e6f742070726576656e7420667572746865722071756572792070726f63657373696e672e220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226e616d65222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a2022546865206e616d65206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a20226465736372697074696f6e222c0a20202020202020202274797065223a2022737472696e67222c0a202020202020202022646f63223a202241206465736372697074696f6e206f6620746865206572726f72220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022706f736974696f6e222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520626c6f62206f666673657420617420776869636820746865206572726f72206f63637572726564220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e70726f6772657373222c0a2020202022646f63223a2022496e666f726d6174696f6e2061626f7574207468652070726f6772657373206f6620746865207175657279222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a202262797465735363616e6e6564222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a2022546865206e756d626572206f6620627974657320746861742068617665206265656e207363616e6e6564220a2020202020207d2c0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d2c0a20207b0a202020202274797065223a20227265636f7264222c0a20202020226e616d65223a2022636f6d2e6d6963726f736f66742e617a7572652e73746f726167652e7175657279426c6f62436f6e74656e74732e656e64222c0a2020202022646f63223a202253656e74206173207468652066696e616c206d657373616765206f662074686520726573706f6e73652c20696e6469636174696e67207468617420616c6c20726573756c74732068617665206265656e2073656e742e222c0a20202020226669656c6473223a205b0a2020202020207b0a2020202020202020226e616d65223a2022746f74616c4279746573222c0a20202020202020202274797065223a20226c6f6e67222c0a202020202020202022646f63223a202254686520746f74616c206e756d626572206f6620627974657320746f206265207363616e6e656420696e2074686973207175657279220a2020202020207d0a202020205d0a20207d0a5d0a00796d4c0f3e9bcb4f8fa2ff91e58363b0028604008004ffffffff800000001000000000000a000c000600050008000a000000000103000c000000080008000000040008000000040000000100000014000000100014000800060007000c000000100010000000000001072400000014000000040000000000000008000c0004000800080000000400000002000000040000006e616d650000000000000000ffffffff700000001000000000000a000e000600050008000a000000000303001000000000000a000c000000040008000a0000003000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000796d4c0f3e9bcb4f8fa2ff91e58363b002040000796d4c0f3e9bcb4f8fa2ff91e58363b0028e01020116436c69656e744572726f726e4e756d626572206f6620636f6c756d6e7320696e2074686520726f7720646f6573206e6f74206d617463682074686520736368656d612e00796d4c0f3e9bcb4f8fa2ff91e58363b00206044040796d4c0f3e9bcb4f8fa2ff91e58363b002040640796d4c0f3e9bcb4f8fa2ff91e58363b0", "hex"), [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'avro/binary', + 'Last-Modified', + 'Wed, 23 Sep 2020 07:38:02 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D85F939A548F3E"', + 'x-ms-creation-time', + 'Wed, 23 Sep 2020 07:38:02 GMT', + 'x-ms-lease-state', + 'available', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-request-id', + 'ff775b88-501e-0005-287c-91eaf9000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '27daec12-f082-427c-bfcb-8c54f3ddafea', + 'Date', + 'Wed, 23 Sep 2020 07:38:02 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160084667955801065') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'x-ms-request-id', + '0b36984e-d01e-0006-0c7c-911999000000', + 'x-ms-client-request-id', + '878568e4-a9ce-4286-b7fd-9849bff17e6f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Wed, 23 Sep 2020 07:38:03 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_removeaccesscontrolrecursive_should_work.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_removeaccesscontrolrecursive_should_work.js new file mode 100644 index 000000000000..d6d87fef4b10 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_removeaccesscontrolrecursive_should_work.js @@ -0,0 +1,305 @@ +let nock = require('nock'); + +module.exports.hash = "58002ae506fe252a2994f2ba7154920f"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242186122909357","file":"file160242186152903731","directory":"directory160242186242404657","subdirectory1":"subdirectory1160242186242404941","fileName1":"fileName1160242186242406524","fileName2":"fileName2160242186242403741","subdirectory2":"subdirectory2160242186242401269","fileName3":"fileName3160242186242407717","fileName4":"fileName4160242186242403760"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:03 GMT', + 'ETag', + '"0x8D86DE6D390DB80"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '7618693b-601e-006a-57cf-9ffd81000000', + 'x-ms-client-request-id', + '8696e700-b2c5-4ddd-9946-19e348765515', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:09:02 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/file160242186152903731') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:03 GMT', + 'ETag', + '"0x8D86DE6D3BFB470"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6df-a01f-0017-4fcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '0653089e-5583-4360-bbfa-b800e3a7532c', + 'Date', + 'Sun, 11 Oct 2020 13:09:02 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186122909357/file160242186152903731', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a6e4-a01f-0017-54cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '56d18754-bb54-4553-bc12-a42e8182540e', + 'Date', + 'Sun, 11 Oct 2020 13:09:03 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186122909357/file160242186152903731') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'ETag', + '"0x8D86DE6D41AC281"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a6e9-a01f-0017-59cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '70631e58-31db-4c0b-9c10-6a262599e089', + 'Date', + 'Sun, 11 Oct 2020 13:09:03 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'ETag', + '"0x8D86DE6D448F80D"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6ee-a01f-0017-5ecf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'de508a91-02e3-42b8-acaa-0438939bb9f5', + 'Date', + 'Sun, 11 Oct 2020 13:09:03 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory1160242186242404941') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'ETag', + '"0x8D86DE6D4758AAA"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6f2-a01f-0017-62cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd4849733-34e2-4489-8098-6f9fbf0d3e5e', + 'Date', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory2160242186242401269') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'ETag', + '"0x8D86DE6D4A28620"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6f7-a01f-0017-67cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'dd5acf10-1ec3-4c93-9d9d-2b83279281c6', + 'Date', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory1160242186242404941/fileName1160242186242406524') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'ETag', + '"0x8D86DE6D4CFC4FA"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6fd-a01f-0017-6dcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '64c5d52b-0104-4a6d-b4de-eca06e43aa44', + 'Date', + 'Sun, 11 Oct 2020 13:09:04 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory1160242186242404941/fileName2160242186242403741') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'ETag', + '"0x8D86DE6D4FCB578"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a701-a01f-0017-70cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'dd0f95d3-1a44-4701-b0aa-360a335739a1', + 'Date', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory2160242186242401269/fileName3160242186242407717') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'ETag', + '"0x8D86DE6D529FF38"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a703-a01f-0017-72cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'f1b2aeb3-17d1-4987-9d53-d08415f7e971', + 'Date', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186122909357/directory160242186242404657/subdirectory2160242186242401269/fileName4160242186242403760') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:06 GMT', + 'ETag', + '"0x8D86DE6D556F2DA"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a706-a01f-0017-75cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '4436b130-1271-4903-ac76-da180f218fec', + 'Date', + 'Sun, 11 Oct 2020 13:09:05 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186122909357/directory160242186242404657') + .query(true) + .reply(200, {"directoriesSuccessful":3,"failedEntries":[],"failureCount":0,"filesSuccessful":4}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a709-a01f-0017-78cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '4103e281-1727-48b6-b8a3-9d9ce4efd9b8', + 'Date', + 'Sun, 11 Oct 2020 13:09:05 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186122909357/directory160242186242404657') + .query(true) + .reply(200, {"directoriesSuccessful":3,"failedEntries":[],"failureCount":0,"filesSuccessful":4}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a70d-a01f-0017-7ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '440f3792-c3b4-46c4-90be-521be2f2f137', + 'Date', + 'Sun, 11 Oct 2020 13:09:06 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242186122909357') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186a3e-601e-006a-33cf-9ffd81000000', + 'x-ms-client-request-id', + 'd90a9784-d6d6-4692-86ac-8fa8e864bb38', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:09:06 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work.js new file mode 100644 index 000000000000..2ce3978b335c --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work.js @@ -0,0 +1,285 @@ +let nock = require('nock'); + +module.exports.hash = "a1335e4f0e821d02462b93ec230af493"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242183831705700","file":"file160242183972906255","directory":"directory160242184177807351","subdirectory1":"subdirectory1160242184177902176","fileName1":"fileName1160242184177901069","fileName2":"fileName2160242184177902649","subdirectory2":"subdirectory2160242184177903211","fileName3":"fileName3160242184177909160","fileName4":"fileName4160242184177900935"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:41 GMT', + 'ETag', + '"0x8D86DE6C68E9FFA"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '761862e2-601e-006a-5fcf-9ffd81000000', + 'x-ms-client-request-id', + '6e817839-47f4-4f2d-8d4f-c82ee86a6ece', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:41 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/file160242183972906255') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:42 GMT', + 'ETag', + '"0x8D86DE6C770BA68"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5a3-a01f-0017-1acf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '6f257ce2-1703-41ad-a67a-827f672646af', + 'Date', + 'Sun, 11 Oct 2020 13:08:42 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242183831705700/file160242183972906255', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a5a7-a01f-0017-1ecf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '291836a1-9dff-474d-97ee-6008227c1e19', + 'Date', + 'Sun, 11 Oct 2020 13:08:42 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242183831705700/file160242183972906255') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:43 GMT', + 'ETag', + '"0x8D86DE6C7CCBD50"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a5af-a01f-0017-25cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'ee2392ca-a5b0-4f21-a8d7-b976125e36b5', + 'Date', + 'Sun, 11 Oct 2020 13:08:42 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:43 GMT', + 'ETag', + '"0x8D86DE6C7FB742C"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5b5-a01f-0017-2bcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '7b839343-6813-459f-819a-6ea726583e9a', + 'Date', + 'Sun, 11 Oct 2020 13:08:43 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory1160242184177902176') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'ETag', + '"0x8D86DE6C828B970"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5b6-a01f-0017-2ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '429ce099-4f38-4e2c-9be2-42a55a20d110', + 'Date', + 'Sun, 11 Oct 2020 13:08:43 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory2160242184177903211') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'ETag', + '"0x8D86DE6C8553529"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5bc-a01f-0017-32cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'c319d4c2-c2b5-4db8-81f9-9bd929af429e', + 'Date', + 'Sun, 11 Oct 2020 13:08:43 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory1160242184177902176/fileName1160242184177901069') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'ETag', + '"0x8D86DE6C88364DA"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5c4-a01f-0017-3acf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '5bed7025-d0f2-4dfe-a52d-d5dc7de85d3d', + 'Date', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory1160242184177902176/fileName2160242184177902649') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'ETag', + '"0x8D86DE6C8B1C81E"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5cc-a01f-0017-42cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'b383b4cd-c48d-4101-9778-97fd2099bc29', + 'Date', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory2160242184177903211/fileName3160242184177909160') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:45 GMT', + 'ETag', + '"0x8D86DE6C8DF5BD6"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5db-a01f-0017-51cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '24e3548b-6f81-4ec2-8b1f-bbfd9547f745', + 'Date', + 'Sun, 11 Oct 2020 13:08:44 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242183831705700/directory160242184177807351/subdirectory2160242184177903211/fileName4160242184177900935') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:45 GMT', + 'ETag', + '"0x8D86DE6C90C4C69"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a5e6-a01f-0017-5bcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '0b69dbba-bf62-4462-8d3f-2530afa2f678', + 'Date', + 'Sun, 11 Oct 2020 13:08:45 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242183831705700/directory160242184177807351') + .query(true) + .reply(200, {"directoriesSuccessful":3,"failedEntries":[],"failureCount":0,"filesSuccessful":4}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a5f0-a01f-0017-65cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '42d4c62c-6b3e-4415-9f1e-9d6c0ee95424', + 'Date', + 'Sun, 11 Oct 2020 13:08:45 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242183831705700') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186488-601e-006a-35cf-9ffd81000000', + 'x-ms-client-request-id', + 'a9b3cda8-046c-4053-ad2b-0a0843550d42', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:45 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_aborter__resume_.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_aborter__resume_.js new file mode 100644 index 000000000000..72c25a0137ac --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_aborter__resume_.js @@ -0,0 +1,307 @@ +let nock = require('nock'); + +module.exports.hash = "40a2a13aeb4cfabdd2f878bc055a89a2"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242185317302296","file":"file160242185347203676","directory":"directory160242185435205746","subdirectory1":"subdirectory1160242185435205538","fileName1":"fileName1160242185435200504","fileName2":"fileName2160242185435201110","subdirectory2":"subdirectory2160242185435206202","fileName3":"fileName3160242185435206246","fileName4":"fileName4160242185435203369"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:55 GMT', + 'ETag', + '"0x8D86DE6CEC35E82"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186738-601e-006a-5ecf-9ffd81000000', + 'x-ms-client-request-id', + '9f720722-5e4a-464e-b70f-af962ed42951', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:54 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/file160242185347203676') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:55 GMT', + 'ETag', + '"0x8D86DE6CEF23ED2"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a671-a01f-0017-64cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '30e6871e-93ca-4a22-896b-9866aecbacaf', + 'Date', + 'Sun, 11 Oct 2020 13:08:54 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185317302296/file160242185347203676', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a674-a01f-0017-67cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'a5b2777a-1d72-4179-a5ba-cf1c72d32e44', + 'Date', + 'Sun, 11 Oct 2020 13:08:55 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185317302296/file160242185347203676') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'ETag', + '"0x8D86DE6CF4B7202"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a67b-a01f-0017-6dcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'e6fab354-acdd-49ab-a20a-0da416a51664', + 'Date', + 'Sun, 11 Oct 2020 13:08:55 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'ETag', + '"0x8D86DE6CF787D25"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a67e-a01f-0017-70cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '5a58cfa5-b3b7-401c-b5d0-061703f50392', + 'Date', + 'Sun, 11 Oct 2020 13:08:55 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory1160242185435205538') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'ETag', + '"0x8D86DE6CFA5BC13"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a681-a01f-0017-73cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '56ff0066-a0fc-4694-8081-e901ec0f74f9', + 'Date', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory2160242185435206202') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'ETag', + '"0x8D86DE6CFD2174D"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a684-a01f-0017-76cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '8cc89b59-e975-467f-8a06-1e21d34ee75f', + 'Date', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory1160242185435205538/fileName1160242185435200504') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:57 GMT', + 'ETag', + '"0x8D86DE6CFFF0EBC"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a686-a01f-0017-78cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1fbd8b2f-d56a-4e34-9654-94c4039ff59f', + 'Date', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory1160242185435205538/fileName2160242185435201110') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:57 GMT', + 'ETag', + '"0x8D86DE6D02BD58A"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a689-a01f-0017-7bcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3c0d2ddf-7104-42c8-b47f-aabded8fd6f0', + 'Date', + 'Sun, 11 Oct 2020 13:08:56 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory2160242185435206202/fileName3160242185435206246') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:57 GMT', + 'ETag', + '"0x8D86DE6D058898C"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a68d-a01f-0017-7fcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '73989f25-1bfd-4933-b4d3-8b90201951fe', + 'Date', + 'Sun, 11 Oct 2020 13:08:57 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185317302296/directory160242185435205746/subdirectory2160242185435206202/fileName4160242185435203369') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:58 GMT', + 'ETag', + '"0x8D86DE6D08652E2"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a690-a01f-0017-02cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '09c57090-13c1-42fb-b802-a83ad23f84ac', + 'Date', + 'Sun, 11 Oct 2020 13:08:57 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185317302296/directory160242185435205746') + .query(true) + .reply(200, {"directoriesSuccessful":2,"failedEntries":[],"failureCount":0,"filesSuccessful":0}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-continuation', + 'VBb2ue2Wkue3410YrAEYpgEveGlhb25saWV1YXBobnMBMDFENjQ1NEZBNDAzQjY0OC9maWxlc3lzdGVtMTYwMjQyMTg1MzE3MzAyMjk2ATAxRDY5RkNGQUM0Q0I0NEEvZGlyZWN0b3J5MTYwMjQyMTg1NDM1MjA1NzQ2L3N1YmRpcmVjdG9yeTExNjAyNDIxODU0MzUyMDU1MzgvZmlsZU5hbWUxMTYwMjQyMTg1NDM1MjAwNTA0FgAAAA==', + 'x-ms-request-id', + '66c1a697-a01f-0017-09cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '381ac342-36dd-49a9-b59d-d93bb9462014', + 'Date', + 'Sun, 11 Oct 2020 13:08:57 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185317302296/directory160242185435205746') + .query(true) + .reply(200, {"directoriesSuccessful":1,"failedEntries":[],"failureCount":0,"filesSuccessful":4}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a69c-a01f-0017-0dcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '7dd630a9-91bd-4743-b886-114d543e04af', + 'Date', + 'Sun, 11 Oct 2020 13:08:58 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242185317302296') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186809-601e-006a-72cf-9ffd81000000', + 'x-ms-client-request-id', + 'b84bfc02-7fbe-4496-9f48-b41718fa67cc', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:58 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__batchsize.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__batchsize.js new file mode 100644 index 000000000000..3abdc06ed5fe --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__batchsize.js @@ -0,0 +1,351 @@ +let nock = require('nock'); + +module.exports.hash = "009d588711fdac7c2896a88469c45466"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242184840703287","file":"file160242184870908359","directory":"directory160242184960105730","subdirectory1":"subdirectory1160242184960105228","fileName1":"fileName1160242184960109876","fileName2":"fileName2160242184960105982","subdirectory2":"subdirectory2160242184960106995","fileName3":"fileName3160242184960106161","fileName4":"fileName4160242184960106516"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:50 GMT', + 'ETag', + '"0x8D86DE6CBEC3AC4"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186578-601e-006a-76cf-9ffd81000000', + 'x-ms-client-request-id', + '5af974e5-cb00-4700-a45b-1e808441351e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:49 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/file160242184870908359') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:50 GMT', + 'ETag', + '"0x8D86DE6CC1C4526"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a628-a01f-0017-1ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1b6646b5-2434-4477-9b7d-82d6d699b393', + 'Date', + 'Sun, 11 Oct 2020 13:08:50 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/file160242184870908359', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a62c-a01f-0017-20cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '8470d66c-caed-4e7f-b272-edd1020e10a0', + 'Date', + 'Sun, 11 Oct 2020 13:08:50 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/file160242184870908359') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'ETag', + '"0x8D86DE6CC766E52"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a62e-a01f-0017-22cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '2ed66973-6659-4ab5-849c-6d8d28e4dd75', + 'Date', + 'Sun, 11 Oct 2020 13:08:50 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'ETag', + '"0x8D86DE6CCA44650"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a632-a01f-0017-26cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'cc400f82-df3d-48cf-ab12-fd37370957a4', + 'Date', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory1160242184960105228') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'ETag', + '"0x8D86DE6CCD19923"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a638-a01f-0017-2ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'f232c7cc-8c8c-4f4a-9ea5-02c50e1158b2', + 'Date', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory2160242184960106995') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'ETag', + '"0x8D86DE6CCFEDA82"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a63d-a01f-0017-31cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd23a3fa5-cc4a-4c11-964f-794f6371647d', + 'Date', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory1160242184960105228/fileName1160242184960109876') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'ETag', + '"0x8D86DE6CD2B95A8"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a645-a01f-0017-39cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '37dd754d-2f5c-4e18-9437-11facae9405c', + 'Date', + 'Sun, 11 Oct 2020 13:08:51 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory1160242184960105228/fileName2160242184960105982') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'ETag', + '"0x8D86DE6CD585EDF"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a64a-a01f-0017-3ecf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd0ce2ce6-995f-4bcd-9cc2-8ceecb969b52', + 'Date', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory2160242184960106995/fileName3160242184960106161') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:53 GMT', + 'ETag', + '"0x8D86DE6CD85855B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a64e-a01f-0017-42cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3127da35-1585-461e-90d1-1e7e84596fcc', + 'Date', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184840703287/directory160242184960105730/subdirectory2160242184960106995/fileName4160242184960106516') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:53 GMT', + 'ETag', + '"0x8D86DE6CDB2976C"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a651-a01f-0017-45cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '52f52675-caf6-49d8-acf9-c56a6f2ba100', + 'Date', + 'Sun, 11 Oct 2020 13:08:52 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/directory160242184960105730') + .query(true) + .reply(200, {"directoriesSuccessful":2,"failedEntries":[],"failureCount":0,"filesSuccessful":0}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-continuation', + 'VBb+y8qNp/iU6z8YrAEYpgEveGlhb25saWV1YXBobnMBMDFENjQ1NEZBNDAzQjY0OC9maWxlc3lzdGVtMTYwMjQyMTg0ODQwNzAzMjg3ATAxRDY5RkNGQTk3NTZDM0IvZGlyZWN0b3J5MTYwMjQyMTg0OTYwMTA1NzMwL3N1YmRpcmVjdG9yeTExNjAyNDIxODQ5NjAxMDUyMjgvZmlsZU5hbWUxMTYwMjQyMTg0OTYwMTA5ODc2FgAAAA==', + 'x-ms-request-id', + '66c1a652-a01f-0017-46cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'f5735335-7dd2-4f02-adc7-eb95278d057f', + 'Date', + 'Sun, 11 Oct 2020 13:08:53 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/directory160242184960105730') + .query(true) + .reply(200, {"directoriesSuccessful":0,"failedEntries":[],"failureCount":0,"filesSuccessful":2}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-continuation', + 'VBaTxefExKKH7bUBGJABGIoBL3hpYW9ubGlldWFwaG5zATAxRDY0NTRGQTQwM0I2NDgvZmlsZXN5c3RlbTE2MDI0MjE4NDg0MDcwMzI4NwEwMUQ2OUZDRkE5NzU2QzNCL2RpcmVjdG9yeTE2MDI0MjE4NDk2MDEwNTczMC9zdWJkaXJlY3RvcnkyMTYwMjQyMTg0OTYwMTA2OTk1FgAAAA==', + 'x-ms-request-id', + '66c1a659-a01f-0017-4dcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '99562f41-a862-4c90-906d-7b9bda555a4b', + 'Date', + 'Sun, 11 Oct 2020 13:08:53 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/directory160242184960105730') + .query(true) + .reply(200, {"directoriesSuccessful":1,"failedEntries":[],"failureCount":0,"filesSuccessful":1}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-continuation', + 'VBbgo7CHho7IhdMBGKwBGKYBL3hpYW9ubGlldWFwaG5zATAxRDY0NTRGQTQwM0I2NDgvZmlsZXN5c3RlbTE2MDI0MjE4NDg0MDcwMzI4NwEwMUQ2OUZDRkE5NzU2QzNCL2RpcmVjdG9yeTE2MDI0MjE4NDk2MDEwNTczMC9zdWJkaXJlY3RvcnkyMTYwMjQyMTg0OTYwMTA2OTk1L2ZpbGVOYW1lNDE2MDI0MjE4NDk2MDEwNjUxNhYAAAA=', + 'x-ms-request-id', + '66c1a65e-a01f-0017-52cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '237b43ec-dc78-49b7-a6f0-dbfede5bc9b9', + 'Date', + 'Sun, 11 Oct 2020 13:08:53 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184840703287/directory160242184960105730') + .query(true) + .reply(200, {"directoriesSuccessful":0,"failedEntries":[],"failureCount":0,"filesSuccessful":1}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a665-a01f-0017-59cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '5a7f97e3-03d9-42f7-85ec-b731861c425a', + 'Date', + 'Sun, 11 Oct 2020 13:08:53 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242184840703287') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186722-601e-006a-4ccf-9ffd81000000', + 'x-ms-client-request-id', + '4d2cf05e-ced3-4da8-8426-60988b171551', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:54 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__maxbatches.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__maxbatches.js new file mode 100644 index 000000000000..8bdaa8983938 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_options__maxbatches.js @@ -0,0 +1,287 @@ +let nock = require('nock'); + +module.exports.hash = "da1657d25943900fe51a0429a42c5f17"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242184453406947","file":"file160242184483409364","directory":"directory160242184572807318","subdirectory1":"subdirectory1160242184572802780","fileName1":"fileName1160242184572806962","fileName2":"fileName2160242184572803175","subdirectory2":"subdirectory2160242184572809149","fileName3":"fileName3160242184572802056","fileName4":"fileName4160242184572804285"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:46 GMT', + 'ETag', + '"0x8D86DE6C99D1FA1"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '761864a1-601e-006a-4bcf-9ffd81000000', + 'x-ms-client-request-id', + '589b4e0a-abb0-4822-83ca-9db15d9f7e39', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:46 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/file160242184483409364') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:46 GMT', + 'ETag', + '"0x8D86DE6C9CCAD5E"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a601-a01f-0017-76cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '0d761bc9-a58b-4fea-a4e0-9fbb497132ca', + 'Date', + 'Sun, 11 Oct 2020 13:08:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184453406947/file160242184483409364', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a605-a01f-0017-7acf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'e1ecb792-d5f5-4fc1-ab63-d74fa93fd068', + 'Date', + 'Sun, 11 Oct 2020 13:08:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184453406947/file160242184483409364') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:47 GMT', + 'ETag', + '"0x8D86DE6CA273D1C"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a606-a01f-0017-7bcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'ff29ac47-a278-478c-b251-d04212290aad', + 'Date', + 'Sun, 11 Oct 2020 13:08:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:47 GMT', + 'ETag', + '"0x8D86DE6CA5539B0"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a607-a01f-0017-7ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '7e495dec-3b5e-4464-a9d0-39397095d566', + 'Date', + 'Sun, 11 Oct 2020 13:08:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory1160242184572802780') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'ETag', + '"0x8D86DE6CA827074"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a60b-a01f-0017-80cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'c7c28151-7753-4780-9633-2fe80ebbe662', + 'Date', + 'Sun, 11 Oct 2020 13:08:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory2160242184572809149') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'ETag', + '"0x8D86DE6CAAF2552"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a610-a01f-0017-05cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'da79d3f8-2855-49e3-93f1-e89ee0bbe0b6', + 'Date', + 'Sun, 11 Oct 2020 13:08:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory1160242184572802780/fileName1160242184572806962') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'ETag', + '"0x8D86DE6CADBEBBE"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a612-a01f-0017-07cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1d9581e9-4729-4786-886f-dfc96dfa568f', + 'Date', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory1160242184572802780/fileName2160242184572803175') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'ETag', + '"0x8D86DE6CB08C755"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a615-a01f-0017-0acf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'a77447d0-93f4-496a-9787-e35e68efe540', + 'Date', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory2160242184572809149/fileName3160242184572802056') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:49 GMT', + 'ETag', + '"0x8D86DE6CB357D95"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a61a-a01f-0017-0fcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '6a25616a-9707-44d0-ac50-80b2b7f20ef9', + 'Date', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242184453406947/directory160242184572807318/subdirectory2160242184572809149/fileName4160242184572804285') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:49 GMT', + 'ETag', + '"0x8D86DE6CB6367EB"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a61d-a01f-0017-12cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'f3e768fa-e89d-4827-9f54-6b94a51fa4b3', + 'Date', + 'Sun, 11 Oct 2020 13:08:48 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242184453406947/directory160242184572807318') + .query(true) + .reply(200, {"directoriesSuccessful":2,"failedEntries":[],"failureCount":0,"filesSuccessful":0}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-continuation', + 'VBal/Y/O+8Gtom4YrAEYpgEveGlhb25saWV1YXBobnMBMDFENjQ1NEZBNDAzQjY0OC9maWxlc3lzdGVtMTYwMjQyMTg0NDUzNDA2OTQ3ATAxRDY5RkNGQTcyNjdBNjIvZGlyZWN0b3J5MTYwMjQyMTg0NTcyODA3MzE4L3N1YmRpcmVjdG9yeTExNjAyNDIxODQ1NzI4MDI3ODAvZmlsZU5hbWUxMTYwMjQyMTg0NTcyODA2OTYyFgAAAA==', + 'x-ms-request-id', + '66c1a61e-a01f-0017-13cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'dcd8842d-6bac-4f69-b818-91fb51624e07', + 'Date', + 'Sun, 11 Oct 2020 13:08:49 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242184453406947') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '7618656f-601e-006a-70cf-9ffd81000000', + 'x-ms-client-request-id', + 'e1f86a07-bac9-45da-9381-cd74f5dcc53f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:49 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures.js new file mode 100644 index 000000000000..f7cfd5aeae7a --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "8a0dcf1b33255a9480250dc1fdc07bde"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242186540708367","file":"file160242186570503731"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186540708367') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:07 GMT', + 'ETag', + '"0x8D86DE6D60E2C0C"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186a55-601e-006a-44cf-9ffd81000000', + 'x-ms-client-request-id', + '29634395-a1d6-4c0a-831c-2062f50a837c', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:09:06 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242186540708367/file160242186570503731') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:07 GMT', + 'ETag', + '"0x8D86DE6D63D8B22"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a719-a01f-0017-08cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '8b7047bf-1f18-472e-9297-f960e526284f', + 'Date', + 'Sun, 11 Oct 2020 13:09:07 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186540708367/file160242186570503731', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a71d-a01f-0017-0ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '89e3b7a9-b722-4bbf-9a39-88e538777050', + 'Date', + 'Sun, 11 Oct 2020 13:09:07 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242186540708367/file160242186570503731') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:08 GMT', + 'ETag', + '"0x8D86DE6D697C349"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a71e-a01f-0017-0dcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '61c8dcac-ee03-4339-96af-b1e28fa6926c', + 'Date', + 'Sun, 11 Oct 2020 13:09:07 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242186540708367') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186a9e-601e-006a-7ecf-9ffd81000000', + 'x-ms-client-request-id', + '03b50494-d6e0-44f2-9329-b1903fa0b0f8', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:09:08 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures__todo.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures__todo.js new file mode 100644 index 000000000000..627829b2e61e --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_setaccesscontrolrecursive_should_work_with_progress_failures__todo.js @@ -0,0 +1,111 @@ +let nock = require('nock'); + +module.exports.hash = "115f635cbcf9b03a9d6ea136672e81a8"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem159298730672405354","file":"file159298730703001527"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159298730672405354') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Wed, 24 Jun 2020 08:28:23 GMT', + 'ETag', + '"0x8D818188F3930B3"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e9cc4569-501e-0079-7901-4ab184000000', + 'x-ms-client-request-id', + '31ba016c-7005-4a6c-9fda-4968ef51bc07', + 'x-ms-version', + '2019-07-07', + 'Date', + 'Wed, 24 Jun 2020 08:28:22 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem159298730672405354/file159298730703001527') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 08:28:23 GMT', + 'ETag', + '"0x8D818188F69A8C7"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '9b1d8600-901f-0014-1b01-4a05cf000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + '6ff110dd-aee9-440f-8479-5bdf1a7db1a7', + 'Date', + 'Wed, 24 Jun 2020 08:28:23 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159298730672405354/file159298730703001527', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '9b1d8602-901f-0014-1d01-4a05cf000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'be7fe2df-f6f7-4a53-af5e-02737082cbbd', + 'Date', + 'Wed, 24 Jun 2020 08:28:23 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem159298730672405354/file159298730703001527') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Wed, 24 Jun 2020 08:28:24 GMT', + 'ETag', + '"0x8D818188FC8157B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '9b1d8603-901f-0014-1e01-4a05cf000000', + 'x-ms-version', + '2019-12-12', + 'x-ms-client-request-id', + 'ee6ac69e-805c-47cd-9b94-9ab835e06860', + 'Date', + 'Wed, 24 Jun 2020 08:28:23 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem159298730672405354') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e9cc462c-501e-0079-0101-4ab184000000', + 'x-ms-client-request-id', + '8a1e9439-2224-4d7f-94b6-3f04b3606a54', + 'x-ms-version', + '2019-07-07', + 'Date', + 'Wed, 24 Jun 2020 08:28:23 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_updateaccesscontrolrecursive_should_work.js b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_updateaccesscontrolrecursive_should_work.js new file mode 100644 index 000000000000..5ba0ad0f1e77 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/datalakepathclient_setaccesscontrolrecursive_nodejs_only/recording_updateaccesscontrolrecursive_should_work.js @@ -0,0 +1,285 @@ +let nock = require('nock'); + +module.exports.hash = "6ba6d49cba26b09c87804042e480c693"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160242185732706180","file":"file160242185762800604","directory":"directory160242185852009366","subdirectory1":"subdirectory1160242185852009199","fileName1":"fileName1160242185852006207","fileName2":"fileName2160242185852006815","subdirectory2":"subdirectory2160242185852008135","fileName3":"fileName3160242185852004818","fileName4":"fileName4160242185852004531"},"newDate":{}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'ETag', + '"0x8D86DE6D13DA239"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186822-601e-006a-07cf-9ffd81000000', + 'x-ms-client-request-id', + '3dcd7ab6-562d-412f-ac57-55dbd539e858', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:08:58 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/file160242185762800604') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'ETag', + '"0x8D86DE6D16C6387"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6ad-a01f-0017-1ecf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'b4f0fd40-3387-47a1-ace6-737aca91c4c8', + 'Date', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185732706180/file160242185762800604', "Hello World") + .query(true) + .reply(202, "", [ + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'true', + 'x-ms-request-id', + '66c1a6b0-a01f-0017-21cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '7568b757-b768-4f6f-bccf-3fb0f443e09c', + 'Date', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185732706180/file160242185762800604') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'ETag', + '"0x8D86DE6D1C6C22B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-server-encrypted', + 'false', + 'x-ms-request-id', + '66c1a6b3-a01f-0017-24cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '5d795b2d-3136-4ce4-9127-2a254544d8f7', + 'Date', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'ETag', + '"0x8D86DE6D1F739F9"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6bb-a01f-0017-2bcf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '041d72d2-2fcb-4cd3-a387-428680d8bdc7', + 'Date', + 'Sun, 11 Oct 2020 13:08:59 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory1160242185852009199') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'ETag', + '"0x8D86DE6D22485BE"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6be-a01f-0017-2ecf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'ae006156-8afd-4cde-aa99-d49fd2542361', + 'Date', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory2160242185852008135') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'ETag', + '"0x8D86DE6D250F176"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6c2-a01f-0017-32cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '8431224b-6a76-495e-8bd7-3d4c5a1ae31b', + 'Date', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory1160242185852009199/fileName1160242185852006207') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'ETag', + '"0x8D86DE6D27DF3CB"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6c6-a01f-0017-36cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '4fb30070-ab84-48d2-ab53-4021412db8b7', + 'Date', + 'Sun, 11 Oct 2020 13:09:00 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory1160242185852009199/fileName2160242185852006815') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'ETag', + '"0x8D86DE6D2AAB2D5"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6c7-a01f-0017-37cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '4c68f09c-52b7-43c7-8067-0d41e179d462', + 'Date', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory2160242185852008135/fileName3160242185852004818') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:02 GMT', + 'ETag', + '"0x8D86DE6D2D8D201"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6cc-a01f-0017-3ccf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '6ff1145e-c44b-4de0-a580-a55e7d96382e', + 'Date', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160242185732706180/directory160242185852009366/subdirectory2160242185852008135/fileName4160242185852004531') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 11 Oct 2020 13:09:02 GMT', + 'ETag', + '"0x8D86DE6D305F3BA"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '66c1a6d1-a01f-0017-41cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '3e04668e-6d29-4fe2-90e7-1b7cbd884bbe', + 'Date', + 'Sun, 11 Oct 2020 13:09:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160242185732706180/directory160242185852009366') + .query(true) + .reply(200, {"directoriesSuccessful":3,"failedEntries":[],"failureCount":0,"filesSuccessful":4}, [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '66c1a6d6-a01f-0017-46cf-9f8ca2000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '77fb3353-e4b4-46a6-826c-96f4913fac0d', + 'Date', + 'Sun, 11 Oct 2020 13:09:02 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160242185732706180') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '76186922-601e-006a-46cf-9ffd81000000', + 'x-ms-client-request-id', + '7fc57abc-2c9b-4d27-ba8a-90fa64a152ca', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 11 Oct 2020 13:09:02 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_for_directory_should_work_for_permissions_m_e_o_p.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_for_directory_should_work_for_permissions_m_e_o_p.js new file mode 100644 index 000000000000..7f775711ed3a --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_for_directory_should_work_for_permissions_m_e_o_p.js @@ -0,0 +1,194 @@ +let nock = require('nock'); + +module.exports.hash = "eed9fe71278951b4c6b8383c48d8a938"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258385782703329","directory":"directory160258385813401905","file":"file160258385843006421"},"newDate":{"now":"2020-10-13T10:10:57.185Z","tmr":"2020-10-13T10:10:57.185Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU1NywibmJmIjoxNjAyNTgzNTU3LCJleHAiOjE2MDI2NzAyNTcsImFpbyI6IkUyUmdZUEJkN0diOHJuTWRiOHZoZXY0ZEJlYzJBd0E9IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJSWjVVZFJ3V1QwZXVzZzk4SFVNREFBIiwidmVyIjoiMS4wIn0.KKUhhdPaPR8KJFkusilUU9Jn6FA9RT6jJyN5eF_JHyHDhjZA5L3FHH0fOqZEqu9JiPeYPE2yfWvBUVU_PH2eDpYNxA9fHNtoJKQo0KSFoIgwpW4IMm2Xynxm0ROK1lkNRRrb17GHLg0trL1z1GEZZqSrv0yKMJDore9g7DZm6FaISPQVQ6mhPDpeh2sdorJ3-HUts4RLZVUUe5PR0sOZMDYxmzpmFw3hqPCkHM7zUvEOLeh42VhTAEMkNANnQCyfc_fwDbZ2f86-ntBLV7J6Uk1k3iEqhhLml_YPFh8psnUrHUqCEceFY4TXCJH2UQuIBOv1VBTWZj4QrdH2gj59HA"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '75549e45-161c-474f-aeb2-0f7c1d430300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AhDSHg2ZqhJAhGzU-t5hr7l00ISJAQAAADF0F9cOAAAA; expires=Thu, 12-Nov-2020 10:10:57 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:10:56 GMT', + 'Content-Length', + '1318' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/', "2020-10-13T09:10:57Z2020-10-18T10:10:57Z") + .query(true) + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:10:57Z2020-10-18T10:10:57Zb2020-02-10kD4QZ+PK6y0ereX8TL+G8B4hFMAjoRjRgh+RB3V+RdM=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990172-d01e-0067-3e49-a15d5c000000', + 'x-ms-client-request-id', + 'e94368f8-38c0-46b7-8a82-abb1f0e4f9d2', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:10:57 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258385782703329') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:57 GMT', + 'ETag', + '"0x8D86F60477DF2C6"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990182-d01e-0067-4c49-a15d5c000000', + 'x-ms-client-request-id', + '7396c100-76b8-40e1-8b73-1702b39ff556', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:10:57 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258385782703329/directory160258385813401905') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:58 GMT', + 'ETag', + '"0x8D86F6047AC9DD9"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0d86afa0-401f-0017-1b49-a1e4ab000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'df0f6488-3cf0-46a9-aa5d-1b2cacac9ff4', + 'Date', + 'Tue, 13 Oct 2020 10:10:57 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258385782703329/directory160258385813401905/file160258385843006421') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:58 GMT', + 'ETag', + '"0x8D86F6047DE499F"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0d86afa2-401f-0017-1d49-a1e4ab000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '45bfd425-ce36-419c-856c-4a7ec4e93a26', + 'Date', + 'Tue, 13 Oct 2020 10:10:58 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem160258385782703329/directory160258385813401905') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:58 GMT', + 'ETag', + '"0x8D86F6047AC9DD9"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-owner', + '1ce13278-a083-4d15-8796-de39717793e1', + 'x-ms-group', + '1ce13278-a083-4d15-8796-de39717793e1', + 'x-ms-permissions', + 'rwxr-x---', + 'x-ms-acl', + 'user::rwx,group::r-x,other::---', + 'x-ms-request-id', + '0d86afa3-401f-0017-1e49-a1e4ab000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1915fa9e-4143-41b1-8d2d-c88dc9075e89', + 'Date', + 'Tue, 13 Oct 2020 10:10:58 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160258385782703329/directory160258385813401905') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:58 GMT', + 'ETag', + '"0x8D86F6047AC9DD9"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + 'd3b7a0c1-801f-0018-4d49-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '2fa749aa-04a1-4d7f-a0b5-b1c10d35b37b', + 'Date', + 'Tue, 13 Oct 2020 10:11:00 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160258385782703329') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '569902a8-d01e-0067-2b49-a15d5c000000', + 'x-ms-client-request-id', + '43d431cf-52a8-40b6-9004-1080f3b944f5', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:01 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_agentobjectid_preauthorizedagentobjectid.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_agentobjectid_preauthorizedagentobjectid.js new file mode 100644 index 000000000000..2cb19a1bcefa --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_agentobjectid_preauthorizedagentobjectid.js @@ -0,0 +1,232 @@ +let nock = require('nock'); + +module.exports.hash = "3f33c5118f10ec7ddcd9bbc8b5a02538"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258386211407154","directory":"directory160258386242003191","file":"file160258386271803326","newFile":"newFile160258386359605359"},"newDate":{"now":"2020-10-13T10:11:01.503Z","tmr":"2020-10-13T10:11:01.503Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU2MSwibmJmIjoxNjAyNTgzNTYxLCJleHAiOjE2MDI2NzAyNjEsImFpbyI6IkUyUmdZUENZL1p6MWZZRDFyQjl2bkVxZXorTTZCUUE9IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJrOUcwSUtBVVQwYW9BVWxzRzR3REFBIiwidmVyIjoiMS4wIn0.RucncTPGzhu4Hk-ifeWWub9Cbbnr4XROFqMHIbRAI2cnQOyC5Hg-mM3-vw--2uPSLefOHWRbawFSVBaPqxQHG0V8Bl6UEPfiSf-HfCkkOaoQYXmmqBmgEz5fWVhpyy9AIFP2XbL2HUnY2l279cuiCD75QydTFkQEsyU_fk9my1FaJ_174zG9ovLc8drxhvGegmcJpUctaK4wHd9TV6vRbbFVWhbvTW-LQ6cj4PjXapDIAJ9wU2TkLimt3DTurUUbLMnJfYG3qrlcI4ytZz6KBkp2oz7Cm2z2nHYr9W3wORbXT4m1SuDAz1pwiC8S-j1MmCBdtY1_kxCTN21gXUZNjA"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '20b4d193-14a0-464f-a801-496c1b8c0300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR1 ProdSlices', + 'Set-Cookie', + 'fpc=AhxzHDpYxKZEh2iEl_xFSL500ISJAQAAADV0F9cOAAAA; expires=Thu, 12-Nov-2020 10:11:01 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:11:01 GMT', + 'Content-Length', + '1318' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/', "2020-10-13T09:11:01Z2020-10-18T10:11:01Z") + .query(true) + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:11:01Z2020-10-18T10:11:01Zb2020-02-10WIJg+ZuuW3afqBgv0ZRnwpw3XO+zGBGDQwa+F55HTAk=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '569902d5-d01e-0067-4d49-a15d5c000000', + 'x-ms-client-request-id', + 'f293ad8a-986a-4c5b-8e3d-ac183d20df83', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:01 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'ETag', + '"0x8D86F604A0C19DC"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '569902f1-d01e-0067-6349-a15d5c000000', + 'x-ms-client-request-id', + 'ff84359c-3463-446d-9e96-342f1e20bae2', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:02 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154/directory160258386242003191') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'ETag', + '"0x8D86F604A3B15F0"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0c3-801f-0018-4e49-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '55a78f13-5b52-4f04-997b-756fd1652d28', + 'Date', + 'Tue, 13 Oct 2020 10:11:01 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154/directory160258386242003191/file160258386271803326') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'ETag', + '"0x8D86F604A691632"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0c7-801f-0018-5149-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '1e838fcf-bc66-4f5a-8a74-43d8cb01927d', + 'Date', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160258386211407154/%2F') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'ETag', + '"0x8D86F604A0D8FE2"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + 'd3b7a0c9-801f-0018-5349-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'cca22c79-3793-4019-88a3-1f0d56d573ad', + 'Date', + 'Tue, 13 Oct 2020 10:11:02 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154/newFile160258386359605359') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:04 GMT', + 'ETag', + '"0x8D86F604B900043"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0ca-801f-0018-5449-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd6f3a47e-f527-48b6-8704-fde17227c5bd', + 'Date', + 'Tue, 13 Oct 2020 10:11:04 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154/newFile160258386359605359') + .query(true) + .reply(403, {"error":{"code":"AuthorizationPermissionMismatch","message":"This request is not authorized to perform this operation using this permission.\nRequestId:d3b7a0cb-801f-0018-5549-a192c7000000\nTime:2020-10-13T10:11:05.2358363Z"}}, [ + 'Content-Length', + '227', + 'Content-Type', + 'application/json;charset=utf-8', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-error-code', + 'AuthorizationPermissionMismatch', + 'x-ms-request-id', + 'd3b7a0cb-801f-0018-5549-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '41e59f0f-74b8-4f1a-9a62-2a6c0eae8ee0', + 'Date', + 'Tue, 13 Oct 2020 10:11:04 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386211407154/newFile160258386359605359') + .query(true) + .reply(409, {"error":{"code":"PathAlreadyExists","message":"The specified path already exists.\nRequestId:d3b7a0cc-801f-0018-5649-a192c7000000\nTime:2020-10-13T10:11:05.5370508Z"}}, [ + 'Content-Length', + '168', + 'Content-Type', + 'application/json;charset=utf-8', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-error-code', + 'PathAlreadyExists', + 'x-ms-request-id', + 'd3b7a0cc-801f-0018-5649-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '86265198-7662-4aab-88f5-3c9203ff8dd8', + 'Date', + 'Tue, 13 Oct 2020 10:11:04 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160258386211407154') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990435-d01e-0067-1c49-a15d5c000000', + 'x-ms-client-request-id', + 'd4a5aebf-0872-4a98-9c08-fa3cb3920dff', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:05 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_correlationid.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_correlationid.js new file mode 100644 index 000000000000..1ef6a1e63fb7 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_delegation_sas/recording_generateuserdelegationsas_should_work_with_correlationid.js @@ -0,0 +1,162 @@ +let nock = require('nock'); + +module.exports.hash = "9bcada1e1c90bd5e6d1bdb8e5fa637b4"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258386657207977","directory":"directory160258386687502922","file":"file160258386717400152"},"newDate":{"now":"2020-10-13T10:11:05.970Z","tmr":"2020-10-13T10:11:05.970Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU2NiwibmJmIjoxNjAyNTgzNTY2LCJleHAiOjE2MDI2NzAyNjYsImFpbyI6IkUyUmdZSGcvS1dqeC96alB5WnNQYUF0MXZMUldBQUE9IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJ5eVNsLXhpZVowbVRBNUo0M1hRREFBIiwidmVyIjoiMS4wIn0.RP3HtU1YeUYRN_-6RtQ-4GNWU5Dw1BKf7HWFw88D9ZkGgZkXNxLzya7S0ATPw16Zc6kXFCDykV4mjYu4oZUI8MoPMNL8csqNYFIOBCdmirjk4USkyS1VY8laqtQIjy4x4Fj8QdGlMYM-fdDhDFxMIu8WZF2Nrm5D-QTAntNTllIFGuNQaZ3vNVl9IhsOnUlB2OT3CGlfvQVNJ6DQcU51QWzoZGbMvo1cxLhyMDbN21wk9BQ5g0armWSQVl2p6H7jFJjtbVKtZjjRAh11lQTdC6sbpEawMHQ_wLwKG48GcGVOjGV9PRjAGpcV82J7mI6jnInNA-2Yz-DnKJz_wUxFLQ"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'fba524cb-9e18-4967-9303-9278dd740300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AvFh3UfIIBxHpbEbNnglEPp00ISJAQAAADp0F9cOAAAA; expires=Thu, 12-Nov-2020 10:11:06 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:11:05 GMT', + 'Content-Length', + '1318' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/', "2020-10-13T09:11:05Z2020-10-18T10:11:05Z") + .query(true) + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:11:05Z2020-10-18T10:11:05Zb2020-02-10jBiwC+AII61ekzCkRzJ7ISWQrb2ks+vT8phJgKl3O9U=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990465-d01e-0067-3b49-a15d5c000000', + 'x-ms-client-request-id', + '530c62e6-286a-49ea-84eb-552c792bd478', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:06 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386657207977') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:06 GMT', + 'ETag', + '"0x8D86F604CB3E81D"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990490-d01e-0067-5e49-a15d5c000000', + 'x-ms-client-request-id', + 'd94e31f5-4a95-4828-9ec5-73e417f870e7', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:06 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386657207977/directory160258386687502922') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:07 GMT', + 'ETag', + '"0x8D86F604CE2F15A"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0cd-801f-0018-5749-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'abc9f2aa-8266-45dc-90ae-79aefcbc4dda', + 'Date', + 'Tue, 13 Oct 2020 10:11:06 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258386657207977/directory160258386687502922/file160258386717400152') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:11:07 GMT', + 'ETag', + '"0x8D86F604D102540"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0ce-801f-0018-5849-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '2aaa4f5a-018a-4e36-8e7e-fd531de9ecf8', + 'Date', + 'Tue, 13 Oct 2020 10:11:06 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .get('/filesystem160258386657207977') + .query(true) + .reply(200, {"paths":[{"contentLength":"0","creationTime":"Tue, 13 Oct 2020 10:11:07 GMT","etag":"0x8D86F604CE2F15A","group":"1ce13278-a083-4d15-8796-de39717793e1","isDirectory":"true","lastModified":"Tue, 13 Oct 2020 10:11:07 GMT","name":"directory160258386687502922","owner":"1ce13278-a083-4d15-8796-de39717793e1","permissions":"rwxr-x---"}]}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json;charset=utf-8', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd3b7a0cf-801f-0018-5949-a192c7000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'a6f8e8ab-83ba-4ab3-bc10-3f47ea604eb5', + 'Date', + 'Tue, 13 Oct 2020 10:11:06 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160258386657207977') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '5699050d-d01e-0067-3549-a15d5c000000', + 'x-ms-client-request-id', + 'b782029d-1317-45fd-9b74-07a88e6c9543', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:11:07 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_could_calculate_directory_depth.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_could_calculate_directory_depth.js new file mode 100644 index 000000000000..2d970261877f --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_could_calculate_directory_depth.js @@ -0,0 +1,137 @@ +let nock = require('nock'); + +module.exports.hash = "f5618eb4b00f99d8fbe537045b47c869"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160119778328205800","directory":"directory160119778601405130","file":"file160119778728208354"},"newDate":{"now":"2020-09-27T09:09:47.683Z","tmr":"2020-09-27T09:09:47.686Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119778328205800') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 09:09:44 GMT', + 'ETag', + '"0x8D862C51351C59F"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '775dc43f-001e-0090-22ad-9477ce000000', + 'x-ms-client-request-id', + '88f199dc-4197-4239-acd4-3077c0bb23ac', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 09:09:44 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119778328205800/directory160119778601405130') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'ETag', + '"0x8D862C514DB4881"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '595272f6-901f-0049-09ad-940f4b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '81d7508e-5e3a-4e29-814b-43ac0e185692', + 'Date', + 'Sun, 27 Sep 2020 09:09:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119778328205800/directory160119778601405130/file160119778728208354') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'ETag', + '"0x8D862C51518BDA4"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '595272f7-901f-0049-0aad-940f4b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '5aa3b393-c51d-46ea-a66c-6479eaecd67d', + 'Date', + 'Sun, 27 Sep 2020 09:09:46 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160119778328205800/directory160119778601405130') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'ETag', + '"0x8D862C514DB4881"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '595272fb-901f-0049-0ead-940f4b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'bb4eee24-07df-44b9-b8bf-952c6f662436', + 'Date', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160119778328205800/directory160119778601405130') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'ETag', + '"0x8D862C514DB4881"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '595272fd-901f-0049-10ad-940f4b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '10b5e382-4343-40e1-a2de-e8759b15b9df', + 'Date', + 'Sun, 27 Sep 2020 09:09:47 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160119778328205800') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '775dc555-001e-0090-7aad-9477ce000000', + 'x-ms-client-request-id', + 'e3082b9f-9edc-482a-bb90-feeeeb405588', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 09:09:47 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_directory_should_work_for_permissions_m_e_o_p.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_directory_should_work_for_permissions_m_e_o_p.js new file mode 100644 index 000000000000..4dd8bcc83825 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_directory_should_work_for_permissions_m_e_o_p.js @@ -0,0 +1,141 @@ +let nock = require('nock'); + +module.exports.hash = "d63dd630beb0486fd25c48dc18b61be9"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160119085691006060","directory":"directory160119085896407057","file":"file160119086034900504"},"newDate":{"now":"2020-09-27T07:14:20.727Z","tmr":"2020-09-27T07:14:20.729Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119085691006060') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:18 GMT', + 'ETag', + '"0x8D862B4F30F7910"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '3950febe-a01e-001f-369d-94fea4000000', + 'x-ms-client-request-id', + '60045a93-3c91-4eca-954b-0128d8c130e2', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 07:14:18 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119085691006060/directory160119085896407057') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'ETag', + '"0x8D862B4F41BA203"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '73d0580c-e01f-0043-5c9d-94abfc000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '2ff267b5-f5a7-44c6-b69c-cdae4e496db1', + 'Date', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119085691006060/directory160119085896407057/file160119086034900504') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'ETag', + '"0x8D862B4F454A259"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '73d0580d-e01f-0043-5d9d-94abfc000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'cb719bb9-762e-4bd6-aaed-b504714d9214', + 'Date', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem160119085691006060/directory160119085896407057') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'ETag', + '"0x8D862B4F41BA203"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-owner', + '$superuser', + 'x-ms-group', + '$superuser', + 'x-ms-permissions', + 'rwxr-x---', + 'x-ms-acl', + 'user::rwx,group::r-x,other::---', + 'x-ms-request-id', + '73d0580e-e01f-0043-5e9d-94abfc000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'f56a21b5-94c5-42a0-bcf4-17145b4ce706', + 'Date', + 'Sun, 27 Sep 2020 07:14:20 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160119085691006060/directory160119085896407057') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:20 GMT', + 'ETag', + '"0x8D862B4F41BA203"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + 'd79f91d8-401f-005a-6c9d-942b47000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '6f3969ba-0dfd-4376-b42f-51c5dba576cd', + 'Date', + 'Sun, 27 Sep 2020 07:14:21 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160119085691006060') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '3951014c-a01e-001f-3a9d-94fea4000000', + 'x-ms-client-request-id', + 'c894f05d-5ed9-4657-8957-5ab62459e5cd', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 07:14:21 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_file_should_work_for_permissions_m_e_o_p.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_file_should_work_for_permissions_m_e_o_p.js new file mode 100644 index 000000000000..ea51cd2f43e5 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_file_should_work_for_permissions_m_e_o_p.js @@ -0,0 +1,165 @@ +let nock = require('nock'); + +module.exports.hash = "e78a610b2e9f5da5139546e4cecffda6"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160257624536405504","directory":"directory160257624730204552","file":"file160257624860209355"},"newDate":{"now":"2020-10-13T08:04:08.916Z","tmr":"2020-10-13T08:04:08.918Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160257624536405504') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:06 GMT', + 'ETag', + '"0x8D86F4E8EBF8128"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '5d6ceaf0-c01e-007b-6f37-a10f3c000000', + 'x-ms-client-request-id', + 'e981c8da-e1a7-489c-a559-94239299b0c3', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 08:04:06 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160257624536405504/directory160257624730204552') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'ETag', + '"0x8D86F4E8FDCE8BB"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '957aa5e5-701f-0033-0437-a1120b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '30ad1f67-30ab-4cd8-9fda-28a5a88b859f', + 'Date', + 'Tue, 13 Oct 2020 08:04:07 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160257624536405504/directory160257624730204552/file160257624860209355') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'ETag', + '"0x8D86F4E900C8E68"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '957aa5e6-701f-0033-0537-a1120b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '533138f5-062d-4556-aa89-af55a6042044', + 'Date', + 'Tue, 13 Oct 2020 08:04:07 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160257624536405504/directory160257624730204552/file160257624860209355') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'ETag', + '"0x8D86F4E900C8E68"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '957aa5e7-701f-0033-0637-a1120b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '93524792-7c74-4e95-80d1-e8c28e7783f2', + 'Date', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem160257624536405504/directory160257624730204552/file160257624860209355') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'ETag', + '"0x8D86F4E900C8E68"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-owner', + 'b77d5205-ddb5-42e1-80ee-26c74a5e9333', + 'x-ms-group', + '$superuser', + 'x-ms-permissions', + 'rw-r-----', + 'x-ms-acl', + 'user::rw-,group::r--,other::---', + 'x-ms-request-id', + '957aa5e8-701f-0033-0737-a1120b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '78e61c93-eb93-4fad-b450-059e7d565024', + 'Date', + 'Tue, 13 Oct 2020 08:04:08 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160257624536405504/directory160257624730204552/file160257624860209355') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 08:04:08 GMT', + 'ETag', + '"0x8D86F4E900C8E68"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '51bd62b8-d01f-0077-0e37-a19834000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'cd263711-b23b-4770-9e70-514b27efe9ee', + 'Date', + 'Tue, 13 Oct 2020 08:04:09 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160257624536405504') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '5d6cec8b-c01e-007b-1b37-a10f3c000000', + 'x-ms-client-request-id', + '13d1f3c8-cf41-463e-80ca-9176150ecf78', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 08:04:10 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_filesystem_should_work_for_permissions_m_e_o_p.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_filesystem_should_work_for_permissions_m_e_o_p.js new file mode 100644 index 000000000000..c0b4f9905e10 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_for_filesystem_should_work_for_permissions_m_e_o_p.js @@ -0,0 +1,141 @@ +let nock = require('nock'); + +module.exports.hash = "b38b2cb51a8273c8fbf7c281a4514192"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160119086619304249","directory":"directory160119086654005398","file":"file160119086686203124"},"newDate":{"now":"2020-09-27T07:14:27.215Z","tmr":"2020-09-27T07:14:27.215Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119086619304249') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'ETag', + '"0x8D862B4F7CA5BF6"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '395102c5-a01e-001f-5d9d-94fea4000000', + 'x-ms-client-request-id', + '0a372421-a47f-49fa-9b6c-a17cf51ab37f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 07:14:25 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119086619304249/directory160119086654005398') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'ETag', + '"0x8D862B4F7FE0B9B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0453a43d-301f-007f-3b9d-94823b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '67f96a25-8d78-469a-87f9-6147181d946a', + 'Date', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160119086619304249/directory160119086654005398/file160119086686203124') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:27 GMT', + 'ETag', + '"0x8D862B4F83324D1"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0453a43e-301f-007f-3c9d-94823b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'a09969f8-9da0-4d70-bcb7-bbc1a51716f2', + 'Date', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem160119086619304249/directory160119086654005398') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'ETag', + '"0x8D862B4F7FE0B9B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-owner', + '$superuser', + 'x-ms-group', + '$superuser', + 'x-ms-permissions', + 'rwxr-x---', + 'x-ms-acl', + 'user::rwx,group::r-x,other::---', + 'x-ms-request-id', + '0453a43f-301f-007f-3d9d-94823b000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '40936cc9-fcf3-49ae-aee3-79380df3249f', + 'Date', + 'Sun, 27 Sep 2020 07:14:26 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .patch('/filesystem160119086619304249/directory160119086654005398') + .query(true) + .reply(200, "", [ + 'Last-Modified', + 'Sun, 27 Sep 2020 07:14:26 GMT', + 'ETag', + '"0x8D862B4F7FE0B9B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-namespace-enabled', + 'true', + 'x-ms-request-id', + '8545d695-c01f-008f-809d-94c4ca000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + 'd22fbe54-4abf-4a01-83bd-3464357fbc97', + 'Date', + 'Sun, 27 Sep 2020 07:14:28 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160119086619304249') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '39510413-a01e-001f-699d-94fea4000000', + 'x-ms-client-request-id', + '1dfe0bb7-613d-419b-924c-a76c8b0d9d97', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 07:14:28 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_construct_sasqueryparameters_with_a_option_bag.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_construct_sasqueryparameters_with_a_option_bag.js new file mode 100644 index 000000000000..c7b887426215 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_construct_sasqueryparameters_with_a_option_bag.js @@ -0,0 +1,5 @@ +let nock = require('nock'); + +module.exports.hash = "dfb5256fbffeadfe6df18dddf4c3fc5b"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file.js index 30e02797672e..61edaebaf496 100644 --- a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file.js +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file.js @@ -1,69 +1,111 @@ let nock = require('nock'); -module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem157534999218909418","file":"file157534999333409585"},"newDate":{"now":"2019-12-03T05:13:11.028Z","tmr":"2019-12-03T05:13:11.028Z"}} +module.exports.hash = "687c424a81d7038365e254ba266ae4d2"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258385407003300","file":"file160258385437501972"},"newDate":{"now":"2020-10-13T10:10:53.291Z","tmr":"2020-10-13T10:10:53.291Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU1MywibmJmIjoxNjAyNTgzNTUzLCJleHAiOjE2MDI2NzAyNTMsImFpbyI6IkUyUmdZRWdNazF6Nm5uK2xFL3Q3L29JNERxZDVBQT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJKc1FSZnhSd2FVLTA2TDJKZmNnREFBIiwidmVyIjoiMS4wIn0.Mf-n_p25FbnRqcHkCPdQF9rq3qVYbGAvRuyRGYjdza17uw4W4IzWZasl-84_kQ9agn7KlkJtMjvb24aSn6sGC6u162XAEciP8uHe9vRWqFg2gKhYwUh-5AcV-CysklQ0ALoUDrlAR2EQnwoj7cnxYcm0_MXNeM20NW3St9_zDVQZ1-b9_WMDooB4oC_76TdrdOx3S4X7d_b4UnNUgsKJoXy7b-ihuLBDRxDZ5VkeWid-Vhn9YsUFXYFUhZrzD95ZMNMKH_OCZDQL5LiNY5ibXFQG9_q9lkiOCw6jLRN-vLjhcRTOnyQZUBsQn22ds-oNcmjkQFhjGsVwnIf0ZnS9Sw"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '7f11c426-7014-4f69-b4e8-bd897dc80300', + 'x-ms-ests-server', + '2.1.11154.7 - EASLR1 ProdSlices', + 'Set-Cookie', + 'fpc=Aht9afRjrH9Jnwk9UB5l-Gx00ISJAQAAACx0F9cOAAAA; expires=Thu, 12-Nov-2020 10:10:53 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:10:52 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-12-03T04:13:11Z2019-12-08T05:13:11Z") + .post('/', "2020-10-13T09:10:53Z2020-10-18T10:10:53Z") .query(true) - .reply(200, "324ed67c-1c74-4563-816e-c4be5f675ef172f988bf-86f1-41af-91ab-2d7cd011db472019-12-03T04:13:11Z2019-12-08T05:13:11Zb2019-02-02m32yGAtQ101vePX+/ce1FinBQ+UgSGe709TeatwLblo=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:10:53Z2020-10-18T10:10:53Zb2020-02-102waOdPZTIZCTFt5ZaOy2Qs1xXb53dUPUQARkNSNimfI=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '08fc1786-b01e-0070-0497-a9365a000000', + '5699000a-d01e-0067-3049-a15d5c000000', 'x-ms-client-request-id', - '79eaf5fc-a788-4fd1-80cd-9d2a187d0270', + '9091f8b8-a3cb-41cd-bebe-763a25a6899e', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:13 GMT' ]); + 'Tue, 13 Oct 2020 10:10:52 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534999218909418') + .put('/filesystem160258385407003300') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:14 GMT', + 'Tue, 13 Oct 2020 10:10:54 GMT', 'ETag', - '"0x8D777AEA98C807C"', + '"0x8D86F6045409284"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '490118a3-501e-0071-7597-a937a7000000', + '56990038-d01e-0067-4d49-a15d5c000000', 'x-ms-client-request-id', - 'f71f62ee-5861-4fba-a2cd-4c6cfc320a58', + '2e5135c6-036b-4f6e-a89d-9e2df0da3d5a', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:14 GMT' ]); + 'Tue, 13 Oct 2020 10:10:54 GMT' +]); nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534999218909418/file157534999333409585') + .put('/filesystem160258385407003300/file160258385437501972') .query(true) - .reply(201, "", [ 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:16 GMT', + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:54 GMT', 'ETag', - '"0x8D777AEAA3D03BC"', + '"0x8D86F6045711464"', 'Server', 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f1a6f1b9-a01f-004d-7e97-a9837c000000', + '0d86af9d-401f-0017-1949-a1e4ab000000', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-client-request-id', - '1ff8c8bb-7762-49ff-b9b1-6b2648be0524', + '852db7ca-c7dd-4b98-9896-db56d9566985', 'Date', - 'Tue, 03 Dec 2019 05:07:15 GMT', + 'Tue, 13 Oct 2020 10:10:54 GMT', 'Content-Length', - '0' ]); + '0' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .head('/filesystem157534999218909418/file157534999333409585') + .head('/filesystem160258385407003300/file160258385437501972') .query(true) - .reply(200, [], [ 'Cache-Control', + .reply(200, [], [ + 'Cache-Control', 'cache-control-override', 'Content-Length', '0', @@ -74,21 +116,21 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Content-Language', 'content-language-override', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:16 GMT', + 'Tue, 13 Oct 2020 10:10:54 GMT', 'Accept-Ranges', 'bytes', 'ETag', - '"0x8D777AEAA3D03BC"', + '"0x8D86F6045711464"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '30efffe2-901e-000a-6497-a95c17000000', + '5699006d-d01e-0067-7349-a15d5c000000', 'x-ms-client-request-id', - 'b11c846a-dba9-4f12-b773-9700fdd33891', + 'df6ef126-8bc4-4018-aa2c-032402314afa', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-creation-time', - 'Tue, 03 Dec 2019 05:07:16 GMT', + 'Tue, 13 Oct 2020 10:10:54 GMT', 'x-ms-lease-status', 'unlocked', 'x-ms-lease-state', @@ -103,25 +145,24 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Hot', 'x-ms-access-tier-inferred', '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,Cache-Control,Content-Disposition,Content-Encoding,Content-Language,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', - 'Access-Control-Allow-Origin', - '*', 'Date', - 'Tue, 03 Dec 2019 05:07:16 GMT' ]); + 'Tue, 13 Oct 2020 10:10:54 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/filesystem157534999218909418') + .delete('/filesystem160258385407003300') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '490121a8-501e-0071-5f97-a937a7000000', + '569900a9-d01e-0067-2149-a15d5c000000', 'x-ms-client-request-id', - '80ed30a1-8398-4ad8-92dc-2400b4354bed', + 'fb509560-eb5d-4bc7-94cb-edc14130bf51', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:17 GMT' ]); + 'Tue, 13 Oct 2020 10:10:55 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file_for_20191212.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file_for_20191212.js new file mode 100644 index 000000000000..2c3b8493df16 --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_file_for_20191212.js @@ -0,0 +1,168 @@ +let nock = require('nock'); + +module.exports.hash = "0b07d2158d3dc30decd63a5cbc3f0ed9"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258385595609680","file":"file160258385626203856"},"newDate":{"now":"2020-10-13T10:10:55.326Z","tmr":"2020-10-13T10:10:55.326Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU1NSwibmJmIjoxNjAyNTgzNTU1LCJleHAiOjE2MDI2NzAyNTUsImFpbyI6IkUyUmdZRkE4V05yT1VMYlEyeUZBcE50OFV2TUdBQT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJGck8yYnZ5c3hVU1BXbWZRY25rREFBIiwidmVyIjoiMS4wIn0.Tx36X6NwoFjZMqjIdFNK5Y2TRJqmw4I-L9816l7YYFLjbgNjPrdkcJL97sxJrERXdH1i3fneP1aRxhoMNRdnfRUgYchwrHyXFM4JdyPlVUE4Bn4Taq4lCYgvTZo5pdlTHA5GissywyP-eyRvzOf5FwZNC_9PBJVB_RhAosZetN21Ch_AfgPYoNdlIdgL6xZGyMrh1o1jYs1CgSpqE6KCAcBCd8ZUyosO1z79U0ctpvhOyEQ5CIRkrhpQS0UVeKTaBC4bQmIp3nBQEhQl34Y_vrP1vP_ShocVoVznrtgJC8pP9u7FZ1oLgxvijmV0LOygNlzEtbDmYu3HYFocjwkULg"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '6eb6b316-acfc-44c5-8f5a-67d072790300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AiKQAsqtSzdKtMXyfbEpJ6B00ISJAQAAAC50F9cOAAAA; expires=Thu, 12-Nov-2020 10:10:55 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:10:55 GMT', + 'Content-Length', + '1318' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .post('/', "2020-10-13T09:10:55Z2020-10-18T10:10:55Z") + .query(true) + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:10:55Z2020-10-18T10:10:55Zb2020-02-10pLlSbJStBZMOkPZ7HpOMmVyngquX+M2fLEU7AEc+4Q0=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '569900e9-d01e-0067-5149-a15d5c000000', + 'x-ms-client-request-id', + '3fea65c5-151d-4cd5-9814-f3de7da42bad', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:10:55 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258385595609680') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:56 GMT', + 'ETag', + '"0x8D86F6046608F02"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990107-d01e-0067-6849-a15d5c000000', + 'x-ms-client-request-id', + '5ed65d59-5b9c-4a91-99e6-89288284ee6f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:10:56 GMT' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem160258385595609680/file160258385626203856') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:56 GMT', + 'ETag', + '"0x8D86F60468F4D9E"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0d86af9e-401f-0017-1a49-a1e4ab000000', + 'x-ms-version', + '2020-02-10', + 'x-ms-client-request-id', + '78d54d6c-4876-4aff-a099-587e87a0b276', + 'Date', + 'Tue, 13 Oct 2020 10:10:55 GMT', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem160258385595609680/file160258385626203856') + .query(true) + .reply(200, [], [ + 'Cache-Control', + 'cache-control-override', + 'Content-Length', + '0', + 'Content-Type', + 'content-type-override', + 'Content-Encoding', + 'content-encoding-override', + 'Content-Language', + 'content-language-override', + 'Last-Modified', + 'Tue, 13 Oct 2020 10:10:56 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D86F60468F4D9E"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '56990127-d01e-0067-0149-a15d5c000000', + 'x-ms-client-request-id', + '41337885-2db8-465a-a9a1-43b8463fcf1c', + 'x-ms-version', + '2020-02-10', + 'x-ms-creation-time', + 'Tue, 13 Oct 2020 10:10:56 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'Content-Disposition', + 'content-disposition-override', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + 'true', + 'Date', + 'Tue, 13 Oct 2020 10:10:56 GMT' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem160258385595609680') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '5699013e-d01e-0067-1549-a15d5c000000', + 'x-ms-client-request-id', + '129ec0d2-35bc-4159-abfa-650dc7e6169b', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 13 Oct 2020 10:10:57 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_all_configurations.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_all_configurations.js index 41a76585cedf..88725e65f820 100644 --- a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_all_configurations.js +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_all_configurations.js @@ -1,77 +1,118 @@ let nock = require('nock'); -module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem157534998436003922"},"newDate":{"now":"2019-12-03T05:13:03.200Z","tmr":"2019-12-03T05:13:03.200Z"}} +module.exports.hash = "8b812ae76b74a458d771329ceb818cc8"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258384921803476"},"newDate":{"now":"2020-10-13T10:10:47.252Z","tmr":"2020-10-13T10:10:47.253Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU0NywibmJmIjoxNjAyNTgzNTQ3LCJleHAiOjE2MDI2NzAyNDcsImFpbyI6IkUyUmdZSWliTmF1SGIvYXhuTFVmbENva3VMWDFBUT09IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiI0M015VjBYY1NFNlNqT2NuOUVBREFBIiwidmVyIjoiMS4wIn0.E8mDC0uQwg5tIwmhvPfQAy0KMyq-PX3CuchNhXau5XIJeFYtXUP16H_ZW39Fy2ZAV_JqS0B7FZtQUPq15M7eqcRMM5BWLvoTd3gRVSeqB9mWRhPENsKe26SShOztGXGDIHgz4e3Yl5h6BHeM2xOIIxCx8QnpaCTIzcGdytXgkrq_E5g2o1AVTOkzEV2VjxCxG5K0OyD9-Y2cvtq3XC_Ldes5o9g8POdrNvHSeGFWD2DBJwfyHzYPakyazZw1BQDB-xj8OND1ngNY4dVclPTx0XK7vPfErzwDropx_I2oNlG3Y05wqiaOLb7me4S7LIkCBR1BWBwzD3NG0UtPyKrIxQ"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '573273e3-dc45-4e48-928c-e727f4400300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AloS1ULb369HklQROf8CklV00ISJAQAAACZ0F9cOAAAA; expires=Thu, 12-Nov-2020 10:10:47 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:10:47 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-12-03T04:13:03Z2019-12-08T05:13:03Z") + .post('/', "2020-10-13T09:10:47Z2020-10-18T10:10:47Z") .query(true) - .reply(200, "324ed67c-1c74-4563-816e-c4be5f675ef172f988bf-86f1-41af-91ab-2d7cd011db472019-12-03T04:13:03Z2019-12-08T05:13:03Zb2019-02-02hpm/LX6MmYqmVlLUTqEdRdJIrcRJW8pPj2XwYwsPfnY=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:10:47Z2020-10-18T10:10:47Zb2020-02-103ZqJlwNZ8nlx0tPOv+5JON0VR71bzg9WKt+0j1IalWw=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '6dc53197-a01e-0046-7397-a99b08000000', + '5698fdbe-d01e-0067-4949-a15d5c000000', 'x-ms-client-request-id', - '92027dcc-93b0-4073-8af0-eb8879b1eb55', + 'c6bc8786-97f1-4a48-97d4-cf8a294a306e', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:05 GMT' ]); + 'Tue, 13 Oct 2020 10:10:48 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534998436003922') + .put('/filesystem160258384921803476') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:07 GMT', + 'Tue, 13 Oct 2020 10:10:49 GMT', 'ETag', - '"0x8D777AEA4E18CD2"', + '"0x8D86F60425D852A"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f291b67f-101e-0010-6797-a97378000000', + '5698fe28-d01e-0067-7b49-a15d5c000000', 'x-ms-client-request-id', - 'ecab1c96-46fb-4738-b9a3-8eba3ee24973', + '2dbbd69d-16db-4210-ba37-78c59d34d0de', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:06 GMT' ]); + 'Tue, 13 Oct 2020 10:10:48 GMT' +]); nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) - .get('/filesystem157534998436003922') + .get('/filesystem160258384921803476') .query(true) - .reply(200, {"paths":[]}, [ 'Transfer-Encoding', + .reply(200, {"paths":[]}, [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/json;charset=utf-8', - 'Vary', - 'Origin', 'Server', 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '817cfcd2-601f-001f-2b97-a99e8e000000', + '0d86af96-401f-0017-1649-a1e4ab000000', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-client-request-id', - '6d35126a-1997-416b-8b48-a8991cd52f92', + '59e60994-727f-464b-8137-5267754830d1', 'Date', - 'Tue, 03 Dec 2019 05:07:08 GMT' ]); + 'Tue, 13 Oct 2020 10:10:50 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/filesystem157534998436003922') + .delete('/filesystem160258384921803476') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f291bc55-101e-0010-4997-a97378000000', + '5698ff49-d01e-0067-2849-a15d5c000000', 'x-ms-client-request-id', - 'f8bab07a-59e3-464e-864f-4fd3d7102f57', + '10e26577-399e-4ac9-9fc9-abf5cf16e170', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:08 GMT' ]); + 'Tue, 13 Oct 2020 10:10:50 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_minimum_parameters.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_minimum_parameters.js index 6844ae006c6e..d2dcd75584e1 100644 --- a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_minimum_parameters.js +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generateuserdelegationsas_should_work_for_filesystem_with_minimum_parameters.js @@ -1,77 +1,118 @@ let nock = require('nock'); -module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem157534998839803889"},"newDate":{"now":"2019-12-03T05:13:07.166Z","tmr":"2019-12-03T05:13:07.166Z"}} +module.exports.hash = "484966e77cfa510699584bf7d95ab9eb"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem160258385238007990"},"newDate":{"now":"2020-10-13T10:10:51.780Z","tmr":"2020-10-13T10:10:51.780Z"}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/aaaaa/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=aaaaa&client_secret=aaaaa&scope=https%3A%2F%2Fstorage.azure.com%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsImlhdCI6MTYwMjU4MzU1MiwibmJmIjoxNjAyNTgzNTUyLCJleHAiOjE2MDI2NzAyNTIsImFpbyI6IkUyUmdZSkNOT25NbDU4R2pyaGJPWEozSEc4ejNBQUE9IiwiYXBwaWQiOiJmZjI4OThiNC0zNjljLTQ3YzMtYTQ3Ni1mNDVmZmM5MDY0ZWYiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwib2lkIjoiMWNlMTMyNzgtYTA4My00ZDE1LTg3OTYtZGUzOTcxNzc5M2UxIiwicmgiOiIwLkFRRUF2NGo1Y3ZHR3IwR1JxeTE4MEJIYlI3U1lLUC1jTnNOSHBIYjBYX3lRWk84YUFBQS4iLCJzdWIiOiIxY2UxMzI3OC1hMDgzLTRkMTUtODc5Ni1kZTM5NzE3NzkzZTEiLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJoMHA2dW8tXzRVeVVZOWlHZFdjREFBIiwidmVyIjoiMS4wIn0.UUV-NNJZTCXnRDczn-AcmZqhNENROmS92NlJi81BlxXaEQl3WDMsJU_jhWeaDV9praZFZx5AonxXWNZqY3DUutLTwy8EOGFl9hMs746z2oMnSWCzDEJaK7gj6tJXSlZjBPK_eI-P1MVSRQvatDFbJC4CahrtqswEricWsYRBPSvBTBVPKgYTvd0-ZN9Oqoraax5IJbJuOVfstOn4mFJVnREzzWDxEMc3mktoFpHMNGbLyFc_7cQ_NsdxRNRBVMH2NZOuRaq70v0qhcXqJIYZ5F5_OGA9qeX8NXAEsZ-r4mYGa17gkI76VjH5E8iTBloHJwx-of78glKuLhuqlEYNCQ"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'ba7a4a87-bf8f-4ce1-9463-d88675670300', + 'x-ms-ests-server', + '2.1.11154.7 - SEASLR2 ProdSlices', + 'Set-Cookie', + 'fpc=AkFYw8aKig1Nh5f9DOGfXPJ00ISJAQAAACt0F9cOAAAA; expires=Thu, 12-Nov-2020 10:10:52 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Tue, 13 Oct 2020 10:10:51 GMT', + 'Content-Length', + '1318' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .post('/', "2019-12-03T04:13:07Z2019-12-08T05:13:07Z") + .post('/', "2020-10-13T09:10:51Z2020-10-18T10:10:51Z") .query(true) - .reply(200, "324ed67c-1c74-4563-816e-c4be5f675ef172f988bf-86f1-41af-91ab-2d7cd011db472019-12-03T04:13:07Z2019-12-08T05:13:07Zb2019-02-02Q16oZ/MkFWdXp1BEHqhKQd3/v04Qsis6Um6dNCBoMNg=", [ 'Transfer-Encoding', + .reply(200, "1ce13278-a083-4d15-8796-de39717793e1aaaaa2020-10-13T09:10:51Z2020-10-18T10:10:51Zb2020-02-10TJAIhY20szrJTtqh3MOKn/5DdU/cszW/qhpe9LOda5k=", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f9aa78f8-d01e-0024-0297-a9dcd0000000', + '5698ff91-d01e-0067-5d49-a15d5c000000', 'x-ms-client-request-id', - '2b8344f8-ca81-4ba9-bd59-61425ba29eb6', + 'b59033a0-84ed-4286-b645-0d5464c646c0', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:09 GMT' ]); + 'Tue, 13 Oct 2020 10:10:51 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534998839803889') + .put('/filesystem160258385238007990') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:11 GMT', + 'Tue, 13 Oct 2020 10:10:52 GMT', 'ETag', - '"0x8D777AEA749DB3A"', + '"0x8D86F60443E35AC"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f9b3a424-301e-006a-2497-a91935000000', + '5698ffab-d01e-0067-7049-a15d5c000000', 'x-ms-client-request-id', - 'c0c4a899-2494-4774-8d7d-2354e53848d3', + '45a32676-8111-41ea-b52d-69dc8ca43a52', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:10 GMT' ]); + 'Tue, 13 Oct 2020 10:10:51 GMT' +]); nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) - .get('/filesystem157534998839803889') + .get('/filesystem160258385238007990') .query(true) - .reply(200, {"paths":[]}, [ 'Transfer-Encoding', + .reply(200, {"paths":[]}, [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/json;charset=utf-8', - 'Vary', - 'Origin', 'Server', 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'fba8f7d2-401f-0021-2d97-a928af000000', + '0d86af9a-401f-0017-1749-a1e4ab000000', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'x-ms-client-request-id', - '77d963b5-9c08-46fd-994a-de476c1bfec6', + '2ba1c216-c172-4d74-91c9-bd2c32108e6f', 'Date', - 'Tue, 03 Dec 2019 05:07:11 GMT' ]); + 'Tue, 13 Oct 2020 10:10:52 GMT' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/filesystem157534998839803889') + .delete('/filesystem160258385238007990') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f9b3a7c4-301e-006a-0197-a91935000000', + '5698ffdc-d01e-0067-1049-a15d5c000000', 'x-ms-client-request-id', - '2be8d73d-ba00-4a8a-8deb-c602d7ce1cc2', + '79e9fc83-a478-4a18-a5ef-ada99367c5b5', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Tue, 03 Dec 2019 05:07:11 GMT' ]); + 'Tue, 13 Oct 2020 10:10:52 GMT' +]); diff --git a/sdk/storage/storage-file-datalake/review/storage-file-datalake.api.md b/sdk/storage/storage-file-datalake/review/storage-file-datalake.api.md index 192a49a0b9b3..e4808adde926 100644 --- a/sdk/storage/storage-file-datalake/review/storage-file-datalake.api.md +++ b/sdk/storage/storage-file-datalake/review/storage-file-datalake.api.md @@ -7,6 +7,7 @@ import { AbortSignalLike } from '@azure/abort-controller'; import { BaseRequestPolicy } from '@azure/core-http'; import { BlobLeaseClient } from '@azure/storage-blob'; +import { BlobQueryArrowConfiguration } from '@azure/storage-blob'; import * as coreHttp from '@azure/core-http'; import { deserializationPolicy } from '@azure/core-http'; import { HttpHeaders } from '@azure/core-http'; @@ -37,6 +38,28 @@ import { UserAgentOptions } from '@azure/core-http'; import { UserDelegationKeyModel } from '@azure/storage-blob'; import { WebResource } from '@azure/core-http'; +// @public +export interface AccessControlChangeCounters { + changedDirectoriesCount: number; + changedFilesCount: number; + failedChangesCount: number; +} + +// @public +export interface AccessControlChangeError { + isDirectory: boolean; + message: string; + name: string; +} + +// @public +export interface AccessControlChanges { + aggregateCounters: AccessControlChangeCounters; + batchCounters: AccessControlChangeCounters; + batchFailures: AccessControlChangeError[]; + continuationToken?: string; +} + // @public (undocumented) export type AccessControlType = "user" | "group" | "mask" | "other"; @@ -129,11 +152,18 @@ export abstract class CredentialPolicy extends BaseRequestPolicy { // @public export type CredentialPolicyCreator = (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => CredentialPolicy; +// @public +export class DataLakeAclChangeFailedError extends Error { + constructor(error: RestError | Error, continuationToken?: string); + continuationToken?: string; + innerError: RestError | Error; +} + // @public export class DataLakeDirectoryClient extends DataLakePathClient { - create(resourceType: PathResourceType, options?: PathCreateOptions): Promise; + create(resourceType: PathResourceTypeModel, options?: PathCreateOptions): Promise; create(options?: DirectoryCreateOptions): Promise; - createIfNotExists(resourceType: PathResourceType, options?: PathCreateIfNotExistsOptions): Promise; + createIfNotExists(resourceType: PathResourceTypeModel, options?: PathCreateIfNotExistsOptions): Promise; createIfNotExists(options?: DirectoryCreateIfNotExistsOptions): Promise; getFileClient(fileName: string): DataLakeFileClient; getSubdirectoryClient(subdirectoryName: string): DataLakeDirectoryClient; @@ -144,9 +174,9 @@ export class DataLakeFileClient extends DataLakePathClient { constructor(url: string, credential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential, options?: StoragePipelineOptions); constructor(url: string, pipeline: Pipeline); append(body: HttpRequestBody, offset: number, length: number, options?: FileAppendOptions): Promise; - create(resourceType: PathResourceType, options?: PathCreateOptions): Promise; + create(resourceType: PathResourceTypeModel, options?: PathCreateOptions): Promise; create(options?: FileCreateOptions): Promise; - createIfNotExists(resourceType: PathResourceType, options?: PathCreateIfNotExistsOptions): Promise; + createIfNotExists(resourceType: PathResourceTypeModel, options?: PathCreateIfNotExistsOptions): Promise; createIfNotExists(options?: FileCreateIfNotExistsOptions): Promise; flush(position: number, options?: FileFlushOptions): Promise; query(query: string, options?: FileQueryOptions): Promise; @@ -154,6 +184,7 @@ export class DataLakeFileClient extends DataLakePathClient { readToBuffer(buffer: Buffer, offset?: number, count?: number, options?: FileReadToBufferOptions): Promise; readToBuffer(offset?: number, count?: number, options?: FileReadToBufferOptions): Promise; readToFile(filePath: string, offset?: number, count?: number, options?: FileReadOptions): Promise; + setExpiry(mode: FileExpiryMode, options?: FileSetExpiryOptions): Promise; upload(data: Buffer | Blob | ArrayBuffer | ArrayBufferView, options?: FileParallelUploadOptions): Promise; uploadFile(filePath: string, options?: FileParallelUploadOptions): Promise; uploadStream(stream: Readable, options?: FileParallelUploadOptions): Promise; @@ -204,8 +235,8 @@ export class DataLakeLeaseClient { export class DataLakePathClient extends StorageClient { constructor(url: string, credential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential, options?: StoragePipelineOptions); constructor(url: string, pipeline: Pipeline); - create(resourceType: PathResourceType, options?: PathCreateOptions): Promise; - createIfNotExists(resourceType: PathResourceType, options?: PathCreateIfNotExistsOptions): Promise; + create(resourceType: PathResourceTypeModel, options?: PathCreateOptions): Promise; + createIfNotExists(resourceType: PathResourceTypeModel, options?: PathCreateIfNotExistsOptions): Promise; delete(recursive?: boolean, options?: PathDeleteOptions): Promise; deleteIfExists(recursive?: boolean, options?: PathDeleteOptions): Promise; exists(options?: PathExistsOptions): Promise; @@ -216,12 +247,15 @@ export class DataLakePathClient extends StorageClient { move(destinationPath: string, options?: PathMoveOptions): Promise; move(destinationFileSystem: string, destinationPath: string, options?: PathMoveOptions): Promise; get name(): string; + removeAccessControlRecursive(acl: RemovePathAccessControlItem[], options?: PathChangeAccessControlRecursiveOptions): Promise; setAccessControl(acl: PathAccessControlItem[], options?: PathSetAccessControlOptions): Promise; + setAccessControlRecursive(acl: PathAccessControlItem[], options?: PathChangeAccessControlRecursiveOptions): Promise; setHttpHeaders(httpHeaders: PathHttpHeaders, options?: PathSetHttpHeadersOptions): Promise; setMetadata(metadata?: Metadata, options?: PathSetMetadataOptions): Promise; setPermissions(permissions: PathPermissions, options?: PathSetPermissionsOptions): Promise; toDirectoryClient(): DataLakeDirectoryClient; toFileClient(): DataLakeFileClient; + updateAccessControlRecursive(acl: PathAccessControlItem[], options?: PathChangeAccessControlRecursiveOptions): Promise; } // @public (undocumented) @@ -233,6 +267,10 @@ export class DataLakeSASPermissions { add: boolean; create: boolean; delete: boolean; + execute: boolean; + manageAccessControl: boolean; + manageOwnership: boolean; + move: boolean; static parse(permissions: string): DataLakeSASPermissions; read: boolean; toString(): string; @@ -241,17 +279,22 @@ export class DataLakeSASPermissions { // @public export interface DataLakeSASSignatureValues { + agentObjectId?: string; cacheControl?: string; contentDisposition?: string; contentEncoding?: string; contentLanguage?: string; contentType?: string; + correlationId?: string; + directoryDepth?: number; expiresOn?: Date; fileSystemName: string; identifier?: string; ipRange?: SasIPRange; + isDirectory?: boolean; pathName?: string; permissions?: DataLakeSASPermissions; + preauthorizedAgentObjectId?: string; protocol?: SASProtocol; snapshotTime?: string; startsOn?: Date; @@ -320,6 +363,9 @@ export interface FileCreateOptions extends PathCreateOptions { export interface FileCreateResponse extends PathCreateResponse { } +// @public +export type FileExpiryMode = 'NeverExpire' | 'RelativeToCreation' | 'RelativeToNow' | 'Absolute'; + // @public (undocumented) export interface FileFlushOptions extends CommonOptions { // (undocumented) @@ -349,6 +395,9 @@ export interface FileParallelUploadOptions extends CommonOptions { umask?: string; } +// @public +export type FileQueryArrowConfiguration = BlobQueryArrowConfiguration; + // @public export interface FileQueryCsvTextConfiguration { columnSeparator?: string; @@ -380,7 +429,7 @@ export interface FileQueryOptions extends CommonOptions { inputTextConfiguration?: FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration; onError?: (error: FileQueryError) => void; onProgress?: (progress: TransferProgressEvent) => void; - outputTextConfiguration?: FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration; + outputTextConfiguration?: FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration | FileQueryArrowConfiguration; } // @public (undocumented) @@ -480,6 +529,32 @@ export interface FileReadToBufferOptions extends CommonOptions { onProgress?: (progress: TransferProgressEvent) => void; } +// @public +export interface FileSetExpiryHeaders { + clientRequestId?: string; + date?: Date; + // (undocumented) + errorCode?: string; + etag?: string; + lastModified?: Date; + requestId?: string; + version?: string; +} + +// @public +export interface FileSetExpiryOptions extends CommonOptions { + abortSignal?: AbortSignalLike; + expiresOn?: Date; + timeToExpireInMs?: number; +} + +// @public +export type FileSetExpiryResponse = FileSetExpiryHeaders & { + _response: coreHttp.HttpResponse & { + parsedHeaders: FileSetExpiryHeaders; + }; +}; + // @public (undocumented) export interface FileSystemCreateHeaders { // (undocumented) @@ -693,7 +768,11 @@ export class FileSystemSASPermissions { add: boolean; create: boolean; delete: boolean; + execute: boolean; list: boolean; + manageAccessControl: boolean; + manageOwnership: boolean; + move: boolean; static parse(permissions: string): FileSystemSASPermissions; read: boolean; toString(): string; @@ -888,22 +967,38 @@ export interface PathAccessControl { // @public (undocumented) export interface PathAccessControlItem { - // (undocumented) accessControlType: AccessControlType; - // (undocumented) defaultScope: boolean; - // (undocumented) entityId: string; - // (undocumented) permissions: RolePermissions; } // @public export interface PathAppendDataHeaders { clientRequestId?: string; + contentMD5?: Uint8Array; date?: Date; + etag?: string; + isServerEncrypted?: boolean; requestId?: string; version?: string; + xMsContentCrc64?: Uint8Array; +} + +// @public +export interface PathChangeAccessControlRecursiveOptions extends CommonOptions { + abortSignal?: AbortSignalLike; + batchSize?: number; + continuationToken?: string; + continueOnFailure?: boolean; + maxBatches?: number; + onProgress?: (progress: AccessControlChanges) => void; +} + +// @public +export interface PathChangeAccessControlRecursiveResponse { + continuationToken?: string; + counters: AccessControlChangeCounters; } // @public @@ -1075,6 +1170,9 @@ export enum PathGetPropertiesAction { GetStatus = "getStatus" } +// @public +export type PathGetPropertiesActionModel = 'getAccessControl' | 'getStatus'; + // @public (undocumented) export interface PathGetPropertiesHeaders { // (undocumented) @@ -1125,6 +1223,7 @@ export interface PathGetPropertiesHeaders { encryptionKeySha256?: string; // (undocumented) etag?: string; + expiresOn?: Date; // (undocumented) isIncrementalCopy?: boolean; // (undocumented) @@ -1291,6 +1390,9 @@ export enum PathRenameMode { Posix = "posix" } +// @public +export type PathRenameModeModel = 'legacy' | 'posix'; + // @public export enum PathResourceType { // (undocumented) @@ -1299,6 +1401,9 @@ export enum PathResourceType { File = "file" } +// @public +export type PathResourceTypeModel = 'directory' | 'file'; + // @public export interface PathSetAccessControlHeaders { clientRequestId?: string; @@ -1458,6 +1563,13 @@ export interface RawAccessPolicy { startsOn?: string; } +// @public (undocumented) +export interface RemovePathAccessControlItem { + accessControlType: AccessControlType; + defaultScope: boolean; + entityId?: string; +} + export { RequestPolicy } export { RequestPolicyFactory } @@ -1490,16 +1602,21 @@ export enum SASProtocol { // @public export class SASQueryParameters { - constructor(version: string, signature: string, permissions?: string, services?: string, resourceTypes?: string, protocol?: SASProtocol, startsOn?: Date, expiresOn?: Date, ipRange?: SasIPRange, identifier?: string, resource?: string, cacheControl?: string, contentDisposition?: string, contentEncoding?: string, contentLanguage?: string, contentType?: string, userDelegationKey?: UserDelegationKey); + constructor(version: string, signature: string, permissions?: string, services?: string, resourceTypes?: string, protocol?: SASProtocol, startsOn?: Date, expiresOn?: Date, ipRange?: SasIPRange, identifier?: string, resource?: string, cacheControl?: string, contentDisposition?: string, contentEncoding?: string, contentLanguage?: string, contentType?: string, userDelegationKey?: UserDelegationKey, directoryDepth?: number, preauthorizedAgentObjectId?: string, agentObjectId?: string, correlationId?: string); + constructor(version: string, signature: string, options?: SASQueryParametersOptions); + readonly agentObjectId?: string; readonly cacheControl?: string; readonly contentDisposition?: string; readonly contentEncoding?: string; readonly contentLanguage?: string; readonly contentType?: string; + readonly correlationId?: string; + readonly directoryDepth?: number; readonly expiresOn?: Date; readonly identifier?: string; get ipRange(): SasIPRange | undefined; readonly permissions?: string; + readonly preauthorizedAgentObjectId?: string; readonly protocol?: SASProtocol; readonly resource?: string; readonly resourceTypes?: string; @@ -1510,6 +1627,29 @@ export class SASQueryParameters { readonly version: string; } +// @public +export interface SASQueryParametersOptions { + agentObjectId?: string; + cacheControl?: string; + contentDisposition?: string; + contentEncoding?: string; + contentLanguage?: string; + contentType?: string; + correlationId?: string; + directoryDepth?: number; + expiresOn?: Date; + identifier?: string; + ipRange?: SasIPRange; + permissions?: string; + preauthorizedAgentObjectId?: string; + protocol?: SASProtocol; + resource?: string; + resourceTypes?: string; + services?: string; + startsOn?: Date; + userDelegationKey?: UserDelegationKey; +} + // @public (undocumented) export interface ServiceGetUserDelegationKeyHeaders { // (undocumented) diff --git a/sdk/storage/storage-file-datalake/src/StorageClient.ts b/sdk/storage/storage-file-datalake/src/StorageClient.ts index a1d557ebb0e7..0f7478a7acc8 100644 --- a/sdk/storage/storage-file-datalake/src/StorageClient.ts +++ b/sdk/storage/storage-file-datalake/src/StorageClient.ts @@ -63,6 +63,7 @@ export abstract class StorageClient { * @memberof StorageClient */ protected readonly pipeline: Pipeline; + /** * Such as AnonymousCredential, StorageSharedKeyCredential or any credential from the @azure/identity package to authenticate requests to the service. You can also provide an object that implements the TokenCredential interface. If not specified, AnonymousCredential is used. * @@ -70,6 +71,7 @@ export abstract class StorageClient { * @memberof StorageClient */ public readonly credential: StorageSharedKeyCredential | AnonymousCredential | TokenCredential; + /** * StorageClient is a reference to protocol layer operations entry, which is * generated by AutoRest generator. @@ -79,6 +81,17 @@ export abstract class StorageClient { * @memberof StorageClient */ protected readonly storageClientContext: StorageClientContext; + + /** + * storageClientContextWithBlobEndpoint is a reference to protocol layer operations entry, which is + * generated by AutoRest generator, with its url pointing to the Blob endpoint. + * + * @protected + * @type {StorageClientContext} + * @memberof StorageClient + */ + protected readonly storageClientContextToBlobEndpoint: StorageClientContext; + /** * @protected * @type {boolean} @@ -103,6 +116,10 @@ export abstract class StorageClient { this.dfsEndpointUrl, pipeline.toServiceClientOptions() ); + this.storageClientContextToBlobEndpoint = new StorageClientContext( + this.blobEndpointUrl, + pipeline.toServiceClientOptions() + ); this.isHttps = iEqual(getURLScheme(this.url) || "", "https"); @@ -120,5 +137,7 @@ export abstract class StorageClient { // Override protocol layer's default content-type const storageClientContext = this.storageClientContext as any; storageClientContext.requestContentType = undefined; + const storageClientContextWithBlobEndpoint = this.storageClientContextToBlobEndpoint as any; + storageClientContextWithBlobEndpoint.requestContentType = undefined; } } diff --git a/sdk/storage/storage-file-datalake/src/clients.ts b/sdk/storage/storage-file-datalake/src/clients.ts index 8462b1f6c305..3dca03ba8938 100644 --- a/sdk/storage/storage-file-datalake/src/clients.ts +++ b/sdk/storage/storage-file-datalake/src/clients.ts @@ -3,46 +3,57 @@ import { HttpRequestBody, isNode, TokenCredential } from "@azure/core-http"; import { BlobClient, BlockBlobClient } from "@azure/storage-blob"; import { CanonicalCode } from "@opentelemetry/api"; +import { Readable } from "stream"; +import { BufferScheduler } from "../../storage-common/src"; import { AnonymousCredential } from "./credentials/AnonymousCredential"; import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; import { DataLakeLeaseClient } from "./DataLakeLeaseClient"; import { PathOperations } from "./generated/src/operations"; import { - DirectoryCreateOptions, + AccessControlChanges, DirectoryCreateIfNotExistsOptions, + DirectoryCreateIfNotExistsResponse, + DirectoryCreateOptions, DirectoryCreateResponse, FileAppendOptions, FileAppendResponse, FileCreateIfNotExistsOptions, + FileCreateIfNotExistsResponse, FileCreateOptions, FileCreateResponse, + FileExpiryMode, FileFlushOptions, FileFlushResponse, FileParallelUploadOptions, + FileQueryOptions, FileReadOptions, FileReadResponse, FileReadToBufferOptions, + FileSetExpiryOptions, + FileSetExpiryResponse, FileUploadResponse, Metadata, PathAccessControlItem, - PathCreateOptions, + PathChangeAccessControlRecursiveOptions, + PathChangeAccessControlRecursiveResponse, PathCreateIfNotExistsOptions, + PathCreateIfNotExistsResponse, + PathCreateOptions, PathCreateResponse, + PathDeleteIfExistsResponse, PathDeleteOptions, PathDeleteResponse, PathExistsOptions, PathGetAccessControlOptions, PathGetAccessControlResponse, - PathGetPropertiesAction, PathGetPropertiesOptions, PathGetPropertiesResponse, PathHttpHeaders, PathMoveOptions, PathMoveResponse, PathPermissions, - PathRenameMode, - PathResourceType, + PathResourceTypeModel, PathSetAccessControlOptions, PathSetAccessControlResponse, PathSetHttpHeadersOptions, @@ -51,35 +62,32 @@ import { PathSetMetadataResponse, PathSetPermissionsOptions, PathSetPermissionsResponse, - PathCreateIfNotExistsResponse, - PathDeleteIfExistsResponse, - DirectoryCreateIfNotExistsResponse, - FileCreateIfNotExistsResponse, - FileQueryOptions + RemovePathAccessControlItem } from "./models"; +import { PathSetAccessControlRecursiveMode } from "./models.internal"; import { newPipeline, Pipeline, StoragePipelineOptions } from "./Pipeline"; import { StorageClient } from "./StorageClient"; import { + toAccessControlChangeFailureArray, toAclString, toPathGetAccessControlResponse, toPermissionsString, toProperties } from "./transforms"; -import { createSpan } from "./utils/tracing"; -import { appendToURLPath, setURLPath } from "./utils/utils.common"; -import { Readable } from "stream"; +import { Batch } from "./utils/Batch"; import { + BLOCK_BLOB_MAX_BLOCKS, DEFAULT_HIGH_LEVEL_CONCURRENCY, + ETagAny, FILE_MAX_SINGLE_UPLOAD_THRESHOLD, - FILE_UPLOAD_MAX_CHUNK_SIZE, FILE_MAX_SIZE_BYTES, FILE_UPLOAD_DEFAULT_CHUNK_SIZE, - BLOCK_BLOB_MAX_BLOCKS, - ETagAny + FILE_UPLOAD_MAX_CHUNK_SIZE } from "./utils/constants"; -import { BufferScheduler } from "../../storage-common/src"; -import { Batch } from "./utils/Batch"; -import { fsStat, fsCreateReadStream } from "./utils/utils.node"; +import { DataLakeAclChangeFailedError } from "./utils/DataLakeAclChangeFailedError"; +import { createSpan } from "./utils/tracing"; +import { appendToURLPath, setURLPath } from "./utils/utils.common"; +import { fsCreateReadStream, fsStat } from "./utils/utils.node"; /** * A DataLakePathClient represents a URL to the Azure Storage path (directory or file). @@ -107,6 +115,104 @@ export class DataLakePathClient extends StorageClient { */ private blobClient: BlobClient; + /** + * SetAccessControlRecursiveInternal operation sets the Access Control on a path and sub paths. + * + * @private + * @param {PathSetAccessControlRecursiveMode} mode Mode \"set\" sets POSIX access control rights on files and directories, + * Mode \"modify\" modifies one or more POSIX access control rights that pre-exist on files and directories, + * Mode \"remove\" removes one or more POSIX access control rights that were present earlier on files and directories. + * @param {PathAccessControlItem[] | RemovePathAccessControlItem[]} acl The POSIX access control list for the file or directory. + * @param {PathChangeAccessControlRecursiveOptions} [options={}] Optional. Options + * @returns {Promise} + * @memberof DataLakePathClient + */ + private async setAccessControlRecursiveInternal( + mode: PathSetAccessControlRecursiveMode, + acl: PathAccessControlItem[] | RemovePathAccessControlItem[], + options: PathChangeAccessControlRecursiveOptions = {} + ): Promise { + if (options.maxBatches !== undefined && options.maxBatches < 1) { + throw RangeError(`Options maxBatches must be larger than 0.`); + } + + if (options.batchSize !== undefined && options.batchSize < 1) { + throw RangeError(`Options batchSize must be larger than 0.`); + } + + const { span, spanOptions } = createSpan( + `DataLakePathClient-setAccessControlRecursiveInternal`, + options.tracingOptions + ); + + const result: PathChangeAccessControlRecursiveResponse = { + counters: { + failedChangesCount: 0, + changedDirectoriesCount: 0, + changedFilesCount: 0 + }, + continuationToken: undefined + }; + + try { + let continuationToken = options.continuationToken; + let batchCounter = 0; + let reachMaxBatches = false; + do { + let response; + try { + response = await this.pathContext.setAccessControlRecursive(mode, { + ...options, + acl: toAclString(acl as PathAccessControlItem[]), + maxRecords: options.batchSize, + continuation: continuationToken, + forceFlag: options.continueOnFailure, + spanOptions + }); + } catch (e) { + throw new DataLakeAclChangeFailedError(e, continuationToken); + } + + batchCounter++; + continuationToken = response.continuation; + + // Update result + result.continuationToken = continuationToken; + result.counters.failedChangesCount += response.failureCount || 0; + result.counters.changedDirectoriesCount += response.directoriesSuccessful || 0; + result.counters.changedFilesCount += response.filesSuccessful || 0; + + // Progress event call back + if (options.onProgress) { + const progress: AccessControlChanges = { + batchFailures: toAccessControlChangeFailureArray(response.failedEntries), + batchCounters: { + failedChangesCount: response.failureCount || 0, + changedDirectoriesCount: response.directoriesSuccessful || 0, + changedFilesCount: response.filesSuccessful || 0 + }, + aggregateCounters: result.counters, + continuationToken: continuationToken + }; + options.onProgress(progress); + } + + reachMaxBatches = + options.maxBatches === undefined ? false : batchCounter >= options.maxBatches; + } while (continuationToken && !reachMaxBatches); + + return result; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + /** * Creates an instance of DataLakePathClient from url and credential. * @@ -220,13 +326,13 @@ export class DataLakePathClient extends StorageClient { * * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create * - * @param {PathResourceType} resourceType Resource type, "directory" or "file". + * @param {PathResourceTypeModel} resourceType Resource type, "directory" or "file". * @param {PathCreateOptions} [options={}] Optional. Options when creating path. * @returns {Promise} * @memberof DataLakePathClient */ public async create( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options: PathCreateOptions = {} ): Promise { options.conditions = options.conditions || {}; @@ -262,7 +368,7 @@ export class DataLakePathClient extends StorageClient { * @memberof DataLakePathClient */ public async createIfNotExists( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options: PathCreateIfNotExistsOptions = {} ): Promise { const { span, spanOptions } = createSpan( @@ -358,7 +464,8 @@ export class DataLakePathClient extends StorageClient { recursive, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, - spanOptions + spanOptions, + abortSignal: options.abortSignal }); continuation = response.continuation; } while (continuation !== undefined && continuation !== ""); @@ -444,11 +551,12 @@ export class DataLakePathClient extends StorageClient { ); try { const response = await this.pathContext.getProperties({ - action: PathGetPropertiesAction.GetAccessControl, + action: "getAccessControl", upn: options.userPrincipalName, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, - spanOptions + spanOptions, + abortSignal: options.abortSignal }); return toPathGetAccessControlResponse(response); } catch (e) { @@ -500,6 +608,108 @@ export class DataLakePathClient extends StorageClient { } } + /** + * Sets the Access Control on a path and sub paths. + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update + * + * @param {PathAccessControlItem[]} acl The POSIX access control list for the file or directory. + * @param {PathChangeAccessControlRecursiveOptions} [options={}] Optional. Options + * @returns {Promise} + * @memberof DataLakePathClient + */ + public async setAccessControlRecursive( + acl: PathAccessControlItem[], + options: PathChangeAccessControlRecursiveOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "DataLakePathClient-setAccessControlRecursive", + options.tracingOptions + ); + try { + return this.setAccessControlRecursiveInternal("set", acl, { + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Modifies the Access Control on a path and sub paths. + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update + * + * @param {PathAccessControlItem[]} acl The POSIX access control list for the file or directory. + * @param {PathChangeAccessControlRecursiveOptions} [options={}] Optional. Options + * @returns {Promise} + * @memberof DataLakePathClient + */ + public async updateAccessControlRecursive( + acl: PathAccessControlItem[], + options: PathChangeAccessControlRecursiveOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "DataLakePathClient-updateAccessControlRecursive", + options.tracingOptions + ); + try { + return this.setAccessControlRecursiveInternal("modify", acl, { + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the Access Control on a path and sub paths. + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update + * + * @param {RemovePathAccessControlItem[]} acl The POSIX access control list for the file or directory. + * @param {PathChangeAccessControlRecursiveOptions} [options={}] Optional. Options + * @returns {Promise} + * @memberof DataLakePathClient + */ + public async removeAccessControlRecursive( + acl: RemovePathAccessControlItem[], + options: PathChangeAccessControlRecursiveOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "DataLakePathClient-removeAccessControlRecursive", + options.tracingOptions + ); + try { + return this.setAccessControlRecursiveInternal("remove", acl, { + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + /** * Sets the file permissions on a path. * @@ -720,7 +930,7 @@ export class DataLakePathClient extends StorageClient { try { return await destPathClient.pathContext.create({ - mode: PathRenameMode.Legacy, // By default + mode: "legacy", // By default renameSource, sourceLeaseId: options.conditions.leaseId, leaseAccessConditions: options.destinationConditions, @@ -731,7 +941,8 @@ export class DataLakePathClient extends StorageClient { sourceIfUnmodifiedSince: options.conditions.ifUnmodifiedSince }, modifiedAccessConditions: options.destinationConditions, - spanOptions + spanOptions, + abortSignal: options.abortSignal }); } catch (e) { span.setStatus({ @@ -759,13 +970,13 @@ export class DataLakeDirectoryClient extends DataLakePathClient { * * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create * - * @param {PathResourceType} resourceType Resource type, must be "directory" for DataLakeDirectoryClient. + * @param {PathResourceTypeModel} resourceType Resource type, must be "directory" for DataLakeDirectoryClient. * @param {PathCreateOptions} [options] Optional. Options when creating directory. * @returns {Promise} * @memberof DataLakeDirectoryClient */ public async create( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options?: PathCreateOptions ): Promise; @@ -781,16 +992,16 @@ export class DataLakeDirectoryClient extends DataLakePathClient { public async create(options?: DirectoryCreateOptions): Promise; public async create( - resourceTypeOrOptions?: PathResourceType | PathCreateOptions, + resourceTypeOrOptions?: PathResourceTypeModel | PathCreateOptions, options: PathCreateOptions = {} ): Promise { - if (resourceTypeOrOptions === PathResourceType.Directory) { - return super.create(resourceTypeOrOptions as PathResourceType, options); + if (resourceTypeOrOptions === "directory") { + return super.create(resourceTypeOrOptions as PathResourceTypeModel, options); } - if (resourceTypeOrOptions === PathResourceType.File) { + if (resourceTypeOrOptions === "file") { throw TypeError( - `DataLakeDirectoryClient:create() resourceType cannot be ${PathResourceType.File}. Refer to DataLakeFileClient for file creation.` + `DataLakeDirectoryClient:create() resourceType cannot be ${resourceTypeOrOptions}. Refer to DataLakeFileClient for file creation.` ); } @@ -801,7 +1012,7 @@ export class DataLakeDirectoryClient extends DataLakePathClient { options.tracingOptions ); try { - return await super.create(PathResourceType.Directory, { + return await super.create("directory", { ...options, tracingOptions: { ...options.tracingOptions, @@ -830,7 +1041,7 @@ export class DataLakeDirectoryClient extends DataLakePathClient { * @memberof DataLakeDirectoryClient */ public async createIfNotExists( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options?: PathCreateIfNotExistsOptions ): Promise; @@ -848,16 +1059,16 @@ export class DataLakeDirectoryClient extends DataLakePathClient { ): Promise; public async createIfNotExists( - resourceTypeOrOptions?: PathResourceType | PathCreateIfNotExistsOptions, + resourceTypeOrOptions?: PathResourceTypeModel | PathCreateIfNotExistsOptions, options: PathCreateIfNotExistsOptions = {} ): Promise { - if (resourceTypeOrOptions === PathResourceType.File) { + if (resourceTypeOrOptions === "file") { throw TypeError( `DataLakeDirectoryClient:createIfNotExists() resourceType cannot be ${resourceTypeOrOptions}. Refer to DataLakeFileClient for file creation.` ); } - if (resourceTypeOrOptions !== PathResourceType.Directory) { + if (resourceTypeOrOptions !== "directory") { options = resourceTypeOrOptions || {}; } @@ -866,7 +1077,7 @@ export class DataLakeDirectoryClient extends DataLakePathClient { options.tracingOptions ); try { - return await super.createIfNotExists(PathResourceType.Directory, { + return await super.createIfNotExists("directory", { ...options, tracingOptions: { ...options.tracingOptions, @@ -930,6 +1141,15 @@ export class DataLakeFileClient extends DataLakePathClient { */ private pathContextInternal: PathOperations; + /** + * pathContextInternal provided by protocol layer, with its url pointing to the Blob endpoint. + * + * @private + * @type {PathOperations} + * @memberof DataLakeFileClient + */ + private pathContextInternalToBlobEndpoint: PathOperations; + /** * blockBlobClientInternal provided by @azure/storage-blob package. * @@ -992,6 +1212,9 @@ export class DataLakeFileClient extends DataLakePathClient { this.pathContextInternal = new PathOperations(this.storageClientContext); this.blockBlobClientInternal = new BlockBlobClient(this.blobEndpointUrl, this.pipeline); + this.pathContextInternalToBlobEndpoint = new PathOperations( + this.storageClientContextToBlobEndpoint + ); } /** @@ -999,13 +1222,13 @@ export class DataLakeFileClient extends DataLakePathClient { * * @see https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create * - * @param {PathResourceType} resourceType Resource type, must be "file" for DataLakeFileClient. + * @param {PathResourceTypeModel} resourceType Resource type, must be "file" for DataLakeFileClient. * @param {PathCreateOptions} [options] Optional. Options when creating file. * @returns {Promise} * @memberof DataLakeFileClient */ public async create( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options?: PathCreateOptions ): Promise; @@ -1021,16 +1244,16 @@ export class DataLakeFileClient extends DataLakePathClient { public async create(options?: FileCreateOptions): Promise; public async create( - resourceTypeOrOptions?: PathResourceType | PathCreateOptions, + resourceTypeOrOptions?: PathResourceTypeModel | PathCreateOptions, options: PathCreateOptions = {} ): Promise { - if (resourceTypeOrOptions === PathResourceType.File) { - return super.create(resourceTypeOrOptions as PathResourceType, options); + if (resourceTypeOrOptions === "file") { + return super.create(resourceTypeOrOptions as PathResourceTypeModel, options); } - if (resourceTypeOrOptions === PathResourceType.Directory) { + if (resourceTypeOrOptions === "directory") { throw TypeError( - `DataLakeFileClient:create() resourceType cannot be ${PathResourceType.Directory}. Refer to DataLakeDirectoryClient for directory creation.` + `DataLakeFileClient:create() resourceType cannot be ${resourceTypeOrOptions}. Refer to DataLakeDirectoryClient for directory creation.` ); } @@ -1038,7 +1261,7 @@ export class DataLakeFileClient extends DataLakePathClient { options.conditions = options.conditions || {}; const { span, spanOptions } = createSpan("DataLakeFileClient-create", options.tracingOptions); try { - return await super.create(PathResourceType.File, { + return await super.create("file", { ...options, tracingOptions: { ...options.tracingOptions, @@ -1067,7 +1290,7 @@ export class DataLakeFileClient extends DataLakePathClient { * @memberof DataLakeFileClient */ public async createIfNotExists( - resourceType: PathResourceType, + resourceType: PathResourceTypeModel, options?: PathCreateIfNotExistsOptions ): Promise; @@ -1085,16 +1308,16 @@ export class DataLakeFileClient extends DataLakePathClient { ): Promise; public async createIfNotExists( - resourceTypeOrOptions?: PathResourceType | PathCreateOptions, + resourceTypeOrOptions?: PathResourceTypeModel | PathCreateOptions, options: PathCreateIfNotExistsOptions = {} ): Promise { - if (resourceTypeOrOptions === PathResourceType.Directory) { + if (resourceTypeOrOptions === "directory") { throw TypeError( `DataLakeFileClient:createIfNotExists() resourceType cannot be ${resourceTypeOrOptions}. Refer to DataLakeDirectoryClient for directory creation.` ); } - if (resourceTypeOrOptions !== PathResourceType.File) { + if (resourceTypeOrOptions !== "file") { options = resourceTypeOrOptions || {}; } @@ -1103,7 +1326,7 @@ export class DataLakeFileClient extends DataLakePathClient { options.tracingOptions ); try { - return await super.createIfNotExists(PathResourceType.File, { + return await super.createIfNotExists("file", { ...options, tracingOptions: { ...options.tracingOptions, @@ -1237,6 +1460,7 @@ export class DataLakeFileClient extends DataLakePathClient { pathHttpHeaders: { contentMD5: options.transactionalContentMD5 }, + abortSignal: options.abortSignal, position: offset, contentLength: length, leaseAccessConditions: options.conditions, @@ -1807,4 +2031,59 @@ export class DataLakeFileClient extends DataLakePathClient { span.end(); } } + + /** + * Sets an expiry time on a file, once that time is met the file is deleted. + * + * @param {FileExpiryMode} mode + * @param {FileSetExpiryOptions} [options={}] + * @returns {Promise} + * @memberof DataLakeFileClient + */ + public async setExpiry( + mode: FileExpiryMode, + options: FileSetExpiryOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "DataLakeFileClient-setExpiry", + options.tracingOptions + ); + try { + let expiresOn: string | undefined = undefined; + if (mode === "RelativeToNow" || mode === "RelativeToCreation") { + if (!options.timeToExpireInMs) { + throw new Error(`Should specify options.timeToExpireInMs when using mode ${mode}.`); + } + // MINOR: need check against <= 2**64, but JS number has the precision problem. + expiresOn = Math.round(options.timeToExpireInMs).toString(); + } + + if (mode === "Absolute") { + if (!options.expiresOn) { + throw new Error(`Should specify options.expiresOn when using mode ${mode}.`); + } + const now = new Date(); + if (!(options.expiresOn!.getTime() > now.getTime())) { + throw new Error( + `options.expiresOn should be later than now: ${now.toUTCString()} when using mode ${mode}, but is ${options.expiresOn?.toUTCString()}` + ); + } + expiresOn = options.expiresOn!.toUTCString(); + } + + const adaptedOptions = { ...options, expiresOn }; + return await this.pathContextInternalToBlobEndpoint.setExpiry(mode, { + ...adaptedOptions, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } } diff --git a/sdk/storage/storage-file-datalake/src/generated/src/models/index.ts b/sdk/storage/storage-file-datalake/src/generated/src/models/index.ts index 5befeea12216..c70dede51990 100644 --- a/sdk/storage/storage-file-datalake/src/generated/src/models/index.ts +++ b/sdk/storage/storage-file-datalake/src/generated/src/models/index.ts @@ -474,6 +474,14 @@ export interface PathUpdateOptionalParams extends coreHttp.RequestOptionsBase { * operation. */ continuation?: string; + /** + * Optional. Valid for "SetAccessControlRecursive" operation. If set to false, the operation will + * terminate quickly on encountering user errors (4XX). If true, the operation will ignore user + * errors and proceed with the operation on other sub-entities of the directory. Continuation + * token will only be returned when forceFlag is true in case of user errors. If not set the + * default value is false for this. + */ + forceFlag?: boolean; /** * This parameter allows the caller to upload data in parallel and control the order in which it * is appended to the file. It is required when uploading data to be appended to the file and @@ -787,6 +795,14 @@ export interface PathSetAccessControlRecursiveOptionalParams extends coreHttp.Re * continue deleting the directory. */ continuation?: string; + /** + * Optional. Valid for "SetAccessControlRecursive" operation. If set to false, the operation will + * terminate quickly on encountering user errors (4XX). If true, the operation will ignore user + * errors and proceed with the operation on other sub-entities of the directory. Continuation + * token will only be returned when forceFlag is true in case of user errors. If not set the + * default value is false for this. + */ + forceFlag?: boolean; /** * Optional. It specifies the maximum number of files or directories on which the acl change will * be applied. If omitted or greater than 2,000, the request will process up to 2,000 items @@ -895,6 +911,10 @@ export interface PathAppendDataOptionalParams extends coreHttp.RequestOptionsBas * of the request content in bytes for "Append Data". */ contentLength?: number; + /** + * Specify the transactional crc64 for the body, to be validated by the service. + */ + transactionalContentCrc64?: Uint8Array; /** * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the * analytics logs when storage analytics logging is enabled. @@ -1668,6 +1688,26 @@ export interface PathAppendDataHeaders { * The version of the REST protocol used to process the request. */ version?: string; + /** + * An HTTP entity tag associated with the file or directory. + */ + etag?: string; + /** + * If the blob has an MD5 hash and this operation is to read the full blob, this response header + * is returned so that the client can check for message content integrity. + */ + contentMD5?: Uint8Array; + /** + * This header is returned so that the client can check for message content integrity. The value + * of this header is computed by the Blob service; it is not necessarily the same value specified + * in the request headers. + */ + xMsContentCrc64?: Uint8Array; + /** + * The value of this header is set to true if the contents of the request are successfully + * encrypted using the specified algorithm, and false otherwise. + */ + isServerEncrypted?: boolean; } /** @@ -1714,11 +1754,7 @@ export interface PathSetExpiryHeaders { * @readonly * @enum {string} */ -export enum PathSetAccessControlRecursiveMode { - Set = 'set', - Modify = 'modify', - Remove = 'remove', -} +export type PathSetAccessControlRecursiveMode = 'set' | 'modify' | 'remove'; /** * Defines values for PathExpiryOptions. @@ -1726,12 +1762,7 @@ export enum PathSetAccessControlRecursiveMode { * @readonly * @enum {string} */ -export enum PathExpiryOptions { - NeverExpire = 'NeverExpire', - RelativeToCreation = 'RelativeToCreation', - RelativeToNow = 'RelativeToNow', - Absolute = 'Absolute', -} +export type PathExpiryOptions = 'NeverExpire' | 'RelativeToCreation' | 'RelativeToNow' | 'Absolute'; /** * Defines values for PathResourceType. @@ -1739,10 +1770,7 @@ export enum PathExpiryOptions { * @readonly * @enum {string} */ -export enum PathResourceType { - Directory = 'directory', - File = 'file', -} +export type PathResourceType = 'directory' | 'file'; /** * Defines values for PathRenameMode. @@ -1750,10 +1778,7 @@ export enum PathResourceType { * @readonly * @enum {string} */ -export enum PathRenameMode { - Legacy = 'legacy', - Posix = 'posix', -} +export type PathRenameMode = 'legacy' | 'posix'; /** * Defines values for PathUpdateAction. @@ -1762,13 +1787,7 @@ export enum PathRenameMode { * @readonly * @enum {string} */ -export enum PathUpdateAction { - Append = 'append', - Flush = 'flush', - SetProperties = 'setProperties', - SetAccessControl = 'setAccessControl', - SetAccessControlRecursive = 'setAccessControlRecursive', -} +export type PathUpdateAction = 'append' | 'flush' | 'setProperties' | 'setAccessControl' | 'setAccessControlRecursive'; /** * Defines values for PathLeaseAction. @@ -1776,13 +1795,7 @@ export enum PathUpdateAction { * @readonly * @enum {string} */ -export enum PathLeaseAction { - Acquire = 'acquire', - Break = 'break', - Change = 'change', - Renew = 'renew', - Release = 'release', -} +export type PathLeaseAction = 'acquire' | 'break' | 'change' | 'renew' | 'release'; /** * Defines values for PathGetPropertiesAction. @@ -1790,10 +1803,7 @@ export enum PathLeaseAction { * @readonly * @enum {string} */ -export enum PathGetPropertiesAction { - GetAccessControl = 'getAccessControl', - GetStatus = 'getStatus', -} +export type PathGetPropertiesAction = 'getAccessControl' | 'getStatus'; /** * Contains response data for the listFileSystems operation. diff --git a/sdk/storage/storage-file-datalake/src/generated/src/models/mappers.ts b/sdk/storage/storage-file-datalake/src/generated/src/models/mappers.ts index 38367cfb49ff..2307d46a988c 100644 --- a/sdk/storage/storage-file-datalake/src/generated/src/models/mappers.ts +++ b/sdk/storage/storage-file-datalake/src/generated/src/models/mappers.ts @@ -1376,6 +1376,30 @@ export const PathAppendDataHeaders: coreHttp.CompositeMapper = { type: { name: "String" } + }, + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + contentMD5: { + serializedName: "content-md5", + type: { + name: "ByteArray" + } + }, + xMsContentCrc64: { + serializedName: "x-ms-content-crc64", + type: { + name: "ByteArray" + } + }, + isServerEncrypted: { + serializedName: "x-ms-request-server-encrypted", + type: { + name: "Boolean" + } } } } diff --git a/sdk/storage/storage-file-datalake/src/generated/src/models/parameters.ts b/sdk/storage/storage-file-datalake/src/generated/src/models/parameters.ts index cb9a8ccbce69..a7203407fdbd 100644 --- a/sdk/storage/storage-file-datalake/src/generated/src/models/parameters.ts +++ b/sdk/storage/storage-file-datalake/src/generated/src/models/parameters.ts @@ -254,6 +254,18 @@ export const expiryOptions: coreHttp.OperationParameter = { } } }; +export const forceFlag: coreHttp.OperationQueryParameter = { + parameterPath: [ + "options", + "forceFlag" + ], + mapper: { + serializedName: "forceFlag", + type: { + name: "Boolean" + } + } +}; export const group: coreHttp.OperationParameter = { parameterPath: [ "options", @@ -665,6 +677,18 @@ export const timeout: coreHttp.OperationQueryParameter = { } } }; +export const transactionalContentCrc64: coreHttp.OperationParameter = { + parameterPath: [ + "options", + "transactionalContentCrc64" + ], + mapper: { + serializedName: "x-ms-content-crc64", + type: { + name: "ByteArray" + } + } +}; export const transactionalContentHash: coreHttp.OperationParameter = { parameterPath: [ "options", @@ -720,7 +744,7 @@ export const version: coreHttp.OperationParameter = { required: true, isConstant: true, serializedName: "x-ms-version", - defaultValue: '2019-12-12', + defaultValue: '2020-02-10', type: { name: "String" } diff --git a/sdk/storage/storage-file-datalake/src/generated/src/operations/pathOperations.ts b/sdk/storage/storage-file-datalake/src/generated/src/operations/pathOperations.ts index e8457dddec57..36cdded813f3 100644 --- a/sdk/storage/storage-file-datalake/src/generated/src/operations/pathOperations.ts +++ b/sdk/storage/storage-file-datalake/src/generated/src/operations/pathOperations.ts @@ -478,6 +478,7 @@ const updateOperationSpec: coreHttp.OperationSpec = { Parameters.maxRecords, Parameters.continuation, Parameters.mode1, + Parameters.forceFlag, Parameters.position, Parameters.retainUncommittedData, Parameters.close, @@ -727,6 +728,7 @@ const setAccessControlRecursiveOperationSpec: coreHttp.OperationSpec = { Parameters.timeout, Parameters.continuation, Parameters.mode1, + Parameters.forceFlag, Parameters.maxRecords, Parameters.action3 ], @@ -802,6 +804,7 @@ const appendDataOperationSpec: coreHttp.OperationSpec = { ], headerParameters: [ Parameters.contentLength, + Parameters.transactionalContentCrc64, Parameters.requestId, Parameters.version, Parameters.transactionalContentHash, diff --git a/sdk/storage/storage-file-datalake/src/generated/src/storageClientContext.ts b/sdk/storage/storage-file-datalake/src/generated/src/storageClientContext.ts index 4f7f4afc89f4..c508830e1d7a 100644 --- a/sdk/storage/storage-file-datalake/src/generated/src/storageClientContext.ts +++ b/sdk/storage/storage-file-datalake/src/generated/src/storageClientContext.ts @@ -41,7 +41,7 @@ export class StorageClientContext extends coreHttp.ServiceClient { super(undefined, options); this.resource = 'filesystem'; - this.version = '2019-12-12'; + this.version = '2020-02-10'; this.baseUri = "{url}"; this.requestContentType = "application/json; charset=utf-8"; this.url = url; diff --git a/sdk/storage/storage-file-datalake/src/index.browser.ts b/sdk/storage/storage-file-datalake/src/index.browser.ts index 84fd3c410ff6..72359067aeaa 100644 --- a/sdk/storage/storage-file-datalake/src/index.browser.ts +++ b/sdk/storage/storage-file-datalake/src/index.browser.ts @@ -13,6 +13,7 @@ export * from "./policies/AnonymousCredentialPolicy"; export * from "./policies/CredentialPolicy"; export * from "./StorageRetryPolicyFactory"; export * from "./models"; +export * from "./utils/DataLakeAclChangeFailedError"; export { CommonOptions } from "./StorageClient"; export { ToBlobEndpointHostMappings, ToDfsEndpointHostMappings } from "./utils/constants"; export { RestError } from "@azure/core-http"; diff --git a/sdk/storage/storage-file-datalake/src/index.ts b/sdk/storage/storage-file-datalake/src/index.ts index da80b3cb1d3c..a383df6f001c 100644 --- a/sdk/storage/storage-file-datalake/src/index.ts +++ b/sdk/storage/storage-file-datalake/src/index.ts @@ -5,13 +5,13 @@ export * from "./DataLakeServiceClient"; export * from "./DataLakeFileSystemClient"; export * from "./clients"; export * from "./DataLakeLeaseClient"; -export * from "./AccountSASPermissions"; -export * from "./AccountSASResourceTypes"; -export * from "./AccountSASServices"; -export * from "./AccountSASSignatureValues"; -export * from "./DataLakeSASPermissions"; -export * from "./DataLakeSASSignatureValues"; -export * from "./FileSystemSASPermissions"; +export * from "./sas/AccountSASPermissions"; +export * from "./sas/AccountSASResourceTypes"; +export * from "./sas/AccountSASServices"; +export * from "./sas/AccountSASSignatureValues"; +export * from "./sas/DataLakeSASPermissions"; +export * from "./sas/DataLakeSASSignatureValues"; +export * from "./sas/FileSystemSASPermissions"; export * from "./StorageBrowserPolicyFactory"; export * from "./credentials/AnonymousCredential"; export * from "./credentials/Credential"; @@ -21,10 +21,11 @@ export * from "./policies/AnonymousCredentialPolicy"; export * from "./policies/CredentialPolicy"; export * from "./StorageRetryPolicyFactory"; export * from "./policies/StorageSharedKeyCredentialPolicy"; -export * from "./SASQueryParameters"; +export * from "./sas/SASQueryParameters"; export * from "./models"; +export * from "./utils/DataLakeAclChangeFailedError"; export { CommonOptions } from "./StorageClient"; -export { SasIPRange } from "./SasIPRange"; +export { SasIPRange } from "./sas/SasIPRange"; export { ToBlobEndpointHostMappings, ToDfsEndpointHostMappings } from "./utils/constants"; export { RestError } from "@azure/core-http"; export { logger } from "./log"; diff --git a/sdk/storage/storage-file-datalake/src/models.internal.ts b/sdk/storage/storage-file-datalake/src/models.internal.ts new file mode 100644 index 000000000000..fbf65c0191af --- /dev/null +++ b/sdk/storage/storage-file-datalake/src/models.internal.ts @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export { PathSetAccessControlRecursiveMode } from "./generated/src/models"; diff --git a/sdk/storage/storage-file-datalake/src/models.ts b/sdk/storage/storage-file-datalake/src/models.ts index 02676f0b6b52..b4348cfcd647 100644 --- a/sdk/storage/storage-file-datalake/src/models.ts +++ b/sdk/storage/storage-file-datalake/src/models.ts @@ -2,19 +2,29 @@ // Licensed under the MIT License. import { AbortSignalLike } from "@azure/abort-controller"; import { HttpResponse, TransferProgressEvent } from "@azure/core-http"; + import { LeaseAccessConditions, ModifiedAccessConditions as ModifiedAccessConditionsModel, - UserDelegationKeyModel + UserDelegationKeyModel, + BlobQueryArrowConfiguration } from "@azure/storage-blob"; export type ModifiedAccessConditions = Omit; +/** + * Options to query file with Apache Arrow format. Only valid for {@link FileQueryOptions.outputTextConfiguration}. + * + * @export + * @interface FileQueryArrowConfiguration + */ +export type FileQueryArrowConfiguration = BlobQueryArrowConfiguration; + import { + FileSystemListPathsHeaders, PathCreateResponse, + PathDeleteResponse, PathGetPropertiesHeaders as PathGetPropertiesHeadersModel, - FileSystemListPathsHeaders, - PathList as PathListModel, - PathDeleteResponse + PathList as PathListModel } from "./generated/src/models"; import { CommonOptions } from "./StorageClient"; @@ -39,15 +49,18 @@ export { PathSetAccessControlHeaders, PathSetAccessControlResponse, PathSetAccessControlResponse as PathSetPermissionsResponse, - PathResourceType, + PathResourceType as PathResourceTypeModel, PathUpdateHeaders, PathAppendDataHeaders, PathFlushDataHeaders, PathAppendDataResponse as FileAppendResponse, PathFlushDataResponse as FileFlushResponse, PathFlushDataResponse as FileUploadResponse, - PathGetPropertiesAction, - PathRenameMode + PathGetPropertiesAction as PathGetPropertiesActionModel, + PathRenameMode as PathRenameModeModel, + PathExpiryOptions as FileExpiryMode, + PathSetExpiryResponse as FileSetExpiryResponse, + PathSetExpiryHeaders as FileSetExpiryHeaders } from "./generated/src/models"; export { PathCreateResponse }; @@ -406,10 +419,59 @@ export interface PathPermissions { export type AccessControlType = "user" | "group" | "mask" | "other"; +export interface RemovePathAccessControlItem { + /** + * Indicates whether this is the default entry for the ACL. + * + * @type {boolean} + * @memberof RemovePathAccessControlItem + */ + defaultScope: boolean; + /** + * Specifies which role this entry targets. + * + * @type {AccessControlType} + * @memberof RemovePathAccessControlItem + */ + accessControlType: AccessControlType; + /** + * Specifies the entity for which this entry applies. + * Must be omitted for types mask or other. It must also be omitted when the user or group is the owner. + * + * @type {string} + * @memberof RemovePathAccessControlItem + */ + entityId?: string; +} + export interface PathAccessControlItem { + /** + * Indicates whether this is the default entry for the ACL. + * + * @type {boolean} + * @memberof PathAccessControlItem + */ defaultScope: boolean; + /** + * Specifies which role this entry targets. + * + * @type {AccessControlType} + * @memberof PathAccessControlItem + */ accessControlType: AccessControlType; + /** + * Specifies the entity for which this entry applies. + * + * @type {string} + * @memberof PathAccessControlItem + */ entityId: string; + /** + * Access control permissions. + * + * @type {RolePermissions} + * @memberof PathAccessControlItem + */ permissions: RolePermissions; } @@ -480,6 +542,181 @@ export interface PathSetAccessControlOptions extends CommonOptions { group?: string; } +/** + * Options type for `setAccessControlRecursive`, `updateAccessControlRecursive` and `removeAccessControlRecursive`. + * + * @export + * @interface PathChangeAccessControlRecursiveOptions + * @extends {CommonOptions} + */ +export interface PathChangeAccessControlRecursiveOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof PathChangeAccessControlRecursiveOptions + */ + abortSignal?: AbortSignalLike; + /** + * Optional. If data set size exceeds batch size then operation will be split into multiple requests so that progress can be tracked. + * Batch size should be between 1 and 2000. The default when unspecified is 2000. + * + * @type {number} + * @memberof PathChangeAccessControlRecursiveOptions + */ + batchSize?: number; + /** + * Optional. Defines maximum number of batches that single change Access Control operation can execute. + * If maximum is reached before all subpaths are processed then continuation token can be used to resume operation. + * Empty value indicates that maximum number of batches in unbound and operation continues till end. + * + * @type {number} + * @memberof PathChangeAccessControlRecursiveOptions + */ + maxBatches?: number; + /** + * Optional. Default false. If set to false, the operation will terminate quickly on encountering user failures. + * If true, the operation will ignore user failures and proceed with the operation on other sub-entities of the directory. + * + * @type {boolean} + * @memberof PathChangeAccessControlRecursiveOptions + */ + continueOnFailure?: boolean; + /** + * Continuation token to continue next batch of operations. + * + * @type {string} + * @memberof PathChangeAccessControlRecursiveOptions + */ + continuationToken?: string; + /** + * Callback where caller can track progress of the operation + * as well as collect paths that failed to change Access Control. + * + * @memberof PathChangeAccessControlRecursiveOptions + */ + onProgress?: (progress: AccessControlChanges) => void; +} + +/** + * Represents an entry that failed to update Access Control List during `setAccessControlRecursive`, `updateAccessControlRecursive` and `removeAccessControlRecursive`. + * + * @export + * @interface AccessControlChangeFailure + */ +export interface AccessControlChangeError { + /** + * Returns name of an entry. + * + * @type {string} + * @memberof AccessControlChangeFailure + */ + name: string; + /** + * Returns whether entry is a directory. + * + * @type {boolean} + * @memberof AccessControlChangeFailure + */ + isDirectory: boolean; + /** + * Returns error message that is the reason why entry failed to update. + * + * @type {string} + * @memberof AccessControlChangeFailure + */ + message: string; +} + +/** + * AccessControlChanges contains batch and cumulative counts of operations that change Access Control Lists recursively. + * Additionally it exposes path entries that failed to update while these operations progress. + * + * @export + * @interface AccessControlChanges + */ +export interface AccessControlChanges { + /** + * Path entries that failed to update Access Control List within single batch. + * + * @type {AccessControlChangeError[]} + * @memberof AccessControlChanges + */ + batchFailures: AccessControlChangeError[]; + /** + * Counts of paths changed within single batch. + * + * @type {AccessControlChangeCounters} + * @memberof AccessControlChanges + */ + batchCounters: AccessControlChangeCounters; + /** + * Counts of paths changed from start of the operation. + * + * @type {AccessControlChangeCounters} + * @memberof AccessControlChanges + */ + aggregateCounters: AccessControlChangeCounters; + /** + * Optional. Value is present when operation is split into multiple batches and can be used to resume progress. + * + * @type {string} + * @memberof AccessControlChanges + */ + continuationToken?: string; +} + +/** + * AccessControlChangeCounters contains counts of operations that change Access Control Lists recursively. + * + * @export + * @interface AccessControlChangeCounters + */ +export interface AccessControlChangeCounters { + /** + * Returns number of directories where Access Control List has been updated successfully. + * + * @type {number} + * @memberof AccessControlChangeCounters + */ + changedDirectoriesCount: number; + /** + * Returns number of files where Access Control List has been updated successfully. + * + * @type {number} + * @memberof AccessControlChangeCounters + */ + changedFilesCount: number; + /** + * Returns number of paths where Access Control List update has failed. + * + * @type {number} + * @memberof AccessControlChangeCounters + */ + failedChangesCount: number; +} + +/** + * Response type for `setAccessControlRecursive`, `updateAccessControlRecursive` and `removeAccessControlRecursive`. + * + * @export + * @interface PathChangeAccessControlRecursiveResponse + */ +export interface PathChangeAccessControlRecursiveResponse { + /** + * Contains counts of paths changed from start of the operation. + */ + counters: AccessControlChangeCounters; + /** + * Optional. Value is present when operation is split into multiple batches and can be used to resume progress. + * + * @type {string} + * @memberof PathChangeAccessControlRecursiveResponse + */ + continuationToken?: string; +} + export interface PathSetPermissionsOptions extends CommonOptions { abortSignal?: AbortSignalLike; conditions?: DataLakeRequestConditions; @@ -530,6 +767,11 @@ export interface PathGetPropertiesHeaders { accessTierInferred?: boolean; archiveStatus?: string; accessTierChangedOn?: Date; + + /** + * The time the file will expire. + */ + expiresOn?: Date; } export type PathGetPropertiesResponse = PathGetPropertiesHeaders & { @@ -663,6 +905,38 @@ export interface PathDeleteIfExistsResponse extends PathDeleteResponse { succeeded: boolean; } +// Keeping these for backward compatibility when we changed to use string unions. +/** + * Defines values for PathGetPropertiesAction. + * Possible values include: 'getAccessControl', 'getStatus' + * @readonly + * @enum {string} + */ +export enum PathGetPropertiesAction { + GetAccessControl = "getAccessControl", + GetStatus = "getStatus" +} +/** + * Defines values for PathRenameMode. + * Possible values include: 'legacy', 'posix' + * @readonly + * @enum {string} + */ +export enum PathRenameMode { + Legacy = "legacy", + Posix = "posix" +} +/** + * Defines values for PathResourceType. + * Possible values include: 'directory', 'file' + * @readonly + * @enum {string} + */ +export enum PathResourceType { + Directory = "directory", + File = "file" +} + /****************************************************************/ /** DataLakeDirectoryClient option and response related models **/ /****************************************************************/ @@ -1079,10 +1353,13 @@ export interface FileQueryOptions extends CommonOptions { /** * Configurations for the query output. * - * @type {FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration} + * @type {FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration | FileQueryArrowConfiguration} * @memberof FileQueryOptions */ - outputTextConfiguration?: FileQueryJsonTextConfiguration | FileQueryCsvTextConfiguration; + outputTextConfiguration?: + | FileQueryJsonTextConfiguration + | FileQueryCsvTextConfiguration + | FileQueryArrowConfiguration; /** * Callback to receive events on the progress of query operation. * @@ -1105,6 +1382,39 @@ export interface FileQueryOptions extends CommonOptions { conditions?: DataLakeRequestConditions; } +/** + * Option interface for the {@link DataLakeFileClient.setExpiry} operation. + * + * @export + * @interface FileSetExpiryOptions + */ +export interface FileSetExpiryOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileSetExpiryOptions + */ + abortSignal?: AbortSignalLike; + + /** + * The time to set the file to expire on, used in combination with the "Absolute" {@link FileExpiryMode}. + * A time in the past is not allowed and milliseconds will be dropped. + * + * @type {Date} + * @memberof FileSetExpiryOptions + */ + expiresOn?: Date; + + /** + * The number of milliseconds to elapse before the file expires, used in combination with the "RelativeToCreation" or "RelativeToNow" {@link FileExpiryMode}. + * + * @type {number} + * @memberof FileSetExpiryOptions + */ + timeToExpireInMs?: number; +} /***********************************************************/ /** DataLakeLeaseClient option and response related models */ /***********************************************************/ diff --git a/sdk/storage/storage-file-datalake/src/AccountSASPermissions.ts b/sdk/storage/storage-file-datalake/src/sas/AccountSASPermissions.ts similarity index 100% rename from sdk/storage/storage-file-datalake/src/AccountSASPermissions.ts rename to sdk/storage/storage-file-datalake/src/sas/AccountSASPermissions.ts diff --git a/sdk/storage/storage-file-datalake/src/AccountSASResourceTypes.ts b/sdk/storage/storage-file-datalake/src/sas/AccountSASResourceTypes.ts similarity index 100% rename from sdk/storage/storage-file-datalake/src/AccountSASResourceTypes.ts rename to sdk/storage/storage-file-datalake/src/sas/AccountSASResourceTypes.ts diff --git a/sdk/storage/storage-file-datalake/src/AccountSASServices.ts b/sdk/storage/storage-file-datalake/src/sas/AccountSASServices.ts similarity index 100% rename from sdk/storage/storage-file-datalake/src/AccountSASServices.ts rename to sdk/storage/storage-file-datalake/src/sas/AccountSASServices.ts diff --git a/sdk/storage/storage-file-datalake/src/AccountSASSignatureValues.ts b/sdk/storage/storage-file-datalake/src/sas/AccountSASSignatureValues.ts similarity index 96% rename from sdk/storage/storage-file-datalake/src/AccountSASSignatureValues.ts rename to sdk/storage/storage-file-datalake/src/sas/AccountSASSignatureValues.ts index f0cd84e68f3e..e74aed7efb52 100644 --- a/sdk/storage/storage-file-datalake/src/AccountSASSignatureValues.ts +++ b/sdk/storage/storage-file-datalake/src/sas/AccountSASSignatureValues.ts @@ -4,11 +4,11 @@ import { AccountSASPermissions } from "./AccountSASPermissions"; import { AccountSASResourceTypes } from "./AccountSASResourceTypes"; import { AccountSASServices } from "./AccountSASServices"; -import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; +import { StorageSharedKeyCredential } from "../credentials/StorageSharedKeyCredential"; import { SasIPRange, ipRangeToString } from "./SasIPRange"; import { SASProtocol, SASQueryParameters } from "./SASQueryParameters"; -import { SERVICE_VERSION } from "./utils/constants"; -import { truncatedISO8061Date } from "./utils/utils.common"; +import { SERVICE_VERSION } from "../utils/constants"; +import { truncatedISO8061Date } from "../utils/utils.common"; /** * ONLY AVAILABLE IN NODE.JS RUNTIME. diff --git a/sdk/storage/storage-file-datalake/src/DataLakeSASPermissions.ts b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASPermissions.ts similarity index 68% rename from sdk/storage/storage-file-datalake/src/DataLakeSASPermissions.ts rename to sdk/storage/storage-file-datalake/src/sas/DataLakeSASPermissions.ts index 2d59ae67829b..146d7806abd8 100644 --- a/sdk/storage/storage-file-datalake/src/DataLakeSASPermissions.ts +++ b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASPermissions.ts @@ -43,6 +43,18 @@ export class DataLakeSASPermissions { case "d": blobSASPermissions.delete = true; break; + case "m": + blobSASPermissions.move = true; + break; + case "e": + blobSASPermissions.execute = true; + break; + case "o": + blobSASPermissions.manageOwnership = true; + break; + case "p": + blobSASPermissions.manageAccessControl = true; + break; default: throw new RangeError(`Invalid permission: ${char}`); } @@ -91,6 +103,41 @@ export class DataLakeSASPermissions { */ public delete: boolean = false; + /** + * Specifies Move access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public move: boolean = false; + + /** + * Specifies Execute access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public execute: boolean = false; + + /** + * Specifies Ownership access granted, which allows the caller to set owner, owning group, + * or act as the owner when renaming or deleting a blob (file or directory) within a folder + * that has the sticky bit set. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public manageOwnership: boolean = false; + + /** + * Specifies Permission access granted, which allows the caller to set permissions and + * POSIX ACLs on blobs (files and directories). + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public manageAccessControl: boolean = false; + /** * Converts the given permissions to a string. Using this method will guarantee the permissions are in an * order accepted by the service. @@ -115,6 +162,18 @@ export class DataLakeSASPermissions { if (this.delete) { permissions.push("d"); } + if (this.move) { + permissions.push("m"); + } + if (this.execute) { + permissions.push("e"); + } + if (this.manageOwnership) { + permissions.push("o"); + } + if (this.manageAccessControl) { + permissions.push("p"); + } return permissions.join(""); } } diff --git a/sdk/storage/storage-file-datalake/src/DataLakeSASSignatureValues.ts b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts similarity index 64% rename from sdk/storage/storage-file-datalake/src/DataLakeSASSignatureValues.ts rename to sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts index 1d59a70dcf00..ad7a0c703bd8 100644 --- a/sdk/storage/storage-file-datalake/src/DataLakeSASSignatureValues.ts +++ b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts @@ -1,14 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; -import { UserDelegationKeyCredential } from "./credentials/UserDelegationKeyCredential"; +import { StorageSharedKeyCredential } from "../credentials/StorageSharedKeyCredential"; +import { UserDelegationKeyCredential } from "../credentials/UserDelegationKeyCredential"; import { DataLakeSASPermissions } from "./DataLakeSASPermissions"; import { FileSystemSASPermissions } from "./FileSystemSASPermissions"; -import { UserDelegationKey } from "./models"; +import { UserDelegationKey } from "../models"; import { ipRangeToString, SasIPRange } from "./SasIPRange"; import { SASProtocol, SASQueryParameters } from "./SASQueryParameters"; -import { SERVICE_VERSION } from "./utils/constants"; -import { truncatedISO8061Date } from "./utils/utils.common"; +import { SERVICE_VERSION } from "../utils/constants"; +import { truncatedISO8061Date } from "../utils/utils.common"; +import { DirectorySASPermissions } from "./DirectorySASPermissions"; /** * ONLY AVAILABLE IN NODE.JS RUNTIME. @@ -86,11 +87,62 @@ export interface DataLakeSASSignatureValues { */ pathName?: string; + /** + * Optional. Beginning in version 2020-02-10, this value defines whether or not the {@link pathName} is a directory. + * If this value is set to true, the Path is a Directory for a Directory SAS. If set to false or default, the Path + * is a File Path for a File Path SAS. + * + * @type {boolean} + * @memberof DataLakeSASSignatureValues + */ + isDirectory?: boolean; + + /** + * Optional. Beginning in version 2020-02-10, indicate the depth of the directory specified in the canonicalizedresource field of the string-to-sign. + * The depth of the directory is the number of directories beneath the root folder. + * + * @type {number} + * @memberof DataLakeSASSignatureValues + */ + directoryDepth?: number; + + /** + * Optional. Beginning in version 2020-02-10, specifies the Authorized AAD Object Id in GUID format. The AAD Object ID of a user + * authorized by the owner of the user delegation key to perform the action granted by the SAS. The Azure Storage service will + * ensure that the owner of the user delegation key has the required permissions before granting access but no additional permission + * check for the user specified in this value will be performed. This cannot be used in conjuction with {@link agentObjectId}. + * This is only used for User Delegation SAS. + * + * @type {string} + * @memberof DataLakeSASSignatureValues + */ + preauthorizedAgentObjectId?: string; + + /** + * Optional. Beginning in version 2020-02-10, specifies the Unauthorized AAD Object Id in GUID format. The AAD Object Id of a user that is assumed + * to be unauthorized by the owner of the user delegation key. The Azure Storage Service will perform an additional POSIX ACL check to determine + * if the user is authorized to perform the requested operation. This cannot be used in conjuction with {@link preauthorizedAgentObjectId}. + * This is only used for User Delegation SAS. + * + * @type {string} + * @memberof DataLakeSASSignatureValues + */ + agentObjectId?: string; + + /** + * Optional. Beginning in version 2020-02-10, this is a GUID value that will be logged in the storage diagnostic logs and can be used to + * correlate SAS generation with storage resource access. This is only used for User Delegation SAS. + * + * @type {string} + * @memberof DataLakeSASSignatureValues + */ + correlationId?: string; + /** * Optional. Snapshot timestamp string the SAS user may access. Only supported from API version 2018-11-09. * * @type {string} - * @memberof IBlobSASSignatureValues + * @memberof DataLakeSASSignatureValues */ snapshotTime?: string; @@ -278,10 +330,18 @@ export function generateDataLakeSASQueryParameters( sharedKeyCredential ); } else { - return generateBlobSASQueryParametersUDK20181109( - dataLakeSASSignatureValues, - userDelegationKeyCredential! - ); + // Version 2020-02-10 delegation SAS signature construction includes preauthorizedAgentObjectId, agentObjectId, correlationId. + if (version >= "2020-02-10") { + return generateBlobSASQueryParametersUDK20200210( + dataLakeSASSignatureValues, + userDelegationKeyCredential! + ); + } else { + return generateBlobSASQueryParametersUDK20181109( + dataLakeSASSignatureValues, + userDelegationKeyCredential! + ); + } } } @@ -337,10 +397,10 @@ function generateBlobSASQueryParameters20150405( : SERVICE_VERSION; let resource: string = "c"; let verifiedPermissions: string | undefined; - - if (dataLakeSASSignatureValues.snapshotTime) { - throw RangeError("'version' must be >= '2018-11-09' when provided 'snapshotTime'."); - } + dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( + dataLakeSASSignatureValues, + version + ); // Calling parse and toString guarantees the proper ordering and throws on invalid characters. if (dataLakeSASSignatureValues.permissions) { @@ -442,22 +502,27 @@ function generateBlobSASQueryParameters20181109( let resource: string = "c"; let verifiedPermissions: string | undefined; - if ( - dataLakeSASSignatureValues.pathName === undefined && - dataLakeSASSignatureValues.snapshotTime - ) { - throw RangeError("Must provide 'blobName' when provided 'snapshotTime'."); - } + dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( + dataLakeSASSignatureValues, + version + ); // Calling parse and toString guarantees the proper ordering and throws on invalid characters. if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { - verifiedPermissions = DataLakeSASPermissions.parse( - dataLakeSASSignatureValues.permissions.toString() - ).toString(); - resource = "b"; - if (dataLakeSASSignatureValues.snapshotTime) { - resource = "bs"; + if (dataLakeSASSignatureValues.isDirectory) { + verifiedPermissions = DirectorySASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "d"; + } else { + verifiedPermissions = DataLakeSASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } } } else { verifiedPermissions = FileSystemSASPermissions.parse( @@ -513,7 +578,9 @@ function generateBlobSASQueryParameters20181109( dataLakeSASSignatureValues.contentDisposition, dataLakeSASSignatureValues.contentEncoding, dataLakeSASSignatureValues.contentLanguage, - dataLakeSASSignatureValues.contentType + dataLakeSASSignatureValues.contentType, + undefined, + dataLakeSASSignatureValues.directoryDepth ); } @@ -524,7 +591,7 @@ function generateBlobSASQueryParameters20181109( * Creates an instance of SASQueryParameters. * * Only accepts required settings needed to create a SAS. For optional settings please - * set corresponding properties directly, such as permissions, startsOn and identifier. + * set corresponding properties directly, such as permissions, startsOn. * * WARNING: identifier will be ignored, permissions and expiresOn are required. * @@ -547,23 +614,149 @@ function generateBlobSASQueryParametersUDK20181109( : SERVICE_VERSION; let resource: string = "c"; let verifiedPermissions: string | undefined; - - if ( - dataLakeSASSignatureValues.pathName === undefined && - dataLakeSASSignatureValues.snapshotTime - ) { - throw RangeError("Must provide 'blobName' when provided 'snapshotTime'."); - } + dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( + dataLakeSASSignatureValues, + version + ); // Calling parse and toString guarantees the proper ordering and throws on invalid characters. if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { - verifiedPermissions = DataLakeSASPermissions.parse( + if (dataLakeSASSignatureValues.isDirectory) { + verifiedPermissions = DirectorySASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "d"; + } else { + verifiedPermissions = DataLakeSASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } + } + } else { + verifiedPermissions = FileSystemSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "b"; - if (dataLakeSASSignatureValues.snapshotTime) { - resource = "bs"; + } + } + + // Signature is generated on the un-url-encoded values. + const stringToSign = [ + verifiedPermissions ? verifiedPermissions : "", + dataLakeSASSignatureValues.startsOn + ? truncatedISO8061Date(dataLakeSASSignatureValues.startsOn, false) + : "", + dataLakeSASSignatureValues.expiresOn + ? truncatedISO8061Date(dataLakeSASSignatureValues.expiresOn, false) + : "", + getCanonicalName( + userDelegationKeyCredential.accountName, + dataLakeSASSignatureValues.fileSystemName, + dataLakeSASSignatureValues.pathName + ), + userDelegationKeyCredential.userDelegationKey.signedObjectId, + userDelegationKeyCredential.userDelegationKey.signedTenantId, + userDelegationKeyCredential.userDelegationKey.signedStartsOn + ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedStartsOn, false) + : "", + userDelegationKeyCredential.userDelegationKey.signedExpiresOn + ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedExpiresOn, false) + : "", + userDelegationKeyCredential.userDelegationKey.signedService, + userDelegationKeyCredential.userDelegationKey.signedVersion, + dataLakeSASSignatureValues.ipRange ? ipRangeToString(dataLakeSASSignatureValues.ipRange) : "", + dataLakeSASSignatureValues.protocol ? dataLakeSASSignatureValues.protocol : "", + version, + resource, + dataLakeSASSignatureValues.snapshotTime, + dataLakeSASSignatureValues.cacheControl, + dataLakeSASSignatureValues.contentDisposition, + dataLakeSASSignatureValues.contentEncoding, + dataLakeSASSignatureValues.contentLanguage, + dataLakeSASSignatureValues.contentType + ].join("\n"); + + const signature = userDelegationKeyCredential.computeHMACSHA256(stringToSign); + + return new SASQueryParameters( + version, + signature, + verifiedPermissions, + undefined, + undefined, + dataLakeSASSignatureValues.protocol, + dataLakeSASSignatureValues.startsOn, + dataLakeSASSignatureValues.expiresOn, + dataLakeSASSignatureValues.ipRange, + dataLakeSASSignatureValues.identifier, + resource, + dataLakeSASSignatureValues.cacheControl, + dataLakeSASSignatureValues.contentDisposition, + dataLakeSASSignatureValues.contentEncoding, + dataLakeSASSignatureValues.contentLanguage, + dataLakeSASSignatureValues.contentType, + userDelegationKeyCredential.userDelegationKey, + dataLakeSASSignatureValues.directoryDepth, + dataLakeSASSignatureValues.preauthorizedAgentObjectId, + dataLakeSASSignatureValues.agentObjectId, + dataLakeSASSignatureValues.correlationId + ); +} + +/** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * IMPLEMENTATION FOR API VERSION FROM 2020-02-10. + * + * Creates an instance of SASQueryParameters. + * + * Only accepts required settings needed to create a SAS. For optional settings please + * set corresponding properties directly, such as permissions, startsOn. + * + * WARNING: identifier will be ignored, permissions and expiresOn are required. + * + * @param {DataLakeSASSignatureValues} dataLakeSASSignatureValues + * @param {UserDelegationKeyCredential} userDelegationKeyCredential + * @returns {SASQueryParameters} + */ +function generateBlobSASQueryParametersUDK20200210( + dataLakeSASSignatureValues: DataLakeSASSignatureValues, + userDelegationKeyCredential: UserDelegationKeyCredential +): SASQueryParameters { + if (!dataLakeSASSignatureValues.permissions || !dataLakeSASSignatureValues.expiresOn) { + throw new RangeError( + "Must provide 'permissions' and 'expiresOn' for Blob SAS generation when generating user delegation SAS." + ); + } + + const version = dataLakeSASSignatureValues.version + ? dataLakeSASSignatureValues.version + : SERVICE_VERSION; + let resource: string = "c"; + let verifiedPermissions: string | undefined; + dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( + dataLakeSASSignatureValues, + version + ); + + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + if (dataLakeSASSignatureValues.permissions) { + if (dataLakeSASSignatureValues.pathName) { + if (dataLakeSASSignatureValues.isDirectory) { + verifiedPermissions = DirectorySASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "d"; + } else { + verifiedPermissions = DataLakeSASPermissions.parse( + dataLakeSASSignatureValues.permissions.toString() + ).toString(); + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } } } else { verifiedPermissions = FileSystemSASPermissions.parse( @@ -596,6 +789,9 @@ function generateBlobSASQueryParametersUDK20181109( : "", userDelegationKeyCredential.userDelegationKey.signedService, userDelegationKeyCredential.userDelegationKey.signedVersion, + dataLakeSASSignatureValues.preauthorizedAgentObjectId, + dataLakeSASSignatureValues.agentObjectId, + dataLakeSASSignatureValues.correlationId, dataLakeSASSignatureValues.ipRange ? ipRangeToString(dataLakeSASSignatureValues.ipRange) : "", dataLakeSASSignatureValues.protocol ? dataLakeSASSignatureValues.protocol : "", version, @@ -627,7 +823,11 @@ function generateBlobSASQueryParametersUDK20181109( dataLakeSASSignatureValues.contentEncoding, dataLakeSASSignatureValues.contentLanguage, dataLakeSASSignatureValues.contentType, - userDelegationKeyCredential.userDelegationKey + userDelegationKeyCredential.userDelegationKey, + dataLakeSASSignatureValues.directoryDepth, + dataLakeSASSignatureValues.preauthorizedAgentObjectId, + dataLakeSASSignatureValues.agentObjectId, + dataLakeSASSignatureValues.correlationId ); } @@ -640,3 +840,80 @@ function getCanonicalName(accountName: string, containerName: string, blobName?: } return elements.join(""); } + +function SASSignatureValuesSanityCheckAndAutofill( + dataLakeSASSignatureValues: DataLakeSASSignatureValues, + version: string +): DataLakeSASSignatureValues { + if ( + version < "2020-02-10" && + (dataLakeSASSignatureValues.isDirectory || dataLakeSASSignatureValues.directoryDepth) + ) { + throw RangeError("'version' must be >= '2020-02-10' to support directory SAS."); + } + if (dataLakeSASSignatureValues.isDirectory && dataLakeSASSignatureValues.pathName === undefined) { + throw RangeError("Must provide 'pathName' when 'isDirectory' is true."); + } + if ( + dataLakeSASSignatureValues.directoryDepth !== undefined && + (!Number.isInteger(dataLakeSASSignatureValues.directoryDepth) || + dataLakeSASSignatureValues.directoryDepth < 0) + ) { + throw RangeError("'directoryDepth' must be a non-negative interger."); + } + if ( + dataLakeSASSignatureValues.isDirectory && + dataLakeSASSignatureValues.directoryDepth === undefined + ) { + // calculate directoryDepth from pathName + if (dataLakeSASSignatureValues.pathName === "/") { + dataLakeSASSignatureValues.directoryDepth = 0; + } else { + dataLakeSASSignatureValues.directoryDepth = dataLakeSASSignatureValues.pathName + ?.split("/") + .filter((x) => x !== "").length; + } + } + + if ( + version < "2020-02-10" && + dataLakeSASSignatureValues.permissions && + (dataLakeSASSignatureValues.permissions.move || + dataLakeSASSignatureValues.permissions.execute || + dataLakeSASSignatureValues.permissions.manageOwnership || + dataLakeSASSignatureValues.permissions.manageAccessControl) + ) { + throw RangeError("'version' must be >= '2020-02-10' when providing m, e, o or p permission."); + } + + if ( + version < "2020-02-10" && + (dataLakeSASSignatureValues.preauthorizedAgentObjectId || + dataLakeSASSignatureValues.agentObjectId || + dataLakeSASSignatureValues.correlationId) + ) { + throw RangeError( + "'version' must be >= '2020-02-10' when providing 'preauthorizedAgentObjectId', 'agentObjectId' or 'correlationId'." + ); + } + if ( + dataLakeSASSignatureValues.preauthorizedAgentObjectId && + dataLakeSASSignatureValues.agentObjectId + ) { + throw RangeError( + "'preauthorizedAgentObjectId' or 'agentObjectId' shouldn't be specified at the same time." + ); + } + + if (dataLakeSASSignatureValues.snapshotTime && version < "2018-11-09") { + throw RangeError("'version' must be >= '2018-11-09' when provided 'snapshotTime'."); + } + if ( + dataLakeSASSignatureValues.pathName === undefined && + dataLakeSASSignatureValues.snapshotTime + ) { + throw RangeError("Must provide 'blobName' when provided 'snapshotTime'."); + } + + return dataLakeSASSignatureValues; +} diff --git a/sdk/storage/storage-file-datalake/src/sas/DirectorySASPermissions.ts b/sdk/storage/storage-file-datalake/src/sas/DirectorySASPermissions.ts new file mode 100644 index 000000000000..0bfcca7126c6 --- /dev/null +++ b/sdk/storage/storage-file-datalake/src/sas/DirectorySASPermissions.ts @@ -0,0 +1,191 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/** + * This is a helper class to construct a string representing the permissions granted by a ServiceSAS to a directory. + * Setting a value to true means that any SAS which uses these permissions will grant permissions for that operation. + * Once all the values are set, this should be serialized with toString and set as the permissions field on a + * {@link DataLakeSASSignatureValues} object. It is possible to construct the permissions string without this class, but + * the order of the permissions is particular and this class guarantees correctness. + * + * @export + * @class DirectorySASPermissions + */ +export class DirectorySASPermissions { + /** + * Creates an {@link DirectorySASPermissions} from the specified permissions string. This method will throw an + * Error if it encounters a character that does not correspond to a valid permission. + * + * @static + * @param {string} permissions + * @returns {DirectorySASPermissions} + * @memberof DirectorySASPermissions + */ + public static parse(permissions: string) { + const directorySASPermissions = new DirectorySASPermissions(); + + for (const char of permissions) { + switch (char) { + case "r": + directorySASPermissions.read = true; + break; + case "a": + directorySASPermissions.add = true; + break; + case "c": + directorySASPermissions.create = true; + break; + case "w": + directorySASPermissions.write = true; + break; + case "d": + directorySASPermissions.delete = true; + break; + case "l": + directorySASPermissions.list = true; + break; + case "m": + directorySASPermissions.move = true; + break; + case "e": + directorySASPermissions.execute = true; + break; + case "o": + directorySASPermissions.ownership = true; + break; + case "p": + directorySASPermissions.permission = true; + break; + default: + throw new RangeError(`Invalid permission ${char}`); + } + } + + return directorySASPermissions; + } + + /** + * Specifies Read access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public read: boolean = false; + + /** + * Specifies Add access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public add: boolean = false; + + /** + * Specifies Create access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public create: boolean = false; + + /** + * Specifies Write access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public write: boolean = false; + + /** + * Specifies Delete access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public delete: boolean = false; + + /** + * Specifies List access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public list: boolean = false; + + /** + * Specifies Move access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public move: boolean = false; + + /** + * Specifies Execute access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public execute: boolean = false; + + /** + * Specifies Ownership access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public ownership: boolean = false; + + /** + * Specifies Permission access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public permission: boolean = false; + + /** + * Converts the given permissions to a string. Using this method will guarantee the permissions are in an + * order accepted by the service. + * + * The order of the characters should be as specified here to ensure correctness. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas + * + * @returns {string} + * @memberof DirectorySASPermissions + */ + public toString(): string { + const permissions: string[] = []; + if (this.read) { + permissions.push("r"); + } + if (this.add) { + permissions.push("a"); + } + if (this.create) { + permissions.push("c"); + } + if (this.write) { + permissions.push("w"); + } + if (this.delete) { + permissions.push("d"); + } + if (this.list) { + permissions.push("l"); + } + if (this.move) { + permissions.push("m"); + } + if (this.execute) { + permissions.push("e"); + } + if (this.ownership) { + permissions.push("o"); + } + if (this.permission) { + permissions.push("p"); + } + return permissions.join(""); + } +} diff --git a/sdk/storage/storage-file-datalake/src/FileSystemSASPermissions.ts b/sdk/storage/storage-file-datalake/src/sas/FileSystemSASPermissions.ts similarity index 70% rename from sdk/storage/storage-file-datalake/src/FileSystemSASPermissions.ts rename to sdk/storage/storage-file-datalake/src/sas/FileSystemSASPermissions.ts index 319e31ef213a..2a97878c5443 100644 --- a/sdk/storage/storage-file-datalake/src/FileSystemSASPermissions.ts +++ b/sdk/storage/storage-file-datalake/src/sas/FileSystemSASPermissions.ts @@ -44,6 +44,18 @@ export class FileSystemSASPermissions { case "l": containerSASPermissions.list = true; break; + case "m": + containerSASPermissions.move = true; + break; + case "e": + containerSASPermissions.execute = true; + break; + case "o": + containerSASPermissions.manageOwnership = true; + break; + case "p": + containerSASPermissions.manageAccessControl = true; + break; default: throw new RangeError(`Invalid permission ${char}`); } @@ -100,6 +112,41 @@ export class FileSystemSASPermissions { */ public list: boolean = false; + /** + * Specifies Move access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public move: boolean = false; + + /** + * Specifies Execute access granted. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public execute: boolean = false; + + /** + * Specifies Ownership access granted, which allows the caller to set owner, owning group, + * or act as the owner when renaming or deleting a blob (file or directory) within a folder + * that has the sticky bit set. + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public manageOwnership: boolean = false; + + /** + * Specifies Permission access granted, which allows the caller to set permissions and + * POSIX ACLs on blobs (files and directories). + * + * @type {boolean} + * @memberof DirectorySASPermissions + */ + public manageAccessControl: boolean = false; + /** * Converts the given permissions to a string. Using this method will guarantee the permissions are in an * order accepted by the service. @@ -130,6 +177,18 @@ export class FileSystemSASPermissions { if (this.list) { permissions.push("l"); } + if (this.move) { + permissions.push("m"); + } + if (this.execute) { + permissions.push("e"); + } + if (this.manageOwnership) { + permissions.push("o"); + } + if (this.manageAccessControl) { + permissions.push("p"); + } return permissions.join(""); } } diff --git a/sdk/storage/storage-file-datalake/src/SASQueryParameters.ts b/sdk/storage/storage-file-datalake/src/sas/SASQueryParameters.ts similarity index 53% rename from sdk/storage/storage-file-datalake/src/SASQueryParameters.ts rename to sdk/storage/storage-file-datalake/src/sas/SASQueryParameters.ts index fbce2ebe2441..541ad7d449ff 100644 --- a/sdk/storage/storage-file-datalake/src/SASQueryParameters.ts +++ b/sdk/storage/storage-file-datalake/src/sas/SASQueryParameters.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { UserDelegationKey } from "./models"; +import { UserDelegationKey } from "../models"; import { ipRangeToString, SasIPRange } from "./SasIPRange"; -import { truncatedISO8061Date } from "./utils/utils.common"; +import { truncatedISO8061Date } from "../utils/utils.common"; /** * Protocols for generated SAS. @@ -22,6 +22,160 @@ export enum SASProtocol { HttpsAndHttp = "https,http" } +/** + * Options interfac to construct {@link SASQueryParameters}. + * + * @export + * @interface SASQueryParametersOptions + */ +export interface SASQueryParametersOptions { + /** + * Optional only when identifier is provided. + * Please refer to {@link AccountSASPermissions}, {@link BlobSASPermissions}, or {@link ContainerSASPermissions} for + * more details. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + permissions?: string; + /** + * Optional. The storage services being accessed (only for Account SAS). Please refer to {@link AccountSASServices} + * for more details. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + services?: string; + /** + * Optional. The storage resource types being accessed (only for Account SAS). Please refer to + * {@link AccountSASResourceTypes} for more details. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + resourceTypes?: string; + /** + * Optional. The allowed HTTP protocol(s). + * + * @type {SASProtocol} + * @memberof SASQueryParametersOptions + */ + protocol?: SASProtocol; + /** + * Optional. The start time for this SAS token. + * + * @type {Date} + * @memberof SASQueryParametersOptions + */ + startsOn?: Date; + /** + * Optional only when identifier is provided. The expiry time for this SAS token. + * + * @type {Date} + * @memberof SASQueryParametersOptions + */ + expiresOn?: Date; + /** + * Optional. IP ranges allowed in this SAS. + * + * @type {SasIPRange} + * @memberof SASQueryParametersOptions + */ + ipRange?: SasIPRange; + /** + * Optional. The signed identifier (only for {@link BlobSASSignatureValues}). + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/establishing-a-stored-access-policy + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + identifier?: string; + /** + * Optional. The storage container or blob (only for {@link BlobSASSignatureValues}). + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + resource?: string; + /** + * Value for cache-control header in Blob/File Service SAS. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + cacheControl?: string; + /** + * Value for content-disposition header in Blob/File Service SAS. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + contentDisposition?: string; + /** + * Value for content-encoding header in Blob/File Service SAS. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + contentEncoding?: string; + /** + * Value for content-length header in Blob/File Service SAS. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + contentLanguage?: string; + /** + * Value for content-type header in Blob/File Service SAS. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + contentType?: string; + /** + * User delegation key properties. + * + * @type {UserDelegationKey} + * @memberof SASQueryParametersOptions + */ + userDelegationKey?: UserDelegationKey; + /** + * Indicate the depth of the directory specified in the canonicalizedresource field of the string-to-sign. + * The depth of the directory is the number of directories beneath the root folder. + * + * @type {number} + * @memberof SASQueryParametersOptions + */ + directoryDepth?: number; + /** + * Authorized AAD Object Id in GUID format. The AAD Object ID of a user authorized by the owner of the User Delegation Key + * to perform the action granted by the SAS. The Azure Storage service will ensure that the owner of the user delegation key + * has the required permissions before granting access but no additional permission check for the user specified in + * this value will be performed. This cannot be used in conjuction with {@link signedUnauthorizedUserObjectId}. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + preauthorizedAgentObjectId?: string; + /** + * Unauthorized AAD Object Id in GUID format. The AAD Object Id of a user that is assumed to be unauthorized by the owner of the User Delegation Key. + * The Azure Storage Service will perform an additional POSIX ACL check to determine if the user is authorized to perform the requested operation. + * This cannot be used in conjuction with {@link signedAuthorizedUserObjectId}. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + agentObjectId?: string; + /** + * A GUID value that will be logged in the storage diagnostic logs and can be used to correlate SAS generation with storage resource access. + * + * @type {string} + * @memberof SASQueryParametersOptions + */ + correlationId?: string; +} + /** * Represents the components that make up an Azure Storage SAS' query parameters. This type is not constructed directly * by the user; it is only generated by the {@link AccountSASSignatureValues} and {@link BlobSASSignatureValues} @@ -230,6 +384,44 @@ export class SASQueryParameters { */ private readonly signedVersion?: string; + /** + * Indicate the depth of the directory specified in the canonicalizedresource field of the string-to-sign. + * The depth of the directory is the number of directories beneath the root folder. + * + * @type {number} + * @memberof SASQueryParameters + */ + public readonly directoryDepth?: number; + + /** + * Authorized AAD Object Id in GUID format. The AAD Object ID of a user authorized by the owner of the User Delegation Key + * to perform the action granted by the SAS. The Azure Storage service will ensure that the owner of the user delegation key + * has the required permissions before granting access but no additional permission check for the user specified in + * this value will be performed. This cannot be used in conjuction with {@link signedUnauthorizedUserObjectId}. + * + * @type {string} + * @memberof SASQueryParameters + */ + public readonly preauthorizedAgentObjectId?: string; + + /** + * Unauthorized AAD Object Id in GUID format. The AAD Object Id of a user that is assumed to be unauthorized by the owner of the User Delegation Key. + * The Azure Storage Service will perform an additional POSIX ACL check to determine if the user is authorized to perform the requested operation. + * This cannot be used in conjuction with {@link signedAuthorizedUserObjectId}. + * + * @type {string} + * @memberof SASQueryParameters + */ + public readonly agentObjectId?: string; + + /** + * A GUID value that will be logged in the storage diagnostic logs and can be used to correlate SAS generation with storage resource access. + * + * @type {string} + * @memberof SASQueryParameters + */ + public readonly correlationId?: string; + /** * Optional. IP range allowed for this SAS. * @@ -286,32 +478,107 @@ export class SASQueryParameters { contentEncoding?: string, contentLanguage?: string, contentType?: string, - userDelegationKey?: UserDelegationKey + userDelegationKey?: UserDelegationKey, + directoryDepth?: number, + preauthorizedAgentObjectId?: string, + agentObjectId?: string, + correlationId?: string + ); + + /** + * Creates an instance of SASQueryParameters. + * + * @param {string} version Representing the storage version + * @param {string} signature Representing the signature for the SAS token + * @param {SASQueryParametersOptions} [options] Optional. Options to construct the SASQueryParameters. + * @memberof SASQueryParameters + */ + constructor(version: string, signature: string, options?: SASQueryParametersOptions); + + constructor( + version: string, + signature: string, + permissionsOrOptions?: string | SASQueryParametersOptions, + services?: string, + resourceTypes?: string, + protocol?: SASProtocol, + startsOn?: Date, + expiresOn?: Date, + ipRange?: SasIPRange, + identifier?: string, + resource?: string, + cacheControl?: string, + contentDisposition?: string, + contentEncoding?: string, + contentLanguage?: string, + contentType?: string, + userDelegationKey?: UserDelegationKey, + directoryDepth?: number, + preauthorizedAgentObjectId?: string, + agentObjectId?: string, + correlationId?: string ) { this.version = version; - this.services = services; - this.resourceTypes = resourceTypes; - this.expiresOn = expiresOn; - this.permissions = permissions; - this.protocol = protocol; - this.startsOn = startsOn; - this.ipRangeInner = ipRange; - this.identifier = identifier; - this.resource = resource; this.signature = signature; - this.cacheControl = cacheControl; - this.contentDisposition = contentDisposition; - this.contentEncoding = contentEncoding; - this.contentLanguage = contentLanguage; - this.contentType = contentType; - - if (userDelegationKey) { - this.signedOid = userDelegationKey.signedObjectId; - this.signedTenantId = userDelegationKey.signedTenantId; - this.signedStartsOn = userDelegationKey.signedStartsOn; - this.signedExpiresOn = userDelegationKey.signedExpiresOn; - this.signedService = userDelegationKey.signedService; - this.signedVersion = userDelegationKey.signedVersion; + + if (permissionsOrOptions !== undefined && typeof permissionsOrOptions !== "string") { + // SASQueryParametersOptions + const options = permissionsOrOptions; + this.services = options.services; + this.resourceTypes = options.resourceTypes; + this.expiresOn = options.expiresOn; + this.permissions = options.permissions; + this.protocol = options.protocol; + this.startsOn = options.startsOn; + this.ipRangeInner = options.ipRange; + this.identifier = options.identifier; + this.resource = options.resource; + this.cacheControl = options.cacheControl; + this.contentDisposition = options.contentDisposition; + this.contentEncoding = options.contentEncoding; + this.contentLanguage = options.contentLanguage; + this.contentType = options.contentType; + this.directoryDepth = options.directoryDepth; + this.preauthorizedAgentObjectId = options.preauthorizedAgentObjectId; + this.agentObjectId = options.agentObjectId; + this.correlationId = options.correlationId; + + if (options.userDelegationKey) { + this.signedOid = options.userDelegationKey.signedObjectId; + this.signedTenantId = options.userDelegationKey.signedTenantId; + this.signedStartsOn = options.userDelegationKey.signedStartsOn; + this.signedExpiresOn = options.userDelegationKey.signedExpiresOn; + this.signedService = options.userDelegationKey.signedService; + this.signedVersion = options.userDelegationKey.signedVersion; + } + } else { + this.services = services; + this.resourceTypes = resourceTypes; + this.expiresOn = expiresOn; + this.permissions = permissionsOrOptions; + this.protocol = protocol; + this.startsOn = startsOn; + this.ipRangeInner = ipRange; + this.identifier = identifier; + this.resource = resource; + this.cacheControl = cacheControl; + this.contentDisposition = contentDisposition; + this.contentEncoding = contentEncoding; + this.contentLanguage = contentLanguage; + this.contentType = contentType; + this.directoryDepth = directoryDepth; + this.preauthorizedAgentObjectId = preauthorizedAgentObjectId; + this.agentObjectId = agentObjectId; + this.correlationId = correlationId; + + if (userDelegationKey) { + this.signedOid = userDelegationKey.signedObjectId; + this.signedTenantId = userDelegationKey.signedTenantId; + this.signedStartsOn = userDelegationKey.signedStartsOn; + this.signedExpiresOn = userDelegationKey.signedExpiresOn; + this.signedService = userDelegationKey.signedService; + this.signedVersion = userDelegationKey.signedVersion; + } } } @@ -344,7 +611,11 @@ export class SASQueryParameters { "rscd", "rsce", "rscl", - "rsct" + "rsct", + "sdd", + "saoid", + "suoid", + "scid" ]; const queries: string[] = []; @@ -436,6 +707,18 @@ export class SASQueryParameters { case "rsct": this.tryAppendQueryParameter(queries, param, this.contentType); break; + case "sdd": + this.tryAppendQueryParameter(queries, param, this.directoryDepth?.toString()); + break; + case "saoid": + this.tryAppendQueryParameter(queries, param, this.preauthorizedAgentObjectId); + break; + case "suoid": + this.tryAppendQueryParameter(queries, param, this.agentObjectId); + break; + case "scid": + this.tryAppendQueryParameter(queries, param, this.correlationId); + break; } } return queries.join("&"); diff --git a/sdk/storage/storage-file-datalake/src/SasIPRange.ts b/sdk/storage/storage-file-datalake/src/sas/SasIPRange.ts similarity index 100% rename from sdk/storage/storage-file-datalake/src/SasIPRange.ts rename to sdk/storage/storage-file-datalake/src/sas/SasIPRange.ts diff --git a/sdk/storage/storage-file-datalake/src/transforms.ts b/sdk/storage/storage-file-datalake/src/transforms.ts index b67642e86e59..1c4a395ff53b 100644 --- a/sdk/storage/storage-file-datalake/src/transforms.ts +++ b/sdk/storage/storage-file-datalake/src/transforms.ts @@ -4,14 +4,16 @@ import { URLBuilder } from "@azure/core-http"; import { PagedAsyncIterableIterator, PageSettings } from "@azure/core-paging"; import { ContainerItem, PublicAccessType as ContainerPublicAccessType } from "@azure/storage-blob"; -import { PathGetPropertiesResponse } from "./generated/src/models"; +import { AclFailedEntry, PathGetPropertiesResponse } from "./generated/src/models"; import { + AccessControlChangeError, FileSystemItem, Metadata, PathAccessControlItem, PathGetAccessControlResponse, PathPermissions, PublicAccessType, + RemovePathAccessControlItem, RolePermissions, ServiceListContainersSegmentResponse, ServiceListFileSystemsSegmentResponse @@ -339,6 +341,53 @@ export function toAccessControlItem(aclItemString: string): PathAccessControlIte }; } +export function toRemoveAccessControlItem(aclItemString: string): RemovePathAccessControlItem { + const error = new RangeError( + `toAccessControlItem() Parameter access control item string "${aclItemString}" is not valid.` + ); + if (aclItemString === "") { + throw error; + } + + aclItemString = aclItemString.toLowerCase(); + + const parts = aclItemString.split(":"); + if (parts.length < 1 || parts.length > 3) { + throw error; + } + + if (parts.length === 3) { + if (parts[0] !== "default") { + throw error; + } + } + + let defaultScope = false; + let index = 0; + if (parts[index] === "default") { + defaultScope = true; + index++; + } + + const accessControlType = parts[index++]; + if ( + accessControlType !== "user" && + accessControlType !== "group" && + accessControlType !== "mask" && + accessControlType !== "other" + ) { + throw error; + } + + const entityId = parts[index++]; + + return { + defaultScope, + accessControlType, + entityId + }; +} + export function toAcl(aclString?: string): PathAccessControlItem[] { if (aclString === undefined || aclString === "" || aclString === null) { return []; @@ -353,10 +402,27 @@ export function toAcl(aclString?: string): PathAccessControlItem[] { return acls; } +export function toRemoveAcl(aclString?: string): RemovePathAccessControlItem[] { + if (aclString === undefined || aclString === "" || aclString === null) { + return []; + } + + const acls = []; + const aclParts = aclString.split(","); + for (const aclPart of aclParts) { + acls.push(toRemoveAccessControlItem(aclPart)); + } + + return acls; +} + export function toAccessControlItemString(item: PathAccessControlItem): string { - return `${item.defaultScope ? "default:" : ""}${item.accessControlType}:${ - item.entityId - }:${toRolePermissionsString(item.permissions)}`; + const entityIdString = item.entityId !== undefined ? `:${item.entityId}` : ""; + const permissionsString = + item.permissions !== undefined ? `:${toRolePermissionsString(item.permissions)}` : ""; + return `${item.defaultScope ? "default:" : ""}${ + item.accessControlType + }${entityIdString}${permissionsString}`; } export function toAclString(acl: PathAccessControlItem[]): string { @@ -374,3 +440,15 @@ export function toPermissionsString(permissions: PathPermissions): string { permissions.extendedAcls ? "+" : "" }`; } + +export function toAccessControlChangeFailureArray( + aclFailedEntry: AclFailedEntry[] = [] +): AccessControlChangeError[] { + return aclFailedEntry.map((aclFailedEntry: AclFailedEntry) => { + return { + name: aclFailedEntry.name || "", + isDirectory: (aclFailedEntry.type || "").toLowerCase() === "directory", + message: aclFailedEntry.errorMessage || "" + }; + }); +} diff --git a/sdk/storage/storage-file-datalake/src/utils/DataLakeAclChangeFailedError.ts b/sdk/storage/storage-file-datalake/src/utils/DataLakeAclChangeFailedError.ts new file mode 100644 index 000000000000..3b65a013666f --- /dev/null +++ b/sdk/storage/storage-file-datalake/src/utils/DataLakeAclChangeFailedError.ts @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import { RestError } from "@azure/core-http"; + +/** + * An error thrown when an operation is interrupted and can be continued later on. + * + * @export + * @class DataLakeAclChangeFailedError + * @extends {Error} + */ +export class DataLakeAclChangeFailedError extends Error { + /** + * Continuation token to continue next batch of operations. + * + * @type {string} + * @memberof DataLakeAclChangeFailedError + */ + public continuationToken?: string; + + /** + * Internal error. + * + * @type {(RestError | Error)} + * @memberof DataLakeAclChangeFailedError + */ + public innerError: RestError | Error; + + constructor(error: RestError | Error, continuationToken?: string) { + super(error.message); + this.name = "DataLakeAclChangeFailedError"; + this.innerError = error; + this.continuationToken = continuationToken; + Object.setPrototypeOf(this, DataLakeAclChangeFailedError.prototype); + } +} diff --git a/sdk/storage/storage-file-datalake/src/utils/constants.ts b/sdk/storage/storage-file-datalake/src/utils/constants.ts index 382ec91f3f06..b771928239f0 100644 --- a/sdk/storage/storage-file-datalake/src/utils/constants.ts +++ b/sdk/storage/storage-file-datalake/src/utils/constants.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export const SDK_VERSION: string = "12.1.2"; -export const SERVICE_VERSION: string = "2019-12-12"; +export const SDK_VERSION: string = "12.2.0-beta.1"; +export const SERVICE_VERSION: string = "2020-02-10"; export const KB: number = 1024; export const MB: number = KB * 1024; diff --git a/sdk/storage/storage-file-datalake/swagger/README.md b/sdk/storage/storage-file-datalake/swagger/README.md index 3f536a85d830..cbf555231550 100644 --- a/sdk/storage/storage-file-datalake/swagger/README.md +++ b/sdk/storage/storage-file-datalake/swagger/README.md @@ -12,105 +12,113 @@ enable-xml: true generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../src/generated -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.StorageDataLake/stable/2019-12-12/DataLakeStorage.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.StorageDataLake/stable/2020-02-10/DataLakeStorage.json model-date-time-as-string: true optional-response-headers: true -enum-types: true ``` + ## Customizations for Track 2 Generator See the [AutoRest samples](https://github.com/Azure/autorest/tree/master/Samples/3b-custom-transformations) for more about how we're customizing things. ### Update DataLakeStorageClientContext to StorageClientContext + ```yaml directive: -- from: swagger-document - where: $.info["x-ms-code-generation-settings"] - transform: > - $.name = "StorageClient" + - from: swagger-document + where: $.info["x-ms-code-generation-settings"] + transform: > + $.name = "StorageClient" ``` ### Remove parameter FileSystem + ```yaml directive: -- from: swagger-document - where: $.parameters - transform: > - $.FileSystem = undefined + - from: swagger-document + where: $.parameters + transform: > + $.FileSystem = undefined ``` ### Remove parameter Path + ```yaml directive: -- from: swagger-document - where: $.parameters - transform: > - $.Path = undefined + - from: swagger-document + where: $.parameters + transform: > + $.Path = undefined ``` -### Rename path-HTTP-headers to path-Http-headers +### workaround: adding parameter location for `PathSetAccessControlRecursiveMode` + ```yaml directive: -- from: swagger-document - where: $.parameters - transform: > - $.CacheControl["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.ContentDisposition["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.ContentEncoding["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.ContentLanguage["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.ContentType["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.TransactionalContentMD5["x-ms-parameter-grouping"].name = "path-Http-headers"; - $.ContentMD5["x-ms-parameter-grouping"].name = "path-Http-headers"; + - from: swagger-document + where: $["parameters"].PathSetAccessControlRecursiveMode + transform: > + $["x-ms-parameter-location"] = "method"; ``` -### Rename response property ACL to acl for Path_GetProperties +### Rename path-HTTP-headers to path-Http-headers + ```yaml directive: -- from: swagger-document - where: $["x-ms-paths"]["/{filesystem}/{path}"].head.responses["200"].headers["x-ms-acl"] - transform: > - $["x-ms-client-name"] = "acl"; + - from: swagger-document + where: $.parameters + transform: > + $.CacheControl["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.ContentDisposition["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.ContentEncoding["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.ContentLanguage["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.ContentType["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.TransactionalContentMD5["x-ms-parameter-grouping"].name = "path-Http-headers"; + $.ContentMD5["x-ms-parameter-grouping"].name = "path-Http-headers"; ``` -### Update last modified property from string type to Date for FileSystem and Path models +### Rename response property ACL to acl for Path_GetProperties + ```yaml directive: -- from: swagger-document - where: $.definitions - transform: > - $.FileSystem.properties.lastModified.format = "date-time-rfc1123"; - $.Path.properties.lastModified.format = "date-time-rfc1123"; + - from: swagger-document + where: $["x-ms-paths"]["/{filesystem}/{path}"].head.responses["200"].headers["x-ms-acl"] + transform: > + $["x-ms-client-name"] = "acl"; ``` -### Update service version +### Update last modified property from string type to Date for FileSystem and Path models ```yaml directive: - from: swagger-document - where: $.parameters.ApiVersionParameter - transform: $.enum = [ "2019-12-12" ]; + where: $.definitions + transform: > + $.FileSystem.properties.lastModified.format = "date-time-rfc1123"; + $.Path.properties.lastModified.format = "date-time-rfc1123"; ``` ### Rename eTag -> etag -``` yaml + +```yaml directive: -- from: swagger-document - where: $["x-ms-paths"]..responses..headers["ETag"] - transform: > - $["x-ms-client-name"] = "etag"; -- from: swagger-document - where: $["definitions"]..["eTag"] - transform: > - $["x-ms-client-name"] = "etag"; + - from: swagger-document + where: $["x-ms-paths"]..responses..headers["ETag"] + transform: > + $["x-ms-client-name"] = "etag"; + - from: swagger-document + where: $["definitions"]..["eTag"] + transform: > + $["x-ms-client-name"] = "etag"; ``` ### workaround: adding parameter location for `PathSetAccessControlRecursiveMode` -``` yaml +```yaml directive: -- from: swagger-document - where: $["parameters"].PathSetAccessControlRecursiveMode - transform: > - $["x-ms-parameter-location"] = "method"; + - from: swagger-document + where: $["parameters"].PathSetAccessControlRecursiveMode + transform: > + $["x-ms-parameter-location"] = "method"; ``` diff --git a/sdk/storage/storage-file-datalake/test/node/pathclient.spec.ts b/sdk/storage/storage-file-datalake/test/node/pathclient.spec.ts index a540a68c1d38..31bf425b4a49 100644 --- a/sdk/storage/storage-file-datalake/test/node/pathclient.spec.ts +++ b/sdk/storage/storage-file-datalake/test/node/pathclient.spec.ts @@ -1,15 +1,19 @@ +import { AbortController } from "@azure/abort-controller"; import { record } from "@azure/test-utils-recorder"; import * as assert from "assert"; import * as dotenv from "dotenv"; import { + AccessControlChangeCounters, + AccessControlChanges, DataLakeFileClient, DataLakeFileSystemClient, + DataLakeServiceClient, PathAccessControlItem, - DataLakeServiceClient + PathPermissions, } from "../../src"; -import { PathPermissions } from "../../src/models"; -import { getDataLakeServiceClient, recorderEnvSetup, bodyToString } from "../utils"; +import { toAcl, toRemoveAcl } from "../../src/transforms"; +import { bodyToString, getDataLakeServiceClient, recorderEnvSetup } from "../utils"; dotenv.config(); @@ -330,4 +334,454 @@ describe("DataLakePathClient Node.js only", () => { const response = await fileClient2.query("select * from BlobStorage"); assert.deepStrictEqual(await bodyToString(response), csvContent); }); + + it("quick query should work with arrow output configuration", async () => { + const csvContent = "100,200,300,400\n150,250,350,450\n"; + const fileClient2 = fileSystemClient.getFileClient(fileName + "2"); + await fileClient2.create(); + await fileClient2.append(csvContent, 0, csvContent.length); + await fileClient2.flush(csvContent.length); + + await fileClient2.query("select * from BlobStorage", { + outputTextConfiguration: { + kind: "arrow", + schema: [ + { + type: "decimal", + name: "name", + precision: 4, + scale: 2 + } + ] + } + }); + }); +}); + +describe("DataLakePathClient setAccessControlRecursive Node.js only", () => { + let fileSystemName: string; + let fileSystemClient: DataLakeFileSystemClient; + let fileName: string; + let fileClient: DataLakeFileClient; + const content = "Hello World"; + let serviceClient: DataLakeServiceClient; + + let recorder: any; + + beforeEach(async function() { + recorder = record(this, recorderEnvSetup); + serviceClient = getDataLakeServiceClient(); + fileSystemName = recorder.getUniqueName("filesystem"); + fileSystemClient = serviceClient.getFileSystemClient(fileSystemName); + await fileSystemClient.create(); + fileName = recorder.getUniqueName("file"); + fileClient = fileSystemClient.getFileClient(fileName); + await fileClient.create(); + await fileClient.append(content, 0, content.length); + await fileClient.flush(content.length); + }); + + afterEach(async function() { + await fileSystemClient.delete(); + recorder.stop(); + }); + + it("setAccessControlRecursive should work", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + const result = await directoryClient.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ) + ); + + assert.deepStrictEqual(3, result.counters.changedDirectoriesCount); + assert.deepStrictEqual(4, result.counters.changedFilesCount); + assert.deepStrictEqual(0, result.counters.failedChangesCount); + assert.deepStrictEqual(undefined, result.continuationToken); + }); + + it("setAccessControlRecursive should work with options - maxBatches", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + let batchCounter = 0; + const result = await directoryClient.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ), + { + batchSize: 2, + maxBatches: 1, + onProgress: () => { + batchCounter++; + } + } + ); + + assert.deepStrictEqual(1, batchCounter); + assert.notDeepStrictEqual(undefined, result.continuationToken); + }); + + it("setAccessControlRecursive should work with options - batchSize", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + let batchCounter = 0; + const cumulativeCounters: AccessControlChangeCounters = { + changedDirectoriesCount: 0, + changedFilesCount: 0, + failedChangesCount: 0 + }; + const result = await directoryClient.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ), + { + batchSize: 2, + onProgress: (progress) => { + assert.ok( + progress.batchCounters.changedDirectoriesCount + + progress.batchCounters.changedFilesCount + + progress.batchCounters.failedChangesCount <= + 2 + ); + cumulativeCounters.changedDirectoriesCount += + progress.batchCounters.changedDirectoriesCount; + cumulativeCounters.changedFilesCount += progress.batchCounters.changedFilesCount; + cumulativeCounters.failedChangesCount += progress.batchCounters.failedChangesCount; + + assert.deepStrictEqual( + progress.aggregateCounters.changedDirectoriesCount, + cumulativeCounters.changedDirectoriesCount + ); + assert.deepStrictEqual( + progress.aggregateCounters.changedFilesCount, + cumulativeCounters.changedFilesCount + ); + assert.deepStrictEqual( + progress.aggregateCounters.failedChangesCount, + cumulativeCounters.failedChangesCount + ); + + batchCounter++; + } + } + ); + + assert.deepStrictEqual(3, cumulativeCounters.changedDirectoriesCount); + assert.deepStrictEqual(4, cumulativeCounters.changedFilesCount); + assert.deepStrictEqual(0, cumulativeCounters.failedChangesCount); + assert.deepStrictEqual(3, result.counters.changedDirectoriesCount); + assert.deepStrictEqual(4, result.counters.changedFilesCount); + assert.deepStrictEqual(0, result.counters.failedChangesCount); + assert.deepStrictEqual(undefined, result.continuationToken); + assert.deepStrictEqual(true, batchCounter > 3); + }); + + it("setAccessControlRecursive should work with aborter & resume, ", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + let continuation; + let midProgress: AccessControlChanges; + try { + const aborter = new AbortController(); + await directoryClient.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ), + { + batchSize: 2, + onProgress: (progress) => { + midProgress = progress; + continuation = progress.continuationToken; + aborter.abort(); + }, + abortSignal: aborter.signal + } + ); + } catch (err) { + assert.equal(err.name, "DataLakeAclChangeFailedError"); + assert.equal(err.innerError.name, "AbortError"); + assert.equal(err.innerError.message, "The operation was aborted.", "Unexpected error caught: " + err); + } + + const result = await directoryClient.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ), + { + continuationToken: continuation + } + ); + + assert.deepStrictEqual( + 3, + result.counters.changedDirectoriesCount + midProgress!.batchCounters.changedDirectoriesCount + ); + assert.deepStrictEqual( + 4, + result.counters.changedFilesCount + midProgress!.batchCounters.changedFilesCount + ); + assert.deepStrictEqual( + 0, + result.counters.failedChangesCount + midProgress!.batchCounters.failedChangesCount + ); + assert.deepStrictEqual(undefined, result.continuationToken); + }); + + it("updateAccessControlRecursive should work", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + const result = await directoryClient.updateAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ) + ); + + assert.deepStrictEqual(3, result.counters.changedDirectoriesCount); + assert.deepStrictEqual(4, result.counters.changedFilesCount); + assert.deepStrictEqual(0, result.counters.failedChangesCount); + assert.deepStrictEqual(undefined, result.continuationToken); + }); + + it("removeAccessControlRecursive should work", async () => { + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const fileClient1 = subDirectoryClient1.getFileClient(fileName1); + const fileClient2 = subDirectoryClient1.getFileClient(fileName2); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const fileClient3 = subDirectoryClient2.getFileClient(fileName3); + const fileClient4 = subDirectoryClient2.getFileClient(fileName4); + + await directoryClient.create(); + await subDirectoryClient1.create(); + await subDirectoryClient2.create(); + + await fileClient1.create(); + await fileClient2.create(); + await fileClient3.create(); + await fileClient4.create(); + + const result = await directoryClient.updateAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ) + ); + + assert.deepStrictEqual(3, result.counters.changedDirectoriesCount); + assert.deepStrictEqual(4, result.counters.changedFilesCount); + assert.deepStrictEqual(0, result.counters.failedChangesCount); + assert.deepStrictEqual(undefined, result.continuationToken); + + const removeResult = await directoryClient.removeAccessControlRecursive( + toRemoveAcl( + "mask," + + "default:user,default:group," + + "user:ec3595d6-2c17-4696-8caa-7e139758d24a,group:ec3595d6-2c17-4696-8caa-7e139758d24a," + + "default:user:ec3595d6-2c17-4696-8caa-7e139758d24a,default:group:ec3595d6-2c17-4696-8caa-7e139758d24a" + ) + ); + + assert.deepStrictEqual(3, removeResult.counters.changedDirectoriesCount); + assert.deepStrictEqual(4, removeResult.counters.changedFilesCount); + assert.deepStrictEqual(0, removeResult.counters.failedChangesCount); + assert.deepStrictEqual(undefined, removeResult.continuationToken); + }); + + it("setAccessControlRecursive should work with progress failures", async () => { + // Manually execution needed + // TODO: Cannot set up environment to reproduce progress failure due to service change + // Blob Data Contributor unexpectedly doesn't have permission for setRecursiveAcl API + // Check with feature team + + // /directory + // /directory/subdirectory1 + // /directory/subdirectory1/fileName1 + // /directory/subdirectory1/fileName2 + // /directory/subdirectory2/fileName3 + // /directory/subdirectory2/fileName4 + // Service client with SharedKey authentication creates following directories and files + // /directory/subdirectory1/fileName5 + // /directory/subdirectory2/fileName6 + + /* + + const token = ""; + const fileSystemClientOAuth = new DataLakeFileSystemClient(fileSystemClient.url, new SimpleTokenCredential(token)); + + const directoryName = recorder.getUniqueName("directory"); + const subDirectoryName1 = recorder.getUniqueName("subdirectory1"); + const fileName1 = recorder.getUniqueName("fileName1"); + const fileName2 = recorder.getUniqueName("fileName2"); + const subDirectoryName2 = recorder.getUniqueName("subdirectory2"); + const fileName3 = recorder.getUniqueName("fileName3"); + const fileName4 = recorder.getUniqueName("fileName4"); + const fileName5 = recorder.getUniqueName("fileName5"); + const fileName6 = recorder.getUniqueName("fileName6"); + + const directoryClient = fileSystemClient.getDirectoryClient(directoryName); + const directoryClientOAuth = fileSystemClientOAuth.getDirectoryClient(directoryName); + const subDirectoryClient1 = directoryClient.getSubdirectoryClient(subDirectoryName1); + const subDirectoryClientOAuth1 = directoryClientOAuth.getSubdirectoryClient(subDirectoryName1); + const fileClientOAuth1 = subDirectoryClientOAuth1.getFileClient(fileName1); + const fileClientOAuth2 = subDirectoryClientOAuth1.getFileClient(fileName2); + const fileClient5 = subDirectoryClient1.getFileClient(fileName5); + const subDirectoryClient2 = directoryClient.getSubdirectoryClient(subDirectoryName2); + const subDirectoryClientOAuth2 = directoryClientOAuth.getSubdirectoryClient(subDirectoryName2); + const fileClientOAuth3 = subDirectoryClientOAuth2.getFileClient(fileName3); + const fileClientOAuth4 = subDirectoryClientOAuth2.getFileClient(fileName4); + const fileClient6 = subDirectoryClient2.getFileClient(fileName6); + + await directoryClientOAuth.create(); + await subDirectoryClientOAuth1.create(); + await subDirectoryClientOAuth2.create(); + + await fileClientOAuth1.create(); + await fileClientOAuth2.create(); + await fileClientOAuth3.create(); + await fileClientOAuth4.create(); + await fileClient5.create(); + await fileClient6.create(); + + // let continuation; + // let midProgress: AccessControlChanges; + + await directoryClientOAuth.setAccessControlRecursive( + toAcl( + "user::rwx,user:ec3595d6-2c17-4696-8caa-7e139758d24a:rw-,group::rw-,mask::rwx,other::---" + ), + { + batchSize: 2, + // onProgress: (progress) => { + // midProgress = progress; + // continuation = progress.continuationToken; + // }, + continueOnFailure: true + } + ); + + */ + }); }); diff --git a/sdk/storage/storage-file-datalake/test/node/sas.spec.ts b/sdk/storage/storage-file-datalake/test/node/sas.spec.ts index 045a8c00fd55..9b397f48aa11 100644 --- a/sdk/storage/storage-file-datalake/test/node/sas.spec.ts +++ b/sdk/storage/storage-file-datalake/test/node/sas.spec.ts @@ -1,3 +1,4 @@ +import { UserDelegationKey } from "@azure/storage-blob"; import { record, Recorder } from "@azure/test-utils-recorder"; import * as assert from "assert"; @@ -6,6 +7,7 @@ import { AccountSASResourceTypes, AccountSASServices, AnonymousCredential, + DataLakeDirectoryClient, DataLakeFileSystemClient, DataLakeSASPermissions, DataLakeServiceClient, @@ -13,13 +15,16 @@ import { generateAccountSASQueryParameters, generateDataLakeSASQueryParameters, newPipeline, - StorageSharedKeyCredential + PathAccessControlItem, + PathPermissions, + StorageSharedKeyCredential, + SASQueryParameters } from "../../src"; import { DataLakeFileClient } from "../../src/"; -import { SASProtocol } from "../../src/SASQueryParameters"; +import { SASProtocol } from "../../src/sas/SASQueryParameters"; import { getDataLakeServiceClient, - getTokenDataLakeServiceClient, + getDataLakeServiceClientWithDefaultCredential, recorderEnvSetup } from "../utils"; @@ -439,11 +444,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for filesystem with all configurations", async function() { - // Try to get DataLakeServiceClient object with TokenCredential - // when DFS_ACCOUNT_TOKEN environment variable is set + // Try to get DataLakeServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let serviceClientWithToken: DataLakeServiceClient | undefined; try { - serviceClientWithToken = getTokenDataLakeServiceClient(); + serviceClientWithToken = getDataLakeServiceClientWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -497,11 +502,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for filesystem with minimum parameters", async function() { - // Try to get DataLakeServiceClient object with TokenCredential - // when DFS_ACCOUNT_TOKEN environment variable is set + // Try to get DataLakeServiceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let serviceClientWithToken: DataLakeServiceClient | undefined; try { - serviceClientWithToken = getTokenDataLakeServiceClient(); + serviceClientWithToken = getDataLakeServiceClientWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -551,11 +556,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { }); it("GenerateUserDelegationSAS should work for file", async function() { - // Try to get serviceClient object with TokenCredential - // when DFS_ACCOUNT_TOKEN environment variable is set + // Try to get serviceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set let serviceClientWithToken: DataLakeServiceClient | undefined; try { - serviceClientWithToken = getTokenDataLakeServiceClient(); + serviceClientWithToken = getDataLakeServiceClientWithDefaultCredential(); } catch {} // Requires bearer token for this case which cannot be generated in the runtime @@ -621,4 +626,495 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { await fileSystemClient.delete(); }); + + it("GenerateUserDelegationSAS should work for file for 2019-12-12", async function() { + // Try to get serviceClient object with DefaultCredential + // when AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET environment variable is set + let serviceClientWithToken: DataLakeServiceClient | undefined; + try { + serviceClientWithToken = getDataLakeServiceClientWithDefaultCredential(); + } catch {} + + // Requires bearer token for this case which cannot be generated in the runtime + // Make sure this case passed in sanity test + if (serviceClientWithToken === undefined) { + this.skip(); + } + + const now = recorder.newDate("now"); + now.setHours(now.getHours() - 1); + const tmr = recorder.newDate("tmr"); + tmr.setDate(tmr.getDate() + 5); + const userDelegationKey = await serviceClientWithToken!.getUserDelegationKey(now, tmr); + + // By default, credential is always the last element of pipeline factories + const factories = (serviceClient as any).pipeline.factories; + const sharedKeyCredential = factories[factories.length - 1] as StorageSharedKeyCredential; + const accountName = sharedKeyCredential.accountName; + + const fileSystemName = recorder.getUniqueName("filesystem"); + const fileSystemClient = serviceClient.getFileSystemClient(fileSystemName); + await fileSystemClient.create(); + + const fileName = recorder.getUniqueName("file"); + const fileClient = fileSystemClient.getFileClient(fileName); + await fileClient.create({ + pathHttpHeaders: { + contentType: "content-type-original" + } + }); + + const fileSAS = generateDataLakeSASQueryParameters( + { + pathName: fileClient.name, + cacheControl: "cache-control-override", + fileSystemName: fileClient.fileSystemName, + contentDisposition: "content-disposition-override", + contentEncoding: "content-encoding-override", + contentLanguage: "content-language-override", + contentType: "content-type-override", + expiresOn: tmr, + ipRange: { start: "0.0.0.0", end: "255.255.255.255" }, + permissions: DataLakeSASPermissions.parse("racwd"), + protocol: SASProtocol.HttpsAndHttp, + startsOn: now, + version: "2019-12-12" + }, + userDelegationKey, + accountName + ); + + const sasClient = `${fileClient.url}?${fileSAS}`; + const fileClientWithSAS = new DataLakeFileClient( + sasClient, + newPipeline(new AnonymousCredential()) + ); + + const properties = await fileClientWithSAS.getProperties(); + assert.equal(properties.cacheControl, "cache-control-override"); + assert.equal(properties.contentDisposition, "content-disposition-override"); + assert.equal(properties.contentEncoding, "content-encoding-override"); + assert.equal(properties.contentLanguage, "content-language-override"); + assert.equal(properties.contentType, "content-type-override"); + + await fileSystemClient.delete(); + }); + + it("construct SASQueryParameters with a option bag", async () => { + // no option and optional parameters + const sasQP = new SASQueryParameters("2020-02-10", "signature"); + assert.equal(sasQP.toString(), "sv=2020-02-10&sig=signature"); + + const sasQP2 = new SASQueryParameters("2020-02-10", "signature", { + permissions: "permissions", + correlationId: "correlationId", + directoryDepth: 2, + preauthorizedAgentObjectId: "preauthorizedAgentObjectId" + }); + assert.equal( + sasQP2.toString(), + "sv=2020-02-10&sp=permissions&sig=signature&sdd=2&saoid=preauthorizedAgentObjectId&scid=correlationId" + ); + + const sasQP3 = new SASQueryParameters( + "2020-02-10", + "signature", + "permissions", + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + 2, + "preauthorizedAgentObjectId", + undefined, + "correlationId" + ); + assert.equal( + sasQP3.toString(), + "sv=2020-02-10&sp=permissions&sig=signature&sdd=2&saoid=preauthorizedAgentObjectId&scid=correlationId" + ); + }); +}); + +describe("SAS generation Node.js only for directory SAS", () => { + let recorder: Recorder; + let serviceClient: DataLakeServiceClient; + let fileSystemClient: DataLakeFileSystemClient; + let directoryClient: DataLakeDirectoryClient; + let fileClient: DataLakeFileClient; + let sharedKeyCredential: StorageSharedKeyCredential; + let now: Date; + let tmr: Date; + + const permissions: PathPermissions = { + extendedAcls: false, + stickyBit: true, + owner: { + read: true, + write: true, + execute: false + }, + group: { + read: true, + write: false, + execute: true + }, + other: { + read: false, + write: true, + execute: false + } + }; + + beforeEach(async function() { + recorder = record(this, recorderEnvSetup); + serviceClient = getDataLakeServiceClient(); + + const fileSystemName = recorder.getUniqueName("filesystem"); + fileSystemClient = serviceClient.getFileSystemClient(fileSystemName); + await fileSystemClient.create(); + + const directoryName = recorder.getUniqueName("directory"); + directoryClient = fileSystemClient.getDirectoryClient(directoryName); + await directoryClient.create(); + + const fileName = recorder.getUniqueName("file"); + fileClient = directoryClient.getFileClient(fileName); + await fileClient.create(); + + now = recorder.newDate("now"); + now.setMinutes(now.getMinutes() - 10); // Skip clock skew with server + tmr = recorder.newDate("tmr"); + tmr.setDate(tmr.getDate() + 10); + + // By default, credential is always the last element of pipeline factories + const factories = (serviceClient as any).pipeline.factories; + sharedKeyCredential = factories[factories.length - 1]; + }); + + afterEach(async function() { + await fileSystemClient.delete(); + await recorder.stop(); + }); + + it("generateDataLakeSASQueryParameters for directory should work for permissions m, e, o, p", async () => { + const directorySAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + pathName: directoryClient.name, + isDirectory: true, + directoryDepth: 1, + expiresOn: tmr, + ipRange: { start: "0.0.0.0", end: "255.255.255.255" }, + permissions: DataLakeSASPermissions.parse("racwdmeop"), + protocol: SASProtocol.HttpsAndHttp, + startsOn: now, + version: "2020-02-10" + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + const sasURL = `${directoryClient.url}?${directorySAS}`; + const directoryClientwithSAS = new DataLakeDirectoryClient( + sasURL, + newPipeline(new AnonymousCredential()) + ); + + // e + await directoryClientwithSAS.getAccessControl(); + + // p + await directoryClientwithSAS.setPermissions(permissions); + }); + + function getDefualtDirctorySAS(directoryName: string): SASQueryParameters { + return generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + pathName: directoryName, + isDirectory: true, + expiresOn: tmr, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + protocol: SASProtocol.HttpsAndHttp, + startsOn: now, + version: "2020-02-10" + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + } + + it("generateDataLakeSASQueryParameters could calculate directory depth", async () => { + const directorySAS = getDefualtDirctorySAS(directoryClient.name); + assert.equal(directorySAS.directoryDepth, 1); + const directoryClientwithSAS = new DataLakeDirectoryClient( + `${directoryClient.url}?${directorySAS}` + ); + await directoryClientwithSAS.setPermissions(permissions); + + // root directory, depth = 0 + const directorySAS2 = getDefualtDirctorySAS(""); + assert.equal(directorySAS2.directoryDepth, 0); + const directoryClientwithSAS2 = new DataLakeDirectoryClient( + `${directoryClient.url}?${directorySAS2}` + ); + await directoryClientwithSAS2.setPermissions(permissions); + + // "/d1/d2/", "d1/d2", "/d1/d2" depth = 2 + const directorySAS3 = getDefualtDirctorySAS("/d1/d2/"); + assert.equal(directorySAS3.directoryDepth, 2); + + const directorySAS4 = getDefualtDirctorySAS("d1/d2"); + assert.equal(directorySAS4.directoryDepth, 2); + + const directorySAS5 = getDefualtDirctorySAS("/d1/d2"); + assert.equal(directorySAS5.directoryDepth, 2); + }); + + it("generateDataLakeSASQueryParameters for file should work for permissions m, e, o, p", async () => { + const fileSAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + pathName: fileClient.name, + expiresOn: tmr, + ipRange: { start: "0.0.0.0", end: "255.255.255.255" }, + permissions: DataLakeSASPermissions.parse("racwdmeop"), + protocol: SASProtocol.HttpsAndHttp, + startsOn: now, + version: "2020-02-10" + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + const sasURL = `${fileClient.url}?${fileSAS}`; + const fileClientWithSAS = new DataLakeFileClient( + sasURL, + newPipeline(new AnonymousCredential()) + ); + + // o + const guid = "b77d5205-ddb5-42e1-80ee-26c74a5e9333"; + await fileClientWithSAS.setAccessControl([], { owner: guid }); + + // e + await fileClientWithSAS.getAccessControl(); + + // p + await fileClientWithSAS.setPermissions(permissions); + }); + + it("generateDataLakeSASQueryParameters for filesystem should work for permissions m, e, o, p", async () => { + const fileSystemSAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + expiresOn: tmr, + ipRange: { start: "0.0.0.0", end: "255.255.255.255" }, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + protocol: SASProtocol.HttpsAndHttp, + startsOn: now, + version: "2020-02-10" + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + const sasURL = `${directoryClient.url}?${fileSystemSAS}`; + const directoryClientwithSAS = new DataLakeDirectoryClient( + sasURL, + newPipeline(new AnonymousCredential()) + ); + + // e + await directoryClientwithSAS.getAccessControl(); + + // p + await directoryClientwithSAS.setPermissions(permissions); + }); +}); + +describe("SAS generation Node.js only for delegation SAS", () => { + let recorder: Recorder; + let oauthServiceClient: DataLakeServiceClient; + let fileSystemClient: DataLakeFileSystemClient; + let directoryClient: DataLakeDirectoryClient; + let fileClient: DataLakeFileClient; + let userDelegationKey: UserDelegationKey; + let now: Date; + let tmr: Date; + let accountName: string; + + const permissions: PathPermissions = { + extendedAcls: false, + stickyBit: true, + owner: { + read: true, + write: true, + execute: false + }, + group: { + read: true, + write: false, + execute: true + }, + other: { + read: false, + write: true, + execute: false + } + }; + + beforeEach(async function() { + recorder = record(this, recorderEnvSetup); + accountName = process.env["DFS_ACCOUNT_NAME"] || ""; + try { + oauthServiceClient = getDataLakeServiceClientWithDefaultCredential(); + } catch (err) { + console.log(err); + this.skip(); + } + + now = recorder.newDate("now"); + now.setHours(now.getHours() - 1); + tmr = recorder.newDate("tmr"); + tmr.setDate(tmr.getDate() + 5); + userDelegationKey = await oauthServiceClient.getUserDelegationKey(now, tmr); + + const fileSystemName = recorder.getUniqueName("filesystem"); + fileSystemClient = oauthServiceClient.getFileSystemClient(fileSystemName); + await fileSystemClient.create(); + + const directoryName = recorder.getUniqueName("directory"); + directoryClient = fileSystemClient.getDirectoryClient(directoryName); + await directoryClient.create(); + + const fileName = recorder.getUniqueName("file"); + fileClient = directoryClient.getFileClient(fileName); + await fileClient.create(); + }); + + afterEach(async function() { + if (fileSystemClient) { + await fileSystemClient.delete(); + } + await recorder.stop(); + }); + + it("GenerateUserDelegationSAS for directory should work for permissions m, e, o, p", async () => { + const fileSystemSAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + pathName: directoryClient.name, + isDirectory: true, + expiresOn: tmr, + permissions: DataLakeSASPermissions.parse("racwdmeop") + }, + userDelegationKey, + accountName + ); + + const sasURL = `${directoryClient.url}?${fileSystemSAS}`; + const directoryClientwithSAS = new DataLakeDirectoryClient(sasURL); + // e + await directoryClientwithSAS.getAccessControl(); + + // p + await directoryClientwithSAS.setPermissions(permissions); + }); + + it("GenerateUserDelegationSAS should work with agentObjectId, preauthorizedAgentObjectId", async () => { + const authorizedGuid = "b77d5205-ddb5-42e1-80ee-26c74a5e9333"; + const rootDirectoryClient = fileSystemClient.getDirectoryClient("/"); + const acl: PathAccessControlItem[] = [ + { + accessControlType: "user", + entityId: authorizedGuid, + defaultScope: false, + permissions: { + read: true, + write: true, + execute: true + } + } + ]; + await rootDirectoryClient.setAccessControl(acl); + + const fileSystemSAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + expiresOn: tmr, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + agentObjectId: authorizedGuid + }, + userDelegationKey, + accountName + ); + + const newFileName = recorder.getUniqueName("newFile"); + const newFileClient = fileSystemClient.getFileClient(newFileName); + const newFileClientWithSAS = new DataLakeFileClient(`${newFileClient.url}?${fileSystemSAS}`); + await newFileClientWithSAS.createIfNotExists(); + + const unauthoriziedGuid = "7d53815c-1b73-49ab-b44d-002bfb890633"; + + // suoid for an unauthoriziedGuid + const fileSystemSAS2 = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + expiresOn: tmr, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + agentObjectId: unauthoriziedGuid + }, + userDelegationKey, + accountName + ); + + const newFileClientWithSAS2 = new DataLakeFileClient(`${newFileClient.url}?${fileSystemSAS2}`); + try { + await newFileClientWithSAS2.createIfNotExists(); + } catch (err) { + assert.deepStrictEqual(err.details.errorCode, "AuthorizationPermissionMismatch"); + } + + // saoid for an unauthoriziedGuid + const fileSystemSAS3 = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + expiresOn: tmr, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + preauthorizedAgentObjectId: unauthoriziedGuid + }, + userDelegationKey, + accountName + ); + const newFileClientWithSAS3 = new DataLakeFileClient(`${newFileClient.url}?${fileSystemSAS3}`); + await newFileClientWithSAS3.createIfNotExists(); + }); + + it("GenerateUserDelegationSAS should work with correlationId", async () => { + const guid = "b77d5205-ddb5-42e1-80ee-26c74a5e9333"; + const fileSystemSAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + expiresOn: tmr, + permissions: FileSystemSASPermissions.parse("racwdlmeop"), + correlationId: guid + }, + userDelegationKey, + accountName + ); + + const fileSystemClientWithSAS = new DataLakeFileSystemClient( + `${fileSystemClient.url}?${fileSystemSAS}` + ); + + await fileSystemClientWithSAS + .listPaths() + .byPage() + .next(); + }); }); diff --git a/sdk/storage/storage-file-datalake/test/pathclient.spec.ts b/sdk/storage/storage-file-datalake/test/pathclient.spec.ts index f0a30186f286..a34c2437f92f 100644 --- a/sdk/storage/storage-file-datalake/test/pathclient.spec.ts +++ b/sdk/storage/storage-file-datalake/test/pathclient.spec.ts @@ -1,5 +1,5 @@ import { AbortController } from "@azure/abort-controller"; -import { isNode, URLBuilder } from "@azure/core-http"; +import { isNode, URLBuilder, delay } from "@azure/core-http"; import { setTracer, SpanGraph, TestTracer } from "@azure/core-tracing"; import { record } from "@azure/test-utils-recorder"; import * as assert from "assert"; @@ -361,4 +361,54 @@ describe("DataLakePathClient", () => { const res2 = await directoryClient.deleteIfExists(); assert.ok(res2.succeeded); }); + + it("set expiry - NeverExpire", async () => { + await fileClient.setExpiry("NeverExpire"); + const getRes = await fileClient.getProperties(); + assert.equal(getRes.expiresOn, undefined); + }); + + it("set expiry - Absolute", async () => { + const now = new Date(); + const recordedNow = recorder.newDate("now"); // Flaky workaround for the recording to work. + const delta = 5 * 1000; + const expiresOn = new Date(now.getTime() + delta); + await fileClient.setExpiry("Absolute", { expiresOn }); + + const getRes = await fileClient.getProperties(); + const recordedExpiresOn = new Date(recordedNow.getTime() + delta); + recordedExpiresOn.setMilliseconds(0); // milliseconds dropped + assert.equal(getRes.expiresOn?.getTime(), recordedExpiresOn.getTime()); + + await delay(delta); + assert.ok(!(await fileClient.exists())); + }); + + it("set expiry - RelativeToNow", async () => { + const delta = 1000; + await fileClient.setExpiry("RelativeToNow", { timeToExpireInMs: delta }); + + await delay(delta); + assert.ok(!(await fileClient.exists())); + }); + + it("set expiry - RelativeToCreation", async () => { + const delta = 1000 * 3600 + 0.12; + await fileClient.setExpiry("RelativeToCreation", { timeToExpireInMs: delta }); + + const getRes = await fileClient.getProperties(); + assert.equal(getRes.expiresOn?.getTime(), getRes.createdOn!.getTime() + Math.round(delta)); + }); + + it("set expiry - override", async () => { + const delta = 1000 * 3600; + await fileClient.setExpiry("RelativeToCreation", { timeToExpireInMs: delta }); + + const getRes = await fileClient.getProperties(); + assert.equal(getRes.expiresOn?.getTime(), getRes.createdOn!.getTime() + delta); + + await fileClient.setExpiry("NeverExpire"); + const getRes2 = await fileClient.getProperties(); + assert.equal(getRes2.expiresOn, undefined); + }); }); diff --git a/sdk/storage/storage-file-datalake/test/utils/index.ts b/sdk/storage/storage-file-datalake/test/utils/index.ts index e60468825990..3914c8b2ea6f 100644 --- a/sdk/storage/storage-file-datalake/test/utils/index.ts +++ b/sdk/storage/storage-file-datalake/test/utils/index.ts @@ -4,6 +4,7 @@ import { randomBytes } from "crypto"; import * as dotenv from "dotenv"; import * as fs from "fs"; import * as path from "path"; +import { DefaultAzureCredential } from "@azure/identity"; import { StorageSharedKeyCredential } from "../../src/credentials/StorageSharedKeyCredential"; import { DataLakeServiceClient } from "../../src/DataLakeServiceClient"; @@ -98,6 +99,25 @@ export function getDataLakeServiceClient( return getGenericDataLakeServiceClient("DFS_", undefined, pipelineOptions); } +export function getDataLakeServiceClientWithDefaultCredential( + accountType: string = "DFS_", + pipelineOptions: StoragePipelineOptions = {}, + accountNameSuffix: string = "" +): DataLakeServiceClient { + const accountNameEnvVar = `${accountType}ACCOUNT_NAME`; + let accountName = process.env[accountNameEnvVar]; + if (!accountName || accountName === "") { + throw new Error(`${accountNameEnvVar} environment variables not specified.`); + } + + const credential = new DefaultAzureCredential(); + const pipeline = newPipeline(credential, { + ...pipelineOptions + }); + const dfsPrimaryURL = `https://${accountName}${accountNameSuffix}.dfs.core.windows.net/`; + return new DataLakeServiceClient(dfsPrimaryURL, pipeline); +} + export function getAlternateDataLakeServiceClient(): DataLakeServiceClient { return getGenericDataLakeServiceClient("SECONDARY_", "-secondary"); } diff --git a/sdk/storage/storage-file-datalake/test/utils/testutils.common.ts b/sdk/storage/storage-file-datalake/test/utils/testutils.common.ts index 334ea5adb093..0a4ae1eb20f6 100644 --- a/sdk/storage/storage-file-datalake/test/utils/testutils.common.ts +++ b/sdk/storage/storage-file-datalake/test/utils/testutils.common.ts @@ -20,7 +20,10 @@ export const recorderEnvSetup: RecorderEnvironmentSetup = { DFS_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockAccountName};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net`, // Comment following line to skip user delegation key/SAS related cases in record and play // which depends on this environment variable - DFS_ACCOUNT_TOKEN: `${mockAccountKey}` + DFS_ACCOUNT_TOKEN: `${mockAccountKey}`, + AZURE_CLIENT_ID: `${mockAccountKey}`, + AZURE_TENANT_ID: `${mockAccountKey}`, + AZURE_CLIENT_SECRET: `${mockAccountKey}` }, customizationsOnRecordings: [ // Used in record mode diff --git a/sdk/storage/storage-file-datalake/tests.yml b/sdk/storage/storage-file-datalake/tests.yml index edda42c7d06a..96b671a47d93 100644 --- a/sdk/storage/storage-file-datalake/tests.yml +++ b/sdk/storage/storage-file-datalake/tests.yml @@ -7,6 +7,7 @@ extends: ResourceServiceDirectory: storage TimeoutInMinutes: 90 ResourceGroupLocation: canadacentral + SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources-preview) EnvVars: AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) diff --git a/sdk/storage/storage-file-share/CHANGELOG.md b/sdk/storage/storage-file-share/CHANGELOG.md index fc2905e4dc2a..1c3ed0249b17 100644 --- a/sdk/storage/storage-file-share/CHANGELOG.md +++ b/sdk/storage/storage-file-share/CHANGELOG.md @@ -1,7 +1,12 @@ # Release History -## 12.2.1 (Unreleased) +## 12.3.0-beta.1 (2020-10-13) +- Updated Azure Storage Service API version to 2020-02-10. +- Added support for SMB Multichannel. +- Added support for Share and Share Snapshot Leases. Now can initialize a `ShareLeaseClient` with a `ShareClient` to manage leases for a share or share snapshot. Most operations on share now also support lease conditions. +- Added support for Get File Range Diff. Added `ShareFileClient.getRangeListDiff()` for getting the list of ranges that differ between a previous share snapshot and the file. +- Added support for Set Share Tier. Added `ShareClient.setAccessTier()` for setting the access tier of the share. ## 12.2.0 (2020-09-08) diff --git a/sdk/storage/storage-file-share/karma.conf.js b/sdk/storage/storage-file-share/karma.conf.js index 59b4dbd6b38a..c3b516d8bb0b 100644 --- a/sdk/storage/storage-file-share/karma.conf.js +++ b/sdk/storage/storage-file-share/karma.conf.js @@ -62,6 +62,8 @@ module.exports = function(config) { "ACCOUNT_SAS", "SOFT_DELETE_ACCOUNT_NAME", "SOFT_DELETE_ACCOUNT_SAS", + "PREMIUM_FILE_ACCOUNT_NAME", + "PREMIUM_FILE_ACCOUNT_SAS", "TEST_MODE" ], diff --git a/sdk/storage/storage-file-share/package.json b/sdk/storage/storage-file-share/package.json index 3b91347acc4e..5468ed856b81 100644 --- a/sdk/storage/storage-file-share/package.json +++ b/sdk/storage/storage-file-share/package.json @@ -1,7 +1,7 @@ { "name": "@azure/storage-file-share", "sdk-type": "client", - "version": "12.2.1", + "version": "12.3.0-beta.1", "description": "Microsoft Azure Storage SDK for JavaScript - File", "main": "./dist/index.js", "module": "./dist-esm/src/index.js", @@ -28,7 +28,7 @@ }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", - "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.2.0 --use=@microsoft.azure/autorest.typescript@5.0.1", + "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.3.0-beta.1 --use=@microsoft.azure/autorest.typescript@5.0.1", "build:es6": "tsc -p tsconfig.json", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_create_largest_file.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_create_largest_file.json index 2a386dbc13ab..b8c8e041de95 100644 --- a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_create_largest_file.json +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_create_largest_file.json @@ -2,7 +2,7 @@ "recordings": [ { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140", "query": { "restype": "share" }, @@ -10,19 +10,17 @@ "status": 201, "response": "", "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:39 GMT", - "etag": "\"0x8D8143D35B3FBFC\"", - "last-modified": "Fri, 19 Jun 2020 10:40:39 GMT", + "etag": "\"0x8D8556C04500287\"", + "last-modified": "Thu, 10 Sep 2020 09:29:29 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "32aeb514-7625-4bf8-85ea-85f5a263b56b", - "x-ms-request-id": "9e66eb6e-c01a-005a-2526-4650ab000000", - "x-ms-version": "2019-12-12" + "x-ms-client-request-id": "445f5d50-a7da-43d7-93b7-c417cb182858", + "x-ms-request-id": "da0f1528-601a-0017-2354-87212a000000", + "x-ms-version": "2020-02-10" } }, { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555/dir159256324113807688", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140/dir159973016984001088", "query": { "restype": "directory" }, @@ -30,74 +28,49 @@ "status": 201, "response": "", "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:39 GMT", - "etag": "\"0x8D8143D360D452D\"", - "last-modified": "Fri, 19 Jun 2020 10:40:40 GMT", + "etag": "\"0x8D8556C04A60786\"", + "last-modified": "Thu, 10 Sep 2020 09:29:29 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "10f055e2-f719-4cac-ae61-85f7c99ba156", + "x-ms-client-request-id": "e005a8c3-09f9-473f-9bfa-d78fdaa59438", "x-ms-file-attributes": "Directory", - "x-ms-file-change-time": "2020-06-19T10:40:40.5325101Z", - "x-ms-file-creation-time": "2020-06-19T10:40:40.5325101Z", + "x-ms-file-change-time": "2020-09-10T09:29:29.5743878Z", + "x-ms-file-creation-time": "2020-09-10T09:29:29.5743878Z", "x-ms-file-id": "13835128424026341376", - "x-ms-file-last-write-time": "2020-06-19T10:40:40.5325101Z", + "x-ms-file-last-write-time": "2020-09-10T09:29:29.5743878Z", "x-ms-file-parent-id": "0", - "x-ms-file-permission-key": "4512302258392269635*6216600178912236746", - "x-ms-request-id": "9e66eb74-c01a-005a-2826-4650ab000000", + "x-ms-file-permission-key": "14827816195503570342*11897905858180131375", + "x-ms-request-id": "da0f152b-601a-0017-2554-87212a000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2019-12-12" + "x-ms-version": "2020-02-10" } }, { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555", - "query": { - "restype": "share", - "comp": "properties" - }, - "requestBody": null, - "status": 200, - "response": "", - "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:40 GMT", - "etag": "\"0x8D8143D366545AA\"", - "last-modified": "Fri, 19 Jun 2020 10:40:41 GMT", - "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "f843f3cb-bffd-4686-93da-0bd1ba0f2a2e", - "x-ms-request-id": "9e66eb79-c01a-005a-2a26-4650ab000000", - "x-ms-version": "2019-12-12" - } - }, - { - "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555/dir159256324113807688/file159256324170602662", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140/dir159973016984001088/file159973017039608104", "query": {}, "requestBody": null, "status": 201, "response": "", "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:40 GMT", - "etag": "\"0x8D8143D36B872F5\"", - "last-modified": "Fri, 19 Jun 2020 10:40:41 GMT", + "etag": "\"0x8D8556C04FB89C7\"", + "last-modified": "Thu, 10 Sep 2020 09:29:30 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "b99bc137-8f20-4420-b168-cd8937f3c786", + "x-ms-client-request-id": "b24e6990-4052-4f77-b531-23ed3608fa94", "x-ms-file-attributes": "Archive", - "x-ms-file-change-time": "2020-06-19T10:40:41.6543477Z", - "x-ms-file-creation-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-change-time": "2020-09-10T09:29:30.1347783Z", + "x-ms-file-creation-time": "2020-09-10T09:29:30.1347783Z", "x-ms-file-id": "11529285414812647424", - "x-ms-file-last-write-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-last-write-time": "2020-09-10T09:29:30.1347783Z", "x-ms-file-parent-id": "13835128424026341376", - "x-ms-file-permission-key": "18367126982671236164*6216600178912236746", - "x-ms-request-id": "9e66eb7c-c01a-005a-2c26-4650ab000000", + "x-ms-file-permission-key": "990002565778260641*11897905858180131375", + "x-ms-request-id": "da0f1530-601a-0017-2754-87212a000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2019-12-12" + "x-ms-version": "2020-02-10" } }, { "method": "PUT", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555/dir159256324113807688/file159256324170602662", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140/dir159973016984001088/file159973017039608104", "query": { "comp": "properties" }, @@ -105,27 +78,25 @@ "status": 200, "response": "", "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:41 GMT", - "etag": "\"0x8D8143D370CBD98\"", - "last-modified": "Fri, 19 Jun 2020 10:40:42 GMT", + "etag": "\"0x8D8556C054E255E\"", + "last-modified": "Thu, 10 Sep 2020 09:29:30 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "4cc77f7f-8c50-424a-b4c4-9ce6eeb502b7", + "x-ms-client-request-id": "a3b300f3-b97b-4231-85a9-84edeb45b537", "x-ms-file-attributes": "Archive", - "x-ms-file-change-time": "2020-06-19T10:40:42.2067608Z", - "x-ms-file-creation-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-change-time": "2020-09-10T09:29:30.6761566Z", + "x-ms-file-creation-time": "2020-09-10T09:29:30.1347783Z", "x-ms-file-id": "11529285414812647424", - "x-ms-file-last-write-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-last-write-time": "2020-09-10T09:29:30.6761566Z", "x-ms-file-parent-id": "13835128424026341376", - "x-ms-file-permission-key": "18367126982671236164*6216600178912236746", - "x-ms-request-id": "9e66eb7f-c01a-005a-2e26-4650ab000000", + "x-ms-file-permission-key": "990002565778260641*11897905858180131375", + "x-ms-request-id": "da0f1532-601a-0017-2954-87212a000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2019-12-12" + "x-ms-version": "2020-02-10" } }, { "method": "HEAD", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555/dir159256324113807688/file159256324170602662", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140/dir159973016984001088/file159973017039608104", "query": {}, "requestBody": null, "status": 200, @@ -133,29 +104,48 @@ "responseHeaders": { "content-length": "4398046511104", "content-type": "application/octet-stream", - "date": "Fri, 19 Jun 2020 10:40:41 GMT", - "etag": "\"0x8D8143D370CBD98\"", - "last-modified": "Fri, 19 Jun 2020 10:40:42 GMT", + "etag": "\"0x8D8556C054E255E\"", + "last-modified": "Thu, 10 Sep 2020 09:29:30 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "48f83eee-52d2-49da-b594-499f4736696f", + "x-ms-client-request-id": "eae04308-7612-4af9-a01d-672d0075ba2c", "x-ms-file-attributes": "Archive", - "x-ms-file-change-time": "2020-06-19T10:40:42.2067608Z", - "x-ms-file-creation-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-change-time": "2020-09-10T09:29:30.6761566Z", + "x-ms-file-creation-time": "2020-09-10T09:29:30.1347783Z", "x-ms-file-id": "11529285414812647424", - "x-ms-file-last-write-time": "2020-06-19T10:40:41.6543477Z", + "x-ms-file-last-write-time": "2020-09-10T09:29:30.6761566Z", "x-ms-file-parent-id": "13835128424026341376", - "x-ms-file-permission-key": "18367126982671236164*6216600178912236746", + "x-ms-file-permission-key": "990002565778260641*11897905858180131375", "x-ms-lease-state": "available", "x-ms-lease-status": "unlocked", - "x-ms-request-id": "9e66eb8f-c01a-005a-3d26-4650ab000000", + "x-ms-request-id": "da0f1534-601a-0017-2b54-87212a000000", "x-ms-server-encrypted": "true", "x-ms-type": "File", - "x-ms-version": "2019-12-12" + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140/dir159973016984001088/file159973017039608104", + "query": { + "comp": "range" + }, + "requestBody": "Hello World", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "sQqNsWTgdUEFt6mb5y4/5Q==", + "etag": "\"0x8D8556C05F1AE96\"", + "last-modified": "Thu, 10 Sep 2020 09:29:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d2832481-35cf-4201-91c4-41ba776dddfa", + "x-ms-request-id": "da0f1536-601a-0017-2d54-87212a000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2020-02-10" } }, { "method": "DELETE", - "url": "https://fakestorageaccount.file.core.windows.net/share159256323960404555", + "url": "https://fakestorageaccount.file.core.windows.net/share159973016793906140", "query": { "restype": "share" }, @@ -163,22 +153,20 @@ "status": 202, "response": "", "responseHeaders": { - "date": "Fri, 19 Jun 2020 10:40:43 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "transfer-encoding": "chunked", - "x-ms-client-request-id": "71ed7150-6223-4657-93d6-f34ecb6979ac", - "x-ms-request-id": "9e66eb9d-c01a-005a-4b26-4650ab000000", - "x-ms-version": "2019-12-12" + "x-ms-client-request-id": "551f765c-718b-4db7-836c-abb6f63e1ab9", + "x-ms-request-id": "da0f1539-601a-0017-2f54-87212a000000", + "x-ms-version": "2020-02-10" } } ], "uniqueTestInfo": { "uniqueName": { - "share": "share159256323960404555", - "dir": "dir159256324113807688", - "file": "file159256324170602662" + "share": "share159973016793906140", + "dir": "dir159973016984001088", + "file": "file159973017039608104" }, "newDate": {} }, - "hash": "c8a45c43f12bee2b017a2fbdf77e5125" + "hash": "c46a56d62d7f7393debea5f0262151df" } \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json new file mode 100644 index 000000000000..d7ebf29bb6ee --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json @@ -0,0 +1,216 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B5AAEA83\"", + "last-modified": "Thu, 24 Sep 2020 08:13:24 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c26da3fc-0238-48dd-8c38-27be38ac20e3", + "x-ms-request-id": "eb66220e-d01a-0005-624a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388", + "query": { + "restype": "directory" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B60062DB\"", + "last-modified": "Thu, 24 Sep 2020 08:13:25 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1aab52dd-91d3-46af-bec9-0915e2a0bc4d", + "x-ms-file-attributes": "Directory", + "x-ms-file-change-time": "2020-09-24T08:13:25.4498011Z", + "x-ms-file-creation-time": "2020-09-24T08:13:25.4498011Z", + "x-ms-file-id": "13835128424026341376", + "x-ms-file-last-write-time": "2020-09-24T08:13:25.4498011Z", + "x-ms-file-parent-id": "0", + "x-ms-file-permission-key": "2065021814682187374*8391130200578712039", + "x-ms-request-id": "eb662220-d01a-0005-6e4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B655BE54\"", + "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3d0c1b34-8062-46c9-9f91-a4aee3a53239", + "x-ms-file-attributes": "Archive", + "x-ms-file-change-time": "2020-09-24T08:13:26.0091988Z", + "x-ms-file-creation-time": "2020-09-24T08:13:26.0091988Z", + "x-ms-file-id": "11529285414812647424", + "x-ms-file-last-write-time": "2020-09-24T08:13:26.0091988Z", + "x-ms-file-parent-id": "13835128424026341376", + "x-ms-file-permission-key": "15912238054059149673*8391130200578712039", + "x-ms-request-id": "eb66222d-d01a-0005-774a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": { + "comp": "range" + }, + "requestBody": "Hello", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==", + "etag": "\"0x8D86061B6A8CF7E\"", + "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "688a1677-133c-42d4-80df-ba9d562a8e16", + "x-ms-request-id": "eb662232-d01a-0005-7c4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": { + "comp": "range" + }, + "requestBody": "World", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "9aeSTmIehMkoCpon4by39g==", + "etag": "\"0x8D86061B6D1E2C4\"", + "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "969f103d-eb6d-4c1c-b40e-81d39cc5ebde", + "x-ms-request-id": "eb662234-d01a-0005-7e4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": { + "comp": "range" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B6FB6B5B\"", + "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "6c9b9cd8-ac53-4f10-baed-91f6e8f8b0c0", + "x-ms-request-id": "eb662237-d01a-0005-014a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681", + "query": { + "restype": "share", + "comp": "snapshot" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B5AAEA83\"", + "last-modified": "Thu, 24 Sep 2020 08:13:24 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e94cbfa7-c623-44d4-a31b-f49bdc35b20b", + "x-ms-request-id": "eb66223d-d01a-0005-074a-921536000000", + "x-ms-snapshot": "2020-09-24T08:13:27.0000000Z", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": { + "comp": "range" + }, + "requestBody": "Hello", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==", + "etag": "\"0x8D86061B776CC5E\"", + "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "55b32162-66d1-4ab0-af6f-32ac401ad9c4", + "x-ms-request-id": "eb662243-d01a-0005-0d4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828", + "query": { + "sharesnapshot": "2020-09-24T08:13:27.0000000Z", + "comp": "rangelist" + }, + "requestBody": null, + "status": 200, + "response": "512512", + "responseHeaders": { + "content-type": "application/xml", + "etag": "\"0x8D86061B6FB6B5B\"", + "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "17a1ce9d-5526-47bd-93cc-c0cbbad57cb6", + "x-ms-content-length": "513", + "x-ms-request-id": "eb662252-d01a-0005-114a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "19853fc6-415d-43fa-9ff6-c97d29f76ded", + "x-ms-request-id": "eb66225e-d01a-0005-1c4a-921536000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160093520308404681", + "dir": "dir160093520502604388", + "file": "file160093520558100828" + }, + "newDate": {} + }, + "hash": "06462ffa1273eddcd96e0ad718d51d94" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json new file mode 100644 index 000000000000..7c19d82db1bc --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json @@ -0,0 +1,196 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B86E0B2A\"", + "last-modified": "Thu, 24 Sep 2020 08:13:29 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "11c289d5-46ea-4704-91ca-0ca2752c0531", + "x-ms-request-id": "eb66226a-d01a-0005-284a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841", + "query": { + "restype": "directory" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B8BFB4F9\"", + "last-modified": "Thu, 24 Sep 2020 08:13:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "bdb8a3ff-e939-40cb-8b0a-59e814ab007a", + "x-ms-file-attributes": "Directory", + "x-ms-file-change-time": "2020-09-24T08:13:30.0590841Z", + "x-ms-file-creation-time": "2020-09-24T08:13:30.0590841Z", + "x-ms-file-id": "13835128424026341376", + "x-ms-file-last-write-time": "2020-09-24T08:13:30.0590841Z", + "x-ms-file-parent-id": "0", + "x-ms-file-permission-key": "2065021814682187374*8391130200578712039", + "x-ms-request-id": "eb662276-d01a-0005-334a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B910F104\"", + "last-modified": "Thu, 24 Sep 2020 08:13:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c1979243-3d45-4aa8-95ef-7331b84e4212", + "x-ms-file-attributes": "Archive", + "x-ms-file-change-time": "2020-09-24T08:13:30.5914628Z", + "x-ms-file-creation-time": "2020-09-24T08:13:30.5914628Z", + "x-ms-file-id": "11529285414812647424", + "x-ms-file-last-write-time": "2020-09-24T08:13:30.5914628Z", + "x-ms-file-parent-id": "13835128424026341376", + "x-ms-file-permission-key": "15912238054059149673*8391130200578712039", + "x-ms-request-id": "eb66228c-d01a-0005-494a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839", + "query": { + "comp": "range" + }, + "requestBody": "Hello", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==", + "etag": "\"0x8D86061B96190B6\"", + "last-modified": "Thu, 24 Sep 2020 08:13:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "37d0ab2a-1ca0-4997-9033-69437445eb71", + "x-ms-request-id": "eb66229c-d01a-0005-574a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846", + "query": { + "restype": "share", + "comp": "snapshot" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B86E0B2A\"", + "last-modified": "Thu, 24 Sep 2020 08:13:29 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c73a5527-2e9e-4361-8256-5eae4a7cbfec", + "x-ms-request-id": "eb6622ad-d01a-0005-664a-921536000000", + "x-ms-snapshot": "2020-09-24T08:13:31.0000000Z", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839", + "query": { + "comp": "range" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061B9DB921C\"", + "last-modified": "Thu, 24 Sep 2020 08:13:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "95afae66-9f39-455c-bddc-428ed7a350cb", + "x-ms-request-id": "eb6622b3-d01a-0005-6c4a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839", + "query": { + "comp": "range" + }, + "requestBody": "World", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "9aeSTmIehMkoCpon4by39g==", + "etag": "\"0x8D86061BA0541D6\"", + "last-modified": "Thu, 24 Sep 2020 08:13:32 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "87781ac4-7ccc-488a-b0fb-df0aff46f33c", + "x-ms-request-id": "eb6622b9-d01a-0005-724a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839", + "query": { + "prevsharesnapshot": "2020-09-24T08:13:31.0000000Z", + "comp": "rangelist" + }, + "requestBody": null, + "status": 200, + "response": "05115121535", + "responseHeaders": { + "content-type": "application/xml", + "etag": "\"0x8D86061BA0541D6\"", + "last-modified": "Thu, 24 Sep 2020 08:13:32 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8d282248-60c0-46d9-88b6-026e032f094b", + "x-ms-content-length": "2049", + "x-ms-request-id": "eb6622c9-d01a-0005-804a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5dc4a1a5-88d0-499e-9d9c-975d6dbb96b1", + "x-ms-request-id": "eb6622d9-d01a-0005-0e4a-921536000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160093520911907846", + "dir": "dir160093520964907841", + "file": "file160093521018504839" + }, + "newDate": {} + }, + "hash": "dc7804588649762fa4dd7991f57a1f80" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json new file mode 100644 index 000000000000..4d63c109c28a --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json @@ -0,0 +1,237 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BAFC7DC2\"", + "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "677dd1c0-7537-4df4-99ac-aafabf6356df", + "x-ms-request-id": "eb6622e8-d01a-0005-1c4a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594", + "query": { + "restype": "directory" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BB4E02FB\"", + "last-modified": "Thu, 24 Sep 2020 08:13:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8dc058fd-d463-4605-8f11-700f68180fa8", + "x-ms-file-attributes": "Directory", + "x-ms-file-change-time": "2020-09-24T08:13:34.3471355Z", + "x-ms-file-creation-time": "2020-09-24T08:13:34.3471355Z", + "x-ms-file-id": "13835128424026341376", + "x-ms-file-last-write-time": "2020-09-24T08:13:34.3471355Z", + "x-ms-file-parent-id": "0", + "x-ms-file-permission-key": "2065021814682187374*8391130200578712039", + "x-ms-request-id": "eb6622f9-d01a-0005-2a4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": {}, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BBA02978\"", + "last-modified": "Thu, 24 Sep 2020 08:13:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cf2beae9-acb0-4775-8d53-388b8ef058a5", + "x-ms-file-attributes": "Archive", + "x-ms-file-change-time": "2020-09-24T08:13:34.8855160Z", + "x-ms-file-creation-time": "2020-09-24T08:13:34.8855160Z", + "x-ms-file-id": "11529285414812647424", + "x-ms-file-last-write-time": "2020-09-24T08:13:34.8855160Z", + "x-ms-file-parent-id": "13835128424026341376", + "x-ms-file-permission-key": "15912238054059149673*8391130200578712039", + "x-ms-request-id": "eb662305-d01a-0005-364a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": { + "comp": "range" + }, + "requestBody": "Hello", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==", + "etag": "\"0x8D86061BBF1B394\"", + "last-modified": "Thu, 24 Sep 2020 08:13:35 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "881218b2-a52d-431d-91b2-ff531d548ff1", + "x-ms-request-id": "eb662312-d01a-0005-434a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444", + "query": { + "restype": "share", + "comp": "snapshot" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BAFC7DC2\"", + "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f7f88397-38ac-4bd2-9f7a-04580fa3ef2d", + "x-ms-request-id": "eb66231b-d01a-0005-4b4a-921536000000", + "x-ms-snapshot": "2020-09-24T08:13:35.0000000Z", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": { + "comp": "range" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BC6C9F14\"", + "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "dc25fc55-e8c1-43dd-8b15-8e08b50cf752", + "x-ms-request-id": "eb66231f-d01a-0005-4f4a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": { + "comp": "range" + }, + "requestBody": "World", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "9aeSTmIehMkoCpon4by39g==", + "etag": "\"0x8D86061BC962791\"", + "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "928f45eb-1f36-464b-b4ea-83d7ac0e1908", + "x-ms-request-id": "eb662324-d01a-0005-544a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444", + "query": { + "restype": "share", + "comp": "snapshot" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "etag": "\"0x8D86061BAFC7DC2\"", + "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "736a00f7-605d-4929-8f40-24bd538a1ea6", + "x-ms-request-id": "eb66232b-d01a-0005-594a-921536000000", + "x-ms-snapshot": "2020-09-24T08:13:36.0000000Z", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": { + "comp": "range" + }, + "requestBody": "Hello", + "status": 201, + "response": "", + "responseHeaders": { + "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==", + "etag": "\"0x8D86061BCEAE698\"", + "last-modified": "Thu, 24 Sep 2020 08:13:37 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cd933ba2-4b8f-410e-ad3a-a9f57f51a0e0", + "x-ms-request-id": "eb662330-d01a-0005-5e4a-921536000000", + "x-ms-request-server-encrypted": "false", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534", + "query": { + "sharesnapshot": "2020-09-24T08:13:36.0000000Z", + "prevsharesnapshot": "2020-09-24T08:13:35.0000000Z", + "comp": "rangelist" + }, + "requestBody": null, + "status": 200, + "response": "05115121535", + "responseHeaders": { + "content-type": "application/xml", + "etag": "\"0x8D86061BC962791\"", + "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f078dcb9-8015-443e-b976-8acc2c971ed9", + "x-ms-content-length": "2049", + "x-ms-request-id": "eb662338-d01a-0005-654a-921536000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "25ba29c7-ea5d-4fde-bacf-ac9d3386ed2c", + "x-ms-request-id": "eb662343-d01a-0005-6b4a-921536000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160093521340408444", + "dir": "dir160093521393907594", + "file": "file160093521447407534" + }, + "newDate": {} + }, + "hash": "5acd47a036848052dec455d515012c9a" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient/recording_setproperties.json b/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient/recording_setproperties.json index 003c95b672aa..90874400a985 100644 --- a/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient/recording_setproperties.json +++ b/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient/recording_setproperties.json @@ -4,61 +4,65 @@ "method": "GET", "url": "https://fakestorageaccount.file.core.windows.net/", "query": { - "comp": "properties", - "restype": "service" + "restype": "service", + "comp": "properties" }, "requestBody": null, "status": 200, - "response": "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT***86400GETexample.com**8888GETexample.com**8888GETexample.com**8888GETexample.com**8888", + "response": "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400GETexample.com**8888GETexample.com**8888false", "responseHeaders": { - "date": "Wed, 11 Sep 2019 02:24:13 GMT", + "content-type": "application/xml", + "date": "Sat, 10 Oct 2020 04:21:47 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "content-type": "application/xml", - "x-ms-request-id": "252c6c58-d01a-0019-2948-684a94000000", - "x-ms-version": "2019-02-02", - "x-ms-client-request-id": "b5abf3c1-f876-4d70-8ecc-fa470fb30819" + "x-ms-client-request-id": "77fc52a0-95ca-466a-9c11-23b07e099c1b", + "x-ms-request-id": "776634be-901a-004c-3dbc-9efe96000000", + "x-ms-version": "2020-02-10" } }, { "method": "PUT", "url": "https://fakestorageaccount.file.core.windows.net/", "query": { - "comp": "properties", - "restype": "service" + "restype": "service", + "comp": "properties" }, - "requestBody": "1.0truetruetrue31.0truetruetrue4*DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT**86400example.comGET**8888example.comGET**8888example.comGET**8888example.comGET**8888", + "requestBody": "1.0truetruetrue31.0truetruetrue4*DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH**86400example.comGET**8888example.comGET**8888example.comGET**8888", "status": 202, "response": "", "responseHeaders": { - "date": "Wed, 11 Sep 2019 02:24:14 GMT", + "content-length": "0", + "date": "Sat, 10 Oct 2020 04:21:48 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-request-id": "252c6c5a-d01a-0019-2b48-684a94000000", - "x-ms-version": "2019-02-02", - "x-ms-client-request-id": "7035c756-35bf-4298-b2a6-deee03355e64", - "content-length": "0" + "x-ms-client-request-id": "b072c9be-86c6-4510-bc52-5a909cf83c77", + "x-ms-request-id": "776634c2-901a-004c-3fbc-9efe96000000", + "x-ms-version": "2020-02-10" } }, { "method": "GET", "url": "https://fakestorageaccount.file.core.windows.net/", "query": { - "comp": "properties", - "restype": "service" + "restype": "service", + "comp": "properties" }, "requestBody": null, "status": 200, - "response": "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT***86400GETexample.com**8888GETexample.com**8888GETexample.com**8888GETexample.com**8888", + "response": "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400GETexample.com**8888GETexample.com**8888GETexample.com**8888false", "responseHeaders": { - "date": "Wed, 11 Sep 2019 02:24:19 GMT", + "content-type": "application/xml", + "date": "Sat, 10 Oct 2020 04:21:54 GMT", "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "content-type": "application/xml", - "x-ms-request-id": "252c6c67-d01a-0019-2f48-684a94000000", - "x-ms-version": "2019-02-02", - "x-ms-client-request-id": "f7582cfb-f18b-4839-9364-7f6dfe00c36a" + "x-ms-client-request-id": "e4a395c3-1868-446c-86e3-937cfd28e28c", + "x-ms-request-id": "776634d0-901a-004c-44bc-9efe96000000", + "x-ms-version": "2020-02-10" } } ], - "uniqueTestInfo": {} + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "7d1b87f258355828270f126918250abb" } \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient_premium/recording_smb_multichannel.json b/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient_premium/recording_smb_multichannel.json new file mode 100644 index 000000000000..f4645581f452 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/fileserviceclient_premium/recording_smb_multichannel.json @@ -0,0 +1,48 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/", + "query": { + "restype": "service", + "comp": "properties" + }, + "requestBody": "true", + "status": 202, + "response": "", + "responseHeaders": { + "date": "Mon, 28 Sep 2020 05:37:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "232c2dcc-ff85-4f5e-ab7f-f74f903b46ae", + "x-ms-request-id": "a2efaa50-101a-0059-8059-95b1cf000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/", + "query": { + "restype": "service", + "comp": "properties" + }, + "requestBody": null, + "status": 200, + "response": "1.0truetruetrue41.0truetruetrue3GET,PUThttp://www.example1.comx-ms-header1,x-ms-header2x-ms-header310DELETEhttp://www.example2.comx-ms-header1x-ms-header2,x-ms-header320DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400true", + "responseHeaders": { + "content-type": "application/xml", + "date": "Mon, 28 Sep 2020 05:37:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "d8ba73f8-abdc-4789-be1e-9e3800b647d1", + "x-ms-request-id": "a2efaa5a-101a-0059-0459-95b1cf000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": {}, + "newDate": {} + }, + "hash": "07d7182d263382fe7ddd0ab3d7ae7c76" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquire_a_broken_lease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquire_a_broken_lease.json new file mode 100644 index 000000000000..1637fe87c53a --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquire_a_broken_lease.json @@ -0,0 +1,192 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:12 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "078a80d8-07a4-4dbf-bf0c-221adaf2daf6", + "x-ms-request-id": "0ce68c4a-701a-0026-46df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:13 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "bac6af8c-e891-42ee-8cde-765720e45bb5", + "x-ms-lease-id": "a951739b-fdf4-4e2b-bb24-ce9d3ea40580", + "x-ms-request-id": "0ce68c4f-701a-0026-48df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:14 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8a4df4f7-952e-4fb8-95c2-932db5d74a06", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c51-701a-0026-49df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:14 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:13 GMT", + "x-ms-client-request-id": "63c66d0c-17f2-4f44-b5c5-c96d94ad98c7", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-state": "broken", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "0ce68c55-701a-0026-4cdf-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:15 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "28454f99-57b2-4ee4-8b17-0f871c08ef33", + "x-ms-lease-id": "a951739b-fdf4-4e2b-bb24-ce9d3ea40580", + "x-ms-request-id": "0ce68c57-701a-0026-4ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:16 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:13 GMT", + "x-ms-client-request-id": "02ac1d5d-a6ca-41ed-9129-f07bb42e24c1", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68c5a-701a-0026-4fdf-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:16 GMT", + "etag": "\"0x8D862F704189B36\"", + "last-modified": "Sun, 27 Sep 2020 15:07:13 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5fcf8cbc-0f2a-491f-a18f-361cf605f255", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c5d-701a-0026-52df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923329702973", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:17 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0df6a693-f351-4c58-8ba7-b8f56c20e883", + "x-ms-request-id": "0ce68c60-701a-0026-54df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121923329702973" + }, + "newDate": {} + }, + "hash": "9bb9ff27d1a7596192f2543142fdec37" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease.json new file mode 100644 index 000000000000..93411a9329bd --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease.json @@ -0,0 +1,121 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121919298303771", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:33 GMT", + "etag": "\"0x8D862F6ECACACD9\"", + "last-modified": "Sun, 27 Sep 2020 15:06:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0e3a51c7-54b6-4c50-8a95-6d90f0e6e9ff", + "x-ms-request-id": "0ce68b9d-701a-0026-4edf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121919298303771", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:34 GMT", + "etag": "\"0x8D862F6ECACACD9\"", + "last-modified": "Sun, 27 Sep 2020 15:06:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3350fd53-37f3-4473-b543-52357d4e2edf", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68ba1-701a-0026-50df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121919298303771", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:35 GMT", + "etag": "\"0x8D862F6ECACACD9\"", + "last-modified": "Sun, 27 Sep 2020 15:06:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:06:34 GMT", + "x-ms-client-request-id": "df2e860d-67f8-4859-87d9-95137402b578", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68ba5-701a-0026-53df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121919298303771", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:35 GMT", + "etag": "\"0x8D862F6ECACACD9\"", + "last-modified": "Sun, 27 Sep 2020 15:06:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "32df462b-25a8-41c2-b114-2fd3f5cb6b52", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68ba9-701a-0026-56df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121919298303771", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "6be03c71-bc84-43d1-beda-c2284e2fdbb6", + "x-ms-request-id": "0ce68bac-701a-0026-58df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121919298303771" + }, + "newDate": {} + }, + "hash": "3271dde67c5296103fdf6f626ed60976" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.json new file mode 100644 index 000000000000..d665c8b10358 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.json @@ -0,0 +1,114 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920597404062", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:45 GMT", + "etag": "\"0x8D862F6F3CC2D1D\"", + "last-modified": "Sun, 27 Sep 2020 15:06:46 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "fe3cb93c-6151-4719-a3fe-c1c8dc3a7040", + "x-ms-request-id": "0ce68bd4-701a-0026-73df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920597404062", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:46 GMT", + "etag": "\"0x8D862F6F3CC2D1D\"", + "last-modified": "Sun, 27 Sep 2020 15:06:46 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2e9a3c89-9e29-4cae-8b41-8c50b684b792", + "x-ms-lease-id": "c8e518e6-713b-4a65-b51b-bf4e611e36cf", + "x-ms-request-id": "0ce68bd7-701a-0026-75df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920597404062", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 409, + "response": "LeaseAlreadyPresentThere is already a lease present.\nRequestId:0ce68bd8-701a-0026-76df-9426be000000\nTime:2020-09-27T15:06:47.7005210Z", + "responseHeaders": { + "content-length": "221", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:06:46 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "92e1bd0e-d693-4e90-bbc9-6999816e2d0a", + "x-ms-error-code": "LeaseAlreadyPresent", + "x-ms-request-id": "0ce68bd8-701a-0026-76df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920597404062", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:47 GMT", + "etag": "\"0x8D862F6F3CC2D1D\"", + "last-modified": "Sun, 27 Sep 2020 15:06:46 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9525d7f0-d136-4a14-b815-ea5d3f34bb23", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68bdd-701a-0026-79df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920597404062", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:48 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3c203d19-b865-496e-ab67-42ea5bcdf7b3", + "x-ms-request-id": "0ce68bdf-701a-0026-7bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121920597404062" + }, + "newDate": {} + }, + "hash": "a7662e80063146772c80486996dac996" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.json new file mode 100644 index 000000000000..62196a34592e --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.json @@ -0,0 +1,115 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920940207206", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:49 GMT", + "etag": "\"0x8D862F6F5E227CF\"", + "last-modified": "Sun, 27 Sep 2020 15:06:49 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c87d8d67-9d9c-4bfa-8a1c-556ad1a4bb24", + "x-ms-request-id": "0ce68be2-701a-0026-7ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920940207206", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:49 GMT", + "etag": "\"0x8D862F6F5E227CF\"", + "last-modified": "Sun, 27 Sep 2020 15:06:49 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5cf1eae1-18af-4cdc-9c35-73e154a823ec", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68be6-701a-0026-7fdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920940207206", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:50 GMT", + "etag": "\"0x8D862F6F5E227CF\"", + "last-modified": "Sun, 27 Sep 2020 15:06:49 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "dc89bb50-c1e2-4958-8b64-deb0ad3ce3ae", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68be8-701a-0026-80df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920940207206", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:50 GMT", + "etag": "\"0x8D862F6F5E227CF\"", + "last-modified": "Sun, 27 Sep 2020 15:06:49 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0bdbd7f4-b12e-41b7-b054-fa764a05ba9f", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68bec-701a-0026-03df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920940207206", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:51 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "bff12c07-b9a0-4f2f-af0a-6bc7ac1332ae", + "x-ms-request-id": "0ce68bf0-701a-0026-06df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121920940207206" + }, + "newDate": {} + }, + "hash": "707c88c66dc0125c8dbd1488ab4ff604" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_for_snapshot.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_for_snapshot.json new file mode 100644 index 000000000000..9508341ef683 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_for_snapshot.json @@ -0,0 +1,150 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:14 GMT", + "etag": "\"0x8D86CF14351E2C7\"", + "last-modified": "Sat, 10 Oct 2020 07:51:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4c6840d7-4b39-4c0c-b6aa-7915b9f832ec", + "x-ms-request-id": "945ebcf3-e01a-001b-11da-9e50a5000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "restype": "share", + "comp": "snapshot" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:14 GMT", + "etag": "\"0x8D86CF14351E2C7\"", + "last-modified": "Sat, 10 Oct 2020 07:51:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "49aaf0e0-a3b4-4739-8946-7bdfe35a3f08", + "x-ms-request-id": "945ebcf6-e01a-001b-13da-9e50a5000000", + "x-ms-snapshot": "2020-10-10T07:51:15.0000000Z", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "sharesnapshot": "2020-10-10T07:51:15.0000000Z", + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:15 GMT", + "etag": "\"0x8D86CF14351E2C7\"", + "last-modified": "Sat, 10 Oct 2020 07:51:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "838e3cd0-3cab-4b2a-ad83-6404ec4c383c", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "945ebcf8-e01a-001b-15da-9e50a5000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "sharesnapshot": "2020-10-10T07:51:15.0000000Z", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:16 GMT", + "etag": "\"0x8D86CF14351E2C7\"", + "last-modified": "Sat, 10 Oct 2020 07:51:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sat, 10 Oct 2020 07:51:14 GMT", + "x-ms-client-request-id": "f36139e1-45ec-4e5c-94e9-29b0ba26e6f5", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "945ebcfc-e01a-001b-18da-9e50a5000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:16 GMT", + "etag": "\"0x8D86CF14351E2C7\"", + "last-modified": "Sat, 10 Oct 2020 07:51:14 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sat, 10 Oct 2020 07:51:14 GMT", + "x-ms-client-request-id": "26f817a6-5d69-4922-906b-b7954756ea80", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "945ebd02-e01a-001b-1ada-9e50a5000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160231627308806358", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sat, 10 Oct 2020 07:51:17 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "60b9fcbe-d47d-4942-a17b-0f6be6180ea2", + "x-ms-request-id": "945ebd05-e01a-001b-1cda-9e50a5000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160231627308806358" + }, + "newDate": {} + }, + "hash": "487acd291d19992deeae80a7526b6cc0" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.json new file mode 100644 index 000000000000..829032d865d7 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.json @@ -0,0 +1,121 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920213300290", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:41 GMT", + "etag": "\"0x8D862F6F17AF32C\"", + "last-modified": "Sun, 27 Sep 2020 15:06:42 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1409e473-5f20-40cc-bc0d-8f0e17cbe65c", + "x-ms-request-id": "0ce68bc0-701a-0026-67df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920213300290", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:42 GMT", + "etag": "\"0x8D862F6F17AF32C\"", + "last-modified": "Sun, 27 Sep 2020 15:06:42 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e11eb253-d103-4001-aea1-685b0f09f519", + "x-ms-lease-id": "7454272a-6a98-4f73-af5c-dad9a63c8afd", + "x-ms-request-id": "0ce68bc4-701a-0026-6adf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920213300290", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:43 GMT", + "etag": "\"0x8D862F6F17AF32C\"", + "last-modified": "Sun, 27 Sep 2020 15:06:42 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:06:42 GMT", + "x-ms-client-request-id": "16497859-d078-4f59-a745-d353046dd2e4", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "fixed", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68bc7-701a-0026-6cdf-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920213300290", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:43 GMT", + "etag": "\"0x8D862F6F17AF32C\"", + "last-modified": "Sun, 27 Sep 2020 15:06:42 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "171746f7-2fce-42cd-bba0-1b4ed42fa030", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68bcd-701a-0026-6fdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121920213300290", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:44 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9127337f-5912-4e35-a714-98166845667e", + "x-ms-request-id": "0ce68bd0-701a-0026-71df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121920213300290" + }, + "newDate": {} + }, + "hash": "421f94daa21c442d8e80b444c7cc0a41" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_a_broken_lease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_a_broken_lease.json new file mode 100644 index 000000000000..ac159d21444d --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_a_broken_lease.json @@ -0,0 +1,137 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:08 GMT", + "etag": "\"0x8D862F701B77FDD\"", + "last-modified": "Sun, 27 Sep 2020 15:07:09 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2166a5c5-9e43-4bea-a6ba-3d9f10688acc", + "x-ms-request-id": "0ce68c3a-701a-0026-3adf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:09 GMT", + "etag": "\"0x8D862F701B77FDD\"", + "last-modified": "Sun, 27 Sep 2020 15:07:09 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2bec6f90-1e09-4681-a4d9-7add4e6afbed", + "x-ms-lease-id": "59fc8e0d-39a3-4640-ac25-22d3cbcb754b", + "x-ms-request-id": "0ce68c3d-701a-0026-3cdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:10 GMT", + "etag": "\"0x8D862F701B77FDD\"", + "last-modified": "Sun, 27 Sep 2020 15:07:09 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "14267976-b466-468a-80a1-0eec36a5e3ec", + "x-ms-lease-time": "14", + "x-ms-request-id": "0ce68c3f-701a-0026-3ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:10 GMT", + "etag": "\"0x8D862F701B77FDD\"", + "last-modified": "Sun, 27 Sep 2020 15:07:09 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c189f0d3-1f76-476e-9723-652dd1235997", + "x-ms-lease-time": "14", + "x-ms-request-id": "0ce68c43-701a-0026-40df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:11 GMT", + "etag": "\"0x8D862F701B77FDD\"", + "last-modified": "Sun, 27 Sep 2020 15:07:09 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d7e37f46-f535-4351-b1dd-55cdeeef5b90", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c45-701a-0026-42df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922935309709", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:12 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0e42be6e-74d2-4529-a553-5b90cd452daf", + "x-ms-request-id": "0ce68c47-701a-0026-44df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121922935309709" + }, + "newDate": {} + }, + "hash": "c354ff97edc6ad0a0a40f332e4643495" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_lease_and_then_release_it.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_lease_and_then_release_it.json new file mode 100644 index 000000000000..d11b910f3811 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_break_lease_and_then_release_it.json @@ -0,0 +1,170 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:04 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "795d78bf-96f5-405e-a0bf-cfc57d1a4ba9", + "x-ms-request-id": "0ce68c25-701a-0026-2bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:05 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "fbaa7e3d-242b-42f2-840b-6d87d38b4a96", + "x-ms-lease-id": "17c9bae3-a7ca-4e94-84d7-2cf88cdd379d", + "x-ms-request-id": "0ce68c29-701a-0026-2ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:05 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:05 GMT", + "x-ms-client-request-id": "ce1927ab-2c32-4e42-a534-d058296d3294", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68c2d-701a-0026-30df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:06 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cb8dc2c4-468e-4e3d-b092-14efe72ae550", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c2e-701a-0026-31df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:07 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:05 GMT", + "x-ms-client-request-id": "9866b443-e7ae-4450-96bd-78673de499e5", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-state": "broken", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "0ce68c31-701a-0026-33df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:07 GMT", + "etag": "\"0x8D862F6FF083692\"", + "last-modified": "Sun, 27 Sep 2020 15:07:05 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4a9f0b82-6b3f-4d73-a74b-f93789618c48", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c35-701a-0026-35df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922480701270", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:08 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "120f6a89-136f-4170-9df7-cbbac8352198", + "x-ms-request-id": "0ce68c37-701a-0026-37df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121922480701270" + }, + "newDate": {} + }, + "hash": "25b29898d8ae054f8ed43fa992363915" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease.json new file mode 100644 index 000000000000..0f5034d4ab8c --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease.json @@ -0,0 +1,115 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921513409290", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:54 GMT", + "etag": "\"0x8D862F6F93B3D7A\"", + "last-modified": "Sun, 27 Sep 2020 15:06:55 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e99338e2-ff1c-48c5-9d44-0ccf5e2118fc", + "x-ms-request-id": "0ce68bfd-701a-0026-0fdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921513409290", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:55 GMT", + "etag": "\"0x8D862F6F93B3D7A\"", + "last-modified": "Sun, 27 Sep 2020 15:06:55 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0eeab36b-563d-4638-8a50-3f170d88ebbc", + "x-ms-lease-id": "2e8edae1-2c50-49d1-b968-4b8dcf5cc613", + "x-ms-request-id": "0ce68c02-701a-0026-11df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921513409290", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:56 GMT", + "etag": "\"0x8D862F6F93B3D7A\"", + "last-modified": "Sun, 27 Sep 2020 15:06:55 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "36feded1-c0ab-44a5-b477-d72b2d467395", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68c04-701a-0026-13df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921513409290", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:56 GMT", + "etag": "\"0x8D862F6F93B3D7A\"", + "last-modified": "Sun, 27 Sep 2020 15:06:55 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "536ed785-c86b-4112-bad3-d26528ab7d24", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c05-701a-0026-14df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921513409290", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:57 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "ec123509-548f-41c1-ba91-18309d5f6c81", + "x-ms-request-id": "0ce68c08-701a-0026-17df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121921513409290" + }, + "newDate": {} + }, + "hash": "45257573d2724104a8397c325ec540bf" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.json new file mode 100644 index 000000000000..fad56b6cbaf1 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.json @@ -0,0 +1,70 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921841100051", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:58 GMT", + "etag": "\"0x8D862F6FB3F0CA1\"", + "last-modified": "Sun, 27 Sep 2020 15:06:58 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c194ef08-3e27-4c7b-83a7-b603db4a0948", + "x-ms-request-id": "0ce68c0b-701a-0026-19df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921841100051", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 409, + "response": "LeaseNotPresentWithLeaseOperationThere is currently no lease on the file share.\nRequestId:0ce68c0e-701a-0026-1bdf-9426be000000\nTime:2020-09-27T15:06:59.7841113Z", + "responseHeaders": { + "content-length": "248", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:06:58 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e9fa9b42-8b0f-4afc-b31e-0b20d605f6af", + "x-ms-error-code": "LeaseNotPresentWithLeaseOperation", + "x-ms-request-id": "0ce68c0e-701a-0026-1bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921841100051", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:59 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "dba9455b-e0d7-490f-8ac7-7366c3c9b16b", + "x-ms-request-id": "0ce68c11-701a-0026-1ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121921841100051" + }, + "newDate": {} + }, + "hash": "e186056390a4b2e47a3ff2e84cd1e298" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_invalid_duration_for_acquirelease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_invalid_duration_for_acquirelease.json new file mode 100644 index 000000000000..4e65c4e28e2c --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_invalid_duration_for_acquirelease.json @@ -0,0 +1,70 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921268005337", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:52 GMT", + "etag": "\"0x8D862F6F7D41925\"", + "last-modified": "Sun, 27 Sep 2020 15:06:53 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4c677dfe-6b3f-4fa7-8c9d-b7dac98a7a57", + "x-ms-request-id": "0ce68bf2-701a-0026-08df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921268005337", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 400, + "response": "InvalidHeaderValueThe value for one of the HTTP headers is not in the correct format.\nRequestId:0ce68bf7-701a-0026-0bdf-9426be000000\nTime:2020-09-27T15:06:54.0460284Zx-ms-lease-duration1", + "responseHeaders": { + "content-length": "326", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:06:53 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "a6804507-25bc-4070-a378-423881b40e5b", + "x-ms-error-code": "InvalidHeaderValue", + "x-ms-request-id": "0ce68bf7-701a-0026-0bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121921268005337", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:06:53 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "490509f5-0b48-4ebf-b06b-3c4569ab558f", + "x-ms-request-id": "0ce68bfa-701a-0026-0ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121921268005337" + }, + "newDate": {} + }, + "hash": "3432549bb6395ae678887f738bffbf31" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_delete.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_delete.json new file mode 100644 index 000000000000..e2db0955bbaa --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_delete.json @@ -0,0 +1,109 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924685607584", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:26 GMT", + "etag": "\"0x8D862F70C231B26\"", + "last-modified": "Sun, 27 Sep 2020 15:07:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b3b93e97-de43-4cb8-9379-3f80870962a6", + "x-ms-request-id": "0ce68c87-701a-0026-6fdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924685607584", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:27 GMT", + "etag": "\"0x8D862F70C231B26\"", + "last-modified": "Sun, 27 Sep 2020 15:07:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3b02d3fa-d43c-4240-8c58-9c492a52c6ae", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68c8b-701a-0026-72df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924685607584", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 412, + "response": "LeaseIdMissingThere is currently a lease on the file share and no lease ID was specified in the request.\nRequestId:0ce68c8f-701a-0026-74df-9426be000000\nTime:2020-09-27T15:07:28.5575651Z", + "responseHeaders": { + "content-length": "273", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:07:27 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e2287af5-d986-4825-b3fd-8ceca39837bc", + "x-ms-error-code": "LeaseIdMissing", + "x-ms-request-id": "0ce68c8f-701a-0026-74df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924685607584", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:28 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "08bd63de-f978-48d0-b4b7-a74f9d6c46e5", + "x-ms-request-id": "0ce68c91-701a-0026-76df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924685607584", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:29 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cbc3a4a9-5411-4d43-919c-c4fcaff588d7", + "x-ms-request-id": "0ce68c95-701a-0026-79df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121924685607584" + }, + "newDate": {} + }, + "hash": "d8ed60c539fec47123c7a461e5b69736" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_get_operations.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_get_operations.json new file mode 100644 index 000000000000..bd6b9f0bef7e --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_get_operations.json @@ -0,0 +1,169 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:29 GMT", + "etag": "\"0x8D862F70E4A0910\"", + "last-modified": "Sun, 27 Sep 2020 15:07:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0182b204-9e83-46de-b164-7ddf4f66dc62", + "x-ms-request-id": "0ce68c9f-701a-0026-7bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:30 GMT", + "etag": "\"0x8D862F70E4A0910\"", + "last-modified": "Sun, 27 Sep 2020 15:07:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "5541b635-9e5f-4131-9fa7-d1dca7f59ef6", + "x-ms-lease-id": "97672963-0e3f-414b-9b2d-8ed7dfce8c7f", + "x-ms-request-id": "0ce68ca4-701a-0026-7ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:31 GMT", + "etag": "\"0x8D862F70E4A0910\"", + "last-modified": "Sun, 27 Sep 2020 15:07:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:30 GMT", + "x-ms-client-request-id": "fe7dc7ff-2d38-4320-8d0e-a71e773b4c93", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68ca6-701a-0026-7fdf-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 412, + "response": "LeaseIdMismatchWithContainerOperationThe lease ID specified did not match the lease ID for the file share.\nRequestId:0ce68ca8-701a-0026-01df-9426be000000\nTime:2020-09-27T15:07:32.9396773Z", + "responseHeaders": { + "content-length": "275", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:07:31 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8b148a8e-cdd1-4386-a309-5857df9168c1", + "x-ms-error-code": "LeaseIdMismatchWithContainerOperation", + "x-ms-request-id": "0ce68ca8-701a-0026-01df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:32 GMT", + "etag": "\"0x8D862F70E4A0910\"", + "last-modified": "Sun, 27 Sep 2020 15:07:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:30 GMT", + "x-ms-client-request-id": "3abe6df4-9bc1-4b3a-a13d-7855a24ebe0e", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68cad-701a-0026-05df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:33 GMT", + "etag": "\"0x8D862F70E4A0910\"", + "last-modified": "Sun, 27 Sep 2020 15:07:30 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "63ef8252-c3c7-492f-818e-22adfab08667", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68cb1-701a-0026-07df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925036906348", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:34 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "77fbd941-c0f7-4e7f-b53a-ee27595ffb7a", + "x-ms-request-id": "0ce68cb4-701a-0026-09df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121925036906348" + }, + "newDate": {} + }, + "hash": "31d5724934e35915065b43a9b336d2d4" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_write_operations.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_write_operations.json new file mode 100644 index 000000000000..0ce354612a97 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_condition_for_write_operations.json @@ -0,0 +1,156 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:35 GMT", + "etag": "\"0x8D862F7115761FA\"", + "last-modified": "Sun, 27 Sep 2020 15:07:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "48ad6b02-9809-4706-9244-d9353bdae9ec", + "x-ms-request-id": "0ce68cb8-701a-0026-0bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:35 GMT", + "etag": "\"0x8D862F7115761FA\"", + "last-modified": "Sun, 27 Sep 2020 15:07:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "281685fa-0fd5-4ed2-b71b-c2f621f7fab7", + "x-ms-lease-id": "f8704852-da74-48b2-b3af-7de0561e6e89", + "x-ms-request-id": "0ce68cbd-701a-0026-0edf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "restype": "share", + "comp": "metadata" + }, + "requestBody": null, + "status": 412, + "response": "LeaseIdMissingThere is currently a lease on the file share and no lease ID was specified in the request.\nRequestId:0ce68cc0-701a-0026-10df-9426be000000\nTime:2020-09-27T15:07:37.6820464Z", + "responseHeaders": { + "content-length": "273", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:07:36 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "ca9f0b6f-d70f-4483-835c-e5d40f2c3115", + "x-ms-error-code": "LeaseIdMissing", + "x-ms-request-id": "0ce68cc0-701a-0026-10df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "restype": "share", + "comp": "metadata" + }, + "requestBody": null, + "status": 412, + "response": "LeaseIdMismatchWithContainerOperationThe lease ID specified did not match the lease ID for the file share.\nRequestId:0ce68cc2-701a-0026-12df-9426be000000\nTime:2020-09-27T15:07:38.3785407Z", + "responseHeaders": { + "content-length": "275", + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:07:37 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3fa08946-09b5-48f8-a5f0-c05d1994d5e7", + "x-ms-error-code": "LeaseIdMismatchWithContainerOperation", + "x-ms-request-id": "0ce68cc2-701a-0026-12df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "restype": "share", + "comp": "metadata" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:37 GMT", + "etag": "\"0x8D862F712EE119F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:38 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d283dfdb-29a9-4f47-ae5f-42fabd1f3ceb", + "x-ms-request-id": "0ce68cc5-701a-0026-14df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:38 GMT", + "etag": "\"0x8D862F712EE119F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:38 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cbc40b22-3f4f-4357-8ea6-79c1dcab60d9", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68cc7-701a-0026-16df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121925548103276", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:39 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "6682b831-5c79-42fb-9b5c-95561317b39b", + "x-ms-request-id": "0ce68cc9-701a-0026-18df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121925548103276" + }, + "newDate": {} + }, + "hash": "4549bc2bdde60a476205f5127ea2f637" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_properties_properly_returned.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_properties_properly_returned.json new file mode 100644 index 000000000000..d7d4a8836579 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_lease_properties_properly_returned.json @@ -0,0 +1,140 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924184606440", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:21 GMT", + "etag": "\"0x8D862F7092974DF\"", + "last-modified": "Sun, 27 Sep 2020 15:07:22 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "56c0fd5d-978f-456d-bff6-b76fb424e841", + "x-ms-request-id": "0ce68c74-701a-0026-62df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924184606440", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:22 GMT", + "etag": "\"0x8D862F7092974DF\"", + "last-modified": "Sun, 27 Sep 2020 15:07:22 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4d870f36-d5bc-411e-ba82-64d37c605b82", + "x-ms-lease-id": "a193f0c2-30f2-4282-b2cf-1887bbcfcbc7", + "x-ms-request-id": "0ce68c77-701a-0026-64df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924184606440", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:22 GMT", + "etag": "\"0x8D862F7092974DF\"", + "last-modified": "Sun, 27 Sep 2020 15:07:22 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:22 GMT", + "x-ms-client-request-id": "b0541531-9df3-4596-8834-f1f4af4ee063", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-duration": "infinite", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-request-id": "0ce68c7a-701a-0026-66df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/", + "query": { + "comp": "list" + }, + "requestBody": null, + "status": 200, + "response": "share160093141210102328Thu, 24 Sep 2020 07:10:13 GMT\"0x8D86058E1C40CB2\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:10:13 GMT$account-encryption-keyfalseshare160093176153301093Thu, 24 Sep 2020 07:16:02 GMT\"0x8D86059B206C943\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:16:02 GMT$account-encryption-keyfalseshare160093195256704532Thu, 24 Sep 2020 07:19:13 GMT\"0x8D8605A23EB8F85\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:19:13 GMT$account-encryption-keyfalseshare160121233635009423Sun, 27 Sep 2020 13:12:16 GMT\"0x8D862E6F4FB4A9C\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:12:16 GMT$account-encryption-keyfalseshare160121235006600409Sun, 27 Sep 2020 13:12:30 GMT\"0x8D862E6FD28EA42\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:12:30 GMT$account-encryption-keyfalseshare160121310851508050Sun, 27 Sep 2020 13:25:09 GMT\"0x8D862E8C1F3100F\"unlockedexpired5120TransactionOptimizedSun, 27 Sep 2020 13:25:09 GMT$account-encryption-keyfalseshare160121326942502893Sun, 27 Sep 2020 13:27:50 GMT\"0x8D862E921DDD8EC\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 13:27:50 GMT$account-encryption-keyfalseshare160121389438808287Sun, 27 Sep 2020 13:38:15 GMT\"0x8D862EA966D8BBD\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:38:15 GMT$account-encryption-keyfalseshare160121491612400623Sun, 27 Sep 2020 13:55:16 GMT\"0x8D862ECF6A57F34\"unlockedexpired5120TransactionOptimizedSun, 27 Sep 2020 13:55:16 GMT$account-encryption-keyfalseshare160121509901107353Sun, 27 Sep 2020 13:58:19 GMT\"0x8D862ED63A7C0E3\"unlockedbroken5120TransactionOptimizedSun, 27 Sep 2020 13:58:19 GMT$account-encryption-keyfalseshare160121551221306317Sun, 27 Sep 2020 14:05:12 GMT\"0x8D862EE59F16DE2\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 14:05:12 GMT$account-encryption-keyfalseshare160121551974009496Sun, 27 Sep 2020 14:05:19 GMT\"0x8D862EE5E6E01B4\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 14:05:19 GMT$account-encryption-keyfalseshare160121870218806337Sun, 27 Sep 2020 14:58:23 GMT\"0x8D862F5C81E89A1\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 14:58:23 GMT$account-encryption-keyfalseshare160121924184606440Sun, 27 Sep 2020 15:07:22 GMT\"0x8D862F7092974DF\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 15:07:22 GMT$account-encryption-keyfalse", + "responseHeaders": { + "content-type": "application/xml", + "date": "Sun, 27 Sep 2020 15:07:23 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "3914bd4c-14dc-468a-8e7f-2e60f4952895", + "x-ms-request-id": "0ce68c7d-701a-0026-69df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924184606440", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:24 GMT", + "etag": "\"0x8D862F7092974DF\"", + "last-modified": "Sun, 27 Sep 2020 15:07:22 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "00dc6f23-150b-4e9b-9617-957ae3dac618", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c81-701a-0026-6bdf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121924184606440", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:25 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1a79040c-52a3-4c35-ac1d-8c416c5e6c96", + "x-ms-request-id": "0ce68c85-701a-0026-6ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121924184606440" + }, + "newDate": {} + }, + "hash": "215f84098c63269b1f047b6b869ee322" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_release_lease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_release_lease.json new file mode 100644 index 000000000000..316a60d45722 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_release_lease.json @@ -0,0 +1,120 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922087003562", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:00 GMT", + "etag": "\"0x8D862F6FCB5EB3F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:01 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c53a7081-55f1-4195-b5f9-2f11caa7b0da", + "x-ms-request-id": "0ce68c16-701a-0026-20df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922087003562", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:01 GMT", + "etag": "\"0x8D862F6FCB5EB3F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:01 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d7b22aac-ffdd-4740-a736-e1c63352cce6", + "x-ms-lease-id": "61a1a395-3747-40b3-a62b-6ca026759778", + "x-ms-request-id": "0ce68c19-701a-0026-22df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922087003562", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:01 GMT", + "etag": "\"0x8D862F6FCB5EB3F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:01 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e516cc08-36fc-4258-baef-8e0e2c82401b", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c1c-701a-0026-25df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922087003562", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:02 GMT", + "etag": "\"0x8D862F6FCB5EB3F\"", + "last-modified": "Sun, 27 Sep 2020 15:07:01 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "TransactionOptimized", + "x-ms-access-tier-change-time": "Sun, 27 Sep 2020 15:07:01 GMT", + "x-ms-client-request-id": "85ae4440-efc5-4642-a8d5-4691fdad3b3a", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "0ce68c1f-701a-0026-27df-9426be000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121922087003562", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:03 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "32d2b28f-5382-4475-925d-198be742580b", + "x-ms-request-id": "0ce68c21-701a-0026-29df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121922087003562" + }, + "newDate": {} + }, + "hash": "a8a98bf1c54106c991df3607be9a6771" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_renew_a_lease.json b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_renew_a_lease.json new file mode 100644 index 000000000000..71fdb97c94e9 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/leaseclient_for_share/recording_renew_a_lease.json @@ -0,0 +1,115 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923882600337", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:18 GMT", + "etag": "\"0x8D862F707648F1E\"", + "last-modified": "Sun, 27 Sep 2020 15:07:19 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2a01a917-daa8-409b-b195-0987713eabb6", + "x-ms-request-id": "0ce68c64-701a-0026-58df-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923882600337", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:19 GMT", + "etag": "\"0x8D862F707648F1E\"", + "last-modified": "Sun, 27 Sep 2020 15:07:19 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f968fe04-4d80-4a13-8c58-1406a6ee35d7", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68c68-701a-0026-5adf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923882600337", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:19 GMT", + "etag": "\"0x8D862F707648F1E\"", + "last-modified": "Sun, 27 Sep 2020 15:07:19 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b61858ac-4418-4e91-928e-5fb00ccc9daa", + "x-ms-lease-id": "e9890485-bf47-4d9a-b3d0-aceb18506124", + "x-ms-request-id": "0ce68c6c-701a-0026-5ddf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923882600337", + "query": { + "comp": "lease", + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:20 GMT", + "etag": "\"0x8D862F707648F1E\"", + "last-modified": "Sun, 27 Sep 2020 15:07:19 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "48e57c5e-04e8-4a4e-93a4-d4054b25b864", + "x-ms-lease-time": "0", + "x-ms-request-id": "0ce68c6e-701a-0026-5edf-9426be000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160121923882600337", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Sun, 27 Sep 2020 15:07:20 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "59008915-3e73-48d6-b7f8-5643161cea1c", + "x-ms-request-id": "0ce68c71-701a-0026-60df-9426be000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160121923882600337" + }, + "newDate": {} + }, + "hash": "b1a585cd2e7ca27eadf2de6c3aaa5eb2" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_create_share_specifying_accesstier_and_listshare.json b/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_create_share_specifying_accesstier_and_listshare.json new file mode 100644 index 000000000000..ed7520ca1084 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_create_share_specifying_accesstier_and_listshare.json @@ -0,0 +1,108 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160223291748509107", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:41:58 GMT", + "etag": "\"0x8D86C2F2F81CAF0\"", + "last-modified": "Fri, 09 Oct 2020 08:41:58 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "95939ed5-05d8-4232-a852-19d4371fe756", + "x-ms-request-id": "cabdd372-901a-0073-1118-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/newshare160223291907902683", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:41:58 GMT", + "etag": "\"0x8D86C2F2FE1FDCA\"", + "last-modified": "Fri, 09 Oct 2020 08:41:59 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8be33499-a83e-4ee4-b0b1-25ca46e8cf00", + "x-ms-request-id": "cabdd376-901a-0073-1418-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/", + "query": { + "prefix": "newshare160223291907902683", + "comp": "list" + }, + "requestBody": null, + "status": 200, + "response": "newshare160223291907902683newshare160223291907902683Fri, 09 Oct 2020 08:41:59 GMT\"0x8D86C2F2FE1FDCA\"unlockedavailable5120HotFri, 09 Oct 2020 08:41:59 GMT$account-encryption-keyfalse", + "responseHeaders": { + "content-type": "application/xml", + "date": "Fri, 09 Oct 2020 08:41:59 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "b6d35e5a-ce2c-426b-8f8c-39c0718a53ec", + "x-ms-request-id": "cabdd379-901a-0073-1618-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/newshare160223291907902683", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:41:59 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "c9399584-b45d-40eb-b44c-42321039f80e", + "x-ms-request-id": "cabdd37c-901a-0073-1818-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160223291748509107", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:42:00 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3e7a8cfe-acf5-4d29-985b-80b3eff56157", + "x-ms-request-id": "cabdd37e-901a-0073-1a18-9e3635000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160223291748509107", + "newshare": "newshare160223291907902683" + }, + "newDate": {} + }, + "hash": "ecaeea5c0525719df5426fd640a49c35" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_setaccesstier.json b/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_setaccesstier.json new file mode 100644 index 000000000000..73a75b0ce203 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/browsers/shareclient/recording_setaccesstier.json @@ -0,0 +1,98 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160223292153606227", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:42:01 GMT", + "etag": "\"0x8D86C2F31569253\"", + "last-modified": "Fri, 09 Oct 2020 08:42:01 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f326ea15-b033-40d5-a6ad-1a89055ff503", + "x-ms-request-id": "cabdd380-901a-0073-1c18-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.file.core.windows.net/share160223292153606227", + "query": { + "restype": "share", + "comp": "properties" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:42:01 GMT", + "etag": "\"0x8D86C2F31B22508\"", + "last-modified": "Fri, 09 Oct 2020 08:42:02 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "d56fc850-6721-444d-a95f-8bea4a422ac8", + "x-ms-request-id": "cabdd384-901a-0073-1e18-9e3635000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.file.core.windows.net/share160223292153606227", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 200, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:42:02 GMT", + "etag": "\"0x8D86C2F31B22508\"", + "last-modified": "Fri, 09 Oct 2020 08:42:02 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-change-time": "Fri, 09 Oct 2020 08:42:02 GMT", + "x-ms-access-tier-transition-state": "pending-from-transactionOptimized", + "x-ms-client-request-id": "1e56ea0d-ac8e-45b4-bada-54ba0e120771", + "x-ms-has-immutability-policy": "false", + "x-ms-has-legal-hold": "false", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-request-id": "cabdd388-901a-0073-2118-9e3635000000", + "x-ms-share-quota": "5120", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.file.core.windows.net/share160223292153606227", + "query": { + "restype": "share" + }, + "requestBody": null, + "status": 202, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Fri, 09 Oct 2020 08:42:02 GMT", + "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "a8daebe7-5e7f-46ab-8243-15fa950bf24b", + "x-ms-request-id": "cabdd38c-901a-0073-2418-9e3635000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "share": "share160223292153606227" + }, + "newDate": {} + }, + "hash": "27122424ce12efd6ef8d210c26be42c2" +} \ No newline at end of file diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_create_largest_file.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_create_largest_file.js index 37fedbe25ad3..9bcb8067656b 100644 --- a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_create_largest_file.js +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_create_largest_file.js @@ -1,57 +1,57 @@ let nock = require('nock'); -module.exports.hash = "60b311a9da34394d5deb32f8e27a78eb"; +module.exports.hash = "1663c2df5ebd1cdca8b3c8eef32dfe82"; -module.exports.testInfo = {"uniqueName":{"share":"share159256179930406953","dir":"dir159256180063107425","file":"file159256180107703922"},"newDate":{}} +module.exports.testInfo = {"uniqueName":{"share":"share159972991476308408","dir":"dir159972991651208876","file":"file159972991679300560"},"newDate":{}} nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share159256179930406953') + .put('/share159972991476308408') .query(true) .reply(201, "", [ 'Transfer-Encoding', 'chunked', 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:39 GMT', + 'Thu, 10 Sep 2020 09:25:15 GMT', 'ETag', - '"0x8D81439DB0EA7D6"', + '"0x8D8556B6D5014FF"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba8a-601a-001e-5e22-46da94000000', + '233acd5e-a01a-0001-2054-87e0b4000000', 'x-ms-client-request-id', - '142546bf-2119-4a2f-aa72-df26a9de8fb4', + '05fa39fe-0acf-4841-9cc8-c557c6786ed6', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'Date', - 'Fri, 19 Jun 2020 10:16:39 GMT' + 'Thu, 10 Sep 2020 09:25:14 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share159256179930406953/dir159256180063107425') + .put('/share159972991476308408/dir159972991651208876') .query(true) .reply(201, "", [ 'Transfer-Encoding', 'chunked', 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:39 GMT', + 'Thu, 10 Sep 2020 09:25:15 GMT', 'ETag', - '"0x8D81439DB572DB3"', + '"0x8D8556B6D7D637E"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba8e-601a-001e-5f22-46da94000000', + '233acd6a-a01a-0001-2154-87e0b4000000', 'x-ms-client-request-id', - '7aa26ff4-af76-4308-84c4-e89df4977ab6', + '447a62b0-7321-4513-ab00-03a4f708c759', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'x-ms-file-change-time', - '2020-06-19T10:16:39.8540211Z', + '2020-09-10T09:25:15.9720830Z', 'x-ms-file-last-write-time', - '2020-06-19T10:16:39.8540211Z', + '2020-09-10T09:25:15.9720830Z', 'x-ms-file-creation-time', - '2020-06-19T10:16:39.8540211Z', + '2020-09-10T09:25:15.9720830Z', 'x-ms-file-permission-key', - '4512302258392269635*6216600178912236746', + '14827816195503570342*11897905858180131375', 'x-ms-file-attributes', 'Directory', 'x-ms-file-id', @@ -61,56 +61,34 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Fri, 19 Jun 2020 10:16:39 GMT' + 'Thu, 10 Sep 2020 09:25:15 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share159256179930406953') - .query(true) - .reply(200, "", [ - 'Transfer-Encoding', - 'chunked', - 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:40 GMT', - 'ETag', - '"0x8D81439DB8A677D"', - 'Server', - 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', - 'x-ms-request-id', - '61abba8f-601a-001e-6022-46da94000000', - 'x-ms-client-request-id', - 'bffc2cb5-6d3c-438b-8667-6164c474d3e1', - 'x-ms-version', - '2019-12-12', - 'Date', - 'Fri, 19 Jun 2020 10:16:39 GMT' -]); - -nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share159256179930406953/dir159256180063107425/file159256180107703922') + .put('/share159972991476308408/dir159972991651208876/file159972991679300560') .reply(201, "", [ 'Transfer-Encoding', 'chunked', 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:40 GMT', + 'Thu, 10 Sep 2020 09:25:16 GMT', 'ETag', - '"0x8D81439DBECAC66"', + '"0x8D8556B6DA84BBF"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba91-601a-001e-6122-46da94000000', + '233acd6b-a01a-0001-2254-87e0b4000000', 'x-ms-client-request-id', - '02f5d8e0-a1d3-4fa5-bd94-9f0d66f6c8cb', + '27d42776-a2b7-49f5-8b97-7520bda4da97', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'x-ms-file-change-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.2532799Z', 'x-ms-file-last-write-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.2532799Z', 'x-ms-file-creation-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.2532799Z', 'x-ms-file-permission-key', - '18367126982671236164*6216600178912236746', + '990002565778260641*11897905858180131375', 'x-ms-file-attributes', 'Archive', 'x-ms-file-id', @@ -120,35 +98,35 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Fri, 19 Jun 2020 10:16:40 GMT' + 'Thu, 10 Sep 2020 09:25:15 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share159256179930406953/dir159256180063107425/file159256180107703922') + .put('/share159972991476308408/dir159972991651208876/file159972991679300560') .query(true) .reply(200, "", [ 'Transfer-Encoding', 'chunked', 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:41 GMT', + 'Thu, 10 Sep 2020 09:25:16 GMT', 'ETag', - '"0x8D81439DC521155"', + '"0x8D8556B6DD1FB3E"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba9c-601a-001e-6222-46da94000000', + '233acd6d-a01a-0001-2354-87e0b4000000', 'x-ms-client-request-id', - 'a7100e5a-efea-477c-9245-10d9ea199980', + '32c7a85d-8d2e-43a3-aa93-b76e0fa73f8b', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'x-ms-file-change-time', - '2020-06-19T10:16:41.4982485Z', + '2020-09-10T09:25:16.5264702Z', 'x-ms-file-last-write-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.5264702Z', 'x-ms-file-creation-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.2532799Z', 'x-ms-file-permission-key', - '18367126982671236164*6216600178912236746', + '990002565778260641*11897905858180131375', 'x-ms-file-attributes', 'Archive', 'x-ms-file-id', @@ -158,28 +136,28 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Fri, 19 Jun 2020 10:16:40 GMT' + 'Thu, 10 Sep 2020 09:25:15 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .head('/share159256179930406953/dir159256180063107425/file159256180107703922') + .head('/share159972991476308408/dir159972991651208876/file159972991679300560') .reply(200, "", [ 'Content-Length', '4398046511104', 'Content-Type', 'application/octet-stream', 'Last-Modified', - 'Fri, 19 Jun 2020 10:16:41 GMT', + 'Thu, 10 Sep 2020 09:25:16 GMT', 'ETag', - '"0x8D81439DC521155"', + '"0x8D8556B6DD1FB3E"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba9d-601a-001e-6322-46da94000000', + '233acd6e-a01a-0001-2454-87e0b4000000', 'x-ms-client-request-id', - '4ddc70bb-8b55-4416-b05d-e7235b377ce7', + 'b0466f3a-36ad-4da5-8816-81de1f6d8cd3', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'x-ms-type', 'File', 'x-ms-server-encrypted', @@ -189,25 +167,55 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-lease-state', 'available', 'x-ms-file-change-time', - '2020-06-19T10:16:41.4982485Z', + '2020-09-10T09:25:16.5264702Z', 'x-ms-file-last-write-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.5264702Z', 'x-ms-file-creation-time', - '2020-06-19T10:16:40.8337510Z', + '2020-09-10T09:25:16.2532799Z', 'x-ms-file-permission-key', - '18367126982671236164*6216600178912236746', + '990002565778260641*11897905858180131375', 'x-ms-file-attributes', 'Archive', 'x-ms-file-id', '11529285414812647424', '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', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Thu, 10 Sep 2020 09:25:15 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share159972991476308408/dir159972991651208876/file159972991679300560', "Hello World") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'sQqNsWTgdUEFt6mb5y4/5Q==', + 'Last-Modified', + 'Thu, 10 Sep 2020 09:25:17 GMT', + 'ETag', + '"0x8D8556B6E255A4A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '233acd6f-a01a-0001-2554-87e0b4000000', + 'x-ms-client-request-id', + '5659561a-d347-459c-80a9-d4717f4e3018', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'true', 'Date', - 'Fri, 19 Jun 2020 10:16:42 GMT' + 'Thu, 10 Sep 2020 09:25:16 GMT' ]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/share159256179930406953') + .delete('/share159972991476308408') .query(true) .reply(202, "", [ 'Transfer-Encoding', @@ -215,11 +223,11 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '61abba9e-601a-001e-6422-46da94000000', + '233acd71-a01a-0001-2654-87e0b4000000', 'x-ms-client-request-id', - 'fdd48eba-1b54-4aba-8f28-900a3a7747e0', + '8931bfa0-f051-4a61-a269-2c556fa6adf1', 'x-ms-version', - '2019-12-12', + '2020-02-10', 'Date', - 'Fri, 19 Jun 2020 10:16:42 GMT' + 'Thu, 10 Sep 2020 09:25:16 GMT' ]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js new file mode 100644 index 000000000000..099babc58a03 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js @@ -0,0 +1,274 @@ +let nock = require('nock'); + +module.exports.hash = "ecc86a388096f76385f242437ba54e04"; + +module.exports.testInfo = {"uniqueName":{"share":"share160093496274204261","dir":"dir160093496386306197","file":"file160093496414402587"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:23 GMT', + 'ETag', + '"0x8D8606125ECAA54"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47ad-101a-0013-5c4a-92d4a8000000', + 'x-ms-client-request-id', + '9f3fc9c8-519a-4053-bd70-a009a88f955b', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:23 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:24 GMT', + 'ETag', + '"0x8D860612619E89B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47b9-101a-0013-664a-92d4a8000000', + 'x-ms-client-request-id', + '74aeced9-0b89-4bfd-bbf7-1de223859b08', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:24.0251547Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:24.0251547Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:24.0251547Z', + 'x-ms-file-permission-key', + '2065021814682187374*8391130200578712039', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:23 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197/file160093496414402587') + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:24 GMT', + 'ETag', + '"0x8D8606126456D6F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47ca-101a-0013-734a-92d4a8000000', + 'x-ms-client-request-id', + '96bc385e-4f8b-4526-a5fb-c1fc21daf807', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:24.3103599Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:24.3103599Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:24.3103599Z', + 'x-ms-file-permission-key', + '15912238054059149673*8391130200578712039', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '11529285414812647424', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:24 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "Hello") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:24 GMT', + 'ETag', + '"0x8D86061266FB986"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47d2-101a-0013-7b4a-92d4a8000000', + 'x-ms-client-request-id', + '8ce7fbac-becb-452a-b555-aeaebe3b1938', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:24 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "World") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + '9aeSTmIehMkoCpon4by39g==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:24 GMT', + 'ETag', + '"0x8D860612699421C"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47d8-101a-0013-014a-92d4a8000000', + 'x-ms-client-request-id', + '746651a4-17d5-4ff7-b38f-53ef2f4d83c6', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:24 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197/file160093496414402587') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:25 GMT', + 'ETag', + '"0x8D8606126C40370"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47e2-101a-0013-084a-92d4a8000000', + 'x-ms-client-request-id', + '6af17d2a-74a5-404b-a24a-31eef1d453da', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:25 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:23 GMT', + 'ETag', + '"0x8D8606125ECAA54"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47e7-101a-0013-0d4a-92d4a8000000', + 'x-ms-client-request-id', + 'ba3683c6-5499-43f8-946b-56beec2e5283', + 'x-ms-version', + '2020-02-10', + 'x-ms-snapshot', + '2020-09-24T08:09:25.0000000Z', + 'Date', + 'Thu, 24 Sep 2020 08:09:25 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "Hello") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:25 GMT', + 'ETag', + '"0x8D860612717FF20"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47eb-101a-0013-114a-92d4a8000000', + 'x-ms-client-request-id', + '76d524ee-b24e-407e-abce-8319533d4cbd', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:25 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160093496274204261/dir160093496386306197/file160093496414402587') + .query(true) + .reply(200, "512512", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:25 GMT', + 'ETag', + '"0x8D8606126C40370"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47f0-101a-0013-164a-92d4a8000000', + 'x-ms-client-request-id', + '5c9e0be1-b194-4f4d-b5bd-db27aa781e4d', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-length', + '513', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Thu, 24 Sep 2020 08:09:25 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160093496274204261') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47f6-101a-0013-1b4a-92d4a8000000', + 'x-ms-client-request-id', + '36207686-0abe-47a3-9690-3c2220535df8', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:26 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js new file mode 100644 index 000000000000..2830a0f21822 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js @@ -0,0 +1,248 @@ +let nock = require('nock'); + +module.exports.hash = "c882d73842127a37a7d097e998563de1"; + +module.exports.testInfo = {"uniqueName":{"share":"share160093496636805058","dir":"dir160093496663502172","file":"file160093496691709903"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:26 GMT', + 'ETag', + '"0x8D860612796617E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc47fb-101a-0013-204a-92d4a8000000', + 'x-ms-client-request-id', + 'b6b37d5c-62c8-4894-b34f-2f3326253c60', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:26 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058/dir160093496663502172') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:26 GMT', + 'ETag', + '"0x8D8606127C17D5D"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4802-101a-0013-264a-92d4a8000000', + 'x-ms-client-request-id', + '6cbd36a6-cff3-43c4-9570-397852d72d50', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:26.8011357Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:26.8011357Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:26.8011357Z', + 'x-ms-file-permission-key', + '2065021814682187374*8391130200578712039', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:26 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058/dir160093496663502172/file160093496691709903') + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:27 GMT', + 'ETag', + '"0x8D8606127EBA251"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4809-101a-0013-2c4a-92d4a8000000', + 'x-ms-client-request-id', + '6cdbf550-0f4e-4494-80e3-1a743894aea8', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:27.0773329Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:27.0773329Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:27.0773329Z', + 'x-ms-file-permission-key', + '15912238054059149673*8391130200578712039', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '11529285414812647424', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:26 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058/dir160093496663502172/file160093496691709903', "Hello") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:27 GMT', + 'ETag', + '"0x8D8606128152AE3"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc480e-101a-0013-314a-92d4a8000000', + 'x-ms-client-request-id', + 'add8c753-ae6e-4012-bd08-c1181d0cc3bb', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:27 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:26 GMT', + 'ETag', + '"0x8D860612796617E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4813-101a-0013-364a-92d4a8000000', + 'x-ms-client-request-id', + 'b093cd21-642d-4506-9547-b124b9f1062d', + 'x-ms-version', + '2020-02-10', + 'x-ms-snapshot', + '2020-09-24T08:09:27.0000000Z', + 'Date', + 'Thu, 24 Sep 2020 08:09:27 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058/dir160093496663502172/file160093496691709903') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:27 GMT', + 'ETag', + '"0x8D860612867788E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc481a-101a-0013-3c4a-92d4a8000000', + 'x-ms-client-request-id', + '2cc2840a-54f4-409a-b6d9-442da3381937', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:27 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496636805058/dir160093496663502172/file160093496691709903', "World") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + '9aeSTmIehMkoCpon4by39g==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:28 GMT', + 'ETag', + '"0x8D860612890B2F6"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4822-101a-0013-434a-92d4a8000000', + 'x-ms-client-request-id', + 'bbf6b3a3-2fea-4bc8-b549-722af5bdc2da', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:28 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160093496636805058/dir160093496663502172/file160093496691709903') + .query(true) + .reply(200, "05115121535", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:28 GMT', + 'ETag', + '"0x8D860612890B2F6"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc482b-101a-0013-4c4a-92d4a8000000', + 'x-ms-client-request-id', + '41c801f7-f850-4164-a7bb-166370c2ab3f', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-length', + '2049', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Thu, 24 Sep 2020 08:09:28 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160093496636805058') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4835-101a-0013-544a-92d4a8000000', + 'x-ms-client-request-id', + '02bf2ca1-1ab0-4d98-89a0-ed1b43b652ef', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:28 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js new file mode 100644 index 000000000000..4cafe4d52262 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js @@ -0,0 +1,298 @@ +let nock = require('nock'); + +module.exports.hash = "ac99b21fb5d35030f069157846c8dc26"; + +module.exports.testInfo = {"uniqueName":{"share":"share160093496883503959","dir":"dir160093496910602647","file":"file160093496938007000"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:28 GMT', + 'ETag', + '"0x8D86061290F6335"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc483e-101a-0013-5d4a-92d4a8000000', + 'x-ms-client-request-id', + '59dd1dec-53d7-425d-9666-30324334ccd5', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:28 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:29 GMT', + 'ETag', + '"0x8D86061293946B7"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc484b-101a-0013-684a-92d4a8000000', + 'x-ms-client-request-id', + 'bc262d54-df93-495e-9ddd-a70b5a28a433', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:29.2638903Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:29.2638903Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:29.2638903Z', + 'x-ms-file-permission-key', + '2065021814682187374*8391130200578712039', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:29 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647/file160093496938007000') + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:29 GMT', + 'ETag', + '"0x8D8606129631D77"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4853-101a-0013-704a-92d4a8000000', + 'x-ms-client-request-id', + '11131696-c253-456e-9f8e-a61a0944b783', + 'x-ms-version', + '2020-02-10', + 'x-ms-file-change-time', + '2020-09-24T08:09:29.5380855Z', + 'x-ms-file-last-write-time', + '2020-09-24T08:09:29.5380855Z', + 'x-ms-file-creation-time', + '2020-09-24T08:09:29.5380855Z', + 'x-ms-file-permission-key', + '15912238054059149673*8391130200578712039', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '11529285414812647424', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:29 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "Hello") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:29 GMT', + 'ETag', + '"0x8D86061298D4262"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc485c-101a-0013-794a-92d4a8000000', + 'x-ms-client-request-id', + 'cd93303c-ce01-4083-b7fc-2b328923923c', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:29 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:28 GMT', + 'ETag', + '"0x8D86061290F6335"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4863-101a-0013-804a-92d4a8000000', + 'x-ms-client-request-id', + 'fe65db0f-b63c-4519-80a3-e3af8225d632', + 'x-ms-version', + '2020-02-10', + 'x-ms-snapshot', + '2020-09-24T08:09:30.0000000Z', + 'Date', + 'Thu, 24 Sep 2020 08:09:29 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647/file160093496938007000') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:30 GMT', + 'ETag', + '"0x8D8606129DFB72A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4869-101a-0013-054a-92d4a8000000', + 'x-ms-client-request-id', + 'd491fba3-2005-47e9-9faf-4096b8778b1f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:30 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "World") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + '9aeSTmIehMkoCpon4by39g==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:30 GMT', + 'ETag', + '"0x8D860612A0A032E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc486f-101a-0013-0b4a-92d4a8000000', + 'x-ms-client-request-id', + 'd12a56d1-1338-4cc2-b596-8ef86649f216', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:30 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959') + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:28 GMT', + 'ETag', + '"0x8D86061290F6335"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4878-101a-0013-144a-92d4a8000000', + 'x-ms-client-request-id', + 'f0fd6edd-c08f-4124-a1bd-66ae79c8eff9', + 'x-ms-version', + '2020-02-10', + 'x-ms-snapshot', + '2020-09-24T08:09:31.0000000Z', + 'Date', + 'Thu, 24 Sep 2020 08:09:30 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "Hello") + .query(true) + .reply(201, "", [ + 'Transfer-Encoding', + 'chunked', + 'Content-MD5', + 'ixqZU8RhEpaoJ6v4xHgE1w==', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:31 GMT', + 'ETag', + '"0x8D860612A5D899F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4881-101a-0013-1d4a-92d4a8000000', + 'x-ms-client-request-id', + '1c5b2cfc-0311-4c82-89b8-d6f043a1bf99', + 'x-ms-version', + '2020-02-10', + 'x-ms-request-server-encrypted', + 'false', + 'Date', + 'Thu, 24 Sep 2020 08:09:31 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160093496883503959/dir160093496910602647/file160093496938007000') + .query(true) + .reply(200, "05115121535", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Last-Modified', + 'Thu, 24 Sep 2020 08:09:30 GMT', + 'ETag', + '"0x8D860612A0A032E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4889-101a-0013-254a-92d4a8000000', + 'x-ms-client-request-id', + 'f2c78a6e-252c-4d5f-8a83-673ab8aed286', + 'x-ms-version', + '2020-02-10', + 'x-ms-content-length', + '2049', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Thu, 24 Sep 2020 08:09:31 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160093496883503959') + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '57bc4893-101a-0013-2d4a-92d4a8000000', + 'x-ms-client-request-id', + '1714bda0-94df-46bb-8f22-38b198f63de0', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Thu, 24 Sep 2020 08:09:31 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileserviceclient/recording_setproperties.js b/sdk/storage/storage-file-share/recordings/node/fileserviceclient/recording_setproperties.js index 6a057e3ca4c5..1e24d88af66f 100644 --- a/sdk/storage/storage-file-share/recordings/node/fileserviceclient/recording_setproperties.js +++ b/sdk/storage/storage-file-share/recordings/node/fileserviceclient/recording_setproperties.js @@ -1,66 +1,71 @@ let nock = require('nock'); -module.exports.testInfo = {} +module.exports.hash = "f5ef0646640da888d3d19fc431bf8367"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) .get('/') .query(true) - .reply(200, "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT***86400GETexample.com**8888GETexample.com**8888GETexample.com**8888GETexample.com**8888", [ 'Transfer-Encoding', + .reply(200, "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400GETexample.com**8888false", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'bf44a376-d01a-0056-3b47-688e8c000000', + 'e7871bc5-d01a-005d-57bc-9e6422000000', 'x-ms-client-request-id', - '9b4295ab-3e8b-4149-be2b-6412f2dc9834', + 'a2bb75da-8683-4ecb-8519-00afab2231f8', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Access-Control-Expose-Headers', 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:20:34 GMT' ]); - + 'Sat, 10 Oct 2020 04:20:42 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/', "1.0truetruetrue31.0truetruetrue4*DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT**86400example.comGET**8888example.comGET**8888example.comGET**8888example.comGET**8888") + .put('/', "1.0truetruetrue31.0truetruetrue4*DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH**86400example.comGET**8888example.comGET**8888") .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '4b3374e7-001a-0054-7747-688c76000000', + 'e7871bc7-d01a-005d-58bc-9e6422000000', 'x-ms-client-request-id', - '36817a18-c47e-42f4-8184-c14480e934dd', + '4eaeb91e-e5bf-4ece-8d6b-98da1a9ea34e', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Date', - 'Wed, 11 Sep 2019 02:20:35 GMT' ]); - + 'Sat, 10 Oct 2020 04:20:43 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) .get('/') .query(true) - .reply(200, "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT***86400GETexample.com**8888GETexample.com**8888GETexample.com**8888GETexample.com**8888", [ 'Transfer-Encoding', + .reply(200, "1.0truetruetrue31.0truetruetrue4DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400GETexample.com**8888GETexample.com**8888false", [ + 'Transfer-Encoding', 'chunked', 'Content-Type', 'application/xml', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '7b569903-001a-001b-4147-68486e000000', + 'e7871bd8-d01a-005d-5cbc-9e6422000000', 'x-ms-client-request-id', - '4261d8cc-6a46-441f-b89f-65e4216317e9', + '83bda732-be36-442e-9015-f84e5b7863af', 'x-ms-version', - '2019-02-02', + '2020-02-10', 'Access-Control-Expose-Headers', 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:20:40 GMT' ]); - + 'Sat, 10 Oct 2020 04:20:48 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/fileserviceclient_premium/recording_smb_multichannel.js b/sdk/storage/storage-file-share/recordings/node/fileserviceclient_premium/recording_smb_multichannel.js new file mode 100644 index 000000000000..1b323ba15ffd --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/fileserviceclient_premium/recording_smb_multichannel.js @@ -0,0 +1,47 @@ +let nock = require('nock'); + +module.exports.hash = "eb5c28f68ec1b06f5b0af59f04f201a8"; + +module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/', "true") + .query(true) + .reply(202, "", [ + 'Transfer-Encoding', + 'chunked', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '84dc4a50-501a-0067-6059-9526b0000000', + 'x-ms-client-request-id', + '268a12f3-4769-4b6d-b7a8-fe90438b0d2a', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Mon, 28 Sep 2020 05:36:40 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/') + .query(true) + .reply(200, "1.0truetruetrue41.0truetruetrue3GET,PUThttp://www.example1.comx-ms-header1,x-ms-header2x-ms-header310DELETEhttp://www.example2.comx-ms-header1x-ms-header2,x-ms-header320DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT,PATCH***86400true", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '84dc4a59-501a-0067-6359-9526b0000000', + 'x-ms-client-request-id', + '7e820c94-59fc-4772-8ee0-693f8acae009', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Mon, 28 Sep 2020 05:36:40 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquire_a_broken_lease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquire_a_broken_lease.js new file mode 100644 index 000000000000..28e06d838557 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquire_a_broken_lease.js @@ -0,0 +1,223 @@ +let nock = require('nock'); + +module.exports.hash = "6d5f59db24f5eaf5cfa76f90ceae5b63"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121915870707782"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915870707782') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a02-701a-006b-34df-94e952000000', + 'x-ms-client-request-id', + 'ff0fc7e4-c258-4727-a4cc-05e520da9b77', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:57 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915870707782') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293435-d01a-0000-23df-946ea6000000', + 'x-ms-client-request-id', + '919e03e9-f503-4e20-85c9-2dd6b67de9ce', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '99c58d68-34fa-4a19-b6f6-ed6a85b7bf9a', + 'Date', + 'Sun, 27 Sep 2020 15:05:58 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915870707782') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a05-701a-006b-35df-94e952000000', + 'x-ms-client-request-id', + '262b8833-c5e5-4e24-a88e-daef62dfcc25', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:58 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121915870707782') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293439-d01a-0000-25df-946ea6000000', + 'x-ms-client-request-id', + '03a8877b-7bde-4bd8-9948-72f6578d59c6', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'broken', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:59 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915870707782') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a06-701a-006b-36df-94e952000000', + 'x-ms-client-request-id', + '377bc8c4-ffdb-4e25-9495-159b0a4bc567', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '99c58d68-34fa-4a19-b6f6-ed6a85b7bf9a', + 'Date', + 'Sun, 27 Sep 2020 15:05:59 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121915870707782') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029343b-d01a-0000-26df-946ea6000000', + 'x-ms-client-request-id', + '2c773a78-2c4e-444c-9e40-cb2606595233', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:00 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915870707782') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:58 GMT', + 'ETag', + '"0x8D862F6D76BBE40"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a0a-701a-006b-38df-94e952000000', + 'x-ms-client-request-id', + '188634eb-e2e7-4062-ac72-bc6dc0c786dc', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:06:00 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121915870707782') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029343f-d01a-0000-27df-946ea6000000', + 'x-ms-client-request-id', + '1477e25d-d679-4630-aa28-66ff023369f7', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:01 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease.js new file mode 100644 index 000000000000..c047d7c7916d --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease.js @@ -0,0 +1,135 @@ +let nock = require('nock'); + +module.exports.hash = "e7c6728c194646a0b741653675f3b017"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121913625009003"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121913625009003') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:37 GMT', + 'ETag', + '"0x8D862F6CACD7503"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19a1-701a-006b-7ddf-94e952000000', + 'x-ms-client-request-id', + 'e03af896-ca88-4ea2-a6c1-9c26c9c3b70d', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:36 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121913625009003') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:37 GMT', + 'ETag', + '"0x8D862F6CACD7503"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19a7-701a-006b-7fdf-94e952000000', + 'x-ms-client-request-id', + '24d20fc5-657b-4412-b319-304b70ef4622', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:05:37 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121913625009003') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:37 GMT', + 'ETag', + '"0x8D862F6CACD7503"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19a8-701a-006b-80df-94e952000000', + 'x-ms-client-request-id', + '1f46739f-e596-4bf7-bba9-cf4a2e5952f1', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:37 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:37 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121913625009003') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:37 GMT', + 'ETag', + '"0x8D862F6CACD7503"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ab-701a-006b-01df-94e952000000', + 'x-ms-client-request-id', + '83ca9df5-68d9-4a20-854b-2367addddfec', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:37 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121913625009003') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ac-701a-006b-02df-94e952000000', + 'x-ms-client-request-id', + '512f26c8-4153-4710-91d6-c6b880f23fe2', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:38 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.js new file mode 100644 index 000000000000..a3122db47543 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_another_lease_id.js @@ -0,0 +1,115 @@ +let nock = require('nock'); + +module.exports.hash = "6bc9e6dba00ba7917561b4297b120d2b"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121914334809671"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914334809671') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:43 GMT', + 'ETag', + '"0x8D862F6CE4450CF"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c3-701a-006b-10df-94e952000000', + 'x-ms-client-request-id', + '5a751af9-44de-4e5c-9881-33f31c77e379', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:42 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914334809671') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:43 GMT', + 'ETag', + '"0x8D862F6CE4450CF"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c6-701a-006b-12df-94e952000000', + 'x-ms-client-request-id', + 'dc7d3aef-9458-4c25-86d5-270e9257c87c', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e04ff2de-d75d-476a-9cb2-3ea66fcb912f', + 'Date', + 'Sun, 27 Sep 2020 15:05:42 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914334809671') + .query(true) + .reply(409, "LeaseAlreadyPresentThere is already a lease present.\nRequestId:09ab19c8-701a-006b-13df-94e952000000\nTime:2020-09-27T15:05:44.2120727Z", [ + 'Content-Length', + '221', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c8-701a-006b-13df-94e952000000', + 'x-ms-client-request-id', + '0ea6de8e-54d6-4eab-80ec-76e5dec25cb9', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseAlreadyPresent', + 'Date', + 'Sun, 27 Sep 2020 15:05:43 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914334809671') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:43 GMT', + 'ETag', + '"0x8D862F6CE4450CF"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c9-701a-006b-14df-94e952000000', + 'x-ms-client-request-id', + '3e903cb4-fc7a-4b30-83df-b5f66cbf2a37', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:43 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121914334809671') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ca-701a-006b-15df-94e952000000', + 'x-ms-client-request-id', + '66b30245-d215-4f56-a055-a75cea1dfd29', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:44 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.js new file mode 100644 index 000000000000..166c7417419e --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_again_with_same_lease_id.js @@ -0,0 +1,117 @@ +let nock = require('nock'); + +module.exports.hash = "9bb69300bde42a870db6ff1116d04dd1"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121914509202924"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914509202924') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:45 GMT', + 'ETag', + '"0x8D862F6CF4EC55A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19cc-701a-006b-16df-94e952000000', + 'x-ms-client-request-id', + 'c98c28ed-9d83-4e19-a967-fed3be225172', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:44 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914509202924') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:45 GMT', + 'ETag', + '"0x8D862F6CF4EC55A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ce-701a-006b-17df-94e952000000', + 'x-ms-client-request-id', + '26938b2b-582a-4369-af7a-8b17a6b58072', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:05:44 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914509202924') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:45 GMT', + 'ETag', + '"0x8D862F6CF4EC55A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19d0-701a-006b-18df-94e952000000', + 'x-ms-client-request-id', + 'f9ca9d53-824f-4ae7-bc5b-7cc7f0c36fde', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:05:45 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914509202924') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:45 GMT', + 'ETag', + '"0x8D862F6CF4EC55A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029340b-d01a-0000-0bdf-946ea6000000', + 'x-ms-client-request-id', + '8c5511e9-264e-4671-9209-78c5c2b3b5a4', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:46 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121914509202924') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19d9-701a-006b-1cdf-94e952000000', + 'x-ms-client-request-id', + 'c1f93a25-8697-4fe9-a0f8-b2225fe4facf', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:46 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_for_snapshot.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_for_snapshot.js new file mode 100644 index 000000000000..e3d38fda8c35 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_for_snapshot.js @@ -0,0 +1,187 @@ +let nock = require('nock'); + +module.exports.hash = "605aa7c32fc39d9cef1923e874e73573"; + +module.exports.testInfo = {"uniqueName":{"share":"share160231621762403825"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160231621762403825') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'ETag', + '"0x8D86CF122C31DE4"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c6eefa50-601a-0077-16da-9ebb32000000', + 'x-ms-client-request-id', + 'fc84405d-a9db-457b-bb36-64bffaf1313e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160231621762403825') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'ETag', + '"0x8D86CF122C31DE4"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '26963bc8-001a-0061-16da-9e4de5000000', + 'x-ms-client-request-id', + '4b3062da-1bb2-4fde-b1b8-4e647f06f113', + 'x-ms-version', + '2020-02-10', + 'x-ms-snapshot', + '2020-10-10T07:50:21.0000000Z', + 'Date', + 'Sat, 10 Oct 2020 07:50:21 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160231621762403825') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'ETag', + '"0x8D86CF122C31DE4"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'a54469d4-001a-0013-23da-9e4aaa000000', + 'x-ms-client-request-id', + 'a45c8417-7156-4341-a75b-e57891ef5b49', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sat, 10 Oct 2020 07:50:21 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160231621762403825') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'ETag', + '"0x8D86CF122C31DE4"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '32797438-201a-003b-47da-9e2b02000000', + 'x-ms-client-request-id', + 'f2cb11c4-fd7d-4748-88bf-9f64b202a9ac', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sat, 10 Oct 2020 07:50:23 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160231621762403825') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'ETag', + '"0x8D86CF122C31DE4"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0f519f12-a01a-0078-5ada-9ecd5e000000', + 'x-ms-client-request-id', + '7df7280b-8e52-4de2-87ef-014f37dcddb6', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sat, 10 Oct 2020 07:50:19 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sat, 10 Oct 2020 07:50:24 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160231621762403825') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '4ad66e7f-401a-005f-20da-9eda9a000000', + 'x-ms-client-request-id', + '7c9541f2-aed4-416e-ab52-94a6fe320bf1', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sat, 10 Oct 2020 07:50:26 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.js new file mode 100644 index 000000000000..2cbb851882b6 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_acquirelease_without_proposed_lease_id_with_a_finite_duration.js @@ -0,0 +1,135 @@ +let nock = require('nock'); + +module.exports.hash = "dc5da3094ca5f35040a8e7541cfa5754"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121914170908383"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914170908383') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:41 GMT', + 'ETag', + '"0x8D862F6CD4A3321"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19b9-701a-006b-09df-94e952000000', + 'x-ms-client-request-id', + '7f0b60d7-9d8a-412c-9565-452c41b0efe7', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:41 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914170908383') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:41 GMT', + 'ETag', + '"0x8D862F6CD4A3321"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19bb-701a-006b-0adf-94e952000000', + 'x-ms-client-request-id', + '0dfa5371-08c1-4a36-ab85-ced76c0b7bba', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e58a14e2-562c-43af-a486-939fa5ce51a4', + 'Date', + 'Sun, 27 Sep 2020 15:05:41 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121914170908383') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:41 GMT', + 'ETag', + '"0x8D862F6CD4A3321"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19bf-701a-006b-0cdf-94e952000000', + 'x-ms-client-request-id', + '699db084-bcbb-4c61-9349-ac266e352b30', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'fixed', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:41 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:41 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914170908383') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:41 GMT', + 'ETag', + '"0x8D862F6CD4A3321"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c1-701a-006b-0edf-94e952000000', + 'x-ms-client-request-id', + '990b4663-d4c0-4db1-bde8-b3785c2b4721', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:42 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121914170908383') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19c2-701a-006b-0fdf-94e952000000', + 'x-ms-client-request-id', + '31daab21-08f5-403d-ac01-bd6c8d40135d', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:42 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_a_broken_lease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_a_broken_lease.js new file mode 100644 index 000000000000..a6eae715bda0 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_a_broken_lease.js @@ -0,0 +1,141 @@ +let nock = require('nock'); + +module.exports.hash = "493a7c86cc031356282fbce76c3dcfab"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121915624906007"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915624906007') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:56 GMT', + 'ETag', + '"0x8D862F6D5F4DFB1"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19f9-701a-006b-2fdf-94e952000000', + 'x-ms-client-request-id', + 'dba7c700-2c80-4264-baab-6b8ed85a6e25', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:55 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915624906007') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:56 GMT', + 'ETag', + '"0x8D862F6D5F4DFB1"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029342e-d01a-0000-1fdf-946ea6000000', + 'x-ms-client-request-id', + 'ef03b1fe-bcc4-42c2-a79b-2a8d6aba56a0', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '03388176-4f73-4aa8-9fec-4b26cb744063', + 'Date', + 'Sun, 27 Sep 2020 15:05:56 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915624906007') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:56 GMT', + 'ETag', + '"0x8D862F6D5F4DFB1"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19fc-701a-006b-30df-94e952000000', + 'x-ms-client-request-id', + 'a326809d-dcca-4c54-8a81-6af8dbe824e4', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '14', + 'Date', + 'Sun, 27 Sep 2020 15:05:56 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915624906007') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:56 GMT', + 'ETag', + '"0x8D862F6D5F4DFB1"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293431-d01a-0000-20df-946ea6000000', + 'x-ms-client-request-id', + '8c31cf4f-f0a8-4fb6-98e4-28a06be1f6ed', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '14', + 'Date', + 'Sun, 27 Sep 2020 15:05:57 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915624906007') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:56 GMT', + 'ETag', + '"0x8D862F6D5F4DFB1"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ff-701a-006b-32df-94e952000000', + 'x-ms-client-request-id', + 'd8712741-8fd5-42f1-8f62-303ff6fb4951', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:57 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121915624906007') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293434-d01a-0000-22df-946ea6000000', + 'x-ms-client-request-id', + '1f96c557-c69f-49cc-b4e8-34ee8bf5700e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:58 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_lease_and_then_release_it.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_lease_and_then_release_it.js new file mode 100644 index 000000000000..4507ccf45d4c --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_break_lease_and_then_release_it.js @@ -0,0 +1,199 @@ +let nock = require('nock'); + +module.exports.hash = "9a059dd3de5d823392423f909fdac826"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121915369200772"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915369200772') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293423-d01a-0000-18df-946ea6000000', + 'x-ms-client-request-id', + '0041fd5b-fc0b-467d-a60f-008c594ee5e3', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:53 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915369200772') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19f2-701a-006b-2bdf-94e952000000', + 'x-ms-client-request-id', + '222b1a4d-8e7b-4414-8f4f-37b5f6773801', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '79efc86e-c051-4696-9c60-eee1a9f93e2a', + 'Date', + 'Sun, 27 Sep 2020 15:05:53 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121915369200772') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293425-d01a-0000-19df-946ea6000000', + 'x-ms-client-request-id', + '8b02749a-66b9-45a5-8607-1dd50df0e26a', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:54 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915369200772') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19f5-701a-006b-2cdf-94e952000000', + 'x-ms-client-request-id', + '3f43de1d-caef-4f80-a649-a17addb83668', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:54 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121915369200772') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293428-d01a-0000-1adf-946ea6000000', + 'x-ms-client-request-id', + 'bf08638b-5f88-4f36-8bc8-5d65812fea43', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'broken', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:55 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915369200772') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:53 GMT', + 'ETag', + '"0x8D862F6D46E9B2F"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19f7-701a-006b-2edf-94e952000000', + 'x-ms-client-request-id', + '8abe0e10-10f4-4008-9051-40b2c0218664', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:54 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121915369200772') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029342b-d01a-0000-1ddf-946ea6000000', + 'x-ms-client-request-id', + '9c8799f3-c8b6-4428-a7e6-ea7324e481e1', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:55 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease.js new file mode 100644 index 000000000000..11e3605e6477 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease.js @@ -0,0 +1,117 @@ +let nock = require('nock'); + +module.exports.hash = "4038737563cbb5fb3335adf53fbfa413"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121914876904135"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914876904135') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:48 GMT', + 'ETag', + '"0x8D862F6D17F787B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19dc-701a-006b-1edf-94e952000000', + 'x-ms-client-request-id', + 'ae80488d-3b36-4e8b-9e6d-1c28a0f047ce', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:48 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914876904135') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:48 GMT', + 'ETag', + '"0x8D862F6D17F787B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293414-d01a-0000-0fdf-946ea6000000', + 'x-ms-client-request-id', + '1ff85c8e-bf37-4dd6-bddc-036fece28e97', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '738a5822-ff90-4d03-aab4-136fb410dacc', + 'Date', + 'Sun, 27 Sep 2020 15:05:48 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914876904135') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:48 GMT', + 'ETag', + '"0x8D862F6D17F787B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19e0-701a-006b-20df-94e952000000', + 'x-ms-client-request-id', + '68bf8427-ad12-472c-81ac-fddd984d9bd9', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:05:48 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914876904135') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:48 GMT', + 'ETag', + '"0x8D862F6D17F787B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293418-d01a-0000-11df-946ea6000000', + 'x-ms-client-request-id', + '2903d1bc-f799-46b4-a7d2-535149d3f19d', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:49 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121914876904135') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19e3-701a-006b-22df-94e952000000', + 'x-ms-client-request-id', + '5362f1cd-c428-4409-951a-2620988fc3cd', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:49 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.js new file mode 100644 index 000000000000..ec6bc8af6e2f --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_changelease_before_acquiring_a_lease.js @@ -0,0 +1,67 @@ +let nock = require('nock'); + +module.exports.hash = "ebfbd5b28ebc766ef7fcc4b5f1e3c195"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121915061801772"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915061801772') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:50 GMT', + 'ETag', + '"0x8D862F6D29A2262"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293419-d01a-0000-12df-946ea6000000', + 'x-ms-client-request-id', + 'f8d1e1d9-9240-4f38-a7b1-9b20fb243fae', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:50 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915061801772') + .query(true) + .reply(409, "LeaseNotPresentWithLeaseOperationThere is currently no lease on the file share.\nRequestId:09ab19e5-701a-006b-23df-94e952000000\nTime:2020-09-27T15:05:51.1790130Z", [ + 'Content-Length', + '248', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19e5-701a-006b-23df-94e952000000', + 'x-ms-client-request-id', + 'a9af1e5f-8eb8-4b67-ad8e-8e83dd800ab9', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseNotPresentWithLeaseOperation', + 'Date', + 'Sun, 27 Sep 2020 15:05:50 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121915061801772') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029341b-d01a-0000-13df-946ea6000000', + 'x-ms-client-request-id', + '28e6eb70-76d2-4a0e-8bc3-6f0b59f8f3b9', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:51 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_invalid_duration_for_acquirelease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_invalid_duration_for_acquirelease.js new file mode 100644 index 000000000000..f583e92020cb --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_invalid_duration_for_acquirelease.js @@ -0,0 +1,67 @@ +let nock = require('nock'); + +module.exports.hash = "654caa107adf9e5140aa8bdb81725c8e"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121914775500736"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914775500736') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:47 GMT', + 'ETag', + '"0x8D862F6D0EC4B5E"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293411-d01a-0000-0ddf-946ea6000000', + 'x-ms-client-request-id', + '17271a22-cdd2-4854-9ffe-4c2b4b99c820', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:47 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121914775500736') + .query(true) + .reply(400, "InvalidHeaderValueThe value for one of the HTTP headers is not in the correct format.\nRequestId:09ab19da-701a-006b-1ddf-94e952000000\nTime:2020-09-27T15:05:48.3009699Zx-ms-lease-duration1", [ + 'Content-Length', + '326', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19da-701a-006b-1ddf-94e952000000', + 'x-ms-client-request-id', + '7eeaebe0-d727-4e32-a9f0-cc6673ecbfb5', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'InvalidHeaderValue', + 'Date', + 'Sun, 27 Sep 2020 15:05:47 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121914775500736') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293413-d01a-0000-0edf-946ea6000000', + 'x-ms-client-request-id', + '4d1defbc-20c2-4031-87da-9f19e734f42e', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:48 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_delete.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_delete.js new file mode 100644 index 000000000000..e73f7da589d8 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_delete.js @@ -0,0 +1,109 @@ +let nock = require('nock'); + +module.exports.hash = "0c0829efdb2bc6b3a538e1d74362f342"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121916619007218"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916619007218') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:06 GMT', + 'ETag', + '"0x8D862F6DBE1C8C2"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293451-d01a-0000-2fdf-946ea6000000', + 'x-ms-client-request-id', + '9d1e9520-7dc4-4f1c-871b-bb8009e53ac4', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:06 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916619007218') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:06 GMT', + 'ETag', + '"0x8D862F6DBE1C8C2"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a20-701a-006b-42df-94e952000000', + 'x-ms-client-request-id', + '8de6c038-0b3a-42b4-8fff-222e5583a978', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:06:05 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916619007218') + .query(true) + .reply(412, "LeaseIdMissingThere is currently a lease on the file share and no lease ID was specified in the request.\nRequestId:10293453-d01a-0000-30df-946ea6000000\nTime:2020-09-27T15:06:07.1545112Z", [ + 'Content-Length', + '273', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293453-d01a-0000-30df-946ea6000000', + 'x-ms-client-request-id', + 'db810f91-bf9e-4757-8888-1edecde92635', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseIdMissing', + 'Date', + 'Sun, 27 Sep 2020 15:06:06 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916619007218') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a26-701a-006b-44df-94e952000000', + 'x-ms-client-request-id', + '878d5d81-092c-4798-8731-d9e861b67210', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:06 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916619007218') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293458-d01a-0000-33df-946ea6000000', + 'x-ms-client-request-id', + '41a75a6b-e4cc-42d9-a22a-dd37a8076891', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:07 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_get_operations.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_get_operations.js new file mode 100644 index 000000000000..d800394d8ec8 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_get_operations.js @@ -0,0 +1,203 @@ +let nock = require('nock'); + +module.exports.hash = "783b0b97c7720d404070d72ec167933d"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121916823006806"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916823006806') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'ETag', + '"0x8D862F6DD18CCA0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a2b-701a-006b-46df-94e952000000', + 'x-ms-client-request-id', + '259a1fed-abfe-4b80-99c8-5d55ab4c597c', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:07 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916823006806') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'ETag', + '"0x8D862F6DD18CCA0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029345a-d01a-0000-34df-946ea6000000', + 'x-ms-client-request-id', + 'c53c9abb-9e04-4bee-a381-f330bb357082', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '4a962ce7-3efb-4627-a830-05c98b03e95e', + 'Date', + 'Sun, 27 Sep 2020 15:06:08 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121916823006806') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'ETag', + '"0x8D862F6DD18CCA0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a2f-701a-006b-47df-94e952000000', + 'x-ms-client-request-id', + '7b111603-eabc-46c0-b2c1-808bb3938b8d', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:08 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121916823006806') + .query(true) + .reply(412, "LeaseIdMismatchWithContainerOperationThe lease ID specified did not match the lease ID for the file share.\nRequestId:1029345c-d01a-0000-35df-946ea6000000\nTime:2020-09-27T15:06:09.6102535Z", [ + 'Content-Length', + '275', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029345c-d01a-0000-35df-946ea6000000', + 'x-ms-client-request-id', + '004a614b-7d18-4a47-93fe-a79c5cdd034e', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseIdMismatchWithContainerOperation', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,x-ms-error-code,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:09 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121916823006806') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'ETag', + '"0x8D862F6DD18CCA0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a32-701a-006b-49df-94e952000000', + 'x-ms-client-request-id', + '9154caa5-8dfe-49b6-a841-30b0b02f42bf', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:09 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916823006806') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:08 GMT', + 'ETag', + '"0x8D862F6DD18CCA0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029345e-d01a-0000-36df-946ea6000000', + 'x-ms-client-request-id', + 'a518811b-0b6f-4c0a-862c-fc18a5706b78', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:06:09 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916823006806') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a33-701a-006b-4adf-94e952000000', + 'x-ms-client-request-id', + '7dcfd868-ccb8-41ae-9ab4-efd70632df39', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:09 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_write_operations.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_write_operations.js new file mode 100644 index 000000000000..f69c68f539e8 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_condition_for_write_operations.js @@ -0,0 +1,159 @@ +let nock = require('nock'); + +module.exports.hash = "44ab307e6c4bc4b593883f54024ed146"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121917079001315"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:10 GMT', + 'ETag', + '"0x8D862F6DEA02FCD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293460-d01a-0000-38df-946ea6000000', + 'x-ms-client-request-id', + '8b85d952-4720-4e12-8f77-f67ac1ebb788', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:10 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:10 GMT', + 'ETag', + '"0x8D862F6DEA02FCD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a36-701a-006b-4cdf-94e952000000', + 'x-ms-client-request-id', + '70c512fb-3dc5-4c2c-99ea-bc254edc6162', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'dbb014b6-5de2-4d8f-8c48-ed7b503b7733', + 'Date', + 'Sun, 27 Sep 2020 15:06:10 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(412, "LeaseIdMissingThere is currently a lease on the file share and no lease ID was specified in the request.\nRequestId:10293463-d01a-0000-39df-946ea6000000\nTime:2020-09-27T15:06:11.7787922Z", [ + 'Content-Length', + '273', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293463-d01a-0000-39df-946ea6000000', + 'x-ms-client-request-id', + 'f2da11ba-e110-4fae-b33c-a4d9b84d5226', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseIdMissing', + 'Date', + 'Sun, 27 Sep 2020 15:06:11 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(412, "LeaseIdMismatchWithContainerOperationThe lease ID specified did not match the lease ID for the file share.\nRequestId:09ab1a39-701a-006b-4ddf-94e952000000\nTime:2020-09-27T15:06:12.1798962Z", [ + 'Content-Length', + '275', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a39-701a-006b-4ddf-94e952000000', + 'x-ms-client-request-id', + '4967bca6-47c9-4f66-976d-3ca66d820f49', + 'x-ms-version', + '2020-02-10', + 'x-ms-error-code', + 'LeaseIdMismatchWithContainerOperation', + 'Date', + 'Sun, 27 Sep 2020 15:06:11 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:12 GMT', + 'ETag', + '"0x8D862F6DF999657"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293465-d01a-0000-3adf-946ea6000000', + 'x-ms-client-request-id', + 'a3149040-0a5c-4076-8bf1-0288f6a2709f', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:12 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121917079001315') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:12 GMT', + 'ETag', + '"0x8D862F6DF999657"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a3c-701a-006b-4fdf-94e952000000', + 'x-ms-client-request-id', + '50d3ae0e-d30b-4cf5-9146-acc879fa7011', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:06:12 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121917079001315') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293467-d01a-0000-3bdf-946ea6000000', + 'x-ms-client-request-id', + '81186509-54c8-415d-94c3-ce811b8cf620', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:12 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_properties_properly_returned.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_properties_properly_returned.js new file mode 100644 index 000000000000..d126fec48f3d --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_lease_properties_properly_returned.js @@ -0,0 +1,159 @@ +let nock = require('nock'); + +module.exports.hash = "60d3362fd95e0f8e316ba3469840044f"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121916362104227"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916362104227') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:03 GMT', + 'ETag', + '"0x8D862F6DA59F6E8"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029344a-d01a-0000-2bdf-946ea6000000', + 'x-ms-client-request-id', + '53981182-3d57-4e8a-bf16-1459ecdf02bd', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:03 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916362104227') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:03 GMT', + 'ETag', + '"0x8D862F6DA59F6E8"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a17-701a-006b-3edf-94e952000000', + 'x-ms-client-request-id', + '8f1703cf-5535-404a-928d-83698c189757', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '409a5c92-4eda-4722-818d-8545d1a6228a', + 'Date', + 'Sun, 27 Sep 2020 15:06:03 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121916362104227') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:03 GMT', + 'ETag', + '"0x8D862F6DA59F6E8"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029344d-d01a-0000-2cdf-946ea6000000', + 'x-ms-client-request-id', + 'e5ad7d9c-3aa4-46d7-8da6-8005417d2e18', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'locked', + 'x-ms-lease-state', + 'leased', + 'x-ms-lease-duration', + 'infinite', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:06:03 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-lease-duration,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:04 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/') + .query(true) + .reply(200, "share160093141210102328Thu, 24 Sep 2020 07:10:13 GMT\"0x8D86058E1C40CB2\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:10:13 GMT$account-encryption-keyfalseshare160093176153301093Thu, 24 Sep 2020 07:16:02 GMT\"0x8D86059B206C943\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:16:02 GMT$account-encryption-keyfalseshare160093195256704532Thu, 24 Sep 2020 07:19:13 GMT\"0x8D8605A23EB8F85\"unlockedavailable5120TransactionOptimizedThu, 24 Sep 2020 07:19:13 GMT$account-encryption-keyfalseshare160121233635009423Sun, 27 Sep 2020 13:12:16 GMT\"0x8D862E6F4FB4A9C\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:12:16 GMT$account-encryption-keyfalseshare160121235006600409Sun, 27 Sep 2020 13:12:30 GMT\"0x8D862E6FD28EA42\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:12:30 GMT$account-encryption-keyfalseshare160121310851508050Sun, 27 Sep 2020 13:25:09 GMT\"0x8D862E8C1F3100F\"unlockedexpired5120TransactionOptimizedSun, 27 Sep 2020 13:25:09 GMT$account-encryption-keyfalseshare160121326942502893Sun, 27 Sep 2020 13:27:50 GMT\"0x8D862E921DDD8EC\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 13:27:50 GMT$account-encryption-keyfalseshare160121389438808287Sun, 27 Sep 2020 13:38:15 GMT\"0x8D862EA966D8BBD\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 13:38:15 GMT$account-encryption-keyfalseshare160121491612400623Sun, 27 Sep 2020 13:55:16 GMT\"0x8D862ECF6A57F34\"unlockedexpired5120TransactionOptimizedSun, 27 Sep 2020 13:55:16 GMT$account-encryption-keyfalseshare160121509901107353Sun, 27 Sep 2020 13:58:19 GMT\"0x8D862ED63A7C0E3\"unlockedbroken5120TransactionOptimizedSun, 27 Sep 2020 13:58:19 GMT$account-encryption-keyfalseshare160121551221306317Sun, 27 Sep 2020 14:05:12 GMT\"0x8D862EE59F16DE2\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 14:05:12 GMT$account-encryption-keyfalseshare160121551974009496Sun, 27 Sep 2020 14:05:19 GMT\"0x8D862EE5E6E01B4\"unlockedavailable5120TransactionOptimizedSun, 27 Sep 2020 14:05:19 GMT$account-encryption-keyfalseshare160121870218806337Sun, 27 Sep 2020 14:58:23 GMT\"0x8D862F5C81E89A1\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 14:58:23 GMT$account-encryption-keyfalseshare160121916362104227Sun, 27 Sep 2020 15:06:03 GMT\"0x8D862F6DA59F6E8\"lockedleasedinfinite5120TransactionOptimizedSun, 27 Sep 2020 15:06:03 GMT$account-encryption-keyfalse", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a1c-701a-006b-40df-94e952000000', + 'x-ms-client-request-id', + 'ed5589be-b7b2-48f5-ba82-13be26968a7e', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:06:04 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916362104227') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:03 GMT', + 'ETag', + '"0x8D862F6DA59F6E8"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293450-d01a-0000-2edf-946ea6000000', + 'x-ms-client-request-id', + 'a58cb950-88f9-4298-ae10-574084530956', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:06:05 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916362104227') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a1f-701a-006b-41df-94e952000000', + 'x-ms-client-request-id', + 'd5c1978a-4687-4656-bd22-71599aa7d748', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:05 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_release_lease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_release_lease.js new file mode 100644 index 000000000000..8fd623d13ef5 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_release_lease.js @@ -0,0 +1,133 @@ +let nock = require('nock'); + +module.exports.hash = "a65d31233d61e48fa43a445144fb1bd3"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121915174409919"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915174409919') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:51 GMT', + 'ETag', + '"0x8D862F6D34596BD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19e9-701a-006b-25df-94e952000000', + 'x-ms-client-request-id', + '5df9990a-4985-4c0c-8e89-80eac0e902d6', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:51 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915174409919') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:51 GMT', + 'ETag', + '"0x8D862F6D34596BD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '1029341e-d01a-0000-15df-946ea6000000', + 'x-ms-client-request-id', + '9cae3085-e564-44d1-8551-9645498da9de', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + '0dbae786-d3e1-44dc-bf8d-b204f15f8798', + 'Date', + 'Sun, 27 Sep 2020 15:05:51 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121915174409919') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:51 GMT', + 'ETag', + '"0x8D862F6D34596BD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19ef-701a-006b-29df-94e952000000', + 'x-ms-client-request-id', + '0186484b-1d66-4a49-9d1e-ee7c9cd6ab57', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:05:51 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160121915174409919') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:05:51 GMT', + 'ETag', + '"0x8D862F6D34596BD"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293422-d01a-0000-17df-946ea6000000', + 'x-ms-client-request-id', + '12b70c9f-ff6e-4371-bc0b-684279e9a84a', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'TransactionOptimized', + 'x-ms-access-tier-change-time', + 'Sun, 27 Sep 2020 15:05:51 GMT', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Sun, 27 Sep 2020 15:05:52 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121915174409919') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab19f0-701a-006b-2adf-94e952000000', + 'x-ms-client-request-id', + '3bad43e7-1b4d-4963-aac5-20ca9aa74bc0', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:05:52 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_renew_a_lease.js b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_renew_a_lease.js new file mode 100644 index 000000000000..eb9d32da0a5c --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/leaseclient_for_share/recording_renew_a_lease.js @@ -0,0 +1,117 @@ +let nock = require('nock'); + +module.exports.hash = "c44ff11ca905a9bc01bf763e55c36b6b"; + +module.exports.testInfo = {"uniqueName":{"share":"share160121916168004389"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916168004389') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:01 GMT', + 'ETag', + '"0x8D862F6D9316731"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a0d-701a-006b-3adf-94e952000000', + 'x-ms-client-request-id', + 'ccb474c2-2540-4dac-a45b-5d97360013aa', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:00 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916168004389') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:01 GMT', + 'ETag', + '"0x8D862F6D9316731"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293444-d01a-0000-29df-946ea6000000', + 'x-ms-client-request-id', + '9d9081c1-1910-4df6-a11f-e47542dfb0d9', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:06:01 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916168004389') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:01 GMT', + 'ETag', + '"0x8D862F6D9316731"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a14-701a-006b-3cdf-94e952000000', + 'x-ms-client-request-id', + '2f91c9e9-d4fc-4ec3-94f4-83fc8e85cd61', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-id', + 'e9890485-bf47-4d9a-b3d0-aceb18506124', + 'Date', + 'Sun, 27 Sep 2020 15:06:01 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160121916168004389') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Sun, 27 Sep 2020 15:06:01 GMT', + 'ETag', + '"0x8D862F6D9316731"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '10293448-d01a-0000-2adf-946ea6000000', + 'x-ms-client-request-id', + '7960eb34-b6f4-4248-9617-7c62580717f8', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-time', + '0', + 'Date', + 'Sun, 27 Sep 2020 15:06:02 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160121916168004389') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '09ab1a16-701a-006b-3ddf-94e952000000', + 'x-ms-client-request-id', + '32b0d990-b5ed-4dbc-8f37-1ede76caf127', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Sun, 27 Sep 2020 15:06:02 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/shareclient/recording_create_share_specifying_accesstier_and_listshare.js b/sdk/storage/storage-file-share/recordings/node/shareclient/recording_create_share_specifying_accesstier_and_listshare.js new file mode 100644 index 000000000000..a8792c0e453b --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/shareclient/recording_create_share_specifying_accesstier_and_listshare.js @@ -0,0 +1,109 @@ +let nock = require('nock'); + +module.exports.hash = "696dcf230d6f213e7bcafda589c44963"; + +module.exports.testInfo = {"uniqueName":{"share":"share160223286231007564","newshare":"newshare160223286388702010"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160223286231007564') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 08:41:03 GMT', + 'ETag', + '"0x8D86C2F0E95EA45"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321ef9-901a-003e-7e17-9ef9d9000000', + 'x-ms-client-request-id', + 'b75fd907-794e-4395-a1af-e3e4d210afbf', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:02 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/newshare160223286388702010') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 08:41:04 GMT', + 'ETag', + '"0x8D86C2F0ECE69AE"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321efc-901a-003e-7f17-9ef9d9000000', + 'x-ms-client-request-id', + '9319bdab-9496-43a5-b30b-60bd9deb24c2', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:03 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/') + .query(true) + .reply(200, "newshare160223286388702010newshare160223286388702010Fri, 09 Oct 2020 08:41:04 GMT\"0x8D86C2F0ECE69AE\"unlockedavailable5120HotFri, 09 Oct 2020 08:41:04 GMT$account-encryption-keyfalse", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321efe-901a-003e-8017-9ef9d9000000', + 'x-ms-client-request-id', + '0364136a-2286-42b0-8ecc-b659911855e1', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 09 Oct 2020 08:41:03 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/newshare160223286388702010') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f00-901a-003e-0217-9ef9d9000000', + 'x-ms-client-request-id', + '082a4bf4-eae5-4924-b189-ace4b20458c5', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:03 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160223286231007564') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f03-901a-003e-0317-9ef9d9000000', + 'x-ms-client-request-id', + '71feaee9-7b0d-4a86-a1bd-ffc4afcf64e7', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:04 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/shareclient/recording_setaccesstier.js b/sdk/storage/storage-file-share/recordings/node/shareclient/recording_setaccesstier.js new file mode 100644 index 000000000000..4fdcc1fd261b --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/shareclient/recording_setaccesstier.js @@ -0,0 +1,109 @@ +let nock = require('nock'); + +module.exports.hash = "97606f0e609c7dd5b3f6d2632d8e969f"; + +module.exports.testInfo = {"uniqueName":{"share":"share160223286522402314"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160223286522402314') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 08:41:05 GMT', + 'ETag', + '"0x8D86C2F0F99CE13"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f04-901a-003e-0417-9ef9d9000000', + 'x-ms-client-request-id', + 'caeb897f-b0ee-4f12-b4c6-7aea17f48b80', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:04 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160223286522402314') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 08:41:05 GMT', + 'ETag', + '"0x8D86C2F0FCA822C"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f07-901a-003e-0617-9ef9d9000000', + 'x-ms-client-request-id', + '4c684016-8e01-4c45-b31e-2d32e05936d5', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:04 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160223286522402314') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 08:41:05 GMT', + 'ETag', + '"0x8D86C2F0FCA822C"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f08-901a-003e-0717-9ef9d9000000', + 'x-ms-client-request-id', + '876b515a-7d8e-4f3d-84e3-d7deef1b3a3c', + 'x-ms-version', + '2020-02-10', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-has-immutability-policy', + 'false', + 'x-ms-has-legal-hold', + 'false', + 'x-ms-share-quota', + '5120', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-change-time', + 'Fri, 09 Oct 2020 08:41:05 GMT', + 'x-ms-access-tier-transition-state', + 'pending-from-transactionOptimized', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-has-immutability-policy,x-ms-has-legal-hold,x-ms-share-quota,x-ms-access-tier,x-ms-access-tier-change-time,x-ms-access-tier-transition-state,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 09 Oct 2020 08:41:05 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160223286522402314') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '99321f0a-901a-003e-0917-9ef9d9000000', + 'x-ms-client-request-id', + '29dc1124-d0e4-4bdb-9b81-10b487fef1bd', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 08:41:05 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/shareclient_nodejs_only/recording_setaccesspolicy_and_getaccesspolicy_with_empty_signedidentifier.js b/sdk/storage/storage-file-share/recordings/node/shareclient_nodejs_only/recording_setaccesspolicy_and_getaccesspolicy_with_empty_signedidentifier.js new file mode 100644 index 000000000000..0b0d257f39b3 --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/shareclient_nodejs_only/recording_setaccesspolicy_and_getaccesspolicy_with_empty_signedidentifier.js @@ -0,0 +1,95 @@ +let nock = require('nock'); + +module.exports.hash = "3ebabd40f7e1e2d99e8708a8b72d7c1c"; + +module.exports.testInfo = {"uniqueName":{"share":"share160224079312107686"},"newDate":{}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160224079312107686') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 10:53:14 GMT', + 'ETag', + '"0x8D86C4185BA2A5B"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e574a944-401a-002d-6b2a-9eddd5000000', + 'x-ms-client-request-id', + 'eb2a5911-6380-4442-864a-6c70df597eae', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 10:53:14 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share160224079312107686', "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=") + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 09 Oct 2020 10:53:14 GMT', + 'ETag', + '"0x8D86C4185ED2986"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e574a947-401a-002d-6c2a-9eddd5000000', + 'x-ms-client-request-id', + '84e0844e-b5b0-4d78-bfe3-cc5d25692a35', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 10:53:14 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share160224079312107686') + .query(true) + .reply(200, "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Last-Modified', + 'Fri, 09 Oct 2020 10:53:14 GMT', + 'ETag', + '"0x8D86C4185ED2986"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e574a949-401a-002d-6e2a-9eddd5000000', + 'x-ms-client-request-id', + '147051c4-d43f-4e80-acd0-724b355fa4e2', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Last-Modified,ETag,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 09 Oct 2020 10:53:15 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share160224079312107686') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'e574a94b-401a-002d-6f2a-9eddd5000000', + 'x-ms-client-request-id', + 'a5f5debb-fc04-44c8-81a9-4d15a428c3de', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Fri, 09 Oct 2020 10:53:15 GMT' +]); diff --git a/sdk/storage/storage-file-share/review/storage-file-share.api.md b/sdk/storage/storage-file-share/review/storage-file-share.api.md index d93458f3ea8d..ef0e9da44b7b 100644 --- a/sdk/storage/storage-file-share/review/storage-file-share.api.md +++ b/sdk/storage/storage-file-share/review/storage-file-share.api.md @@ -91,6 +91,14 @@ export class AnonymousCredentialPolicy extends CredentialPolicy { export { BaseRequestPolicy } +// @public +export interface ClearRange { + // (undocumented) + end: number; + // (undocumented) + start: number; +} + // @public export interface CloseHandlesInfo { // (undocumented) @@ -142,7 +150,7 @@ export abstract class CredentialPolicy extends BaseRequestPolicy { export type CredentialPolicyCreator = (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => CredentialPolicy; // @public -export type DeleteSnapshotsOptionType = 'include'; +export type DeleteSnapshotsOptionType = 'include' | 'include-leased'; export { deserializationPolicy } @@ -682,6 +690,15 @@ export type FileGetPropertiesResponse = FileGetPropertiesHeaders & { }; }; +// @public +export type FileGetRangeListDiffResponse = ShareFileRangeList & FileGetRangeListHeaders & { + _response: coreHttp.HttpResponse & { + parsedHeaders: FileGetRangeListHeaders; + bodyAsText: string; + parsedBody: ShareFileRangeList; + }; +}; + // @public export interface FileGetRangeListHeaders { date?: Date; @@ -835,6 +852,7 @@ export interface FileServiceProperties { cors?: CorsRule[]; hourMetrics?: Metrics; minuteMetrics?: Metrics; + protocol?: ShareProtocolSettings; } // @public @@ -1071,6 +1089,7 @@ export interface LeaseOperationResponseHeaders { etag?: string; lastModified?: Date; leaseId?: string; + leaseTimeInSeconds?: number; requestId?: string; version?: string; } @@ -1301,6 +1320,9 @@ export interface ServiceUndeleteShareOptions extends CommonOptions { export interface SetPropertiesResponse extends FileSetHTTPHeadersResponse { } +// @public +export type ShareAccessTier = 'TransactionOptimized' | 'Hot' | 'Cool'; + // Warning: (ae-forgotten-export) The symbol "StorageClient" needs to be exported by the entry point index.d.ts // // @public @@ -1329,10 +1351,12 @@ export class ShareClient extends StorageClient { getDirectoryClient(directoryName: string): ShareDirectoryClient; getPermission(filePermissionKey: string, options?: ShareGetPermissionOptions): Promise; getProperties(options?: ShareGetPropertiesOptions): Promise; + getShareLeaseClient(proposeLeaseId?: string): ShareLeaseClient; getStatistics(options?: ShareGetStatisticsOptions): Promise; get name(): string; get rootDirectoryClient(): ShareDirectoryClient; setAccessPolicy(shareAcl?: SignedIdentifier[], options?: ShareSetAccessPolicyOptions): Promise; + setAccessTier(accessTier: ShareAccessTier, options?: ShareSetAccessTierOptions): Promise; setMetadata(metadata?: Metadata, options?: ShareSetMetadataOptions): Promise; setQuota(quotaInGB: number, options?: ShareSetQuotaOptions): Promise; withSnapshot(snapshot: string): ShareClient; @@ -1357,6 +1381,7 @@ export interface ShareCreateIfNotExistsResponse extends ShareCreateResponse { // @public export interface ShareCreateOptions extends CommonOptions { abortSignal?: AbortSignalLike; + accessTier?: ShareAccessTier; metadata?: { [propertyName: string]: string; }; @@ -1437,6 +1462,7 @@ export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse { export interface ShareDeleteMethodOptions extends CommonOptions { abortSignal?: AbortSignalLike; deleteSnapshots?: DeleteSnapshotsOptionType; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1486,6 +1512,7 @@ export class ShareDirectoryClient extends StorageClient { // @public export interface ShareExistsOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1506,6 +1533,7 @@ export class ShareFileClient extends StorageClient { forceCloseHandle(handleId: string, options?: FileForceCloseHandlesOptions): Promise; getProperties(options?: FileGetPropertiesOptions): Promise; getRangeList(options?: FileGetRangeListOptions): Promise; + getRangeListDiff(prevShareSnapshot: string, options?: FileGetRangeListOptions): Promise; getShareLeaseClient(proposeLeaseId?: string): ShareLeaseClient; listHandles(options?: FileListHandlesOptions): PagedAsyncIterableIterator; get name(): string; @@ -1523,6 +1551,15 @@ export class ShareFileClient extends StorageClient { uploadResetableStream(streamFactory: (offset: number, count?: number) => NodeJS.ReadableStream, size: number, options?: FileParallelUploadOptions): Promise; uploadSeekableBlob(blobFactory: (offset: number, size: number) => Blob, size: number, options?: FileParallelUploadOptions): Promise; uploadStream(stream: Readable, size: number, bufferSize: number, maxBuffers: number, options?: FileUploadStreamOptions): Promise; + withShareSnapshot(shareSnapshot: string): ShareFileClient; +} + +// @public +export interface ShareFileRangeList { + // (undocumented) + clearRanges?: ClearRange[]; + // (undocumented) + ranges?: RangeModel[]; } // @public @@ -1539,6 +1576,7 @@ export interface ShareGetAccessPolicyHeaders { // @public export interface ShareGetAccessPolicyOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public (undocumented) @@ -1577,11 +1615,17 @@ export type ShareGetPermissionResponse = SharePermission & ShareGetPermissionHea // @public export interface ShareGetPropertiesHeaders { + accessTier?: string; + accessTierChangeTime?: Date; + accessTierTransitionState?: string; date?: Date; // (undocumented) errorCode?: string; etag?: string; lastModified?: Date; + leaseDuration?: LeaseDurationType; + leaseState?: LeaseStateType; + leaseStatus?: LeaseStatusType; // (undocumented) metadata?: { [propertyName: string]: string; @@ -1598,6 +1642,7 @@ export interface ShareGetPropertiesHeaders { // @public export interface ShareGetPropertiesOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1621,6 +1666,7 @@ export interface ShareGetStatisticsHeaders { // @public export interface ShareGetStatisticsOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1657,12 +1703,13 @@ export interface ShareItem { // @public export class ShareLeaseClient { - constructor(client: ShareFileClient, leaseId?: string); + constructor(client: ShareFileClient | ShareClient, leaseId?: string); acquireLease(duration?: number, options?: LeaseOperationOptions): Promise; breakLease(options?: LeaseOperationOptions): Promise; changeLease(proposedLeaseId: string, options?: LeaseOperationOptions): Promise; get leaseId(): string; releaseLease(options?: LeaseOperationOptions): Promise; + renewLease(options?: LeaseOperationOptions): Promise; get url(): string; } @@ -1673,12 +1720,21 @@ export interface SharePermission { // @public export interface ShareProperties { + // (undocumented) + accessTier?: string; + // (undocumented) + accessTierChangeTime?: Date; + // (undocumented) + accessTierTransitionState?: string; // (undocumented) deletedTime?: Date; // (undocumented) etag: string; // (undocumented) lastModified: Date; + leaseDuration?: LeaseDurationType; + leaseState?: LeaseStateType; + leaseStatus?: LeaseStatusType; // (undocumented) nextAllowedQuotaDowngradeTime?: Date; // (undocumented) @@ -1693,6 +1749,11 @@ export interface ShareProperties { remainingRetentionDays?: number; } +// @public +export interface ShareProtocolSettings { + smb?: ShareSmbSettings; +} + // @public export class ShareSASPermissions { create: boolean; @@ -1735,6 +1796,7 @@ export interface ShareSetAccessPolicyHeaders { // @public export interface ShareSetAccessPolicyOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1744,6 +1806,12 @@ export type ShareSetAccessPolicyResponse = ShareSetAccessPolicyHeaders & { }; }; +// @public +export interface ShareSetAccessTierOptions extends CommonOptions { + abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; +} + // @public export interface ShareSetMetadataHeaders { date?: Date; @@ -1758,6 +1826,7 @@ export interface ShareSetMetadataHeaders { // @public export interface ShareSetMetadataOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public @@ -1768,7 +1837,7 @@ export type ShareSetMetadataResponse = ShareSetMetadataHeaders & { }; // @public -export interface ShareSetQuotaHeaders { +export interface ShareSetPropertiesHeaders { date?: Date; // (undocumented) errorCode?: string; @@ -1778,17 +1847,29 @@ export interface ShareSetQuotaHeaders { version?: string; } +// @public +export type ShareSetPropertiesResponse = ShareSetPropertiesHeaders & { + _response: coreHttp.HttpResponse & { + parsedHeaders: ShareSetPropertiesHeaders; + }; +}; + +// @public +export type ShareSetQuotaHeaders = ShareSetPropertiesHeaders; + // @public export interface ShareSetQuotaOptions extends CommonOptions { abortSignal?: AbortSignalLike; + leaseAccessConditions?: LeaseAccessConditions; } // @public -export type ShareSetQuotaResponse = ShareSetQuotaHeaders & { - _response: coreHttp.HttpResponse & { - parsedHeaders: ShareSetQuotaHeaders; - }; -}; +export type ShareSetQuotaResponse = ShareSetPropertiesResponse; + +// @public +export interface ShareSmbSettings { + multichannel?: SmbMultichannel; +} // @public export interface ShareStats { @@ -1811,6 +1892,11 @@ export interface SignedIdentifierModel { id: string; } +// @public +export interface SmbMultichannel { + enabled?: boolean; +} + // @public export interface SourceModifiedAccessConditions { sourceIfMatchCrc64?: Uint8Array; diff --git a/sdk/storage/storage-file-share/sample.env b/sdk/storage/storage-file-share/sample.env index 5eabd1722fed..fa2a131c708c 100644 --- a/sdk/storage/storage-file-share/sample.env +++ b/sdk/storage/storage-file-share/sample.env @@ -19,8 +19,14 @@ DIR_NAME= # change it to "record" to generate new recordings, or "live" to bypass the recorder entirely. # TEST_MODE=playback -# Used for share soft delete. +# Optional, used for share soft delete. SOFT_DELETE_ACCOUNT_NAME= SOFT_DELETE_ACCOUNT_KEY= SOFT_DELETE_STORAGE_CONNECTION_STRING= -SOFT_DELETE_ACCOUNT_SAS= \ No newline at end of file +SOFT_DELETE_ACCOUNT_SAS= + +# Optional, used for tests on premium file accounts. +PREMIUM_FILE_ACCOUNT_NAME= +PREMIUM_FILE_ACCOUNT_KEY= +PREMIUM_FILE_STORAGE_CONNECTION_STRING= +PREMIUM_FILE_ACCOUNT_SAS= diff --git a/sdk/storage/storage-file-share/src/Clients.ts b/sdk/storage/storage-file-share/src/Clients.ts new file mode 100644 index 000000000000..70d2b16694f1 --- /dev/null +++ b/sdk/storage/storage-file-share/src/Clients.ts @@ -0,0 +1,6039 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { HttpRequestBody, HttpResponse, isNode, TransferProgressEvent } from "@azure/core-http"; +import { CanonicalCode } from "@opentelemetry/api"; +import { AbortSignalLike } from "@azure/abort-controller"; +import { + CopyFileSmbInfo, + DeleteSnapshotsOptionType, + DirectoryCreateResponse, + DirectoryDeleteResponse, + DirectoryGetPropertiesResponse, + DirectoryItem, + DirectoryListFilesAndDirectoriesSegmentResponse, + DirectoryListHandlesResponse, + DirectorySetMetadataResponse, + DirectorySetPropertiesResponse, + DirectoryForceCloseHandlesHeaders, + FileAbortCopyResponse, + FileCreateResponse, + FileDeleteResponse, + FileDownloadOptionalParams, + FileDownloadResponseModel, + FileForceCloseHandlesHeaders, + FileGetPropertiesResponse, + FileGetRangeListHeaders, + FileGetRangeListDiffResponse, + FileItem, + FileListHandlesResponse, + FileSetHTTPHeadersResponse, + FileSetMetadataResponse, + FileStartCopyResponse, + FileUploadRangeFromURLResponse, + FileUploadRangeResponse, + HandleItem, + LeaseAccessConditions, + RangeModel, + ShareCreatePermissionResponse, + ShareCreateResponse, + ShareCreateSnapshotResponse, + ShareDeleteResponse, + ShareGetAccessPolicyHeaders, + ShareGetPermissionResponse, + ShareGetPropertiesResponse, + ShareGetStatisticsResponseModel, + ShareSetAccessPolicyResponse, + ShareSetMetadataResponse, + ShareSetQuotaResponse, + SignedIdentifierModel, + SourceModifiedAccessConditions, + ShareAccessTier, + ShareSetPropertiesResponse +} from "./generatedModels"; +import { Share, Directory, File } from "./generated/src/operations"; +import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; +import { + DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS, + DEFAULT_HIGH_LEVEL_CONCURRENCY, + FILE_MAX_SIZE_BYTES, + FILE_RANGE_MAX_SIZE_BYTES, + URLConstants +} from "./utils/constants"; +import { + appendToURLPath, + setURLParameter, + truncatedISO8061Date, + extractConnectionStringParts, + getShareNameAndPathFromUrl +} from "./utils/utils.common"; +import { Credential } from "./credentials/Credential"; +import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; +import { AnonymousCredential } from "./credentials/AnonymousCredential"; +import { createSpan } from "./utils/tracing"; +import { StorageClient, CommonOptions } from "./StorageClient"; +import "@azure/core-paging"; +import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; +import { FileSystemAttributes } from "./FileSystemAttributes"; +import { FileDownloadResponse } from "./FileDownloadResponse"; +import { Range, rangeToString } from "./Range"; +import { + CloseHandlesInfo, + FileAndDirectoryCreateCommonOptions, + FileAndDirectorySetPropertiesCommonOptions, + fileAttributesToString, + fileCreationTimeToString, + FileHttpHeaders, + fileLastWriteTimeToString, + Metadata, + validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions, + validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions +} from "./models"; +import { Batch } from "./utils/Batch"; +import { BufferScheduler } from "./utils/BufferScheduler"; +import { Readable } from "stream"; +import { + fsStat, + fsCreateReadStream, + readStreamToLocalFile, + streamToBuffer +} from "./utils/utils.node"; +import { StorageClientContext } from "./generated/src/storageClientContext"; +import { SERVICE_VERSION } from "./utils/constants"; +import { generateUuid } from "@azure/core-http"; + +/** + * Options to configure the {@link ShareClient.create} operation. + * + * @export + * @interface ShareCreateOptions + */ +export interface ShareCreateOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareCreateOptions + */ + abortSignal?: AbortSignalLike; + /** + * A name-value pair to associate with a file storage object. + * + * @type {{ [propertyName: string]: string }} + * @memberof ShareCreateOptions + */ + metadata?: { [propertyName: string]: string }; + + /** + * Specifies the maximum size of the share, in + * gigabytes. + * + * @type {number} + * @memberof ShareCreateOptions + */ + quota?: number; + + /** + * Specifies the access tier of the share. Possible values include: 'TransactionOptimized', + * 'Hot', 'Cool' + * @type {ShareAccessTier} + * @memberof ShareCreateOptions + */ + accessTier?: ShareAccessTier; +} + +/** + * Options to configure the {@link ShareClient.delete} operation. + * + * @export + * @interface ShareDeleteMethodOptions + */ +export interface ShareDeleteMethodOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareDeleteMethodOptions + */ + abortSignal?: AbortSignalLike; + /** + * Specifies the option + * include to delete the base share and all of its snapshots. Possible values + * include: 'include' + * + * @type {DeleteSnapshotsOptionType} + * @memberof ShareDeleteMethodOptions + */ + deleteSnapshots?: DeleteSnapshotsOptionType; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareDeleteMethodOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.setMetadata} operation. + * + * @export + * @interface ShareSetMetadataOptions + */ +export interface ShareSetMetadataOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareSetMetadataOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareSetMetadataOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.setAccessPolicy} operation. + * + * @export + * @interface ShareSetAccessPolicyOptions + */ +export interface ShareSetAccessPolicyOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareSetAccessPolicyOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareSetAccessPolicyOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.getAccessPolicy} operation. + * + * @export + * @interface ShareGetAccessPolicyOptions + */ +export interface ShareGetAccessPolicyOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareGetAccessPolicyOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareGetAccessPolicyOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.exists} operation. + * + * @export + * @interface ShareExistsOptions + */ +export interface ShareExistsOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareExistsOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareExistsOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.getProperties} operation. + * + * @export + * @interface ShareGetPropertiesOptions + */ +export interface ShareGetPropertiesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareGetPropertiesOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareGetPropertiesOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.setQuota} operation. + * + * @export + * @interface ShareSetQuotaOptions + */ +export interface ShareSetQuotaOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareSetQuotaOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareSetQuotaOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.setAccessTier} operation. + * + * @export + * @interface ShareSetAccessTierOptions + */ +export interface ShareSetAccessTierOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareSetAccessTierOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareSetAccessTierOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareClient.getStatistics} operation. + * + * @export + * @interface ShareGetStatisticsOptions + */ +export interface ShareGetStatisticsOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareGetStatisticsOptions + */ + abortSignal?: AbortSignalLike; + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this ID. + * + * @type {LeaseAccessConditions} + * @memberof ShareGetStatisticsOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Signed Identifier + * + * @export + * @interface SignedIdentifier + */ +export interface SignedIdentifier { + /** + * @member {string} id a unique id + */ + id: string; + /** + * @member {AccessPolicy} accessPolicy + */ + accessPolicy: { + /** + * @member {Date} startsOn the date-time the policy is active. + */ + startsOn: Date; + /** + * @member {string} expiresOn the date-time the policy expires. + */ + expiresOn: Date; + /** + * @member {string} permissions the permissions for the acl policy + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl + */ + permissions: string; + }; +} + +export declare type ShareGetAccessPolicyResponse = { + signedIdentifiers: SignedIdentifier[]; +} & ShareGetAccessPolicyHeaders & { + /** + * The underlying HTTP response. + */ + _response: HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareGetAccessPolicyHeaders; + /** + * The response body as text (string format) + */ + bodyAsText: string; + /** + * The response body as parsed JSON or XML + */ + parsedBody: SignedIdentifierModel[]; + }; + }; + +/** + * Options to configure the {@link ShareClient.createSnapshot} operation. + * + * @export + * @interface ShareCreateSnapshotOptions + */ +export interface ShareCreateSnapshotOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareCreateSnapshotOptions + */ + abortSignal?: AbortSignalLike; + /** + * A name-value pair to associate with a file storage object. + * + * @type {{ [propertyName: string]: string }} + * @memberof ShareCreateOptions + */ + metadata?: { [propertyName: string]: string }; +} + +/** + * Options to configure the {@link ShareClient.createPermission} operation. + * + * @export + * @interface ShareCreatePermissionOptions + */ +export interface ShareCreatePermissionOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareCreatePermissionOptions + */ + abortSignal?: AbortSignalLike; +} +/** + * Options to configure the {@link ShareClient.getPermission} operation. + * + * @export + * @interface ShareGetPermissionOptions + */ +export interface ShareGetPermissionOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof ShareGetPermissionOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Response data for the {@link ShareClient.getStatistics} Operation. + * + * @export + * @interface ShareGetStatisticsResponse + */ +export type ShareGetStatisticsResponse = ShareGetStatisticsResponseModel & { + /** + * @deprecated shareUsage is going to be deprecated. Please use ShareUsageBytes instead. + * + * The approximate size of the data stored on the share, rounded up to the nearest gigabyte. Note + * that this value may not include all recently created or recently resized files. + * + * @type {number} + * @memberof ShareGetStatisticsResponse + */ + shareUsage: number; +}; + +/** + * Contains response data for the {@link ShareClient.createIfNotExists} operation. + * + * @export + * @interface ShareCreateIfNotExistsResponse + */ +export interface ShareCreateIfNotExistsResponse extends ShareCreateResponse { + /** + * Indicate whether the share is successfully created. Is false when the share is not changed as it already exists. + * + * @type {boolean} + * @memberof ShareCreateIfNotExistsResponse + */ + succeeded: boolean; +} + +/** + * Contains response data for the {@link ShareClient.deleteIfExists} operation. + * + * @export + * @interface ShareDeleteIfExistsResponse + */ +export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse { + /** + * Indicate whether the share is successfully deleted. Is false if the share does not exist in the first place. + * + * @type {boolean} + * @memberof ShareDeleteIfExistsResponse + */ + succeeded: boolean; +} + +/** + * A ShareClient represents a URL to the Azure Storage share allowing you to manipulate its directories and files. + * + * @export + * @class ShareClient + */ +export class ShareClient extends StorageClient { + /** + * Share operation context provided by protocol layer. + * + * @private + * @type {Share} + * @memberof ShareClient + */ + private context: Share; + + private _name: string; + + /** + * The name of the share + * + * @type {string} + * @memberof ShareClient + */ + public get name(): string { + return this._name; + } + + /** + * @param {string} connectionString Account connection string or a SAS connection string of an Azure storage account. + * [ Note - Account connection string can only be used in NODE.JS runtime. ] + * Account connection string example - + * `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net` + * SAS connection string example - + * `BlobEndpoint=https://myaccount.blob.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString` + * @param {string} name Share name. + * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. + * @memberof ShareClient + */ + constructor(connectionString: string, name: string, options?: StoragePipelineOptions); + /** + * Creates an instance of ShareClient. + * + * @param {string} url A URL string pointing to Azure Storage file share, such as + * "https://myaccount.file.core.windows.net/share". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/share?sasString". + * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. + * If not specified, AnonymousCredential is used. + * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. + * @memberof ShareClient + */ + constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); + /** + * Creates an instance of ShareClient. + * + * @param {string} url A URL string pointing to Azure Storage file share, such as + * "https://myaccount.file.core.windows.net/share". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/share?sasString". + * @param {Pipeline} pipeline Call newPipeline() to create a default + * pipeline, or provide a customized pipeline. + * @memberof ShareClient + */ + constructor(url: string, pipeline: Pipeline); + constructor( + urlOrConnectionString: string, + credentialOrPipelineOrShareName?: Credential | Pipeline | string, + options?: StoragePipelineOptions + ) { + let pipeline: Pipeline; + let url: string; + if (credentialOrPipelineOrShareName instanceof Pipeline) { + // (url: string, pipeline: Pipeline) + url = urlOrConnectionString; + pipeline = credentialOrPipelineOrShareName; + } else if (credentialOrPipelineOrShareName instanceof Credential) { + // (url: string, credential?: Credential, options?: StoragePipelineOptions) + url = urlOrConnectionString; + pipeline = newPipeline(credentialOrPipelineOrShareName, options); + } else if ( + !credentialOrPipelineOrShareName && + typeof credentialOrPipelineOrShareName !== "string" + ) { + // (url: string, credential?: Credential, options?: StoragePipelineOptions) + // The second parameter is undefined. Use anonymous credential. + url = urlOrConnectionString; + pipeline = newPipeline(new AnonymousCredential(), options); + } else if ( + credentialOrPipelineOrShareName && + typeof credentialOrPipelineOrShareName === "string" + ) { + // (connectionString: string, name: string, options?: StoragePipelineOptions) + const extractedCreds = extractConnectionStringParts(urlOrConnectionString); + const name = credentialOrPipelineOrShareName; + if (extractedCreds.kind === "AccountConnString") { + if (isNode) { + const sharedKeyCredential = new StorageSharedKeyCredential( + extractedCreds.accountName!, + extractedCreds.accountKey + ); + url = appendToURLPath(extractedCreds.url, name); + pipeline = newPipeline(sharedKeyCredential, options); + } else { + throw new Error("Account connection string is only supported in Node.js environment"); + } + } else if (extractedCreds.kind === "SASConnString") { + url = appendToURLPath(extractedCreds.url, name) + "?" + extractedCreds.accountSas; + pipeline = newPipeline(new AnonymousCredential(), options); + } else { + throw new Error( + "Connection string must be either an Account connection string or a SAS connection string" + ); + } + } else { + throw new Error("Expecting non-empty strings for name parameter"); + } + super(url, pipeline); + this._name = getShareNameAndPathFromUrl(this.url).shareName; + this.context = new Share(this.storageClientContext); + } + + /** + * Creates a new ShareClient object identical to the source but with the specified snapshot timestamp. + * Provide "" will remove the snapshot and return a URL to the base share. + * + * @param {string} snapshot The snapshot timestamp. + * @returns {ShareClient} A new ShareClient object identical to the source but with the specified snapshot timestamp + * @memberof ShareClient + */ + public withSnapshot(snapshot: string): ShareClient { + return new ShareClient( + setURLParameter( + this.url, + URLConstants.Parameters.SHARE_SNAPSHOT, + snapshot.length === 0 ? undefined : snapshot + ), + this.pipeline + ); + } + + /** + * Creates a new share under the specified account. If the share with + * the same name already exists, the operation fails. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share + * + * @param {ShareCreateOptions} [options] Options to Share Create operation. + * @returns {Promise} Response data for the Share Create operation. + * @memberof ShareClient + */ + public async create(options: ShareCreateOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareClient-create", options.tracingOptions); + try { + return await this.context.create({ + ...options, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a new share under the specified account. If the share with + * the same name already exists, it is not changed. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share + * + * @param {ShareCreateOptions} [options] + * @returns {Promise} + * @memberof ShareClient + */ + public async createIfNotExists( + options: ShareCreateOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareClient-createIfNotExists", + options.tracingOptions + ); + try { + const res = await this.create({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + succeeded: true, + ...res + }; + } catch (e) { + if (e.details?.errorCode === "ShareAlreadyExists") { + span.setStatus({ + code: CanonicalCode.ALREADY_EXISTS, + message: "Expected exception when creating a share only if it doesn't already exist." + }); + return { + succeeded: false, + ...e.response?.parsedHeaders, + _response: e.response + }; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a {@link ShareDirectoryClient} object. + * + * @param directoryName A directory name + * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given directory name. + * @memberof ShareClient + */ + public getDirectoryClient(directoryName: string): ShareDirectoryClient { + return new ShareDirectoryClient( + appendToURLPath(this.url, encodeURIComponent(directoryName)), + this.pipeline + ); + } + + /** + * Gets the directory client for the root directory of this share. + * Note that the root directory always exists and cannot be deleted. + * + * @readonly + * @type {ShareDirectoryClient} A new ShareDirectoryClient object for the root directory. + * @memberof ShareClient + */ + public get rootDirectoryClient(): ShareDirectoryClient { + return this.getDirectoryClient(""); + } + + /** + * Creates a new subdirectory under this share. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory + * + * @param {string} directoryName + * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. + * @returns {Promise<{ directoryClient: ShareDirectoryClient, directoryCreateResponse: DirectoryCreateResponse }>} Directory creation response data and the corresponding directory client. + * @memberof ShareClient + */ + public async createDirectory( + directoryName: string, + options: DirectoryCreateOptions = {} + ): Promise<{ + directoryClient: ShareDirectoryClient; + directoryCreateResponse: DirectoryCreateResponse; + }> { + const { span, spanOptions } = createSpan("ShareClient-createDirectory", options.tracingOptions); + try { + const directoryClient = this.getDirectoryClient(directoryName); + const directoryCreateResponse = await directoryClient.create({ + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + return { + directoryClient, + directoryCreateResponse + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the specified empty sub directory under this share. + * Note that the directory must be empty before it can be deleted. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory + * + * @param {string} directoryName + * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. + * @returns {Promise} Directory deletion response data. + * @memberof ShareClient + */ + public async deleteDirectory( + directoryName: string, + options: DirectoryDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-deleteDirectory", options.tracingOptions); + try { + const directoryClient = this.getDirectoryClient(directoryName); + return await directoryClient.delete({ + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a new file or replaces a file under the root directory of this share. + * Note it only initializes the file with no content. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file + * + * @param {string} fileName + * @param {number} size Specifies the maximum size in bytes for the file, up to 4 TB. + * @param {FileCreateOptions} [options] Options to File Create operation. + * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client. + * @memberof ShareClient + */ + public async createFile( + fileName: string, + size: number, + options: FileCreateOptions = {} + ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> { + const { span, spanOptions } = createSpan("ShareClient-createFile", options.tracingOptions); + try { + const directoryClient = this.rootDirectoryClient; + const fileClient = directoryClient.getFileClient(fileName); + const fileCreateResponse = await fileClient.create(size, { + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + return { + fileClient, + fileCreateResponse + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes a file under the root directory of this share from the storage account. + * When a file is successfully deleted, it is immediately removed from the storage + * account's index and is no longer accessible to clients. The file's data is later + * removed from the service during garbage collection. + * + * Delete File will fail with status code 409 (Conflict) and error code `SharingViolation` + * if the file is open on an SMB client. + * + * Delete File is not supported on a share snapshot, which is a read-only copy of + * a share. An attempt to perform this operation on a share snapshot will fail with 400 + * (`InvalidQueryParameterValue`) + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 + * + * @param {string} directoryName + * @param {string} fileName + * @param {FileDeleteOptions} [options] Options to File Delete operation. + * @returns Promise File Delete response data. + * @memberof ShareClient + */ + public async deleteFile( + fileName: string, + options: FileDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-deleteFile", options.tracingOptions); + try { + const directoryClient = this.rootDirectoryClient; + const fileClient = directoryClient.getFileClient(fileName); + return await fileClient.delete({ + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns true if the Azrue share resource represented by this client exists; false otherwise. + * + * NOTE: use this function with care since an existing share might be deleted by other clients or + * applications. Vice versa new shares might be added by other clients or applications after this + * function completes. + * + * @param {ShareExistsOptions} [options] options to Exists operation. + * @returns {Promise} + * @memberof ShareClient + */ + public async exists(options: ShareExistsOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareClient-exists", options.tracingOptions); + try { + await this.getProperties({ + ...options, + tracingOptions: { ...options.tracingOptions, spanOptions } + }); + return true; + } catch (e) { + if (e.statusCode === 404) { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when checking share existence" + }); + return false; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns all user-defined metadata and system properties for the specified + * share. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-properties + * + * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if + * they originally contained uppercase characters. This differs from the metadata keys returned by + * the `listShares` method of {@link ShareServiceClient} using the `includeMetadata` option, which + * will retain their original casing. + * + * @returns {Promise} Response data for the Share Get Properties operation. + * @memberof ShareClient + */ + public async getProperties( + options: ShareGetPropertiesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-getProperties", options.tracingOptions); + try { + return await this.context.getProperties({ + ...options, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Marks the specified share for deletion. The share and any directories or files + * contained within it are later deleted during garbage collection. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share + * + * @param {ShareDeleteMethodOptions} [options] Options to Share Delete operation. + * @returns {Promise} Response data for the Share Delete operation. + * @memberof ShareClient + */ + public async delete(options: ShareDeleteMethodOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareClient-delete", options.tracingOptions); + try { + return await this.context.deleteMethod({ + ...options, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Marks the specified share for deletion if it exists. The share and any directories or files + * contained within it are later deleted during garbage collection. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share + * + * @param {ShareDeleteMethodOptions} [options] + * @returns {Promise} + * @memberof ShareClient + */ + public async deleteIfExists( + options: ShareDeleteMethodOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-deleteIfExists", options.tracingOptions); + try { + const res = await this.delete({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + succeeded: true, + ...res + }; + } catch (e) { + if (e.details?.errorCode === "ShareNotFound") { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when deleting a share only if it exists." + }); + return { + succeeded: false, + ...e.response?.parsedHeaders, + _response: e.response + }; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets one or more user-defined name-value pairs for the specified share. + * + * If no option provided, or no metadata defined in the option parameter, the share + * metadata will be removed. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-metadata + * + * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed. + * @param {ShareSetMetadataOptions} [option] Options to Share Set Metadata operation. + * @returns {Promise} Response data for the Share Set Metadata operation. + * @memberof ShareClient + */ + public async setMetadata( + metadata?: Metadata, + options: ShareSetMetadataOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-setMetadata", options.tracingOptions); + try { + return await this.context.setMetadata({ + ...options, + metadata, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Gets the permissions for the specified share. The permissions indicate + * whether share data may be accessed publicly. + * + * WARNING: JavaScript Date will potential lost precision when parsing start and expiry string. + * For example, new Date("2018-12-31T03:44:23.8827891Z").toISOString() will get "2018-12-31T03:44:23.882Z". + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-acl + * + * @param {ShareGetAccessPolicyOptions} [option] Options to Share Get Access Policy operation. + * @returns {Promise} Response data for the Share Get Access Policy operation. + * @memberof ShareClient + */ + public async getAccessPolicy( + options: ShareGetAccessPolicyOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-getAccessPolicy", options.tracingOptions); + try { + const response = await this.context.getAccessPolicy({ + ...options, + spanOptions + }); + + const res: ShareGetAccessPolicyResponse = { + _response: response._response, + date: response.date, + etag: response.etag, + lastModified: response.lastModified, + requestId: response.requestId, + signedIdentifiers: [], + version: response.version + }; + + for (const identifier of response) { + let accessPolicy: any = undefined; + if (identifier.accessPolicy) { + accessPolicy = { + permissions: identifier.accessPolicy.permissions + }; + + if (identifier.accessPolicy.expiresOn) { + accessPolicy.expiresOn = new Date(identifier.accessPolicy.expiresOn); + } + + if (identifier.accessPolicy.startsOn) { + accessPolicy.startsOn = new Date(identifier.accessPolicy.startsOn); + } + } + + res.signedIdentifiers.push({ + accessPolicy, + id: identifier.id + }); + } + + return res; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets the permissions for the specified share. The permissions indicate + * whether directories or files in a share may be accessed publicly. + * + * When you set permissions for a share, the existing permissions are replaced. + * If no shareAcl provided, the existing share ACL will be + * removed. + * + * When you establish a stored access policy on a share, it may take up to 30 seconds to take effect. + * During this interval, a shared access signature that is associated with the stored access policy will + * fail with status code 403 (Forbidden), until the access policy becomes active. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl + * + * @param {SignedIdentifier[]} [shareAcl] Array of signed identifiers, each having a unique Id and details of access policy. + * @param {ShareSetAccessPolicyOptions} [option] Options to Share Set Access Policy operation. + * @returns {Promise} Response data for the Share Set Access Policy operation. + * @memberof ShareClient + */ + public async setAccessPolicy( + shareAcl?: SignedIdentifier[], + options: ShareSetAccessPolicyOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-setAccessPolicy", options.tracingOptions); + try { + const acl: SignedIdentifierModel[] = []; + for (const identifier of shareAcl || []) { + acl.push({ + accessPolicy: { + expiresOn: identifier.accessPolicy?.expiresOn + ? truncatedISO8061Date(identifier.accessPolicy.expiresOn) + : undefined, + permissions: identifier.accessPolicy?.permissions, + startsOn: identifier.accessPolicy?.startsOn + ? truncatedISO8061Date(identifier.accessPolicy.startsOn) + : undefined + }, + id: identifier.id + }); + } + + return await this.context.setAccessPolicy({ + ...options, + shareAcl: acl, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a read-only snapshot of a share. + * + * @param {ShareCreateSnapshotOptions} [options={}] Options to Share Create Snapshot operation. + * @returns {Promise} Response data for the Share Create Snapshot operation. + * @memberof ShareClient + */ + public async createSnapshot( + options: ShareCreateSnapshotOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-createSnapshot", options.tracingOptions); + try { + return await this.context.createSnapshot({ + abortSignal: options.abortSignal, + ...options, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets quota for the specified share. + * + * @param {number} quotaInGB Specifies the maximum size of the share in gigabytes + * @param {ShareSetQuotaOptions} [option] Options to Share Set Quota operation. + * @returns {Promise} Response data for the Share Get Quota operation. + * @memberof ShareClient + */ + public async setQuota( + quotaInGB: number, + options: ShareSetQuotaOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-setQuota", options.tracingOptions); + try { + if (quotaInGB <= 0 || quotaInGB > 5120) { + throw new RangeError( + `Share quota must be greater than 0, and less than or equal to 5Tib (5120GB)` + ); + } + return await this.context.setProperties({ + ...options, + quota: quotaInGB, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets access tier of the share. + * + * @param {ShareAccessTier} accessTier Access tier to set on the share. + * @param {ShareSetAccessTierOptions} [option] Options to Share Set Quota operation. + * @returns {Promise} Response data for the Share Get Quota operation. + * @memberof ShareClient + */ + public async setAccessTier( + accessTier: ShareAccessTier, + options: ShareSetAccessTierOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-setAccessTier", options.tracingOptions); + try { + return await this.context.setProperties({ + ...options, + accessTier, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Retrieves statistics related to the share. + * + * @param {ShareGetStatisticsOptions} [option] Options to Share Get Statistics operation. + * @returns {Promise} Response data for the Share Get Statistics operation. + * @memberof ShareClient + */ + public async getStatistics( + options: ShareGetStatisticsOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-getStatistics", options.tracingOptions); + try { + const response = await this.context.getStatistics({ + ...options, + spanOptions + }); + + const GBBytes = 1024 * 1024 * 1024; + return { ...response, shareUsage: Math.ceil(response.shareUsageBytes / GBBytes) }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a file permission (a security descriptor) at the share level. + * The created security descriptor can be used for the files/directories in the share. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-permission + * + * @param {ShareCreatePermissionOptions} [options] Options to Share Create Permission operation. + * @param filePermission File permission described in the SDDL + */ + public async createPermission( + filePermission: string, + options: ShareCreatePermissionOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareClient-createPermission", + options.tracingOptions + ); + try { + return await this.context.createPermission( + { + permission: filePermission + }, + { + abortSignal: options.abortSignal, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Gets the Security Descriptor Definition Language (SDDL) for a given file permission key + * which indicates a security descriptor. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-permission + * + * @param {ShareGetPermissionOptions} [options] Options to Share Create Permission operation. + * @param filePermissionKey File permission key which indicates the security descriptor of the permission. + */ + public async getPermission( + filePermissionKey: string, + options: ShareGetPermissionOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareClient-getPermission", options.tracingOptions); + try { + return await this.context.getPermission(filePermissionKey, { + aborterSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Get a {@link ShareLeaseClient} that manages leases on the share. + * + * @param {string} [proposeLeaseId] Initial proposed lease Id. + * @returns {ShareLeaseClient} A new ShareLeaseClient object for managing leases on the share. + * @memberof ShareClient + */ + public getShareLeaseClient(proposeLeaseId?: string) { + return new ShareLeaseClient(this, proposeLeaseId); + } +} + +/** + * Options to configure {@link ShareDirectoryClient.create} operation. + * + * @export + * @interface DirectoryCreateOptions + */ +export interface DirectoryCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryCreateOptions + */ + abortSignal?: AbortSignalLike; + /** + * A collection of key-value string pair to associate with the file storage object. + * + * @type {Metadata} + * @memberof DirectoryCreateOptions + */ + metadata?: Metadata; +} + +export interface DirectoryProperties + extends FileAndDirectorySetPropertiesCommonOptions, + CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryProperties + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure Directory - List Files and Directories Segment operations. + * + * See: + * - {@link ShareDirectoryClient.iterateFilesAndDirectoriesSegments} + * - {@link ShareDirectoryClient.listFilesAndDirectoriesItems} + * - {@link ShareDirectoryClient.listFilesAndDirectoriesSegment} + * + * @interface DirectoryListFilesAndDirectoriesSegmentOptions + */ +interface DirectoryListFilesAndDirectoriesSegmentOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryListFilesAndDirectoriesSegmentOptions + */ + abortSignal?: AbortSignalLike; + /** + * Filters the results to return only entries whose + * name begins with the specified prefix. + * + * @type {string} + * @memberof DirectoryListFilesAndDirectoriesSegmentOptions + */ + prefix?: string; + + /** + * Specifies the maximum number of entries to + * return. If the request does not specify maxResults, or specifies a value + * greater than 5,000, the server will return up to 5,000 items. + * + * @type {number} + * @memberof DirectoryListFilesAndDirectoriesSegmentOptions + */ + maxResults?: number; +} + +/** + * Options to configure {@link ShareDirectoryClient.listFilesAndDirectories} operation. + * + * @export + * @interface DirectoryListFilesAndDirectoriesOptions + */ +export interface DirectoryListFilesAndDirectoriesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryListFilesAndDirectoriesOptions + */ + abortSignal?: AbortSignalLike; + /** + * Filters the results to return only entries whose + * name begins with the specified prefix. + * + * @type {string} + * @memberof DirectoryListFilesAndDirectoriesOptions + */ + prefix?: string; +} + +/** + * Options to configure the {@link ShareDirectoryClient.delete} operation. + * + * @export + * @interface DirectoryDeleteOptions + */ +export interface DirectoryDeleteOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryDeleteOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure the {@link ShareDirectoryClient.exists} operation. + * + * @export + * @interface DirectoryExistsOptions + */ +export interface DirectoryExistsOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryExistsOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure the {@link ShareDirectoryClient.getProperties} operation. + * + * @export + * @interface DirectoryGetPropertiesOptions + */ +export interface DirectoryGetPropertiesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryGetPropertiesOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure the {@link ShareDirectoryClient.setMetadata} operation. + * + * @export + * @interface DirectorySetMetadataOptions + */ +export interface DirectorySetMetadataOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectorySetMetadataOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure Directory - List Handles Segment operations. + * + * See: + * - {@link ShareDirectoryClient.listHandlesSegment} + * - {@link ShareDirectoryClient.iterateHandleSegments} + * - {@link ShareDirectoryClient.listHandleItems} + * + * + * @export + * @interface DirectoryListHandlesSegmentOptions + */ +export interface DirectoryListHandlesSegmentOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryListHandlesSegmentOptions + */ + abortSignal?: AbortSignalLike; + /** + * Specifies the maximum number of entries to return. If the request does not specify maxResults, + * or specifies a value greater than 5,000, the server will return up to 5,000 items. + * + * @type {number} + * @memberof DirectoryListHandlesSegmentOptions + */ + maxResults?: number; + /** + * Specifies operation should apply to the directory specified in the URI, its files, its + * subdirectories and their files. + * + * @type {boolean} + * @memberof DirectoryListHandlesSegmentOptions + */ + recursive?: boolean; +} + +/** + * Options to configure the {@link ShareDirectoryClient.listHandles} operation. + * + * @export + * @interface DirectoryListHandlesOptions + */ +export interface DirectoryListHandlesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryListHandlesOptions + */ + abortSignal?: AbortSignalLike; + /** + * Specifies whether operation should apply to the directory specified in the URI, its files, its + * subdirectories and their files. + * + * @type {boolean} + * @memberof DirectoryListHandlesOptions + */ + recursive?: boolean; +} + +/** + * Options to configure Directory - Force Close Handles Segment operations. + * + * See: + * - {@link ShareDirectoryClient.forceCloseHandlesSegment} + * - {@link ShareDirectoryClient.forceCloseAllHandles} + * + * @export + * @interface DirectoryForceCloseHandlesSegmentOptions + */ +export interface DirectoryForceCloseHandlesSegmentOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryForceCloseHandlesSegmentOptions + */ + abortSignal?: AbortSignalLike; + /** + * Specifies operation should apply to the directory specified in the URI, its files, its + * subdirectories and their files. + * + * @type {boolean} + * @memberof DirectoryForceCloseHandlesSegmentOptions + */ + recursive?: boolean; +} + +/** + * Additional response header values for close handles request. + */ +export interface DirectoryCloseHandlesHeaders { + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + /** + * A UTC date/time value generated by the service that indicates the time at which the response + * was initiated. + */ + date?: Date; + /** + * A string describing next handle to be closed. It is returned when more handles need to be + * closed to complete the request. + */ + marker?: string; +} + +/** + * Response type for {@link ShareDirectoryClient.forceCloseHandle}. + */ +export type DirectoryForceCloseHandlesResponse = CloseHandlesInfo & + DirectoryCloseHandlesHeaders & { + /** + * The underlying HTTP response. + */ + _response: HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: DirectoryForceCloseHandlesHeaders; + }; + }; + +/** + * Options to configure {@link ShareDirectoryClient.forceCloseHandle}. + * + * @export + * @interface DirectoryForceCloseHandlesOptions + */ +export interface DirectoryForceCloseHandlesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof DirectoryForceCloseHandlesOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Contains response data for the {@link DirectoryClient.createIfNotExists} operation. + * + * @export + * @interface DirectoryCreateIfNotExistsResponse + */ +export interface DirectoryCreateIfNotExistsResponse extends DirectoryCreateResponse { + /** + * Indicate whether the directory is successfully created. Is false when the directory is not changed as it already exists. + * + * @type {boolean} + * @memberof DirectoryCreateIfNotExistsResponse + */ + succeeded: boolean; +} + +/** + * Contains response data for the {@link DirectoryClient.deleteIfExists} operation. + * + * @export + * @interface DirectoryDeleteIfExistsResponse + */ +export interface DirectoryDeleteIfExistsResponse extends DirectoryDeleteResponse { + /** + * Indicate whether the directory is successfully deleted. Is false if the directory does not exist in the first place. + * + * @type {boolean} + * @memberof DirectoryDeleteIfExistsResponse + */ + succeeded: boolean; +} + +/** + * A ShareDirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories. + * + * @export + * @class ShareDirectoryClient + */ +export class ShareDirectoryClient extends StorageClient { + /** + * context provided by protocol layer. + * + * @private + * @type {Directory} + * @memberof ShareDirectoryClient + */ + private context: Directory; + + private _shareName: string; + private _path: string; + private _name: string; + + /** + * The share name corresponding to this directory client + * + * @type {string} + * @memberof ShareDirectoryClient + */ + public get shareName(): string { + return this._shareName; + } + + /** + * The full path of the directory + * + * @type {string} + * @memberof ShareDirectoryClient + */ + public get path(): string { + return this._path; + } + + /** + * The name of the directory + * + * @type {string} + * @memberof ShareDirectoryClient + */ + public get name(): string { + return this._name; + } + + /** + * Creates an instance of DirectoryClient. + * + * @param {string} url A URL string pointing to Azure Storage file directory, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString". + * This method accepts an encoded URL or non-encoded URL pointing to a directory. + * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. + * However, if a directory name includes %, directory name must be encoded in the URL. + * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25". + * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. + * If not specified, AnonymousCredential is used. + * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. + * @memberof ShareDirectoryClient + */ + constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); + /** + * Creates an instance of DirectoryClient. + * + * @param {string} url A URL string pointing to Azure Storage file directory, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString". + * This method accepts an encoded URL or non-encoded URL pointing to a directory. + * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. + * However, if a directory name includes %, directory name must be encoded in the URL. + * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25". + * @param {Pipeline} pipeline Call newPipeline() to create a default + * pipeline, or provide a customized pipeline. + * @memberof ShareDirectoryClient + */ + constructor(url: string, pipeline: Pipeline); + constructor( + url: string, + credentialOrPipeline?: Credential | Pipeline, + options: StoragePipelineOptions = {} + ) { + let pipeline: Pipeline; + if (credentialOrPipeline instanceof Pipeline) { + pipeline = credentialOrPipeline; + } else if (credentialOrPipeline instanceof Credential) { + pipeline = newPipeline(credentialOrPipeline, options); + } else { + // The second parameter is undefined. Use anonymous credential. + pipeline = newPipeline(new AnonymousCredential(), options); + } + + super(url, pipeline); + ({ + baseName: this._name, + shareName: this._shareName, + path: this._path + } = getShareNameAndPathFromUrl(this.url)); + this.context = new Directory(this.storageClientContext); + } + + /** + * Creates a new directory under the specified share or parent directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory + * + * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. + * @returns {Promise} Response data for the Directory operation. + * @memberof ShareDirectoryClient + */ + public async create(options: DirectoryCreateOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareDirectoryClient-create", options.tracingOptions); + try { + if (!options.fileAttributes) { + options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options); + // By default set it as a directory. + const attributes: FileSystemAttributes = new FileSystemAttributes(); + attributes.directory = true; + options.fileAttributes = attributes; + } + + return await this.context.create( + fileAttributesToString(options.fileAttributes!), + fileCreationTimeToString(options.creationTime!), + fileLastWriteTimeToString(options.lastWriteTime!), + { + abortSignal: options.abortSignal, + metadata: options.metadata, + filePermission: options.filePermission, + filePermissionKey: options.filePermissionKey, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a new directory under the specified share or parent directory if it does not already exists. + * If the directory already exists, it is not modified. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory + * + * @param {DirectoryCreateOptions} [options] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async createIfNotExists( + options: DirectoryCreateOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-createIfNotExists", + options.tracingOptions + ); + try { + const res = await this.create({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + succeeded: true, + ...res + }; + } catch (e) { + if (e.details?.errorCode === "ResourceAlreadyExists") { + span.setStatus({ + code: CanonicalCode.ALREADY_EXISTS, + message: "Expected exception when creating a directory only if it does not already exist." + }); + return { + succeeded: false, + ...e.response?.parsedHeaders, + _response: e.response + }; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets properties on the directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-properties + * + * @param {properties} [DirectoryProperties] Directory properties. If no values are provided, + * existing values will be preserved. + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async setProperties( + properties: DirectoryProperties = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-setProperties", + properties.tracingOptions + ); + try { + properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties); + + return await this.context.setProperties( + fileAttributesToString(properties.fileAttributes!), + fileCreationTimeToString(properties.creationTime!), + fileLastWriteTimeToString(properties.lastWriteTime!), + { + abortSignal: properties.abortSignal, + filePermission: properties.filePermission, + filePermissionKey: properties.filePermissionKey, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a ShareDirectoryClient object for a sub directory. + * + * @param subDirectoryName A subdirectory name + * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given subdirectory name. + * @memberof ShareDirectoryClient + * + * Example usage: + * + * ```js + * const directoryClient = shareClient.getDirectoryClient(""); + * await directoryClient.create(); + * console.log("Created directory successfully"); + * ``` + */ + public getDirectoryClient(subDirectoryName: string): ShareDirectoryClient { + return new ShareDirectoryClient( + appendToURLPath(this.url, encodeURIComponent(subDirectoryName)), + this.pipeline + ); + } + + /** + * Creates a new subdirectory under this directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory + * + * @param {string} directoryName + * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. + * @returns {Promise<{ directoryClient: ShareDirectoryClient; directoryCreateResponse: DirectoryCreateResponse; }>} Directory create response data and the corresponding DirectoryClient instance. + * @memberof ShareDirectoryClient + */ + public async createSubdirectory( + directoryName: string, + options: DirectoryCreateOptions = {} + ): Promise<{ + directoryClient: ShareDirectoryClient; + directoryCreateResponse: DirectoryCreateResponse; + }> { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-createSubdirectory", + options.tracingOptions + ); + try { + const directoryClient = this.getDirectoryClient(directoryName); + const directoryCreateResponse = await directoryClient.create({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + directoryClient, + directoryCreateResponse + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the specified empty sub directory under this directory. + * Note that the directory must be empty before it can be deleted. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory + * + * @param {string} directoryName + * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. + * @returns {DirectoryDeleteResponse} Directory deletion response data. + * @memberof ShareDirectoryClient + */ + public async deleteSubdirectory( + directoryName: string, + options: DirectoryDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-deleteSubdirectory", + options.tracingOptions + ); + try { + const directoryClient = this.getDirectoryClient(directoryName); + return await directoryClient.delete({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a new file or replaces a file under this directory. Note it only initializes the file with no content. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file + * + * @param {string} fileName + * @param {number} size Specifies the maximum size in bytes for the file, up to 4 TB. + * @param {FileCreateOptions} [options] Options to File Create operation. + * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client. + * @memberof ShareDirectoryClient + */ + public async createFile( + fileName: string, + size: number, + options: FileCreateOptions = {} + ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-createFile", + options.tracingOptions + ); + try { + const fileClient = this.getFileClient(fileName); + const fileCreateResponse = await fileClient.create(size, { + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + fileClient, + fileCreateResponse + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the specified file under this directory from the storage account. + * When a file is successfully deleted, it is immediately removed from the storage + * account's index and is no longer accessible to clients. The file's data is later + * removed from the service during garbage collection. + * + * Delete File will fail with status code 409 (Conflict) and error code SharingViolation + * if the file is open on an SMB client. + * + * Delete File is not supported on a share snapshot, which is a read-only copy of + * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 + * + * @param {string} fileName Name of the file to delete + * @param {FileDeleteOptions} [options] Options to File Delete operation. + * @returns {Promise} File deletion response data. + * @memberof ShareDirectoryClient + */ + public async deleteFile( + fileName: string, + options: FileDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-deleteFile", + options.tracingOptions + ); + try { + const fileClient = this.getFileClient(fileName); + return await fileClient.delete({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Creates a {@link ShareFileClient} object. + * + * @param {string} fileName A file name. + * @returns {ShareFileClient} A new ShareFileClient object for the given file name. + * @memberof ShareFileClient + * + * Example usage: + * + * ```js + * const content = "Hello world!" + * + * const fileClient = directoryClient.getFileClient(""); + * + * await fileClient.create(content.length); + * console.log("Created file successfully!"); + * + * await fileClient.uploadRange(content, 0, content.length); + * console.log("Updated file successfully!") + * ``` + */ + public getFileClient(fileName: string): ShareFileClient { + return new ShareFileClient( + appendToURLPath(this.url, encodeURIComponent(fileName)), + this.pipeline + ); + } + + /** + * Returns true if the specified directory exists; false otherwise. + * + * NOTE: use this function with care since an existing directory might be deleted by other clients or + * applications. Vice versa new directories might be added by other clients or applications after this + * function completes. + * + * @param {DirectoryExistsOptions} [options] options to Exists operation. + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async exists(options: DirectoryExistsOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareDirectoryClient-exists", options.tracingOptions); + try { + await this.getProperties({ + abortSignal: options.abortSignal, + tracingOptions: { + ...options.tracingOptions, + spanOptions + } + }); + return true; + } catch (e) { + if (e.statusCode === 404) { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when checking directory existence" + }); + return false; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns all system properties for the specified directory, and can also be used to check the + * existence of a directory. The data returned does not include the files in the directory or any + * subdirectories. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-directory-properties + * + * @param {DirectoryGetPropertiesOptions} [options] Options to Directory Get Properties operation. + * @returns {Promise} Response data for the Directory Get Properties operation. + * @memberof ShareDirectoryClient + */ + public async getProperties( + options: DirectoryGetPropertiesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-getProperties", + options.tracingOptions + ); + try { + return await this.context.getProperties({ + abortSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the specified empty directory. Note that the directory must be empty before it can be + * deleted. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory + * + * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. + * @returns {Promise} Response data for the Directory Delete operation. + * @memberof ShareDirectoryClient + */ + public async delete(options: DirectoryDeleteOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareDirectoryClient-delete", options.tracingOptions); + try { + return await this.context.deleteMethod({ + abortSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the specified empty directory if it exists. Note that the directory must be empty before it can be + * deleted. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory + * + * @param {DirectoryDeleteOptions} [options] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async deleteIfExists( + options: DirectoryDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-deleteIfExists", + options.tracingOptions + ); + try { + const res = await this.delete({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + succeeded: true, + ...res + }; + } catch (e) { + if (e.details?.errorCode === "ResourceNotFound") { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when deleting a directory only if it exists." + }); + return { + succeeded: false, + ...e.response?.parsedHeaders, + _response: e.response + }; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Updates user defined metadata for the specified directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata + * + * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed + * @param {DirectorySetMetadataOptions} [options] Options to Directory Set Metadata operation. + * @returns {Promise} Response data for the Directory Set Metadata operation. + * @memberof ShareDirectoryClient + */ + public async setMetadata( + metadata?: Metadata, + options: DirectorySetMetadataOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-setMetadata", + options.tracingOptions + ); + try { + return await this.context.setMetadata({ + abortSignal: options.abortSignal, + metadata, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns an AsyncIterableIterator for {@link DirectoryListFilesAndDirectoriesSegmentResponse} objects + * + * @private + * @param {string} [marker] A string value that identifies the portion of + * the list of files and directories to be returned with the next listing operation. The + * operation returns the ContinuationToken value within the response body if the + * listing operation did not return all files and directories remaining to be listed + * with the current page. The ContinuationToken value can be used as the value for + * the marker parameter in a subsequent call to request the next page of list + * items. The marker value is opaque to the client. + * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation. + * @returns {AsyncIterableIterator} + * @memberof ShareDirectoryClient + */ + private async *iterateFilesAndDirectoriesSegments( + marker?: string, + options: DirectoryListFilesAndDirectoriesSegmentOptions = {} + ): AsyncIterableIterator { + if (options.prefix === "") { + options.prefix = undefined; + } + + let listFilesAndDirectoriesResponse; + do { + listFilesAndDirectoriesResponse = await this.listFilesAndDirectoriesSegment(marker, options); + marker = listFilesAndDirectoriesResponse.continuationToken; + yield await listFilesAndDirectoriesResponse; + } while (marker); + } + + /** + * Returns an AsyncIterableIterator for file and directory items + * + * @private + * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation. + * @returns {AsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } & DirectoryItem>} + * @memberof ShareDirectoryClient + */ + private async *listFilesAndDirectoriesItems( + options: DirectoryListFilesAndDirectoriesSegmentOptions = {} + ): AsyncIterableIterator< + ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem) + > { + if (options.prefix === "") { + options.prefix = undefined; + } + + let marker: string | undefined; + for await (const listFilesAndDirectoriesResponse of this.iterateFilesAndDirectoriesSegments( + marker, + options + )) { + for (const file of listFilesAndDirectoriesResponse.segment.fileItems) { + yield { kind: "file", ...file }; + } + for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) { + yield { kind: "directory", ...directory }; + } + } + } + + /** + * Returns an async iterable iterator to list all the files and directories + * under the specified account. + * + * .byPage() returns an async iterable iterator to list the files and directories in pages. + * + * Example using `for await` syntax: + * + * ```js + * let i = 1; + * for await (const entity of directoryClient.listFilesAndDirectories()) { + * if (entity.kind === "directory") { + * console.log(`${i++} - directory\t: ${entity.name}`); + * } else { + * console.log(`${i++} - file\t: ${entity.name}`); + * } + * } + * ``` + * + * Example using `iter.next()`: + * + * ```js + * let i = 1; + * let iter = directoryClient.listFilesAndDirectories(); + * let entity = await iter.next(); + * while (!entity.done) { + * if (entity.value.kind === "directory") { + * console.log(`${i++} - directory\t: ${entity.value.name}`); + * } else { + * console.log(`${i++} - file\t: ${entity.value.name}`); + * } + * entity = await iter.next(); + * } + * ``` + * + * Example using `byPage()`: + * + * ```js + * // passing optional maxPageSize in the page settings + * let i = 1; + * for await (const response of directoryClient + * .listFilesAndDirectories() + * .byPage({ maxPageSize: 20 })) { + * for (const fileItem of response.segment.fileItems) { + * console.log(`${i++} - file\t: ${fileItem.name}`); + * } + * for (const dirItem of response.segment.directoryItems) { + * console.log(`${i++} - directory\t: ${dirItem.name}`); + * } + * } + * ``` + * + * Example using paging with a marker: + * + * ```js + * let i = 1; + * let iterator = directoryClient.listFilesAndDirectories().byPage({ maxPageSize: 3 }); + * let response = (await iterator.next()).value; + * + * // Prints 3 file and directory names + * for (const fileItem of response.segment.fileItems) { + * console.log(`${i++} - file\t: ${fileItem.name}`); + * } + * + * for (const dirItem of response.segment.directoryItems) { + * console.log(`${i++} - directory\t: ${dirItem.name}`); + * } + * + * // Gets next marker + * let dirMarker = response.continuationToken; + * + * // Passing next marker as continuationToken + * iterator = directoryClient + * .listFilesAndDirectories() + * .byPage({ continuationToken: dirMarker, maxPageSize: 4 }); + * response = (await iterator.next()).value; + * + * // Prints 10 file and directory names + * for (const fileItem of response.segment.fileItems) { + * console.log(`${i++} - file\t: ${fileItem.name}`); + * } + * + * for (const dirItem of response.segment.directoryItems) { + * console.log(`${i++} - directory\t: ${dirItem.name}`); + * } + * ``` + * + * @param {DirectoryListFilesAndDirectoriesOptions} [options] Options to list files and directories operation. + * @memberof ShareDirectoryClient + * @returns {PagedAsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } , DirectoryListFilesAndDirectoriesSegmentResponse>} + * An asyncIterableIterator that supports paging. + */ + public listFilesAndDirectories( + options: DirectoryListFilesAndDirectoriesOptions = {} + ): PagedAsyncIterableIterator< + ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem), + DirectoryListFilesAndDirectoriesSegmentResponse + > { + if (options.prefix === "") { + options.prefix = undefined; + } + + // AsyncIterableIterator to iterate over files and directories + const iter = this.listFilesAndDirectoriesItems(options); + return { + /** + * @member {Promise} [next] The next method, part of the iteration protocol + */ + async next() { + return iter.next(); + }, + /** + * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol + */ + [Symbol.asyncIterator]() { + return this; + }, + /** + * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time + */ + byPage: (settings: PageSettings = {}) => { + return this.iterateFilesAndDirectoriesSegments(settings.continuationToken, { + maxResults: settings.maxPageSize, + ...options + }); + } + }; + } + + /** + * Returns a list of files or directories under the specified share or directory. It lists the + * contents only for a single level of the directory hierarchy. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-directories-and-files + * + * @param {string} [marker] A string value that identifies the portion of the list to be returned with the next list operation. + * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to Directory List Files and Directories Segment operation. + * @returns {Promise} Response data for the Directory List Files and Directories operation. + * @memberof ShareDirectoryClient + */ + private async listFilesAndDirectoriesSegment( + marker?: string, + options: DirectoryListFilesAndDirectoriesSegmentOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-listFilesAndDirectoriesSegment", + options.tracingOptions + ); + + if (options.prefix === "") { + options.prefix = undefined; + } + + try { + return await this.context.listFilesAndDirectoriesSegment({ + marker, + ...options, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns an AsyncIterableIterator for {@link DirectoryListHandlesResponse} + * + * @private + * @param {string} [marker] A string value that identifies the portion of the list to be + * returned with the next list handles operation. The operation returns a + * marker value within the response body if the list returned was not complete. + * The marker value may then be used in a subsequent call to request the next + * set of list items. + * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation. + * @returns {AsyncIterableIterator} + * @memberof ShareDirectoryClient + */ + private async *iterateHandleSegments( + marker?: string, + options: DirectoryListHandlesSegmentOptions = {} + ): AsyncIterableIterator { + let listHandlesResponse; + if (!!marker || marker === undefined) { + do { + listHandlesResponse = await this.listHandlesSegment(marker, options); + marker = listHandlesResponse.continuationToken; + yield await listHandlesResponse; + } while (marker); + } + } + + /** + * Returns an AsyncIterableIterator for handles + * + * @private + * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation. + * @returns {AsyncIterableIterator} + * @memberof ShareDirectoryClient + */ + private async *listHandleItems( + options: DirectoryListHandlesSegmentOptions = {} + ): AsyncIterableIterator { + let marker: string | undefined; + for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) { + if (listHandlesResponse.handleList) { + for (const handle of listHandlesResponse.handleList) { + yield handle; + } + } + } + } + + /** + * Returns an async iterable iterator to list all the handles. + * under the specified account. + * + * .byPage() returns an async iterable iterator to list the handles in pages. + * + * Example using `for await` syntax: + * + * ```js + * let i = 1; + * let iter = dirClient.listHandles(); + * for await (const handle of iter) { + * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); + * } + * ``` + * + * Example using `iter.next()`: + * + * ```js + * let i = 1; + * let iter = dirClient.listHandles(); + * let handleItem = await iter.next(); + * while (!handleItem.done) { + * console.log(`Handle ${i++}: ${handleItem.value.path}, opened time ${handleItem.value.openTime}, clientIp ${handleItem.value.clientIp}`); + * handleItem = await iter.next(); + * } + * ``` + * + * Example using `byPage()`: + * + * ```js + * // passing optional maxPageSize in the page settings + * let i = 1; + * for await (const response of dirClient.listHandles({ recursive: true }).byPage({ maxPageSize: 20 })) { + * if (response.handleList) { + * for (const handle of response.handleList) { + * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); + * } + * } + * } + * ``` + * + * Example using paging with a marker: + * + * ```js + * let i = 1; + * let iterator = dirClient.listHandles().byPage({ maxPageSize: 2 }); + * let response = await iterator.next(); + * + * // Prints 2 handles + * if (response.value.handleList) { + * for (const handle of response.value.handleList) { + * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); + * } + * } + * + * // Gets next marker + * let marker = response.value.continuationToken; + * + * // Passing next marker as continuationToken + * console.log(` continuation`); + * iterator = dirClient.listHandles().byPage({ continuationToken: marker, maxPageSize: 10 }); + * response = await iterator.next(); + * + * // Prints 2 more handles assuming you have more than four directory/files opened + * if (!response.done && response.value.handleList) { + * for (const handle of response.value.handleList) { + * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); + * } + * } + * ``` + * + * @param {DirectoryListHandlesOptions} [options] Options to list handles operation. + * @memberof ShareDirectoryClient + * @returns {PagedAsyncIterableIterator} + * An asyncIterableIterator that supports paging. + */ + public listHandles( + options: DirectoryListHandlesOptions = {} + ): PagedAsyncIterableIterator { + // an AsyncIterableIterator to iterate over handles + const iter = this.listHandleItems(options); + return { + /** + * @member {Promise} [next] The next method, part of the iteration protocol + */ + async next() { + return iter.next(); + }, + /** + * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol + */ + [Symbol.asyncIterator]() { + return this; + }, + /** + * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time + */ + byPage: (settings: PageSettings = {}) => { + return this.iterateHandleSegments(settings.continuationToken, { + maxResults: settings.maxPageSize, + ...options + }); + } + }; + } + + /** + * Lists handles for a directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles + * + * @param {string} [marker] Optional. A string value that identifies the portion of the list to be + * returned with the next list handles operation. The operation returns a + * marker value within the response body if the list returned was not complete. + * The marker value may then be used in a subsequent call to request the next + * set of list items. + * @param {DirectoryListHandlesSegmentOptions} [options={}] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + private async listHandlesSegment( + marker?: string, + options: DirectoryListHandlesSegmentOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-listHandlesSegment", + options.tracingOptions + ); + try { + marker = marker === "" ? undefined : marker; + const response = await this.context.listHandles({ + marker, + ...options, + spanOptions + }); + + // TODO: Protocol layer issue that when handle list is in returned XML + // response.handleList is an empty string + if ((response.handleList as any) === "") { + response.handleList = undefined; + } + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Force close all handles for a directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {string} [marker] Optional. A string value that identifies the position of handles that will + * be closed with the next force close handles operation. + * The operation returns a marker value within the response + * body if there are more handles to close. The marker value + * may then be used in a subsequent call to close the next set of handles. + * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + private async forceCloseHandlesSegment( + marker?: string, + options: DirectoryForceCloseHandlesSegmentOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-forceCloseHandlesSegment", + options.tracingOptions + ); + try { + marker = marker === "" ? undefined : marker; + const rawResponse = await this.context.forceCloseHandles("*", { + marker, + ...options, + spanOptions + }); + const response = rawResponse as DirectoryForceCloseHandlesResponse; + response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; + response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Force close all handles for a directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async forceCloseAllHandles( + options: DirectoryForceCloseHandlesSegmentOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-forceCloseAllHandles", + options.tracingOptions + ); + try { + let handlesClosed = 0; + let numberOfHandlesFailedToClose = 0; + let marker: string | undefined = ""; + + do { + const response: DirectoryForceCloseHandlesResponse = await this.forceCloseHandlesSegment( + marker, + { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } + ); + marker = response.marker; + response.closedHandlesCount && (handlesClosed += response.closedHandlesCount); + response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount); + } while (marker); + + return { closedHandlesCount: handlesClosed, closeFailureCount: numberOfHandlesFailedToClose }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Force close a specific handle for a directory. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(), + * goto documents of Aborter for more examples about request cancellation + * @param {string} handleId Specific handle ID, cannot be asterisk "*". + * Use forceCloseHandlesSegment() to close all handles. + * @param {DirectoryForceCloseHandlesOptions} [options={}] + * @returns {Promise} + * @memberof ShareDirectoryClient + */ + public async forceCloseHandle( + handleId: string, + options: DirectoryForceCloseHandlesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareDirectoryClient-forceCloseHandle", + options.tracingOptions + ); + try { + if (handleId === "*") { + throw new RangeError( + `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.` + ); + } + + const rawResponse = await this.context.forceCloseHandles(handleId, { + abortSignal: options.abortSignal, + spanOptions + }); + const response = rawResponse as DirectoryForceCloseHandlesResponse; + response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; + response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } +} + +/** + * Options to configure the {@link ShareFileClient.create} operation. + * + * @export + * @interface FileCreateOptions + */ +export interface FileCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileCreateOptions + */ + abortSignal?: AbortSignalLike; + /** + * File HTTP headers like Content-Type. + * + * @type {FileHttpHeaders} + * @memberof FileCreateOptions + */ + fileHttpHeaders?: FileHttpHeaders; + + /** + * A collection of key-value string pair to associate with the file storage object. + * + * @type {Metadata} + * @memberof FileCreateOptions + */ + metadata?: Metadata; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileCreateOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +export interface FileProperties extends FileAndDirectorySetPropertiesCommonOptions, CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileProperties + */ + abortSignal?: AbortSignalLike; + /** + * File HTTP headers like Content-Type. + * + * @type {FileHttpHeaders} + * @memberof FileProperties + */ + fileHttpHeaders?: FileHttpHeaders; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileProperties + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +export interface SetPropertiesResponse extends FileSetHTTPHeadersResponse {} + +/** + * Options to configure the {@link ShareFileClient.delete} operation. + * + * @export + * @interface FileDeleteOptions + */ +export interface FileDeleteOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileDeleteOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileDeleteOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure File - Download operations. + * + * See: + * - {@link ShareFileClient.download} + * - {@link ShareFileClient.downloadToFile} + * + * @export + * @interface FileDownloadOptions + */ +export interface FileDownloadOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileDownloadOptions + */ + abortSignal?: AbortSignalLike; + /** + * Optional. ONLY AVAILABLE IN NODE.JS. + * + * How many retries will perform when original body download stream unexpected ends. + * Above kind of ends will not trigger retry policy defined in a pipeline, + * because they doesn't emit network errors. + * + * With this option, every additional retry means an additional ShareFileClient.download() request will be made + * from the broken point, until the requested range has been successfully downloaded or maxRetryRequests is reached. + * + * Default value is 5, please set a larger value when loading large files in poor network. + * + * @type {number} + * @memberof FileDownloadOptions + */ + maxRetryRequests?: number; + + /** + * When this header is set to true and + * specified together with the Range header, the service returns the MD5 hash + * for the range, as long as the range is less than or equal to 4 MB in size. + * + * @type {boolean} + * @memberof FileDownloadOptions + */ + rangeGetContentMD5?: boolean; + + /** + * Download progress updating event handler. + * + * @memberof FileDownloadOptions + */ + onProgress?: (progress: TransferProgressEvent) => void; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileDownloadOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.uploadRange} operation. + * + * @export + * @interface FileUploadRangeOptions + */ +export interface FileUploadRangeOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileUploadRangeOptions + */ + abortSignal?: AbortSignalLike; + /** + * An MD5 hash of the content. This hash is + * used to verify the integrity of the data during transport. When the + * Content-MD5 header is specified, the File service compares the hash of the + * content that has arrived with the header value that was sent. If the two + * hashes do not match, the operation will fail with error code 400 (Bad + * Request). + * + * @type {Uint8Array} + * @memberof FileUploadRangeOptions + */ + contentMD5?: Uint8Array; + + /** + * Progress updating event handler. + * + * @memberof FileUploadRangeOptions + */ + onProgress?: (progress: TransferProgressEvent) => void; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileUploadRangeOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.uploadRangeFromURL} operation. + * + * @export + * @interface FileUploadRangeFromURLOptions + */ +export interface FileUploadRangeFromURLOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileUploadRangeFromURLOptions + */ + abortSignal?: AbortSignalLike; + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * Specify the crc64 calculated for the range of bytes that must be read from the copy source. + */ + sourceContentCrc64?: Uint8Array; + /** + * Additional parameters for the operation + */ + sourceConditions?: SourceModifiedAccessConditions; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileUploadRangeFromURLOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * The option is defined as parity to REST definition. + * While it's not ready to be used now, considering Crc64 of source content is + * not accessible. + */ +// export interface IFileUploadRangeFromURLOptions extends CommonOptions { +// /** +// * Crc64 of the source content. +// * +// * @type {Uint8Array} +// * @memberof IFileUploadRangeFromURLOptions +// */ +// sourceContentCrc64?: Uint8Array; + +// /** +// * Source modified access condition. +// * +// * @type {SourceModifiedAccessConditions} +// * @memberof IFileUploadRangeFromURLOptions +// */ +// sourceModifiedAccessConditions?: SourceModifiedAccessConditions; +// } + +/** + * Options to configure the {@link ShareFileClient.getRangeList} operation. + * + * @export + * @interface FileGetRangeListOptions + */ +export interface FileGetRangeListOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileGetRangeListOptions + */ + abortSignal?: AbortSignalLike; + /** + * Optional. Specifies the range of bytes over which to list ranges, inclusively. + * + * @type {Range} + * @memberof FileGetRangeListOptions + */ + range?: Range; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileGetRangeListOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.exists} operation. + * + * @export + * @interface FileExistsOptions + */ +export interface FileExistsOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileExistsOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure the {@link ShareFileClient.getProperties} operation. + * + * @export + * @interface FileGetPropertiesOptions + */ +export interface FileGetPropertiesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileGetPropertiesOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileGetPropertiesOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Contains response data for the {@link ShareFileClient.getRangeList} operation. + */ +export type FileGetRangeListResponse = FileGetRangeListHeaders & { + /** + * Range list for an Azure file. + * + * @type {RangeModel[]} + */ + rangeList: RangeModel[]; + + /** + * The underlying HTTP response. + */ + _response: HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: FileGetRangeListHeaders; + /** + * The response body as text (string format) + */ + bodyAsText: string; + /** + * The response body as parsed JSON or XML + */ + parsedBody: RangeModel[]; + }; +}; + +/** + * Options to configure the {@link ShareFileClient.startCopyFromURL} operation. + * + * @export + * @interface FileStartCopyOptions + */ +export interface FileStartCopyOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileStartCopyOptions + */ + abortSignal?: AbortSignalLike; + /** + * A collection of key-value string pair to associate with the file storage object. + * + * @type {Metadata} + * @memberof FileStartCopyOptions + */ + metadata?: Metadata; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileStartCopyOptions + */ + leaseAccessConditions?: LeaseAccessConditions; + /** + * If specified the permission (security descriptor) shall be set for the directory/file. This + * header can be used if Permission size is <= 8KB, else x-ms-file-permission-key header shall be + * used. Default value: Inherit. If SDDL is specified as input, it must have owner, group and + * dacl. Note: Only one of the x-ms-file-permission or x-ms-file-permission-key should be + * specified. + * + * @type {string} + * @memberof FileStartCopyOptions + */ + filePermission?: string; + /** + * Key of the permission to be set for the directory/file. Note: Only one of the + * x-ms-file-permission or x-ms-file-permission-key should be specified. + * + * @type {string} + * @memberof FileStartCopyOptions + */ + filePermissionKey?: string; + /** + * SMB info. + * + * @type {CopyFileSmbInfo} + * @memberof FileStartCopyOptions + */ + copyFileSmbInfo?: CopyFileSmbInfo; +} + +/** + * Options to configure the {@link ShareFileClient.setMetadata} operation. + * + * @export + * @interface FileSetMetadataOptions + */ +export interface FileSetMetadataOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileSetMetadataOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileSetMetadataOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.setHttpHeaders} operation. + * + * @export + * @interface FileSetHttpHeadersOptions + */ +export interface FileSetHttpHeadersOptions + extends FileAndDirectorySetPropertiesCommonOptions, + CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileSetHttpHeadersOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileSetHttpHeadersOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.abortCopyFromURL} operation. + * + * @export + * @interface FileAbortCopyFromURLOptions + */ +export interface FileAbortCopyFromURLOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileAbortCopyFromURLOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileAbortCopyFromURLOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.resize} operation. + * + * @export + * @interface FileResizeOptions + */ +export interface FileResizeOptions + extends FileAndDirectorySetPropertiesCommonOptions, + CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileResizeOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileResizeOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure the {@link ShareFileClient.clearRange} operation. + * + * @export + * @interface FileClearRangeOptions + */ +export interface FileClearRangeOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileClearRangeOptions + */ + abortSignal?: AbortSignalLike; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileClearRangeOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Options to configure File - List Handles Segment operations. + * + * See: + * - {@link ShareFileClient.listHandlesSegment} + * - {@link ShareFileClient.iterateHandleSegments} + * - {@link ShareFileClient.listHandleItems} + * + * @export + * @interface FileListHandlesSegmentOptions + */ +export interface FileListHandlesSegmentOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileClearRangeOptions + */ + abortSignal?: AbortSignalLike; + /** + * Specifies the maximum number of entries to return. If the request does not specify maxResults, + * or specifies a value greater than 5,000, the server will return up to 5,000 items. + * + * @type {number} + * @memberof FileListHandlesSegmentOptions + */ + maxPageSize?: number; +} + +export interface FileListHandlesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileClearRangeOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Options to configure File - Force Close Handles operations. + * + * See: + * - {@link ShareFileClient.forceCloseHandlesSegment} + * - {@link ShareFileClient.forceCloseAllHandles} + * - {@link ShareFileClient.forceCloseHandle} + * + * @export + * @interface FileForceCloseHandlesOptions + */ +export interface FileForceCloseHandlesOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileForceCloseHandlesOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * Additional response header values for close handles request. + */ +export interface FileCloseHandlesHeaders { + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + /** + * A UTC date/time value generated by the service that indicates the time at which the response + * was initiated. + */ + date?: Date; + /** + * A string describing next handle to be closed. It is returned when more handles need to be + * closed to complete the request. + */ + marker?: string; +} + +/** + * Response type for {@link ShareFileClient.forceCloseHandle}. + */ +export type FileForceCloseHandlesResponse = CloseHandlesInfo & + FileCloseHandlesHeaders & { + /** + * The underlying HTTP response. + */ + _response: HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: FileForceCloseHandlesHeaders; + }; + }; + +/** + * Option interface for ShareFileClient.uploadStream(). + * + * @export + * @interface FileUploadStreamOptions + */ +export interface FileUploadStreamOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileUploadStreamOptions + */ + abortSignal?: AbortSignalLike; + /** + * Azure File HTTP Headers. + * + * @type {FileHttpHeaders} + * @memberof FileUploadStreamOptions + */ + fileHttpHeaders?: FileHttpHeaders; + + /** + * Metadata of the Azure file. + * + * @type {Metadata} + * @memberof FileUploadStreamOptions + */ + metadata?: Metadata; + + /** + * Progress updater. + * + * @memberof FileUploadStreamOptions + */ + onProgress?: (progress: TransferProgressEvent) => void; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileUploadStreamOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Option interface for File - Upload operations + * + * See: + * - {@link ShareFileClient.uploadFile} + * - {@link ShareFileClient.uploadSeekableStream} + * + * @export + * @interface FileParallelUploadOptions + */ +export interface FileParallelUploadOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileParallelUploadOptions + */ + abortSignal?: AbortSignalLike; + /** + * RangeSize specifies the range size to use in each parallel upload, + * the default (and maximum size) is FILE_RANGE_MAX_SIZE_BYTES. + * + * @type {number} + * @memberof FileParallelUploadOptions + */ + rangeSize?: number; + + /** + * Progress updater. + * + * @memberof FileParallelUploadOptions + */ + onProgress?: (progress: TransferProgressEvent) => void; + + /** + * File HTTP Headers. + * + * @type {FileHttpHeaders} + * @memberof FileParallelUploadOptions + */ + fileHttpHeaders?: FileHttpHeaders; + + /** + * Metadata of an Azure file. + * + * @type {Metadata} + * @memberof FileParallelUploadOptions + */ + metadata?: Metadata; + + /** + * Concurrency indicates the maximum number of ranges to upload in parallel. + * If not provided, 5 concurrency will be used by default. + * + * @type {number} + * @memberof FileParallelUploadOptions + */ + concurrency?: number; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileParallelUploadOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Option interface for the {@link ShareFileClient.downloadToBuffer} operation. + * + * @export + * @interface FileDownloadToBufferOptions + */ +export interface FileDownloadToBufferOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof FileDownloadToBufferOptions + */ + abortSignal?: AbortSignalLike; + /** + * When downloading Azure files, download method will try to split large file into small ranges. + * Every small range will be downloaded via a separate request. + * This option defines size data every small request trying to download. + * Must be > 0, will use the default value if undefined, + * + * @type {number} + * @memberof FileDownloadToBufferOptions + */ + rangeSize?: number; + + /** + * Optional. ONLY AVAILABLE IN NODE.JS. + * + * How many retries will perform when original range download stream unexpected ends. + * Above kind of ends will not trigger retry policy defined in a pipeline, + * because they doesn't emit network errors. + * + * With this option, every additional retry means an additional ShareFileClient.download() request will be made + * from the broken point, until the requested range has been successfully downloaded or + * maxRetryRequestsPerRange is reached. + * + * Default value is 5, please set a larger value when in poor network. + * + * @type {number} + * @memberof FileDownloadToBufferOptions + */ + maxRetryRequestsPerRange?: number; + + /** + * Progress updater. + * + * @memberof FileDownloadToBufferOptions + */ + onProgress?: (progress: TransferProgressEvent) => void; + + /** + * Concurrency indicates the maximum number of ranges to download in parallel. + * If not provided, 5 concurrency will be used by default. + * + * @type {number} + * @memberof FileDownloadToBufferOptions + */ + concurrency?: number; + /** + * Lease access conditions. + * + * @type {LeaseAccessConditions} + * @memberof FileDownloadToBufferOptions + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Contains response data for the {@link ShareFileClient.deleteIfExists} operation. + * + * @export + * @interface FileDeleteIfExistsResponse + */ +export interface FileDeleteIfExistsResponse extends FileDeleteResponse { + /** + * Indicate whether the file is successfully deleted. Is false if the file does not exist in the first place. + * + * @type {boolean} + * @memberof FileDeleteIfExistsResponse + */ + succeeded: boolean; +} + +/** + * A ShareFileClient represents a URL to an Azure Storage file. + * + * @export + * @class ShareFileClient + */ +export class ShareFileClient extends StorageClient { + /** + * context provided by protocol layer. + * + * @private + * @type {File} + * @memberof ShareFileClient + */ + private context: File; + + private _shareName: string; + private _path: string; + private _name: string; + + /** + * The share name corresponding to this file client + * + * @type {string} + * @memberof ShareFileClient + */ + public get shareName(): string { + return this._shareName; + } + + /** + * The full path of the file + * + * @type {string} + * @memberof ShareFileClient + */ + public get path(): string { + return this._path; + } + + /** + * The name of the file + * + * @type {string} + * @memberof ShareFileClient + */ + public get name(): string { + return this._name; + } + + /** + * Creates an instance of ShareFileClient. + * + * @param {string} url A URL string pointing to Azure Storage file, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString". + * This method accepts an encoded URL or non-encoded URL pointing to a file. + * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. + * However, if a file or directory name includes %, file or directory name must be encoded in the URL. + * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25". + * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. + * If not specified, AnonymousCredential is used. + * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. + * @memberof ShareFileClient + */ + constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); + /** + * Creates an instance of ShareFileClient. + * + * @param {string} url A URL string pointing to Azure Storage file, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can + * append a SAS if using AnonymousCredential, such as + * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString". + * This method accepts an encoded URL or non-encoded URL pointing to a file. + * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. + * However, if a file or directory name includes %, file or directory name must be encoded in the URL. + * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25". + * @param {Pipeline} pipeline Call newPipeline() to create a default + * pipeline, or provide a customized pipeline. + * @memberof ShareFileClient + */ + constructor(url: string, pipeline: Pipeline); + constructor( + url: string, + credentialOrPipeline?: Credential | Pipeline, + options?: StoragePipelineOptions + ) { + let pipeline: Pipeline; + if (credentialOrPipeline instanceof Pipeline) { + pipeline = credentialOrPipeline; + } else if (credentialOrPipeline instanceof Credential) { + pipeline = newPipeline(credentialOrPipeline, options); + } else { + // The second parameter is undefined. Use anonymous credential. + pipeline = newPipeline(new AnonymousCredential(), options); + } + + super(url, pipeline); + ({ + baseName: this._name, + shareName: this._shareName, + path: this._path + } = getShareNameAndPathFromUrl(this.url)); + this.context = new File(this.storageClientContext); + } + + /** + * Creates a new ShareFileClient object identical to the source but with the specified share snapshot timestamp. + * Provide "" will remove the snapshot and return a URL to the base ShareFileClient. + * + * @param {string} shareSnapshot The share snapshot timestamp. + * @returns {ShareFileClient} A new ShareFileClient object identical to the source but with the specified share snapshot timestamp. + * @memberof ShareFileClient + */ + public withShareSnapshot(shareSnapshot: string): ShareFileClient { + return new ShareFileClient( + setURLParameter( + this.url, + URLConstants.Parameters.SHARE_SNAPSHOT, + shareSnapshot.length === 0 ? undefined : shareSnapshot + ), + this.pipeline + ); + } + + /** + * Creates a new file or replaces a file. Note it only initializes the file with no content. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file + * + * @param {number} size Specifies the maximum size in bytes for the file, up to 4 TB. + * @param {FileCreateOptions} [options] Options to File Create operation. + * @returns {Promise} Response data for the File Create operation. + * @memberof ShareFileClient + * + * Example usage: + * + * ```js + * const content = "Hello world!"; + * + * // Create the file + * await fileClient.create(content.length); + * console.log("Created file successfully!"); + * + * // Then upload data to the file + * await fileClient.uploadRange(content, 0, content.length); + * console.log("Updated file successfully!") + * ``` + */ + public async create(size: number, options: FileCreateOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-create", options.tracingOptions); + try { + if (size < 0 || size > FILE_MAX_SIZE_BYTES) { + throw new RangeError(`File size must >= 0 and < ${FILE_MAX_SIZE_BYTES}.`); + } + options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options); + + if (!options.fileAttributes) { + // Note: It would be Archive in service side if None is set. + const attributes: FileSystemAttributes = new FileSystemAttributes(); + attributes.none = true; + options.fileAttributes = attributes; + } + + options.fileHttpHeaders = options.fileHttpHeaders || {}; + + return await this.context.create( + size, + fileAttributesToString(options.fileAttributes!), + fileCreationTimeToString(options.creationTime!), + fileLastWriteTimeToString(options.lastWriteTime!), + { + abortSignal: options.abortSignal, + fileHttpHeaders: options.fileHttpHeaders, + metadata: options.metadata, + filePermission: options.filePermission, + filePermissionKey: options.filePermissionKey, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Reads or downloads a file from the system, including its metadata and properties. + * + * * In Node.js, data returns in a Readable stream `readableStreamBody` + * * In browsers, data returns in a promise `contentAsBlob` + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file + * + * @param {number} [offset] From which position of the file to download, >= 0 + * @param {number} [count] How much data to be downloaded, > 0. Will download to the end when undefined + * @param {FileDownloadOptions} [options] Options to File Download operation. + * @returns {Promise} Response data for the File Download operation. + * @memberof ShareFileClient + * + * Example usage (Node.js): + * + * ```js + * // Download a file to a string + * const downloadFileResponse = await fileClient.download(); + * console.log( + * "Downloaded file content:", + * (await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()} + * ); + * + * // A helper method used to read a Node.js readable stream into string + * async function streamToBuffer(readableStream) { + * return new Promise((resolve, reject) => { + * const chunks = []; + * readableStream.on("data", (data) => { + * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); + * }); + * readableStream.on("end", () => { + * resolve(Buffer.concat(chunks)); + * }); + * readableStream.on("error", reject); + * }); + * } + * ``` + * + * Example usage (browsers): + * + * ```js + * // Download a file to a string + * const downloadFileResponse = await fileClient.download(0); + * console.log( + * "Downloaded file content:", + * await blobToString(await downloadFileResponse.blobBody)} + * ); + * + * // A helper method used to convert a browser Blob into string. + * export async function blobToString(blob: Blob): Promise { + * const fileReader = new FileReader(); + * return new Promise((resolve, reject) => { + * fileReader.onloadend = (ev: any) => { + * resolve(ev.target!.result); + * }; + * fileReader.onerror = reject; + * fileReader.readAsText(blob); + * }); + * } + * ``` + */ + public async download( + offset: number = 0, + count?: number, + options: FileDownloadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-download", options.tracingOptions); + try { + if (options.rangeGetContentMD5 && offset === 0 && count === undefined) { + throw new RangeError(`rangeGetContentMD5 only works with partial data downloading`); + } + + const downloadFullFile = offset === 0 && !count; + const res = await this.context.download({ + abortSignal: options.abortSignal, + onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream + range: downloadFullFile ? undefined : rangeToString({ offset, count }), + rangeGetContentMD5: options.rangeGetContentMD5, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + + // Return browser response immediately + if (!isNode) { + return res; + } + + // We support retrying when download stream unexpected ends in Node.js runtime + // Following code shouldn't be bundled into browser build, however some + // bundlers may try to bundle following code and "FileReadResponse.ts". + // In this case, "FileDownloadResponse.browser.ts" will be used as a shim of "FileDownloadResponse.ts" + // The config is in package.json "browser" field + if (options.maxRetryRequests === undefined || options.maxRetryRequests < 0) { + // TODO: Default value or make it a required parameter? + options.maxRetryRequests = DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS; + } + + if (res.contentLength === undefined) { + throw new RangeError(`File download response doesn't contain valid content length header`); + } + + return new FileDownloadResponse( + res, + async (start: number): Promise => { + const updatedOptions: FileDownloadOptionalParams = { + range: rangeToString({ + count: offset + res.contentLength! - start, + offset: start + }) + }; + + // Debug purpose only + // console.log( + // `Read from internal stream, range: ${ + // updatedOptions.range + // }, options: ${JSON.stringify(updatedOptions)}` + // ); + + return ( + await this.context.download({ + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + ...updatedOptions, + spanOptions + }) + ).readableStreamBody!; + }, + offset, + res.contentLength!, + { + abortSignal: options.abortSignal, + maxRetryRequests: options.maxRetryRequests, + onProgress: options.onProgress + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns true if the specified file exists; false otherwise. + * + * NOTE: use this function with care since an existing file might be deleted by other clients or + * applications. Vice versa new files might be added by other clients or applications after this + * function completes. + * + * @param {FileExistsOptions} [options] options to Exists operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async exists(options: FileExistsOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-exists", options.tracingOptions); + try { + await this.getProperties({ + abortSignal: options.abortSignal, + tracingOptions: { + ...options.tracingOptions, + spanOptions + } + }); + return true; + } catch (e) { + if (e.statusCode === 404) { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when checking file existence" + }); + return false; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns all user-defined metadata, standard HTTP properties, and system properties + * for the file. It does not return the content of the file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file-properties + * + * @param {FileGetPropertiesOptions} [options] Options to File Get Properties operation. + * @returns {Promise} Response data for the File Get Properties operation. + * @memberof ShareFileClient + */ + public async getProperties( + options: FileGetPropertiesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-getProperties", + options.tracingOptions + ); + try { + return this.context.getProperties({ + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets properties on the file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties + * + * @param {FileProperties} [properties] File properties. For file HTTP headers(e.g. Content-Type), + * if no values are provided, existing HTTP headers will be removed. + * For other file properties(e.g. fileAttributes), if no values are provided, + * existing values will be preserved. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async setProperties(properties: FileProperties = {}): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-setProperties", + properties.tracingOptions + ); + try { + properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties); + + properties.fileHttpHeaders = properties.fileHttpHeaders || {}; + + return await this.context.setHTTPHeaders( + fileAttributesToString(properties.fileAttributes!), + fileCreationTimeToString(properties.creationTime!), + fileLastWriteTimeToString(properties.lastWriteTime!), + { + abortSignal: properties.abortSignal, + fileHttpHeaders: properties.fileHttpHeaders, + filePermission: properties.filePermission, + filePermissionKey: properties.filePermissionKey, + leaseAccessConditions: properties.leaseAccessConditions, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the file from the storage account. + * When a file is successfully deleted, it is immediately removed from the storage + * account's index and is no longer accessible to clients. The file's data is later + * removed from the service during garbage collection. + * + * Delete File will fail with status code 409 (Conflict) and error code SharingViolation + * if the file is open on an SMB client. + * + * Delete File is not supported on a share snapshot, which is a read-only copy of + * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 + * + * @param {FileDeleteOptions} [options] Options to File Delete operation. + * @returns {Promise} Response data for the File Delete operation. + * @memberof ShareFileClient + */ + public async delete(options: FileDeleteOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-delete", options.tracingOptions); + try { + return await this.context.deleteMethod({ + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Removes the file from the storage account if it exists. + * When a file is successfully deleted, it is immediately removed from the storage + * account's index and is no longer accessible to clients. The file's data is later + * removed from the service during garbage collection. + * + * Delete File will fail with status code 409 (Conflict) and error code SharingViolation + * if the file is open on an SMB client. + * + * Delete File is not supported on a share snapshot, which is a read-only copy of + * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 + * + * @param {FileDeleteOptions} [options] + * @returns {Promise} + * @memberof ShareFileClient + */ + public async deleteIfExists( + options: FileDeleteOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-deleteIfExists", + options.tracingOptions + ); + try { + const res = await this.delete({ + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + return { + succeeded: true, + ...res + }; + } catch (e) { + if (e.details?.errorCode === "ResourceNotFound") { + span.setStatus({ + code: CanonicalCode.NOT_FOUND, + message: "Expected exception when deleting a file only if it exists." + }); + return { + succeeded: false, + ...e.response?.parsedHeaders, + _response: e.response + }; + } + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Sets HTTP headers on the file. + * + * If no option provided, or no value provided for the file HTTP headers in the options, + * these file HTTP headers without a value will be cleared. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties + * + * @param {fileHttpHeaders} [FileHttpHeaders] File HTTP headers like Content-Type. + * Provide undefined will remove existing HTTP headers. + * @param {FileSetHttpHeadersOptions} [options] Options to File Set HTTP Headers operation. + * @returns {Promise} Response data for the File Set HTTP Headers operation. + * @memberof ShareFileClient + */ + public async setHttpHeaders( + fileHttpHeaders: FileHttpHeaders = {}, + options: FileSetHttpHeadersOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-setHTTPHeaders", + options.tracingOptions + ); + try { + // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved + options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options); + return await this.context.setHTTPHeaders( + fileAttributesToString(options.fileAttributes!), + fileCreationTimeToString(options.creationTime!), + fileLastWriteTimeToString(options.lastWriteTime!), + { + abortSignal: options.abortSignal, + fileHttpHeaders, + filePermission: options.filePermission, + filePermissionKey: options.filePermissionKey, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Resize file. + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties + * + * @param {number} length Resizes a file to the specified size in bytes. + * If the specified byte value is less than the current size of the file, + * then all ranges above the specified byte value are cleared. + * @param {FileResizeOptions} [options] Options to File Resize operation. + * @returns {Promise} Response data for the File Set HTTP Headers operation. + * @memberof ShareFileClient + */ + public async resize( + length: number, + options: FileResizeOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-resize", options.tracingOptions); + try { + if (length < 0) { + throw new RangeError(`Size cannot less than 0 when resizing file.`); + } + // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved. + options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options); + + return await this.context.setHTTPHeaders( + fileAttributesToString(options.fileAttributes!), + fileCreationTimeToString(options.creationTime!), + fileLastWriteTimeToString(options.lastWriteTime!), + { + abortSignal: options.abortSignal, + fileContentLength: length, + filePermission: options.filePermission, + filePermissionKey: options.filePermissionKey, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Updates user-defined metadata for the specified file. + * + * If no metadata defined in the option parameter, the file + * metadata will be removed. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-metadata + * + * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed + * @param {FileSetMetadataOptions} [options] Options to File Set Metadata operation. + * @returns {Promise} Response data for the File Set Metadata operation. + * @memberof ShareFileClient + */ + public async setMetadata( + metadata: Metadata = {}, + options: FileSetMetadataOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-setMetadata", options.tracingOptions); + try { + return await this.context.setMetadata({ + abortSignal: options.abortSignal, + metadata, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Upload a range of bytes to a file. Both the start and count of the + * range must be specified. The range can be up to 4 MB in size. + * + * @param {HttpRequestBody} body Blob, string, ArrayBuffer, ArrayBufferView or a function + * which returns a new Readable stream whose offset is from data source beginning. + * @param {number} offset Offset position of the destination Azure File to upload. + * @param {number} contentLength Length of body in bytes. Use Buffer.byteLength() to calculate body length for a + * string including non non-Base64/Hex-encoded characters. + * @param {FileUploadRangeOptions} [options={}] Options to File Upload Range operation. + * @returns {Promise} Response data for the File Upload Range operation. + * @memberof ShareFileClient + * + * Example usage: + * + * ```js + * const content = "Hello world!"; + * + * // Create the file + * await fileClient.create(content.length); + * console.log("Created file successfully!"); + * + * // Then upload data to the file + * await fileClient.uploadRange(content, 0, content.length); + * console.log("Updated file successfully!") + * ``` + */ + public async uploadRange( + body: HttpRequestBody, + offset: number, + contentLength: number, + options: FileUploadRangeOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-uploadRange", options.tracingOptions); + try { + if (offset < 0) { + throw new RangeError(`offset must be >= 0`); + } + + if (contentLength <= 0 || contentLength > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`contentLength must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); + } + + if (contentLength > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`offset must be < ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); + } + + return await this.context.uploadRange( + rangeToString({ count: contentLength, offset }), + "update", + contentLength, + { + abortSignal: options.abortSignal, + contentMD5: options.contentMD5, + onUploadProgress: options.onProgress, + body: body, + spanOptions, + leaseAccessConditions: options.leaseAccessConditions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Upload a range of bytes to a file where the contents are read from a another file's URL. + * The range can be up to 4 MB in size. + * + * @param {string} sourceURL Specify a URL to the copy source, Shared Access Signature(SAS) maybe needed for authentication. + * @param {number} sourceOffset The source offset to copy from. Pass 0 to copy from the beginning of source file. + * @param {number} destOffset Offset of destination file. + * @param {number} count Number of bytes to be uploaded from source file. + * @param {FileUploadRangeFromURLOptions} [options={}] Options to configure File - Upload Range from URL operation. + * @returns {Promise} + * @memberof FileURL + */ + public async uploadRangeFromURL( + sourceURL: string, + sourceOffset: number, + destOffset: number, + count: number, + options: FileUploadRangeFromURLOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-uploadRangeFromURL", + options.tracingOptions + ); + try { + if (sourceOffset < 0 || destOffset < 0) { + throw new RangeError(`sourceOffset and destOffset must be >= 0`); + } + + if (count <= 0 || count > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`count must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); + } + + return await this.context.uploadRangeFromURL( + rangeToString({ offset: destOffset, count }), + sourceURL, + 0, + { + abortSignal: options.abortSignal, + sourceRange: rangeToString({ offset: sourceOffset, count }), + sourceModifiedAccessConditions: options.sourceConditions, + ...options, + spanOptions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + /** + * Clears the specified range and + * releases the space used in storage for that range. + * + * @param {number} offset + * @param {number} contentLength + * @param {FileClearRangeOptions} [options] Options to File Clear Range operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async clearRange( + offset: number, + contentLength: number, + options: FileClearRangeOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-clearRange", options.tracingOptions); + try { + if (offset < 0 || contentLength <= 0) { + throw new RangeError(`offset must >= 0 and contentLength must be > 0`); + } + + return await this.context.uploadRange( + rangeToString({ count: contentLength, offset }), + "clear", + 0, + { + abortSignal: options.abortSignal, + spanOptions, + leaseAccessConditions: options.leaseAccessConditions + } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns the list of valid ranges for a file. + * + * @param {FileGetRangeListOptions} [options] Options to File Get range List operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async getRangeList( + options: FileGetRangeListOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-getRangeList", + options.tracingOptions + ); + try { + const originalResponse = await this.context.getRangeList({ + abortSignal: options.abortSignal, + range: options.range ? rangeToString(options.range) : undefined, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + + // Only returns ranges, ignoring clearRanges. + const parsedBody = originalResponse._response.parsedBody.ranges + ? originalResponse._response.parsedBody.ranges + : []; + return { + ...originalResponse, + _response: { ...originalResponse._response, parsedBody }, + rangeList: originalResponse.ranges ? originalResponse.ranges : [] + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns the list of ranges that differ between a previous share snapshot and this file. + * + * @param {string} [prevShareSnapshot] The previous snapshot parameter is an opaque DateTime value that specifies the previous share snapshot to compare with. + * @param {FileGetRangeListOptions} [options] + * @returns {Promise} + * @memberof ShareFileClient + */ + public async getRangeListDiff( + prevShareSnapshot: string, + options: FileGetRangeListOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-getRangeListDiff", + options.tracingOptions + ); + try { + return await this.context.getRangeList({ + prevsharesnapshot: prevShareSnapshot, + ...options, + range: options.range ? rangeToString(options.range) : undefined, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Copies a blob or file to a destination file within the storage account. + * + * @param {string} copySource Specifies the URL of the source file or blob, up to 2 KB in length. + * To copy a file to another file within the same storage account, you may use Shared Key to + * authenticate the source file. If you are copying a file from another storage account, or if you + * are copying a blob from the same storage account or another storage account, then you must + * authenticate the source file or blob using a shared access signature. If the source is a public + * blob, no authentication is required to perform the copy operation. A file in a share snapshot + * can also be specified as a copy source. + * @param {FileStartCopyOptions} [options] Options to File Start Copy operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async startCopyFromURL( + copySource: string, + options: FileStartCopyOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-startCopyFromURL", + options.tracingOptions + ); + try { + return await this.context.startCopy(copySource, { + abortSignal: options.abortSignal, + metadata: options.metadata, + leaseAccessConditions: options.leaseAccessConditions, + filePermission: options.filePermission, + filePermissionKey: options.filePermissionKey, + copyFileSmbInfo: options.copyFileSmbInfo, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Aborts a pending Copy File operation, and leaves a destination file with zero length and full + * metadata. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/abort-copy-file + * + * @param {string} copyId Id of the Copy File operation to abort. + * @param {FileAbortCopyFromURLOptions} [options] Options to File Abort Copy From URL operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async abortCopyFromURL( + copyId: string, + options: FileAbortCopyFromURLOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-abortCopyFromURL", + options.tracingOptions + ); + try { + return await this.context.abortCopy(copyId, { + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + // High Level functions + + /** + * Uploads a Buffer(Node)/Blob/ArrayBuffer/ArrayBufferView to an Azure File. + * + * @param {Buffer | Blob | ArrayBuffer | ArrayBufferView} data Buffer(Node), Blob, ArrayBuffer or ArrayBufferView + * @param {FileParallelUploadOptions} [options] + * @returns {Promise} + */ + public async uploadData( + data: Buffer | Blob | ArrayBuffer | ArrayBufferView, + options: FileParallelUploadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-uploadData", options.tracingOptions); + try { + if (isNode && data instanceof Buffer) { + return this.uploadBuffer( + (offset, count) => data.slice(offset, offset + count), + data.byteLength, + { + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + } + ); + } else { + const browserBlob = new Blob([data]); + return this.uploadSeekableBlob( + (offset: number, size: number): Blob => { + return browserBlob.slice(offset, offset + size); + }, + browserBlob.size, + { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } + ); + } + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN BROWSERS. + * + * Uploads a browser Blob object to an Azure file. Requires a blobFactory as the data source, + * which need to return a Blob object with the offset and size provided. + * + * @param {(offset: number, size: number) => Blob} blobFactory + * @param {number} size + * @param {FileParallelUploadOptions} [options] + * @returns {Promise} + */ + async uploadSeekableBlob( + blobFactory: (offset: number, size: number) => Blob, + size: number, + options: FileParallelUploadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-UploadSeekableBlob", + options.tracingOptions + ); + try { + if (!options.rangeSize) { + options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; + } + if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); + } + + if (!options.fileHttpHeaders) { + options.fileHttpHeaders = {}; + } + + if (!options.concurrency) { + options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; + } + if (options.concurrency < 0) { + throw new RangeError(`options.concurrency cannot less than 0.`); + } + + // Create the file + await this.create(size, { + abortSignal: options.abortSignal, + fileHttpHeaders: options.fileHttpHeaders, + metadata: options.metadata, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + + const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; + let transferProgress: number = 0; + + const batch = new Batch(options.concurrency); + for (let i = 0; i < numBlocks; i++) { + batch.addOperation( + async (): Promise => { + const start = options.rangeSize! * i; + const end = i === numBlocks - 1 ? size : start + options.rangeSize!; + const contentLength = end - start; + await this.uploadRange(blobFactory(start, contentLength), start, contentLength, { + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + // Update progress after block is successfully uploaded to server, in case of block trying + // TODO: Hook with convenience layer progress event in finer level + transferProgress += contentLength; + if (options.onProgress) { + options.onProgress({ loadedBytes: transferProgress }); + } + } + ); + } + return await batch.do(); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * Uploads a local file to an Azure file. + * + * @param {string} filePath Full path of local file + * @param {ShareFileClient} fileClient ShareFileClient + * @param {FileParallelUploadOptions} [options] + * @returns {(Promise)} + */ + public async uploadFile( + filePath: string, + options: FileParallelUploadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan("ShareFileClient-uploadFile", options.tracingOptions); + try { + const size = (await fsStat(filePath)).size; + return await this.uploadResetableStream( + (offset, count) => + fsCreateReadStream(filePath, { + autoClose: true, + end: count ? offset + count - 1 : Infinity, + start: offset + }), + size, + { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } + ); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * Accepts a Node.js Readable stream factory, and uploads in blocks to an Azure File. + * The Readable stream factory must returns a Node.js Readable stream starting from the offset defined. The offset + * is the offset in the Azure file to be uploaded. + * + * @export + * @param {(offset: number) => NodeJS.ReadableStream} streamFactory Returns a Node.js Readable stream starting + * from the offset defined + * @param {number} size Size of the Azure file + * @param {ShareFileClient} fileClient ShareFileClient + * @param {FileParallelUploadOptions} [options] + * @returns {(Promise)} + */ + async uploadResetableStream( + streamFactory: (offset: number, count?: number) => NodeJS.ReadableStream, + size: number, + options: FileParallelUploadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-uploadResetableStream", + options.tracingOptions + ); + try { + if (!options.rangeSize) { + options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; + } + if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); + } + + if (!options.fileHttpHeaders) { + options.fileHttpHeaders = {}; + } + + if (!options.concurrency) { + options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; + } + if (options.concurrency < 0) { + throw new RangeError(`options.concurrency cannot less than 0.`); + } + + // Create the file + await this.create(size, { + abortSignal: options.abortSignal, + fileHttpHeaders: options.fileHttpHeaders, + metadata: options.metadata, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + + const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; + let transferProgress: number = 0; + const batch = new Batch(options.concurrency); + + for (let i = 0; i < numBlocks; i++) { + batch.addOperation( + async (): Promise => { + const start = options.rangeSize! * i; + const end = i === numBlocks - 1 ? size : start + options.rangeSize!; + const contentLength = end - start; + await this.uploadRange( + () => streamFactory(start, contentLength), + start, + contentLength, + { + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + } + ); + // Update progress after block is successfully uploaded to server, in case of block trying + transferProgress += contentLength; + if (options.onProgress) { + options.onProgress({ loadedBytes: transferProgress }); + } + } + ); + } + return await batch.do(); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * @export + * @param {(offset: number, count: number) => Buffer} bufferChunk Returns a Node.js Buffer chunk starting + * from the offset defined till the count + * @param {number} size Size of the Azure file + * @param {ShareFileClient} fileClient ShareFileClient + * @param {FileParallelUploadOptions} [options] + * @returns {(Promise)} + */ + private async uploadBuffer( + bufferChunk: (offset: number, count: number) => Buffer, + size: number, + options: FileParallelUploadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-uploadBuffer", + options.tracingOptions + ); + try { + if (!options.rangeSize) { + options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; + } + if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); + } + + if (!options.fileHttpHeaders) { + options.fileHttpHeaders = {}; + } + + if (!options.concurrency) { + options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; + } + if (options.concurrency < 0) { + throw new RangeError(`options.concurrency cannot less than 0.`); + } + + // Create the file + await this.create(size, { + abortSignal: options.abortSignal, + fileHttpHeaders: options.fileHttpHeaders, + metadata: options.metadata, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + + const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; + let transferProgress: number = 0; + const batch = new Batch(options.concurrency); + + for (let i = 0; i < numBlocks; i++) { + batch.addOperation( + async (): Promise => { + const start = options.rangeSize! * i; + const end = i === numBlocks - 1 ? size : start + options.rangeSize!; + const contentLength = end - start; + await this.uploadRange(bufferChunk(start, contentLength), start, contentLength, { + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + // Update progress after block is successfully uploaded to server, in case of block trying + transferProgress += contentLength; + if (options.onProgress) { + options.onProgress({ loadedBytes: transferProgress }); + } + } + ); + } + return await batch.do(); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * Downloads an Azure file in parallel to a buffer. + * Offset and count are optional, pass 0 for both to download the entire file. + * + * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two + * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size, + * consider {@link downloadToFile}. + * + * @param {Buffer} buffer Buffer to be fill, must have length larger than count + * @param {number} offset From which position of the Azure File to download + * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined + * @param {FileDownloadToBufferOptions} [options] + * @returns {Promise} + */ + public async downloadToBuffer( + buffer: Buffer, + offset?: number, + count?: number, + options?: FileDownloadToBufferOptions + ): Promise; + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME + * + * Downloads an Azure file in parallel to a buffer. + * Offset and count are optional, pass 0 for both to download the entire file + * + * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two + * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size, + * consider {@link downloadToFile}. + * + * @param {number} offset From which position of the Azure file to download + * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined + * @param {FileDownloadToBufferOptions} [options] + * @returns {Promise} + */ + public async downloadToBuffer( + offset?: number, + count?: number, + options?: FileDownloadToBufferOptions + ): Promise; + + public async downloadToBuffer( + bufferOrOffset?: Buffer | number, + offsetOrCount?: number, + countOrOptions?: FileDownloadToBufferOptions | number, + optOptions: FileDownloadToBufferOptions = {} + ): Promise { + let buffer: Buffer | undefined = undefined; + let offset: number; + let count: number; + let options: FileDownloadToBufferOptions = optOptions; + + if (bufferOrOffset instanceof Buffer) { + buffer = bufferOrOffset; + offset = offsetOrCount || 0; + count = typeof countOrOptions === "number" ? countOrOptions : 0; + } else { + offset = typeof bufferOrOffset === "number" ? bufferOrOffset : 0; + count = typeof offsetOrCount === "number" ? offsetOrCount : 0; + options = (countOrOptions as FileDownloadToBufferOptions) || {}; + } + + const { span, spanOptions } = createSpan( + "ShareFileClient-downloadToBuffer", + options.tracingOptions + ); + + try { + if (!options.rangeSize) { + options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; + } + if (options.rangeSize < 0) { + throw new RangeError("rangeSize option must be > 0"); + } + + if (offset < 0) { + throw new RangeError("offset option must be >= 0"); + } + + if (count && count <= 0) { + throw new RangeError("count option must be > 0"); + } + + if (!options.concurrency) { + options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; + } + if (options.concurrency < 0) { + throw new RangeError(`options.concurrency cannot less than 0.`); + } + + // Customer doesn't specify length, get it + if (!count) { + const response = await this.getProperties({ + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + count = response.contentLength! - offset; + if (count < 0) { + throw new RangeError( + `offset ${offset} shouldn't be larger than file size ${response.contentLength!}` + ); + } + } + + if (!buffer) { + try { + buffer = Buffer.alloc(count); + } catch (error) { + throw new Error( + `Unable to allocate a buffer of size: ${count} bytes. Please try passing your own Buffer to ` + + 'the "downloadToBuffer method or try using other methods like "download" or "downloadToFile".' + + `\t ${error.message}` + ); + } + } + + if (buffer.length < count) { + throw new RangeError( + `The buffer's size should be equal to or larger than the request count of bytes: ${count}` + ); + } + + let transferProgress: number = 0; + const batch = new Batch(options.concurrency); + for (let off = offset; off < offset + count; off = off + options.rangeSize) { + batch.addOperation(async () => { + // Exclusive chunk end position + let chunkEnd = offset + count!; + if (off + options.rangeSize! < chunkEnd) { + chunkEnd = off + options.rangeSize!; + } + const response = await this.download(off, chunkEnd - off, { + abortSignal: options.abortSignal, + maxRetryRequests: options.maxRetryRequestsPerRange, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + const stream = response.readableStreamBody!; + await streamToBuffer(stream, buffer!, off - offset, chunkEnd - offset); + // Update progress after block is downloaded, in case of block trying + // Could provide finer grained progress updating inside HTTP requests, + // only if convenience layer download try is enabled + transferProgress += chunkEnd - off; + if (options.onProgress) { + options.onProgress({ loadedBytes: transferProgress }); + } + }); + } + await batch.do(); + return buffer; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * Uploads a Node.js Readable stream into an Azure file. + * This method will try to create an Azure, then starts uploading chunk by chunk. + * Size of chunk is defined by `bufferSize` parameter. + * Please make sure potential size of stream doesn't exceed file size. + * + * PERFORMANCE IMPROVEMENT TIPS: + * * Input stream highWaterMark is better to set a same value with bufferSize + * parameter, which will avoid Buffer.concat() operations. + * + * @param {Readable} stream Node.js Readable stream. Must be less or equal than file size. + * @param {number} size Size of file to be created. Maximum size allowed is 4 TB. + * If this value is larger than stream size, there will be empty bytes in file tail. + * @param {number} bufferSize Size of every buffer allocated in bytes, also the chunk/range size during + * the uploaded file. Size must be > 0 and <= 4 * 1024 * 1024 (4MB) + * @param {number} maxBuffers Max buffers will allocate during uploading, positive correlation + * with max uploading concurrency + * @param {FileUploadStreamOptions} [options] + * @returns {Promise} + */ + public async uploadStream( + stream: Readable, + size: number, + bufferSize: number, + maxBuffers: number, + options: FileUploadStreamOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-uploadStream", + options.tracingOptions + ); + try { + if (!options.fileHttpHeaders) { + options.fileHttpHeaders = {}; + } + + if (bufferSize <= 0 || bufferSize > FILE_RANGE_MAX_SIZE_BYTES) { + throw new RangeError(`bufferSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); + } + + if (maxBuffers < 0) { + throw new RangeError(`maxBuffers must be > 0.`); + } + + // Create the file + await this.create(size, { + abortSignal: options.abortSignal, + fileHttpHeaders: options.fileHttpHeaders, + metadata: options.metadata, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + + let transferProgress: number = 0; + const scheduler = new BufferScheduler( + stream, + bufferSize, + maxBuffers, + async (buffer: Buffer, offset?: number) => { + if (transferProgress + buffer.length > size) { + throw new RangeError( + `Stream size is larger than file size ${size} bytes, uploading failed. ` + + `Please make sure stream length is less or equal than file size.` + ); + } + + await this.uploadRange(buffer, offset!, buffer.length, { + abortSignal: options.abortSignal, + leaseAccessConditions: options.leaseAccessConditions, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + + // Update progress after block is successfully uploaded to server, in case of block trying + transferProgress += buffer.length; + if (options.onProgress) { + options.onProgress({ loadedBytes: transferProgress }); + } + }, + // Concurrency should set a smaller value than maxBuffers, which is helpful to + // reduce the possibility when a outgoing handler waits for stream data, in + // this situation, outgoing handlers are blocked. + // Outgoing queue shouldn't be empty. + Math.ceil((maxBuffers / 4) * 3) + ); + return await scheduler.do(); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * ONLY AVAILABLE IN NODE.JS RUNTIME. + * + * Downloads an Azure Blob to a local file. + * Fails if the the given file path already exits. + * Offset and count are optional, pass 0 and undefined respectively to download the entire blob. + * + * @param {string} filePath + * @param {number} [offset] From which position of the block blob to download. + * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined. + * @param {BlobDownloadOptions} [options] Options to Blob download options. + * @returns {Promise} The response data for blob download operation, + * but with readableStreamBody set to undefined since its + * content is already read and written into a local file + * at the specified path. + * @memberof BlobClient + */ + public async downloadToFile( + filePath: string, + offset: number = 0, + count?: number, + options: FileDownloadOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-downloadToFile", + options.tracingOptions + ); + try { + const response = await this.download(offset, count, { + ...options, + tracingOptions: { ...options!.tracingOptions, spanOptions } + }); + if (response.readableStreamBody) { + await readStreamToLocalFile(response.readableStreamBody, filePath); + } + + // The stream is no longer accessible so setting it to undefined. + (response as any).fileDownloadStream = undefined; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Lists handles for a file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles + * + * @param {string} [marker] Optional. A string value that identifies the portion of the list to be + * returned with the next list handles operation. The operation returns a + * marker value within the response body if the list returned was not complete. + * The marker value may then be used in a subsequent call to request the next + * set of list items. + * @param {FileListHandlesSegmentOptions} [options={}] + * @returns {Promise} + * @memberof FileURL + */ + private async listHandlesSegment( + marker?: string, + options: FileListHandlesSegmentOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-listHandlesSegment", + options.tracingOptions + ); + try { + marker = marker === "" ? undefined : marker; + const response = await this.context.listHandles({ + abortSignal: options.abortSignal, + marker, + ...options, + spanOptions + }); + + // TODO: Protocol layer issue that when handle list is in returned XML + // response.handleList is an empty string + if ((response.handleList as any) === "") { + response.handleList = undefined; + } + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Returns an AsyncIterableIterator for FileListHandlesResponse + * + * @private + * @param {string} [marker] A string value that identifies the portion of the list to be + * returned with the next list handles operation. The operation returns a + * marker value within the response body if the list returned was not complete. + * The marker value may then be used in a subsequent call to request the next + * set of list items. + * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation. + * @returns {AsyncIterableIterator} + * @memberof ShareFileClient + */ + private async *iterateHandleSegments( + marker?: string, + options: FileListHandlesSegmentOptions = {} + ): AsyncIterableIterator { + let listHandlesResponse; + if (!!marker || marker === undefined) { + do { + listHandlesResponse = await this.listHandlesSegment(marker, options); + marker = listHandlesResponse.continuationToken; + yield listHandlesResponse; + } while (marker); + } + } + + /** + * Returns an AsyncIterableIterator for handles + * + * @private + * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation. + * @returns {AsyncIterableIterator} + * @memberof ShareFileClient + */ + private async *listHandleItems( + options: FileListHandlesSegmentOptions = {} + ): AsyncIterableIterator { + let marker: string | undefined; + for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) { + if (listHandlesResponse.handleList) { + for (const handle of listHandlesResponse.handleList) { + yield handle; + } + } + } + } + + /** + * Returns an async iterable iterator to list all the handles. + * under the specified account. + * + * .byPage() returns an async iterable iterator to list the handles in pages. + * + * @param {FileListHandlesOptions} [options] Options to list handles operation. + * @memberof ShareFileClient + * @returns {PagedAsyncIterableIterator} + * An asyncIterableIterator that supports paging. + */ + public listHandles( + options: FileListHandlesOptions = {} + ): PagedAsyncIterableIterator { + // an AsyncIterableIterator to iterate over handles + const iter = this.listHandleItems(options); + return { + /** + * @member {Promise} [next] The next method, part of the iteration protocol + */ + async next() { + return iter.next(); + }, + /** + * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol + */ + [Symbol.asyncIterator]() { + return this; + }, + /** + * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time + */ + byPage: (settings: PageSettings = {}) => { + return this.iterateHandleSegments(settings.continuationToken, { + maxPageSize: settings.maxPageSize, + ...options + }); + } + }; + } + + /** + * Force close all handles for a file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {string} [marker] Optional. A string value that identifies the position of handles that will + * be closed with the next force close handles operation. + * The operation returns a marker value within the response + * body if there are more handles to close. The marker value + * may then be used in a subsequent call to close the next set of handles. + * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + private async forceCloseHandlesSegment( + marker?: string, + options: FileForceCloseHandlesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-forceCloseHandlesSegment", + options.tracingOptions + ); + try { + marker = marker === "" ? undefined : marker; + const rawResponse = await this.context.forceCloseHandles("*", { + abortSignal: options.abortSignal, + marker, + spanOptions + }); + const response = rawResponse as FileForceCloseHandlesResponse; + response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; + response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Force close all handles for a file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async forceCloseAllHandles( + options: FileForceCloseHandlesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-forceCloseAllHandles", + options.tracingOptions + ); + try { + let handlesClosed = 0; + let numberOfHandlesFailedToClose = 0; + let marker: string | undefined = ""; + + do { + const response: FileForceCloseHandlesResponse = await this.forceCloseHandlesSegment( + marker, + { tracingOptions: { ...options!.tracingOptions, spanOptions } } + ); + marker = response.marker; + response.closedHandlesCount && (handlesClosed += response.closedHandlesCount); + response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount); + } while (marker); + + return { + closedHandlesCount: handlesClosed, + closeFailureCount: numberOfHandlesFailedToClose + }; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Force close a specific handle for a file. + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles + * + * @param {string} handleId Specific handle ID, cannot be asterisk "*". + * Use forceCloseAllHandles() to close all handles. + * @param FileForceCloseHandlesOptions} [options] Options to force close handles operation. + * @returns {Promise} + * @memberof ShareFileClient + */ + public async forceCloseHandle( + handleId: string, + options: FileForceCloseHandlesOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareFileClient-forceCloseHandle", + options.tracingOptions + ); + try { + if (handleId === "*") { + throw new RangeError( + `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.` + ); + } + + const rawResponse = await this.context.forceCloseHandles(handleId, { + abortSignal: options.abortSignal, + spanOptions + }); + const response = rawResponse as FileForceCloseHandlesResponse; + response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; + response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * Get a {@link ShareLeaseClient} that manages leases on the file. + * + * @param {string} [proposeLeaseId] Initial proposed lease Id. + * @returns {ShareLeaseClient} A new ShareLeaseClient object for managing leases on the file. + * @memberof ShareFileClient + */ + public getShareLeaseClient(proposeLeaseId?: string) { + return new ShareLeaseClient(this, proposeLeaseId); + } +} + +/** + * The details of the response for a specific lease operation. + */ +export interface LeaseOperationResponseHeaders { + /** + * The ETag contains a value that you can use to perform operations conditionally. If the request + * version is 2011-08-18 or newer, the ETag value will be in quotes. + */ + etag?: string; + /** + * Returns the date and time the file was last modified. Any operation that modifies the file, + * including an update of the file's metadata or properties, changes the last-modified time of + * the file. + */ + lastModified?: Date; + /** + * Approximate time remaining in the lease period, in seconds. Only availabe for {@link ShareLeaseClient.breakLease} for share lease. + */ + leaseTimeInSeconds?: number; + /** + * Uniquely identifies a file's lease, won't be set when returned by releaseLease. + */ + leaseId?: string; + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the Blob service used to execute the request. This header is returned + * for requests made against version 2009-09-19 and above. + */ + version?: string; + /** + * UTC date/time value generated by the service that indicates the time at which the response was + * initiated + */ + date?: Date; + errorCode?: string; +} + +/** + * Contains the response data for operations that acquire, change, break or release a lease. + * + * See {@link ShareLeaseClient}. + */ +export type LeaseOperationResponse = LeaseOperationResponseHeaders & { + /** + * The underlying HTTP response. + */ + _response: HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: LeaseOperationResponseHeaders; + }; +}; + +/** + * lease operations options. + * + * @export + * @interface LeaseOperationOptions + */ +export interface LeaseOperationOptions extends CommonOptions { + /** + * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. + * For example, use the @azure/abort-controller to create an `AbortSignal`. + * + * @type {AbortSignalLike} + * @memberof LeaseOperationOptions + */ + abortSignal?: AbortSignalLike; +} + +/** + * A client that manages leases for a {@link ShareFileClient} or {@link ShareClient}. + * @see https://docs.microsoft.com/rest/api/storageservices/lease-file + * and + * @see https://docs.microsoft.com/rest/api/storageservices/lease-share + * + * @export + * @class ShareLeaseClient + */ +export class ShareLeaseClient { + private _leaseId: string; + private _url: string; + private fileOrShare: File | Share; + private isShare: boolean; + /** + * Gets the lease Id. + * + * @readonly + * @memberof ShareLeaseClient + * @type {string} + */ + public get leaseId(): string { + return this._leaseId; + } + + /** + * Gets the url. + * + * @readonly + * @memberof ShareLeaseClient + * @type {string} + */ + public get url(): string { + return this._url; + } + + /** + * Creates an instance of ShareLeaseClient. + * @param {ShareFileClient} client The client to make the lease operation requests. + * @param {string} leaseId Initial proposed lease id. + * @memberof ShareLeaseClient + */ + constructor(client: ShareFileClient | ShareClient, leaseId?: string) { + const clientContext = new StorageClientContext( + SERVICE_VERSION, + client.url, + (client as any).pipeline.toServiceClientOptions() + ); + + if (client instanceof ShareClient) { + this.isShare = true; + this.fileOrShare = new Share(clientContext); + } else { + this.isShare = false; + this.fileOrShare = new File(clientContext); + } + this._url = client.url; + + if (!leaseId) { + leaseId = generateUuid(); + } + this._leaseId = leaseId; + } + + /** + * Establishes and manages a lock on a file, share or share snapshot for write and delete operations. + * + * @param {number} duration Specifies the duration of lease in seconds. For file, the only allowed value is -1 for a lease that never expires. For share, must be -1 or between 15 to 60. + * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. + * @returns {Promise} Response data for acquire lease operation. + * @memberof ShareLeaseClient + */ + public async acquireLease( + duration: number = -1, + options: LeaseOperationOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareLeaseClient-acquireLease", + options.tracingOptions + ); + try { + return await this.fileOrShare.acquireLease({ + abortSignal: options.abortSignal, + duration, + proposedLeaseId: this._leaseId, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * To change the ID of an existing lease. + * + * @param {string} proposedLeaseId the proposed new lease Id. + * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. + * @returns {Promise} Response data for change lease operation. + * @memberof ShareLeaseClient + */ + public async changeLease( + proposedLeaseId: string, + options: LeaseOperationOptions = {} + ): Promise { + const { span, spanOptions } = createSpan( + "ShareLeaseClient-changeLease", + options.tracingOptions + ); + try { + const response = await this.fileOrShare.changeLease(this._leaseId, { + proposedLeaseId, + abortSignal: options.abortSignal, + spanOptions + }); + this._leaseId = proposedLeaseId; + return response; + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * To free the lease if it is no longer needed so that another client may + * immediately acquire a lease. + * + * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. + * @returns {Promise} Response data for release lease operation. + * @memberof ShareLeaseClient + */ + public async releaseLease(options: LeaseOperationOptions = {}): Promise { + const { span, spanOptions } = createSpan( + "ShareLeaseClient-releaseLease", + options.tracingOptions + ); + try { + return await this.fileOrShare.releaseLease(this._leaseId, { + abortSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * To force end the lease. + * + * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. + * @returns {Promise} Response data for break lease operation. + * @memberof ShareLeaseClient + */ + public async breakLease(options: LeaseOperationOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareLeaseClient-breakLease", options.tracingOptions); + try { + return await this.fileOrShare.breakLease({ + abortSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } + + /** + * To renew the lease. Only available for lease on share or share snapshot. + * Note that the lease may be renewed even if it has expired as long as the share has not been leased again since the expiration of that lease. + * When you renew a lease, the lease duration clock resets. + * + * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. + * @returns {Promise} Response data for renew lease operation. + * @memberof ShareLeaseClient + */ + public async renewLease(options: LeaseOperationOptions = {}): Promise { + const { span, spanOptions } = createSpan("ShareLeaseClient-renewLease", options.tracingOptions); + + if (!this.isShare) { + throw new RangeError("The renewLease operation is not available for lease on file."); + } + + try { + return await (this.fileOrShare as Share).renewLease(this._leaseId, { + abortSignal: options.abortSignal, + spanOptions + }); + } catch (e) { + span.setStatus({ + code: CanonicalCode.UNKNOWN, + message: e.message + }); + throw e; + } finally { + span.end(); + } + } +} diff --git a/sdk/storage/storage-file-share/src/ShareClient.ts b/sdk/storage/storage-file-share/src/ShareClient.ts deleted file mode 100644 index e64e532ae62c..000000000000 --- a/sdk/storage/storage-file-share/src/ShareClient.ts +++ /dev/null @@ -1,1223 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { HttpResponse, isNode } from "@azure/core-http"; -import { CanonicalCode } from "@opentelemetry/api"; -import { AbortSignalLike } from "@azure/abort-controller"; -import { - DeleteSnapshotsOptionType, - DirectoryCreateResponse, - DirectoryDeleteResponse, - FileCreateResponse, - FileDeleteResponse, - ShareCreatePermissionResponse, - ShareCreateResponse, - ShareCreateSnapshotResponse, - ShareDeleteResponse, - ShareGetAccessPolicyHeaders, - ShareGetPermissionResponse, - ShareGetPropertiesResponse, - ShareSetAccessPolicyResponse, - ShareSetMetadataResponse, - ShareSetQuotaResponse, - SignedIdentifierModel, - ShareGetStatisticsResponseModel -} from "./generatedModels"; -import { Share } from "./generated/src/operations"; -import { Metadata } from "./models"; -import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; -import { StorageClient, CommonOptions } from "./StorageClient"; -import { URLConstants } from "./utils/constants"; -import { - appendToURLPath, - setURLParameter, - truncatedISO8061Date, - extractConnectionStringParts, - getShareNameAndPathFromUrl -} from "./utils/utils.common"; -import { - ShareDirectoryClient, - DirectoryCreateOptions, - DirectoryDeleteOptions -} from "./ShareDirectoryClient"; -import { FileCreateOptions, FileDeleteOptions, ShareFileClient } from "./ShareFileClient"; -import { Credential } from "./credentials/Credential"; -import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; -import { AnonymousCredential } from "./credentials/AnonymousCredential"; -import { createSpan } from "./utils/tracing"; - -/** - * Options to configure the {@link ShareClient.create} operation. - * - * @export - * @interface ShareCreateOptions - */ -export interface ShareCreateOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareCreateOptions - */ - abortSignal?: AbortSignalLike; - /** - * A name-value pair to associate with a file storage object. - * - * @type {{ [propertyName: string]: string }} - * @memberof ShareCreateOptions - */ - metadata?: { [propertyName: string]: string }; - - /** - * Specifies the maximum size of the share, in - * gigabytes. - * - * @type {number} - * @memberof ShareCreateOptions - */ - quota?: number; -} - -/** - * Options to configure the {@link ShareClient.delete} operation. - * - * @export - * @interface ShareDeleteMethodOptions - */ -export interface ShareDeleteMethodOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareDeleteMethodOptions - */ - abortSignal?: AbortSignalLike; - /** - * Specifies the option - * include to delete the base share and all of its snapshots. Possible values - * include: 'include' - * - * @type {DeleteSnapshotsOptionType} - * @memberof ShareDeleteMethodOptions - */ - deleteSnapshots?: DeleteSnapshotsOptionType; -} - -/** - * Options to configure the {@link ShareClient.setMetadata} operation. - * - * @export - * @interface ShareSetMetadataOptions - */ -export interface ShareSetMetadataOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareSetMetadataOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.setAccessPolicy} operation. - * - * @export - * @interface ShareSetAccessPolicyOptions - */ -export interface ShareSetAccessPolicyOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareSetAccessPolicyOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.getAccessPolicy} operation. - * - * @export - * @interface ShareGetAccessPolicyOptions - */ -export interface ShareGetAccessPolicyOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareGetAccessPolicyOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.exists} operation. - * - * @export - * @interface ShareExistsOptions - */ -export interface ShareExistsOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareExistsOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.getProperties} operation. - * - * @export - * @interface ShareGetPropertiesOptions - */ -export interface ShareGetPropertiesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareGetPropertiesOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.setQuota} operation. - * - * @export - * @interface ShareSetQuotaOptions - */ -export interface ShareSetQuotaOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareSetQuotaOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareClient.getStatistics} operation. - * - * @export - * @interface ShareGetStatisticsOptions - */ -export interface ShareGetStatisticsOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareGetStatisticsOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Signed Identifier - * - * @export - * @interface SignedIdentifier - */ -export interface SignedIdentifier { - /** - * @member {string} id a unique id - */ - id: string; - /** - * @member {AccessPolicy} accessPolicy - */ - accessPolicy: { - /** - * @member {Date} startsOn the date-time the policy is active. - */ - startsOn: Date; - /** - * @member {string} expiresOn the date-time the policy expires. - */ - expiresOn: Date; - /** - * @member {string} permissions the permissions for the acl policy - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl - */ - permissions: string; - }; -} - -export declare type ShareGetAccessPolicyResponse = { - signedIdentifiers: SignedIdentifier[]; -} & ShareGetAccessPolicyHeaders & { - /** - * The underlying HTTP response. - */ - _response: HttpResponse & { - /** - * The parsed HTTP response headers. - */ - parsedHeaders: ShareGetAccessPolicyHeaders; - /** - * The response body as text (string format) - */ - bodyAsText: string; - /** - * The response body as parsed JSON or XML - */ - parsedBody: SignedIdentifierModel[]; - }; - }; - -/** - * Options to configure the {@link ShareClient.createSnapshot} operation. - * - * @export - * @interface ShareCreateSnapshotOptions - */ -export interface ShareCreateSnapshotOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareCreateSnapshotOptions - */ - abortSignal?: AbortSignalLike; - /** - * A name-value pair to associate with a file storage object. - * - * @type {{ [propertyName: string]: string }} - * @memberof ShareCreateOptions - */ - metadata?: { [propertyName: string]: string }; -} - -/** - * Options to configure the {@link ShareClient.createPermission} operation. - * - * @export - * @interface ShareCreatePermissionOptions - */ -export interface ShareCreatePermissionOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareCreatePermissionOptions - */ - abortSignal?: AbortSignalLike; -} -/** - * Options to configure the {@link ShareClient.getPermission} operation. - * - * @export - * @interface ShareGetPermissionOptions - */ -export interface ShareGetPermissionOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof ShareGetPermissionOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Response data for the {@link ShareClient.getStatistics} Operation. - * - * @export - * @interface ShareGetStatisticsResponse - */ -export type ShareGetStatisticsResponse = ShareGetStatisticsResponseModel & { - /** - * @deprecated shareUsage is going to be deprecated. Please use ShareUsageBytes instead. - * - * The approximate size of the data stored on the share, rounded up to the nearest gigabyte. Note - * that this value may not include all recently created or recently resized files. - * - * @type {number} - * @memberof ShareGetStatisticsResponse - */ - shareUsage: number; -}; - -/** - * Contains response data for the {@link ShareClient.createIfNotExists} operation. - * - * @export - * @interface ShareCreateIfNotExistsResponse - */ -export interface ShareCreateIfNotExistsResponse extends ShareCreateResponse { - /** - * Indicate whether the share is successfully created. Is false when the share is not changed as it already exists. - * - * @type {boolean} - * @memberof ShareCreateIfNotExistsResponse - */ - succeeded: boolean; -} - -/** - * Contains response data for the {@link ShareClient.deleteIfExists} operation. - * - * @export - * @interface ShareDeleteIfExistsResponse - */ -export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse { - /** - * Indicate whether the share is successfully deleted. Is false if the share does not exist in the first place. - * - * @type {boolean} - * @memberof ShareDeleteIfExistsResponse - */ - succeeded: boolean; -} - -/** - * A ShareClient represents a URL to the Azure Storage share allowing you to manipulate its directories and files. - * - * @export - * @class ShareClient - */ -export class ShareClient extends StorageClient { - /** - * Share operation context provided by protocol layer. - * - * @private - * @type {Share} - * @memberof ShareClient - */ - private context: Share; - - private _name: string; - - /** - * The name of the share - * - * @type {string} - * @memberof ShareClient - */ - public get name(): string { - return this._name; - } - - /** - * @param {string} connectionString Account connection string or a SAS connection string of an Azure storage account. - * [ Note - Account connection string can only be used in NODE.JS runtime. ] - * Account connection string example - - * `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net` - * SAS connection string example - - * `BlobEndpoint=https://myaccount.blob.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString` - * @param {string} name Share name. - * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. - * @memberof ShareClient - */ - constructor(connectionString: string, name: string, options?: StoragePipelineOptions); - /** - * Creates an instance of ShareClient. - * - * @param {string} url A URL string pointing to Azure Storage file share, such as - * "https://myaccount.file.core.windows.net/share". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/share?sasString". - * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. - * If not specified, AnonymousCredential is used. - * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. - * @memberof ShareClient - */ - constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); - /** - * Creates an instance of ShareClient. - * - * @param {string} url A URL string pointing to Azure Storage file share, such as - * "https://myaccount.file.core.windows.net/share". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/share?sasString". - * @param {Pipeline} pipeline Call newPipeline() to create a default - * pipeline, or provide a customized pipeline. - * @memberof ShareClient - */ - constructor(url: string, pipeline: Pipeline); - constructor( - urlOrConnectionString: string, - credentialOrPipelineOrShareName?: Credential | Pipeline | string, - options?: StoragePipelineOptions - ) { - let pipeline: Pipeline; - let url: string; - if (credentialOrPipelineOrShareName instanceof Pipeline) { - // (url: string, pipeline: Pipeline) - url = urlOrConnectionString; - pipeline = credentialOrPipelineOrShareName; - } else if (credentialOrPipelineOrShareName instanceof Credential) { - // (url: string, credential?: Credential, options?: StoragePipelineOptions) - url = urlOrConnectionString; - pipeline = newPipeline(credentialOrPipelineOrShareName, options); - } else if ( - !credentialOrPipelineOrShareName && - typeof credentialOrPipelineOrShareName !== "string" - ) { - // (url: string, credential?: Credential, options?: StoragePipelineOptions) - // The second parameter is undefined. Use anonymous credential. - url = urlOrConnectionString; - pipeline = newPipeline(new AnonymousCredential(), options); - } else if ( - credentialOrPipelineOrShareName && - typeof credentialOrPipelineOrShareName === "string" - ) { - // (connectionString: string, name: string, options?: StoragePipelineOptions) - const extractedCreds = extractConnectionStringParts(urlOrConnectionString); - const name = credentialOrPipelineOrShareName; - if (extractedCreds.kind === "AccountConnString") { - if (isNode) { - const sharedKeyCredential = new StorageSharedKeyCredential( - extractedCreds.accountName!, - extractedCreds.accountKey - ); - url = appendToURLPath(extractedCreds.url, name); - pipeline = newPipeline(sharedKeyCredential, options); - } else { - throw new Error("Account connection string is only supported in Node.js environment"); - } - } else if (extractedCreds.kind === "SASConnString") { - url = appendToURLPath(extractedCreds.url, name) + "?" + extractedCreds.accountSas; - pipeline = newPipeline(new AnonymousCredential(), options); - } else { - throw new Error( - "Connection string must be either an Account connection string or a SAS connection string" - ); - } - } else { - throw new Error("Expecting non-empty strings for name parameter"); - } - super(url, pipeline); - this._name = getShareNameAndPathFromUrl(this.url).shareName; - this.context = new Share(this.storageClientContext); - } - - /** - * Creates a new ShareClient object identical to the source but with the specified snapshot timestamp. - * Provide "" will remove the snapshot and return a URL to the base share. - * - * @param {string} snapshot The snapshot timestamp. - * @returns {ShareClient} A new ShareClient object identical to the source but with the specified snapshot timestamp - * @memberof ShareClient - */ - public withSnapshot(snapshot: string): ShareClient { - return new ShareClient( - setURLParameter( - this.url, - URLConstants.Parameters.SHARE_SNAPSHOT, - snapshot.length === 0 ? undefined : snapshot - ), - this.pipeline - ); - } - - /** - * Creates a new share under the specified account. If the share with - * the same name already exists, the operation fails. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share - * - * @param {ShareCreateOptions} [options] Options to Share Create operation. - * @returns {Promise} Response data for the Share Create operation. - * @memberof ShareClient - */ - public async create(options: ShareCreateOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareClient-create", options.tracingOptions); - try { - return await this.context.create({ - ...options, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a new share under the specified account. If the share with - * the same name already exists, it is not changed. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share - * - * @param {ShareCreateOptions} [options] - * @returns {Promise} - * @memberof ShareClient - */ - public async createIfNotExists( - options: ShareCreateOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareClient-createIfNotExists", - options.tracingOptions - ); - try { - const res = await this.create({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - succeeded: true, - ...res - }; - } catch (e) { - if (e.details?.errorCode === "ShareAlreadyExists") { - span.setStatus({ - code: CanonicalCode.ALREADY_EXISTS, - message: "Expected exception when creating a share only if it doesn't already exist." - }); - return { - succeeded: false, - ...e.response?.parsedHeaders, - _response: e.response - }; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a {@link ShareDirectoryClient} object. - * - * @param directoryName A directory name - * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given directory name. - * @memberof ShareClient - */ - public getDirectoryClient(directoryName: string): ShareDirectoryClient { - return new ShareDirectoryClient( - appendToURLPath(this.url, encodeURIComponent(directoryName)), - this.pipeline - ); - } - - /** - * Gets the directory client for the root directory of this share. - * Note that the root directory always exists and cannot be deleted. - * - * @readonly - * @type {ShareDirectoryClient} A new ShareDirectoryClient object for the root directory. - * @memberof ShareClient - */ - public get rootDirectoryClient(): ShareDirectoryClient { - return this.getDirectoryClient(""); - } - - /** - * Creates a new subdirectory under this share. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory - * - * @param {string} directoryName - * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. - * @returns {Promise<{ directoryClient: ShareDirectoryClient, directoryCreateResponse: DirectoryCreateResponse }>} Directory creation response data and the corresponding directory client. - * @memberof ShareClient - */ - public async createDirectory( - directoryName: string, - options: DirectoryCreateOptions = {} - ): Promise<{ - directoryClient: ShareDirectoryClient; - directoryCreateResponse: DirectoryCreateResponse; - }> { - const { span, spanOptions } = createSpan("ShareClient-createDirectory", options.tracingOptions); - try { - const directoryClient = this.getDirectoryClient(directoryName); - const directoryCreateResponse = await directoryClient.create({ - ...options, - tracingOptions: { ...options.tracingOptions, spanOptions } - }); - return { - directoryClient, - directoryCreateResponse - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the specified empty sub directory under this share. - * Note that the directory must be empty before it can be deleted. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory - * - * @param {string} directoryName - * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. - * @returns {Promise} Directory deletion response data. - * @memberof ShareClient - */ - public async deleteDirectory( - directoryName: string, - options: DirectoryDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-deleteDirectory", options.tracingOptions); - try { - const directoryClient = this.getDirectoryClient(directoryName); - return await directoryClient.delete({ - ...options, - tracingOptions: { ...options.tracingOptions, spanOptions } - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a new file or replaces a file under the root directory of this share. - * Note it only initializes the file with no content. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file - * - * @param {string} fileName - * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB. - * @param {FileCreateOptions} [options] Options to File Create operation. - * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client. - * @memberof ShareClient - */ - public async createFile( - fileName: string, - size: number, - options: FileCreateOptions = {} - ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> { - const { span, spanOptions } = createSpan("ShareClient-createFile", options.tracingOptions); - try { - const directoryClient = this.rootDirectoryClient; - const fileClient = directoryClient.getFileClient(fileName); - const fileCreateResponse = await fileClient.create(size, { - ...options, - tracingOptions: { ...options.tracingOptions, spanOptions } - }); - return { - fileClient, - fileCreateResponse - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes a file under the root directory of this share from the storage account. - * When a file is successfully deleted, it is immediately removed from the storage - * account's index and is no longer accessible to clients. The file's data is later - * removed from the service during garbage collection. - * - * Delete File will fail with status code 409 (Conflict) and error code `SharingViolation` - * if the file is open on an SMB client. - * - * Delete File is not supported on a share snapshot, which is a read-only copy of - * a share. An attempt to perform this operation on a share snapshot will fail with 400 - * (`InvalidQueryParameterValue`) - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 - * - * @param {string} directoryName - * @param {string} fileName - * @param {FileDeleteOptions} [options] Options to File Delete operation. - * @returns Promise File Delete response data. - * @memberof ShareClient - */ - public async deleteFile( - fileName: string, - options: FileDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-deleteFile", options.tracingOptions); - try { - const directoryClient = this.rootDirectoryClient; - const fileClient = directoryClient.getFileClient(fileName); - return await fileClient.delete({ - ...options, - tracingOptions: { ...options.tracingOptions, spanOptions } - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns true if the Azrue share resource represented by this client exists; false otherwise. - * - * NOTE: use this function with care since an existing share might be deleted by other clients or - * applications. Vice versa new shares might be added by other clients or applications after this - * function completes. - * - * @param {ShareExistsOptions} [options] options to Exists operation. - * @returns {Promise} - * @memberof ShareClient - */ - public async exists(options: ShareExistsOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareClient-exists", options.tracingOptions); - try { - await this.getProperties({ - abortSignal: options.abortSignal, - tracingOptions: { ...options.tracingOptions, spanOptions } - }); - return true; - } catch (e) { - if (e.statusCode === 404) { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when checking share existence" - }); - return false; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns all user-defined metadata and system properties for the specified - * share. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-properties - * - * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if - * they originally contained uppercase characters. This differs from the metadata keys returned by - * the `listShares` method of {@link ShareServiceClient} using the `includeMetadata` option, which - * will retain their original casing. - * - * @returns {Promise} Response data for the Share Get Properties operation. - * @memberof ShareClient - */ - public async getProperties( - options: ShareGetPropertiesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-getProperties", options.tracingOptions); - try { - return await this.context.getProperties({ - abortSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Marks the specified share for deletion. The share and any directories or files - * contained within it are later deleted during garbage collection. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share - * - * @param {ShareDeleteMethodOptions} [options] Options to Share Delete operation. - * @returns {Promise} Response data for the Share Delete operation. - * @memberof ShareClient - */ - public async delete(options: ShareDeleteMethodOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareClient-delete", options.tracingOptions); - try { - return await this.context.deleteMethod({ - ...options, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Marks the specified share for deletion if it exists. The share and any directories or files - * contained within it are later deleted during garbage collection. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share - * - * @param {ShareDeleteMethodOptions} [options] - * @returns {Promise} - * @memberof ShareClient - */ - public async deleteIfExists( - options: ShareDeleteMethodOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-deleteIfExists", options.tracingOptions); - try { - const res = await this.delete({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - succeeded: true, - ...res - }; - } catch (e) { - if (e.details?.errorCode === "ShareNotFound") { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when deleting a share only if it exists." - }); - return { - succeeded: false, - ...e.response?.parsedHeaders, - _response: e.response - }; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets one or more user-defined name-value pairs for the specified share. - * - * If no option provided, or no metadata defined in the option parameter, the share - * metadata will be removed. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-metadata - * - * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed. - * @param {ShareSetMetadataOptions} [option] Options to Share Set Metadata operation. - * @returns {Promise} Response data for the Share Set Metadata operation. - * @memberof ShareClient - */ - public async setMetadata( - metadata?: Metadata, - options: ShareSetMetadataOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-setMetadata", options.tracingOptions); - try { - return await this.context.setMetadata({ - abortSignal: options.abortSignal, - metadata, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Gets the permissions for the specified share. The permissions indicate - * whether share data may be accessed publicly. - * - * WARNING: JavaScript Date will potential lost precision when parsing start and expiry string. - * For example, new Date("2018-12-31T03:44:23.8827891Z").toISOString() will get "2018-12-31T03:44:23.882Z". - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-acl - * - * @param {ShareGetAccessPolicyOptions} [option] Options to Share Get Access Policy operation. - * @returns {Promise} Response data for the Share Get Access Policy operation. - * @memberof ShareClient - */ - public async getAccessPolicy( - options: ShareGetAccessPolicyOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-getAccessPolicy", options.tracingOptions); - try { - const response = await this.context.getAccessPolicy({ - abortSignal: options.abortSignal, - spanOptions - }); - - const res: ShareGetAccessPolicyResponse = { - _response: response._response, - date: response.date, - etag: response.etag, - lastModified: response.lastModified, - requestId: response.requestId, - signedIdentifiers: [], - version: response.version - }; - - for (const identifier of response) { - res.signedIdentifiers.push({ - accessPolicy: { - expiresOn: new Date(identifier.accessPolicy!.expiresOn!), - permissions: identifier.accessPolicy!.permissions!, - startsOn: new Date(identifier.accessPolicy!.startsOn!) - }, - id: identifier.id - }); - } - - return res; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets the permissions for the specified share. The permissions indicate - * whether directories or files in a share may be accessed publicly. - * - * When you set permissions for a share, the existing permissions are replaced. - * If no shareAcl provided, the existing share ACL will be - * removed. - * - * When you establish a stored access policy on a share, it may take up to 30 seconds to take effect. - * During this interval, a shared access signature that is associated with the stored access policy will - * fail with status code 403 (Forbidden), until the access policy becomes active. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl - * - * @param {SignedIdentifier[]} [shareAcl] Array of signed identifiers, each having a unique Id and details of access policy. - * @param {ShareSetAccessPolicyOptions} [option] Options to Share Set Access Policy operation. - * @returns {Promise} Response data for the Share Set Access Policy operation. - * @memberof ShareClient - */ - public async setAccessPolicy( - shareAcl?: SignedIdentifier[], - options: ShareSetAccessPolicyOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-setAccessPolicy", options.tracingOptions); - try { - const acl: SignedIdentifierModel[] = []; - for (const identifier of shareAcl || []) { - acl.push({ - accessPolicy: { - expiresOn: truncatedISO8061Date(identifier.accessPolicy.expiresOn), - permissions: identifier.accessPolicy.permissions, - startsOn: truncatedISO8061Date(identifier.accessPolicy.startsOn) - }, - id: identifier.id - }); - } - - return await this.context.setAccessPolicy({ - abortSignal: options.abortSignal, - shareAcl: acl, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a read-only snapshot of a share. - * - * @param {ShareCreateSnapshotOptions} [options={}] Options to Share Create Snapshot operation. - * @returns {Promise} Response data for the Share Create Snapshot operation. - * @memberof ShareClient - */ - public async createSnapshot( - options: ShareCreateSnapshotOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-createSnapshot", options.tracingOptions); - try { - return await this.context.createSnapshot({ - abortSignal: options.abortSignal, - ...options, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets quota for the specified share. - * - * @param {number} quotaInGB Specifies the maximum size of the share in gigabytes - * @param {ShareSetQuotaOptions} [option] Options to Share Set Quota operation. - * @returns {Promise} Response data for the Share Get Quota operation. - * @memberof ShareClient - */ - public async setQuota( - quotaInGB: number, - options: ShareSetQuotaOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-setQuota", options.tracingOptions); - try { - if (quotaInGB <= 0 || quotaInGB > 5120) { - throw new RangeError( - `Share quota must be greater than 0, and less than or equal to 5Tib (5120GB)` - ); - } - return await this.context.setQuota({ - abortSignal: options.abortSignal, - quota: quotaInGB, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Retrieves statistics related to the share. - * - * @param {ShareGetStatisticsOptions} [option] Options to Share Get Statistics operation. - * @returns {Promise} Response data for the Share Get Statistics operation. - * @memberof ShareClient - */ - public async getStatistics( - options: ShareGetStatisticsOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-getStatistics", options.tracingOptions); - try { - const response = await this.context.getStatistics({ - abortSignal: options.abortSignal, - spanOptions - }); - - const GBBytes = 1024 * 1024 * 1024; - return { ...response, shareUsage: Math.ceil(response.shareUsageBytes / GBBytes) }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a file permission (a security descriptor) at the share level. - * The created security descriptor can be used for the files/directories in the share. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-permission - * - * @param {ShareCreatePermissionOptions} [options] Options to Share Create Permission operation. - * @param filePermission File permission described in the SDDL - */ - public async createPermission( - filePermission: string, - options: ShareCreatePermissionOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareClient-createPermission", - options.tracingOptions - ); - try { - return await this.context.createPermission( - { - permission: filePermission - }, - { - abortSignal: options.abortSignal, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Gets the Security Descriptor Definition Language (SDDL) for a given file permission key - * which indicates a security descriptor. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-permission - * - * @param {ShareGetPermissionOptions} [options] Options to Share Create Permission operation. - * @param filePermissionKey File permission key which indicates the security descriptor of the permission. - */ - public async getPermission( - filePermissionKey: string, - options: ShareGetPermissionOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareClient-getPermission", options.tracingOptions); - try { - return await this.context.getPermission(filePermissionKey, { - aborterSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } -} diff --git a/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts b/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts deleted file mode 100644 index ca018b60e0e3..000000000000 --- a/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts +++ /dev/null @@ -1,1587 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { AbortSignalLike } from "@azure/abort-controller"; -import { - DirectoryCreateResponse, - DirectoryDeleteResponse, - DirectoryGetPropertiesResponse, - DirectoryItem, - DirectoryListFilesAndDirectoriesSegmentResponse, - DirectoryListHandlesResponse, - DirectorySetMetadataResponse, - DirectorySetPropertiesResponse, - FileCreateResponse, - FileDeleteResponse, - FileItem, - HandleItem, - DirectoryForceCloseHandlesHeaders -} from "./generatedModels"; -import { Directory } from "./generated/src/operations"; -import { - Metadata, - FileAndDirectoryCreateCommonOptions, - FileAndDirectorySetPropertiesCommonOptions, - validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions, - fileAttributesToString, - fileCreationTimeToString, - fileLastWriteTimeToString, - validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions, - CloseHandlesInfo -} from "./models"; -import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; -import { appendToURLPath, getShareNameAndPathFromUrl } from "./utils/utils.common"; -import { StorageClient, CommonOptions } from "./StorageClient"; -import "@azure/core-paging"; -import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; -import { ShareFileClient, FileCreateOptions, FileDeleteOptions } from "./ShareFileClient"; -import { Credential } from "./credentials/Credential"; -import { AnonymousCredential } from "./credentials/AnonymousCredential"; -import { FileSystemAttributes } from "./FileSystemAttributes"; -import { createSpan } from "./utils/tracing"; -import { CanonicalCode } from "@opentelemetry/api"; -import { HttpResponse } from "@azure/core-http"; - -/** - * Options to configure {@link ShareDirectoryClient.create} operation. - * - * @export - * @interface DirectoryCreateOptions - */ -export interface DirectoryCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryCreateOptions - */ - abortSignal?: AbortSignalLike; - /** - * A collection of key-value string pair to associate with the file storage object. - * - * @type {Metadata} - * @memberof DirectoryCreateOptions - */ - metadata?: Metadata; -} - -export interface DirectoryProperties - extends FileAndDirectorySetPropertiesCommonOptions, - CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryProperties - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure Directory - List Files and Directories Segment operations. - * - * See: - * - {@link ShareDirectoryClient.iterateFilesAndDirectoriesSegments} - * - {@link ShareDirectoryClient.listFilesAndDirectoriesItems} - * - {@link ShareDirectoryClient.listFilesAndDirectoriesSegment} - * - * @interface DirectoryListFilesAndDirectoriesSegmentOptions - */ -interface DirectoryListFilesAndDirectoriesSegmentOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryListFilesAndDirectoriesSegmentOptions - */ - abortSignal?: AbortSignalLike; - /** - * Filters the results to return only entries whose - * name begins with the specified prefix. - * - * @type {string} - * @memberof DirectoryListFilesAndDirectoriesSegmentOptions - */ - prefix?: string; - - /** - * Specifies the maximum number of entries to - * return. If the request does not specify maxResults, or specifies a value - * greater than 5,000, the server will return up to 5,000 items. - * - * @type {number} - * @memberof DirectoryListFilesAndDirectoriesSegmentOptions - */ - maxResults?: number; -} - -/** - * Options to configure {@link ShareDirectoryClient.listFilesAndDirectories} operation. - * - * @export - * @interface DirectoryListFilesAndDirectoriesOptions - */ -export interface DirectoryListFilesAndDirectoriesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryListFilesAndDirectoriesOptions - */ - abortSignal?: AbortSignalLike; - /** - * Filters the results to return only entries whose - * name begins with the specified prefix. - * - * @type {string} - * @memberof DirectoryListFilesAndDirectoriesOptions - */ - prefix?: string; -} - -/** - * Options to configure the {@link ShareDirectoryClient.delete} operation. - * - * @export - * @interface DirectoryDeleteOptions - */ -export interface DirectoryDeleteOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryDeleteOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareDirectoryClient.exists} operation. - * - * @export - * @interface DirectoryExistsOptions - */ -export interface DirectoryExistsOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryExistsOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareDirectoryClient.getProperties} operation. - * - * @export - * @interface DirectoryGetPropertiesOptions - */ -export interface DirectoryGetPropertiesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryGetPropertiesOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareDirectoryClient.setMetadata} operation. - * - * @export - * @interface DirectorySetMetadataOptions - */ -export interface DirectorySetMetadataOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectorySetMetadataOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure Directory - List Handles Segment operations. - * - * See: - * - {@link ShareDirectoryClient.listHandlesSegment} - * - {@link ShareDirectoryClient.iterateHandleSegments} - * - {@link ShareDirectoryClient.listHandleItems} - * - * - * @export - * @interface DirectoryListHandlesSegmentOptions - */ -export interface DirectoryListHandlesSegmentOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryListHandlesSegmentOptions - */ - abortSignal?: AbortSignalLike; - /** - * Specifies the maximum number of entries to return. If the request does not specify maxResults, - * or specifies a value greater than 5,000, the server will return up to 5,000 items. - * - * @type {number} - * @memberof DirectoryListHandlesSegmentOptions - */ - maxResults?: number; - /** - * Specifies operation should apply to the directory specified in the URI, its files, its - * subdirectories and their files. - * - * @type {boolean} - * @memberof DirectoryListHandlesSegmentOptions - */ - recursive?: boolean; -} - -/** - * Options to configure the {@link ShareDirectoryClient.listHandles} operation. - * - * @export - * @interface DirectoryListHandlesOptions - */ -export interface DirectoryListHandlesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryListHandlesOptions - */ - abortSignal?: AbortSignalLike; - /** - * Specifies whether operation should apply to the directory specified in the URI, its files, its - * subdirectories and their files. - * - * @type {boolean} - * @memberof DirectoryListHandlesOptions - */ - recursive?: boolean; -} - -/** - * Options to configure Directory - Force Close Handles Segment operations. - * - * See: - * - {@link ShareDirectoryClient.forceCloseHandlesSegment} - * - {@link ShareDirectoryClient.forceCloseAllHandles} - * - * @export - * @interface DirectoryForceCloseHandlesSegmentOptions - */ -export interface DirectoryForceCloseHandlesSegmentOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryForceCloseHandlesSegmentOptions - */ - abortSignal?: AbortSignalLike; - /** - * Specifies operation should apply to the directory specified in the URI, its files, its - * subdirectories and their files. - * - * @type {boolean} - * @memberof DirectoryForceCloseHandlesSegmentOptions - */ - recursive?: boolean; -} - -/** - * Additional response header values for close handles request. - */ -export interface DirectoryCloseHandlesHeaders { - /** - * This header uniquely identifies the request that was made and can be used for troubleshooting - * the request. - */ - requestId?: string; - /** - * Indicates the version of the File service used to execute the request. - */ - version?: string; - /** - * A UTC date/time value generated by the service that indicates the time at which the response - * was initiated. - */ - date?: Date; - /** - * A string describing next handle to be closed. It is returned when more handles need to be - * closed to complete the request. - */ - marker?: string; -} - -/** - * Response type for {@link ShareDirectoryClient.forceCloseHandle}. - */ -export type DirectoryForceCloseHandlesResponse = CloseHandlesInfo & - DirectoryCloseHandlesHeaders & { - /** - * The underlying HTTP response. - */ - _response: HttpResponse & { - /** - * The parsed HTTP response headers. - */ - parsedHeaders: DirectoryForceCloseHandlesHeaders; - }; - }; - -/** - * Options to configure {@link ShareDirectoryClient.forceCloseHandle}. - * - * @export - * @interface DirectoryForceCloseHandlesOptions - */ -export interface DirectoryForceCloseHandlesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof DirectoryForceCloseHandlesOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Contains response data for the {@link DirectoryClient.createIfNotExists} operation. - * - * @export - * @interface DirectoryCreateIfNotExistsResponse - */ -export interface DirectoryCreateIfNotExistsResponse extends DirectoryCreateResponse { - /** - * Indicate whether the directory is successfully created. Is false when the directory is not changed as it already exists. - * - * @type {boolean} - * @memberof DirectoryCreateIfNotExistsResponse - */ - succeeded: boolean; -} - -/** - * Contains response data for the {@link DirectoryClient.deleteIfExists} operation. - * - * @export - * @interface DirectoryDeleteIfExistsResponse - */ -export interface DirectoryDeleteIfExistsResponse extends DirectoryDeleteResponse { - /** - * Indicate whether the directory is successfully deleted. Is false if the directory does not exist in the first place. - * - * @type {boolean} - * @memberof DirectoryDeleteIfExistsResponse - */ - succeeded: boolean; -} - -/** - * A ShareDirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories. - * - * @export - * @class ShareDirectoryClient - */ -export class ShareDirectoryClient extends StorageClient { - /** - * context provided by protocol layer. - * - * @private - * @type {Directory} - * @memberof ShareDirectoryClient - */ - private context: Directory; - - private _shareName: string; - private _path: string; - private _name: string; - - /** - * The share name corresponding to this directory client - * - * @type {string} - * @memberof ShareDirectoryClient - */ - public get shareName(): string { - return this._shareName; - } - - /** - * The full path of the directory - * - * @type {string} - * @memberof ShareDirectoryClient - */ - public get path(): string { - return this._path; - } - - /** - * The name of the directory - * - * @type {string} - * @memberof ShareDirectoryClient - */ - public get name(): string { - return this._name; - } - - /** - * Creates an instance of DirectoryClient. - * - * @param {string} url A URL string pointing to Azure Storage file directory, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString". - * This method accepts an encoded URL or non-encoded URL pointing to a directory. - * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. - * However, if a directory name includes %, directory name must be encoded in the URL. - * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25". - * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. - * If not specified, AnonymousCredential is used. - * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. - * @memberof ShareDirectoryClient - */ - constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); - /** - * Creates an instance of DirectoryClient. - * - * @param {string} url A URL string pointing to Azure Storage file directory, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString". - * This method accepts an encoded URL or non-encoded URL pointing to a directory. - * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. - * However, if a directory name includes %, directory name must be encoded in the URL. - * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25". - * @param {Pipeline} pipeline Call newPipeline() to create a default - * pipeline, or provide a customized pipeline. - * @memberof ShareDirectoryClient - */ - constructor(url: string, pipeline: Pipeline); - constructor( - url: string, - credentialOrPipeline?: Credential | Pipeline, - options: StoragePipelineOptions = {} - ) { - let pipeline: Pipeline; - if (credentialOrPipeline instanceof Pipeline) { - pipeline = credentialOrPipeline; - } else if (credentialOrPipeline instanceof Credential) { - pipeline = newPipeline(credentialOrPipeline, options); - } else { - // The second parameter is undefined. Use anonymous credential. - pipeline = newPipeline(new AnonymousCredential(), options); - } - - super(url, pipeline); - ({ - baseName: this._name, - shareName: this._shareName, - path: this._path - } = getShareNameAndPathFromUrl(this.url)); - this.context = new Directory(this.storageClientContext); - } - - /** - * Creates a new directory under the specified share or parent directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory - * - * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. - * @returns {Promise} Response data for the Directory operation. - * @memberof ShareDirectoryClient - */ - public async create(options: DirectoryCreateOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareDirectoryClient-create", options.tracingOptions); - try { - if (!options.fileAttributes) { - options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options); - // By default set it as a directory. - const attributes: FileSystemAttributes = new FileSystemAttributes(); - attributes.directory = true; - options.fileAttributes = attributes; - } - - return await this.context.create( - fileAttributesToString(options.fileAttributes!), - fileCreationTimeToString(options.creationTime!), - fileLastWriteTimeToString(options.lastWriteTime!), - { - abortSignal: options.abortSignal, - metadata: options.metadata, - filePermission: options.filePermission, - filePermissionKey: options.filePermissionKey, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a new directory under the specified share or parent directory if it does not already exists. - * If the directory already exists, it is not modified. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory - * - * @param {DirectoryCreateOptions} [options] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async createIfNotExists( - options: DirectoryCreateOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-createIfNotExists", - options.tracingOptions - ); - try { - const res = await this.create({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - succeeded: true, - ...res - }; - } catch (e) { - if (e.details?.errorCode === "ResourceAlreadyExists") { - span.setStatus({ - code: CanonicalCode.ALREADY_EXISTS, - message: "Expected exception when creating a directory only if it does not already exist." - }); - return { - succeeded: false, - ...e.response?.parsedHeaders, - _response: e.response - }; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets properties on the directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-properties - * - * @param {properties} [DirectoryProperties] Directory properties. If no values are provided, - * existing values will be preserved. - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async setProperties( - properties: DirectoryProperties = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-setProperties", - properties.tracingOptions - ); - try { - properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties); - - return await this.context.setProperties( - fileAttributesToString(properties.fileAttributes!), - fileCreationTimeToString(properties.creationTime!), - fileLastWriteTimeToString(properties.lastWriteTime!), - { - abortSignal: properties.abortSignal, - filePermission: properties.filePermission, - filePermissionKey: properties.filePermissionKey, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a ShareDirectoryClient object for a sub directory. - * - * @param subDirectoryName A subdirectory name - * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given subdirectory name. - * @memberof ShareDirectoryClient - * - * Example usage: - * - * ```js - * const directoryClient = shareClient.getDirectoryClient(""); - * await directoryClient.create(); - * console.log("Created directory successfully"); - * ``` - */ - public getDirectoryClient(subDirectoryName: string): ShareDirectoryClient { - return new ShareDirectoryClient( - appendToURLPath(this.url, encodeURIComponent(subDirectoryName)), - this.pipeline - ); - } - - /** - * Creates a new subdirectory under this directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory - * - * @param {string} directoryName - * @param {DirectoryCreateOptions} [options] Options to Directory Create operation. - * @returns {Promise<{ directoryClient: ShareDirectoryClient; directoryCreateResponse: DirectoryCreateResponse; }>} Directory create response data and the corresponding DirectoryClient instance. - * @memberof ShareDirectoryClient - */ - public async createSubdirectory( - directoryName: string, - options: DirectoryCreateOptions = {} - ): Promise<{ - directoryClient: ShareDirectoryClient; - directoryCreateResponse: DirectoryCreateResponse; - }> { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-createSubdirectory", - options.tracingOptions - ); - try { - const directoryClient = this.getDirectoryClient(directoryName); - const directoryCreateResponse = await directoryClient.create({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - directoryClient, - directoryCreateResponse - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the specified empty sub directory under this directory. - * Note that the directory must be empty before it can be deleted. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory - * - * @param {string} directoryName - * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. - * @returns {DirectoryDeleteResponse} Directory deletion response data. - * @memberof ShareDirectoryClient - */ - public async deleteSubdirectory( - directoryName: string, - options: DirectoryDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-deleteSubdirectory", - options.tracingOptions - ); - try { - const directoryClient = this.getDirectoryClient(directoryName); - return await directoryClient.delete({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a new file or replaces a file under this directory. Note it only initializes the file with no content. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file - * - * @param {string} fileName - * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB. - * @param {FileCreateOptions} [options] Options to File Create operation. - * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client. - * @memberof ShareDirectoryClient - */ - public async createFile( - fileName: string, - size: number, - options: FileCreateOptions = {} - ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-createFile", - options.tracingOptions - ); - try { - const fileClient = this.getFileClient(fileName); - const fileCreateResponse = await fileClient.create(size, { - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - fileClient, - fileCreateResponse - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the specified file under this directory from the storage account. - * When a file is successfully deleted, it is immediately removed from the storage - * account's index and is no longer accessible to clients. The file's data is later - * removed from the service during garbage collection. - * - * Delete File will fail with status code 409 (Conflict) and error code SharingViolation - * if the file is open on an SMB client. - * - * Delete File is not supported on a share snapshot, which is a read-only copy of - * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 - * - * @param {string} fileName Name of the file to delete - * @param {FileDeleteOptions} [options] Options to File Delete operation. - * @returns {Promise} File deletion response data. - * @memberof ShareDirectoryClient - */ - public async deleteFile( - fileName: string, - options: FileDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-deleteFile", - options.tracingOptions - ); - try { - const fileClient = this.getFileClient(fileName); - return await fileClient.delete({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Creates a {@link ShareFileClient} object. - * - * @param {string} fileName A file name. - * @returns {ShareFileClient} A new ShareFileClient object for the given file name. - * @memberof ShareFileClient - * - * Example usage: - * - * ```js - * const content = "Hello world!" - * - * const fileClient = directoryClient.getFileClient(""); - * - * await fileClient.create(content.length); - * console.log("Created file successfully!"); - * - * await fileClient.uploadRange(content, 0, content.length); - * console.log("Updated file successfully!") - * ``` - */ - public getFileClient(fileName: string): ShareFileClient { - return new ShareFileClient( - appendToURLPath(this.url, encodeURIComponent(fileName)), - this.pipeline - ); - } - - /** - * Returns true if the specified directory exists; false otherwise. - * - * NOTE: use this function with care since an existing directory might be deleted by other clients or - * applications. Vice versa new directories might be added by other clients or applications after this - * function completes. - * - * @param {DirectoryExistsOptions} [options] options to Exists operation. - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async exists(options: DirectoryExistsOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareDirectoryClient-exists", options.tracingOptions); - try { - await this.getProperties({ - abortSignal: options.abortSignal, - tracingOptions: { - ...options.tracingOptions, - spanOptions - } - }); - return true; - } catch (e) { - if (e.statusCode === 404) { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when checking directory existence" - }); - return false; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns all system properties for the specified directory, and can also be used to check the - * existence of a directory. The data returned does not include the files in the directory or any - * subdirectories. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-directory-properties - * - * @param {DirectoryGetPropertiesOptions} [options] Options to Directory Get Properties operation. - * @returns {Promise} Response data for the Directory Get Properties operation. - * @memberof ShareDirectoryClient - */ - public async getProperties( - options: DirectoryGetPropertiesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-getProperties", - options.tracingOptions - ); - try { - return await this.context.getProperties({ - abortSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the specified empty directory. Note that the directory must be empty before it can be - * deleted. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory - * - * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation. - * @returns {Promise} Response data for the Directory Delete operation. - * @memberof ShareDirectoryClient - */ - public async delete(options: DirectoryDeleteOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareDirectoryClient-delete", options.tracingOptions); - try { - return await this.context.deleteMethod({ - abortSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the specified empty directory if it exists. Note that the directory must be empty before it can be - * deleted. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory - * - * @param {DirectoryDeleteOptions} [options] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async deleteIfExists( - options: DirectoryDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-deleteIfExists", - options.tracingOptions - ); - try { - const res = await this.delete({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - succeeded: true, - ...res - }; - } catch (e) { - if (e.details?.errorCode === "ResourceNotFound") { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when deleting a directory only if it exists." - }); - return { - succeeded: false, - ...e.response?.parsedHeaders, - _response: e.response - }; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Updates user defined metadata for the specified directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata - * - * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed - * @param {DirectorySetMetadataOptions} [options] Options to Directory Set Metadata operation. - * @returns {Promise} Response data for the Directory Set Metadata operation. - * @memberof ShareDirectoryClient - */ - public async setMetadata( - metadata?: Metadata, - options: DirectorySetMetadataOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-setMetadata", - options.tracingOptions - ); - try { - return await this.context.setMetadata({ - abortSignal: options.abortSignal, - metadata, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns an AsyncIterableIterator for {@link DirectoryListFilesAndDirectoriesSegmentResponse} objects - * - * @private - * @param {string} [marker] A string value that identifies the portion of - * the list of files and directories to be returned with the next listing operation. The - * operation returns the ContinuationToken value within the response body if the - * listing operation did not return all files and directories remaining to be listed - * with the current page. The ContinuationToken value can be used as the value for - * the marker parameter in a subsequent call to request the next page of list - * items. The marker value is opaque to the client. - * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation. - * @returns {AsyncIterableIterator} - * @memberof ShareDirectoryClient - */ - private async *iterateFilesAndDirectoriesSegments( - marker?: string, - options: DirectoryListFilesAndDirectoriesSegmentOptions = {} - ): AsyncIterableIterator { - if (options.prefix === "") { - options.prefix = undefined; - } - - let listFilesAndDirectoriesResponse; - do { - listFilesAndDirectoriesResponse = await this.listFilesAndDirectoriesSegment(marker, options); - marker = listFilesAndDirectoriesResponse.continuationToken; - yield await listFilesAndDirectoriesResponse; - } while (marker); - } - - /** - * Returns an AsyncIterableIterator for file and directory items - * - * @private - * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation. - * @returns {AsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } & DirectoryItem>} - * @memberof ShareDirectoryClient - */ - private async *listFilesAndDirectoriesItems( - options: DirectoryListFilesAndDirectoriesSegmentOptions = {} - ): AsyncIterableIterator< - ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem) - > { - if (options.prefix === "") { - options.prefix = undefined; - } - - let marker: string | undefined; - for await (const listFilesAndDirectoriesResponse of this.iterateFilesAndDirectoriesSegments( - marker, - options - )) { - for (const file of listFilesAndDirectoriesResponse.segment.fileItems) { - yield { kind: "file", ...file }; - } - for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) { - yield { kind: "directory", ...directory }; - } - } - } - - /** - * Returns an async iterable iterator to list all the files and directories - * under the specified account. - * - * .byPage() returns an async iterable iterator to list the files and directories in pages. - * - * Example using `for await` syntax: - * - * ```js - * let i = 1; - * for await (const entity of directoryClient.listFilesAndDirectories()) { - * if (entity.kind === "directory") { - * console.log(`${i++} - directory\t: ${entity.name}`); - * } else { - * console.log(`${i++} - file\t: ${entity.name}`); - * } - * } - * ``` - * - * Example using `iter.next()`: - * - * ```js - * let i = 1; - * let iter = directoryClient.listFilesAndDirectories(); - * let entity = await iter.next(); - * while (!entity.done) { - * if (entity.value.kind === "directory") { - * console.log(`${i++} - directory\t: ${entity.value.name}`); - * } else { - * console.log(`${i++} - file\t: ${entity.value.name}`); - * } - * entity = await iter.next(); - * } - * ``` - * - * Example using `byPage()`: - * - * ```js - * // passing optional maxPageSize in the page settings - * let i = 1; - * for await (const response of directoryClient - * .listFilesAndDirectories() - * .byPage({ maxPageSize: 20 })) { - * for (const fileItem of response.segment.fileItems) { - * console.log(`${i++} - file\t: ${fileItem.name}`); - * } - * for (const dirItem of response.segment.directoryItems) { - * console.log(`${i++} - directory\t: ${dirItem.name}`); - * } - * } - * ``` - * - * Example using paging with a marker: - * - * ```js - * let i = 1; - * let iterator = directoryClient.listFilesAndDirectories().byPage({ maxPageSize: 3 }); - * let response = (await iterator.next()).value; - * - * // Prints 3 file and directory names - * for (const fileItem of response.segment.fileItems) { - * console.log(`${i++} - file\t: ${fileItem.name}`); - * } - * - * for (const dirItem of response.segment.directoryItems) { - * console.log(`${i++} - directory\t: ${dirItem.name}`); - * } - * - * // Gets next marker - * let dirMarker = response.continuationToken; - * - * // Passing next marker as continuationToken - * iterator = directoryClient - * .listFilesAndDirectories() - * .byPage({ continuationToken: dirMarker, maxPageSize: 4 }); - * response = (await iterator.next()).value; - * - * // Prints 10 file and directory names - * for (const fileItem of response.segment.fileItems) { - * console.log(`${i++} - file\t: ${fileItem.name}`); - * } - * - * for (const dirItem of response.segment.directoryItems) { - * console.log(`${i++} - directory\t: ${dirItem.name}`); - * } - * ``` - * - * @param {DirectoryListFilesAndDirectoriesOptions} [options] Options to list files and directories operation. - * @memberof ShareDirectoryClient - * @returns {PagedAsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } , DirectoryListFilesAndDirectoriesSegmentResponse>} - * An asyncIterableIterator that supports paging. - */ - public listFilesAndDirectories( - options: DirectoryListFilesAndDirectoriesOptions = {} - ): PagedAsyncIterableIterator< - ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem), - DirectoryListFilesAndDirectoriesSegmentResponse - > { - if (options.prefix === "") { - options.prefix = undefined; - } - - // AsyncIterableIterator to iterate over files and directories - const iter = this.listFilesAndDirectoriesItems(options); - return { - /** - * @member {Promise} [next] The next method, part of the iteration protocol - */ - async next() { - return iter.next(); - }, - /** - * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol - */ - [Symbol.asyncIterator]() { - return this; - }, - /** - * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time - */ - byPage: (settings: PageSettings = {}) => { - return this.iterateFilesAndDirectoriesSegments(settings.continuationToken, { - maxResults: settings.maxPageSize, - ...options - }); - } - }; - } - - /** - * Returns a list of files or directories under the specified share or directory. It lists the - * contents only for a single level of the directory hierarchy. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-directories-and-files - * - * @param {string} [marker] A string value that identifies the portion of the list to be returned with the next list operation. - * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to Directory List Files and Directories Segment operation. - * @returns {Promise} Response data for the Directory List Files and Directories operation. - * @memberof ShareDirectoryClient - */ - private async listFilesAndDirectoriesSegment( - marker?: string, - options: DirectoryListFilesAndDirectoriesSegmentOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-listFilesAndDirectoriesSegment", - options.tracingOptions - ); - - if (options.prefix === "") { - options.prefix = undefined; - } - - try { - return await this.context.listFilesAndDirectoriesSegment({ - marker, - ...options, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns an AsyncIterableIterator for {@link DirectoryListHandlesResponse} - * - * @private - * @param {string} [marker] A string value that identifies the portion of the list to be - * returned with the next list handles operation. The operation returns a - * marker value within the response body if the list returned was not complete. - * The marker value may then be used in a subsequent call to request the next - * set of list items. - * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation. - * @returns {AsyncIterableIterator} - * @memberof ShareDirectoryClient - */ - private async *iterateHandleSegments( - marker?: string, - options: DirectoryListHandlesSegmentOptions = {} - ): AsyncIterableIterator { - let listHandlesResponse; - if (!!marker || marker === undefined) { - do { - listHandlesResponse = await this.listHandlesSegment(marker, options); - marker = listHandlesResponse.continuationToken; - yield await listHandlesResponse; - } while (marker); - } - } - - /** - * Returns an AsyncIterableIterator for handles - * - * @private - * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation. - * @returns {AsyncIterableIterator} - * @memberof ShareDirectoryClient - */ - private async *listHandleItems( - options: DirectoryListHandlesSegmentOptions = {} - ): AsyncIterableIterator { - let marker: string | undefined; - for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) { - if (listHandlesResponse.handleList) { - for (const handle of listHandlesResponse.handleList) { - yield handle; - } - } - } - } - - /** - * Returns an async iterable iterator to list all the handles. - * under the specified account. - * - * .byPage() returns an async iterable iterator to list the handles in pages. - * - * Example using `for await` syntax: - * - * ```js - * let i = 1; - * let iter = dirClient.listHandles(); - * for await (const handle of iter) { - * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); - * } - * ``` - * - * Example using `iter.next()`: - * - * ```js - * let i = 1; - * let iter = dirClient.listHandles(); - * let handleItem = await iter.next(); - * while (!handleItem.done) { - * console.log(`Handle ${i++}: ${handleItem.value.path}, opened time ${handleItem.value.openTime}, clientIp ${handleItem.value.clientIp}`); - * handleItem = await iter.next(); - * } - * ``` - * - * Example using `byPage()`: - * - * ```js - * // passing optional maxPageSize in the page settings - * let i = 1; - * for await (const response of dirClient.listHandles({ recursive: true }).byPage({ maxPageSize: 20 })) { - * if (response.handleList) { - * for (const handle of response.handleList) { - * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); - * } - * } - * } - * ``` - * - * Example using paging with a marker: - * - * ```js - * let i = 1; - * let iterator = dirClient.listHandles().byPage({ maxPageSize: 2 }); - * let response = await iterator.next(); - * - * // Prints 2 handles - * if (response.value.handleList) { - * for (const handle of response.value.handleList) { - * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); - * } - * } - * - * // Gets next marker - * let marker = response.value.continuationToken; - * - * // Passing next marker as continuationToken - * console.log(` continuation`); - * iterator = dirClient.listHandles().byPage({ continuationToken: marker, maxPageSize: 10 }); - * response = await iterator.next(); - * - * // Prints 2 more handles assuming you have more than four directory/files opened - * if (!response.done && response.value.handleList) { - * for (const handle of response.value.handleList) { - * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`); - * } - * } - * ``` - * - * @param {DirectoryListHandlesOptions} [options] Options to list handles operation. - * @memberof ShareDirectoryClient - * @returns {PagedAsyncIterableIterator} - * An asyncIterableIterator that supports paging. - */ - public listHandles( - options: DirectoryListHandlesOptions = {} - ): PagedAsyncIterableIterator { - // an AsyncIterableIterator to iterate over handles - const iter = this.listHandleItems(options); - return { - /** - * @member {Promise} [next] The next method, part of the iteration protocol - */ - async next() { - return iter.next(); - }, - /** - * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol - */ - [Symbol.asyncIterator]() { - return this; - }, - /** - * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time - */ - byPage: (settings: PageSettings = {}) => { - return this.iterateHandleSegments(settings.continuationToken, { - maxResults: settings.maxPageSize, - ...options - }); - } - }; - } - - /** - * Lists handles for a directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles - * - * @param {string} [marker] Optional. A string value that identifies the portion of the list to be - * returned with the next list handles operation. The operation returns a - * marker value within the response body if the list returned was not complete. - * The marker value may then be used in a subsequent call to request the next - * set of list items. - * @param {DirectoryListHandlesSegmentOptions} [options={}] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - private async listHandlesSegment( - marker?: string, - options: DirectoryListHandlesSegmentOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-listHandlesSegment", - options.tracingOptions - ); - try { - marker = marker === "" ? undefined : marker; - const response = await this.context.listHandles({ - marker, - ...options, - spanOptions - }); - - // TODO: Protocol layer issue that when handle list is in returned XML - // response.handleList is an empty string - if ((response.handleList as any) === "") { - response.handleList = undefined; - } - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Force close all handles for a directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {string} [marker] Optional. A string value that identifies the position of handles that will - * be closed with the next force close handles operation. - * The operation returns a marker value within the response - * body if there are more handles to close. The marker value - * may then be used in a subsequent call to close the next set of handles. - * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - private async forceCloseHandlesSegment( - marker?: string, - options: DirectoryForceCloseHandlesSegmentOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-forceCloseHandlesSegment", - options.tracingOptions - ); - try { - marker = marker === "" ? undefined : marker; - const rawResponse = await this.context.forceCloseHandles("*", { - marker, - ...options, - spanOptions - }); - const response = rawResponse as DirectoryForceCloseHandlesResponse; - response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; - response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Force close all handles for a directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async forceCloseAllHandles( - options: DirectoryForceCloseHandlesSegmentOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-forceCloseAllHandles", - options.tracingOptions - ); - try { - let handlesClosed = 0; - let numberOfHandlesFailedToClose = 0; - let marker: string | undefined = ""; - - do { - const response: DirectoryForceCloseHandlesResponse = await this.forceCloseHandlesSegment( - marker, - { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } - ); - marker = response.marker; - response.closedHandlesCount && (handlesClosed += response.closedHandlesCount); - response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount); - } while (marker); - - return { closedHandlesCount: handlesClosed, closeFailureCount: numberOfHandlesFailedToClose }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Force close a specific handle for a directory. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(), - * goto documents of Aborter for more examples about request cancellation - * @param {string} handleId Specific handle ID, cannot be asterisk "*". - * Use forceCloseHandlesSegment() to close all handles. - * @param {DirectoryForceCloseHandlesOptions} [options={}] - * @returns {Promise} - * @memberof ShareDirectoryClient - */ - public async forceCloseHandle( - handleId: string, - options: DirectoryForceCloseHandlesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareDirectoryClient-forceCloseHandle", - options.tracingOptions - ); - try { - if (handleId === "*") { - throw new RangeError( - `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.` - ); - } - - const rawResponse = await this.context.forceCloseHandles(handleId, { - abortSignal: options.abortSignal, - spanOptions - }); - const response = rawResponse as DirectoryForceCloseHandlesResponse; - response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; - response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } -} diff --git a/sdk/storage/storage-file-share/src/ShareFileClient.ts b/sdk/storage/storage-file-share/src/ShareFileClient.ts deleted file mode 100644 index 86d55c274c0b..000000000000 --- a/sdk/storage/storage-file-share/src/ShareFileClient.ts +++ /dev/null @@ -1,3045 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { HttpRequestBody, HttpResponse, isNode, TransferProgressEvent } from "@azure/core-http"; -import { CanonicalCode } from "@opentelemetry/api"; -import { AbortSignalLike } from "@azure/abort-controller"; -import { FileDownloadResponse } from "./FileDownloadResponse"; -import { - FileAbortCopyResponse, - FileCreateResponse, - FileDeleteResponse, - FileDownloadOptionalParams, - FileDownloadResponseModel, - FileGetPropertiesResponse, - FileGetRangeListHeaders, - FileListHandlesResponse, - FileSetHTTPHeadersResponse, - FileSetMetadataResponse, - FileStartCopyResponse, - SourceModifiedAccessConditions, - FileUploadRangeFromURLResponse, - FileUploadRangeResponse, - HandleItem, - RangeModel, - FileForceCloseHandlesHeaders, - CopyFileSmbInfo, - LeaseAccessConditions -} from "./generatedModels"; -import { File } from "./generated/src/operations"; -import { Range, rangeToString } from "./Range"; -import { - FileHttpHeaders, - Metadata, - FileAndDirectoryCreateCommonOptions, - FileAndDirectorySetPropertiesCommonOptions, - fileAttributesToString, - fileCreationTimeToString, - fileLastWriteTimeToString, - validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions, - validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions, - CloseHandlesInfo -} from "./models"; -import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; -import { StorageClient, CommonOptions } from "./StorageClient"; -import { - DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS, - FILE_MAX_SIZE_BYTES, - FILE_RANGE_MAX_SIZE_BYTES, - DEFAULT_HIGH_LEVEL_CONCURRENCY -} from "./utils/constants"; -import "@azure/core-paging"; -import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging"; -import { Credential } from "./credentials/Credential"; -import { Batch } from "./utils/Batch"; -import { BufferScheduler } from "./utils/BufferScheduler"; -import { Readable } from "stream"; -import { AnonymousCredential } from "./credentials/AnonymousCredential"; -import { - readStreamToLocalFile, - streamToBuffer, - fsStat, - fsCreateReadStream -} from "./utils/utils.node"; -import { FileSystemAttributes } from "./FileSystemAttributes"; -import { getShareNameAndPathFromUrl } from "./utils/utils.common"; -import { createSpan } from "./utils/tracing"; -import { StorageClientContext } from "./generated/src/storageClientContext"; -import { SERVICE_VERSION } from "./utils/constants"; -import { generateUuid } from "@azure/core-http"; - -/** - * Options to configure the {@link ShareFileClient.create} operation. - * - * @export - * @interface FileCreateOptions - */ -export interface FileCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileCreateOptions - */ - abortSignal?: AbortSignalLike; - /** - * File HTTP headers like Content-Type. - * - * @type {FileHttpHeaders} - * @memberof FileCreateOptions - */ - fileHttpHeaders?: FileHttpHeaders; - - /** - * A collection of key-value string pair to associate with the file storage object. - * - * @type {Metadata} - * @memberof FileCreateOptions - */ - metadata?: Metadata; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileCreateOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -export interface FileProperties extends FileAndDirectorySetPropertiesCommonOptions, CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileProperties - */ - abortSignal?: AbortSignalLike; - /** - * File HTTP headers like Content-Type. - * - * @type {FileHttpHeaders} - * @memberof FileProperties - */ - fileHttpHeaders?: FileHttpHeaders; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileProperties - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -export interface SetPropertiesResponse extends FileSetHTTPHeadersResponse {} - -/** - * Options to configure the {@link ShareFileClient.delete} operation. - * - * @export - * @interface FileDeleteOptions - */ -export interface FileDeleteOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileDeleteOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileDeleteOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure File - Download operations. - * - * See: - * - {@link ShareFileClient.download} - * - {@link ShareFileClient.downloadToFile} - * - * @export - * @interface FileDownloadOptions - */ -export interface FileDownloadOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileDownloadOptions - */ - abortSignal?: AbortSignalLike; - /** - * Optional. ONLY AVAILABLE IN NODE.JS. - * - * How many retries will perform when original body download stream unexpected ends. - * Above kind of ends will not trigger retry policy defined in a pipeline, - * because they doesn't emit network errors. - * - * With this option, every additional retry means an additional ShareFileClient.download() request will be made - * from the broken point, until the requested range has been successfully downloaded or maxRetryRequests is reached. - * - * Default value is 5, please set a larger value when loading large files in poor network. - * - * @type {number} - * @memberof FileDownloadOptions - */ - maxRetryRequests?: number; - - /** - * When this header is set to true and - * specified together with the Range header, the service returns the MD5 hash - * for the range, as long as the range is less than or equal to 4 MB in size. - * - * @type {boolean} - * @memberof FileDownloadOptions - */ - rangeGetContentMD5?: boolean; - - /** - * Download progress updating event handler. - * - * @memberof FileDownloadOptions - */ - onProgress?: (progress: TransferProgressEvent) => void; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileDownloadOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.uploadRange} operation. - * - * @export - * @interface FileUploadRangeOptions - */ -export interface FileUploadRangeOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileUploadRangeOptions - */ - abortSignal?: AbortSignalLike; - /** - * An MD5 hash of the content. This hash is - * used to verify the integrity of the data during transport. When the - * Content-MD5 header is specified, the File service compares the hash of the - * content that has arrived with the header value that was sent. If the two - * hashes do not match, the operation will fail with error code 400 (Bad - * Request). - * - * @type {Uint8Array} - * @memberof FileUploadRangeOptions - */ - contentMD5?: Uint8Array; - - /** - * Progress updating event handler. - * - * @memberof FileUploadRangeOptions - */ - onProgress?: (progress: TransferProgressEvent) => void; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileUploadRangeOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.uploadRangeFromURL} operation. - * - * @export - * @interface FileUploadRangeFromURLOptions - */ -export interface FileUploadRangeFromURLOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileUploadRangeFromURLOptions - */ - abortSignal?: AbortSignalLike; - /** - * The timeout parameter is expressed in seconds. For more information, see Setting - * Timeouts for File Service Operations. - */ - timeoutInSeconds?: number; - /** - * Specify the crc64 calculated for the range of bytes that must be read from the copy source. - */ - sourceContentCrc64?: Uint8Array; - /** - * Additional parameters for the operation - */ - sourceConditions?: SourceModifiedAccessConditions; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileUploadRangeFromURLOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * The option is defined as parity to REST definition. - * While it's not ready to be used now, considering Crc64 of source content is - * not accessible. - */ -// export interface IFileUploadRangeFromURLOptions extends CommonOptions { -// /** -// * Crc64 of the source content. -// * -// * @type {Uint8Array} -// * @memberof IFileUploadRangeFromURLOptions -// */ -// sourceContentCrc64?: Uint8Array; - -// /** -// * Source modified access condition. -// * -// * @type {SourceModifiedAccessConditions} -// * @memberof IFileUploadRangeFromURLOptions -// */ -// sourceModifiedAccessConditions?: SourceModifiedAccessConditions; -// } - -/** - * Options to configure the {@link ShareFileClient.getRangeList} operation. - * - * @export - * @interface FileGetRangeListOptions - */ -export interface FileGetRangeListOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileGetRangeListOptions - */ - abortSignal?: AbortSignalLike; - /** - * Optional. Specifies the range of bytes over which to list ranges, inclusively. - * - * @type {Range} - * @memberof FileGetRangeListOptions - */ - range?: Range; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileGetRangeListOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.exists} operation. - * - * @export - * @interface FileExistsOptions - */ -export interface FileExistsOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileExistsOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure the {@link ShareFileClient.getProperties} operation. - * - * @export - * @interface FileGetPropertiesOptions - */ -export interface FileGetPropertiesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileGetPropertiesOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileGetPropertiesOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Contains response data for the {@link ShareFileClient.getRangeList} operation. - */ -export type FileGetRangeListResponse = FileGetRangeListHeaders & { - /** - * Range list for an Azure file. - * - * @type {RangeModel[]} - */ - rangeList: RangeModel[]; - - /** - * The underlying HTTP response. - */ - _response: HttpResponse & { - /** - * The parsed HTTP response headers. - */ - parsedHeaders: FileGetRangeListHeaders; - /** - * The response body as text (string format) - */ - bodyAsText: string; - /** - * The response body as parsed JSON or XML - */ - parsedBody: RangeModel[]; - }; -}; - -/** - * Options to configure the {@link ShareFileClient.startCopyFromURL} operation. - * - * @export - * @interface FileStartCopyOptions - */ -export interface FileStartCopyOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileStartCopyOptions - */ - abortSignal?: AbortSignalLike; - /** - * A collection of key-value string pair to associate with the file storage object. - * - * @type {Metadata} - * @memberof FileStartCopyOptions - */ - metadata?: Metadata; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileStartCopyOptions - */ - leaseAccessConditions?: LeaseAccessConditions; - /** - * If specified the permission (security descriptor) shall be set for the directory/file. This - * header can be used if Permission size is <= 8KB, else x-ms-file-permission-key header shall be - * used. Default value: Inherit. If SDDL is specified as input, it must have owner, group and - * dacl. Note: Only one of the x-ms-file-permission or x-ms-file-permission-key should be - * specified. - * - * @type {string} - * @memberof FileStartCopyOptions - */ - filePermission?: string; - /** - * Key of the permission to be set for the directory/file. Note: Only one of the - * x-ms-file-permission or x-ms-file-permission-key should be specified. - * - * @type {string} - * @memberof FileStartCopyOptions - */ - filePermissionKey?: string; - /** - * SMB info. - * - * @type {CopyFileSmbInfo} - * @memberof FileStartCopyOptions - */ - copyFileSmbInfo?: CopyFileSmbInfo; -} - -/** - * Options to configure the {@link ShareFileClient.setMetadata} operation. - * - * @export - * @interface FileSetMetadataOptions - */ -export interface FileSetMetadataOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileSetMetadataOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileSetMetadataOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.setHttpHeaders} operation. - * - * @export - * @interface FileSetHttpHeadersOptions - */ -export interface FileSetHttpHeadersOptions - extends FileAndDirectorySetPropertiesCommonOptions, - CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileSetHttpHeadersOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileSetHttpHeadersOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.abortCopyFromURL} operation. - * - * @export - * @interface FileAbortCopyFromURLOptions - */ -export interface FileAbortCopyFromURLOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileAbortCopyFromURLOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileAbortCopyFromURLOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.resize} operation. - * - * @export - * @interface FileResizeOptions - */ -export interface FileResizeOptions - extends FileAndDirectorySetPropertiesCommonOptions, - CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileResizeOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileResizeOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure the {@link ShareFileClient.clearRange} operation. - * - * @export - * @interface FileClearRangeOptions - */ -export interface FileClearRangeOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileClearRangeOptions - */ - abortSignal?: AbortSignalLike; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileClearRangeOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Options to configure File - List Handles Segment operations. - * - * See: - * - {@link ShareFileClient.listHandlesSegment} - * - {@link ShareFileClient.iterateHandleSegments} - * - {@link ShareFileClient.listHandleItems} - * - * @export - * @interface FileListHandlesSegmentOptions - */ -export interface FileListHandlesSegmentOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileClearRangeOptions - */ - abortSignal?: AbortSignalLike; - /** - * Specifies the maximum number of entries to return. If the request does not specify maxResults, - * or specifies a value greater than 5,000, the server will return up to 5,000 items. - * - * @type {number} - * @memberof FileListHandlesSegmentOptions - */ - maxPageSize?: number; -} - -export interface FileListHandlesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileClearRangeOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Options to configure File - Force Close Handles operations. - * - * See: - * - {@link ShareFileClient.forceCloseHandlesSegment} - * - {@link ShareFileClient.forceCloseAllHandles} - * - {@link ShareFileClient.forceCloseHandle} - * - * @export - * @interface FileForceCloseHandlesOptions - */ -export interface FileForceCloseHandlesOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileForceCloseHandlesOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * Additional response header values for close handles request. - */ -export interface FileCloseHandlesHeaders { - /** - * This header uniquely identifies the request that was made and can be used for troubleshooting - * the request. - */ - requestId?: string; - /** - * Indicates the version of the File service used to execute the request. - */ - version?: string; - /** - * A UTC date/time value generated by the service that indicates the time at which the response - * was initiated. - */ - date?: Date; - /** - * A string describing next handle to be closed. It is returned when more handles need to be - * closed to complete the request. - */ - marker?: string; -} - -/** - * Response type for {@link ShareFileClient.forceCloseHandle}. - */ -export type FileForceCloseHandlesResponse = CloseHandlesInfo & - FileCloseHandlesHeaders & { - /** - * The underlying HTTP response. - */ - _response: HttpResponse & { - /** - * The parsed HTTP response headers. - */ - parsedHeaders: FileForceCloseHandlesHeaders; - }; - }; - -/** - * Option interface for ShareFileClient.uploadStream(). - * - * @export - * @interface FileUploadStreamOptions - */ -export interface FileUploadStreamOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileUploadStreamOptions - */ - abortSignal?: AbortSignalLike; - /** - * Azure File HTTP Headers. - * - * @type {FileHttpHeaders} - * @memberof FileUploadStreamOptions - */ - fileHttpHeaders?: FileHttpHeaders; - - /** - * Metadata of the Azure file. - * - * @type {Metadata} - * @memberof FileUploadStreamOptions - */ - metadata?: Metadata; - - /** - * Progress updater. - * - * @memberof FileUploadStreamOptions - */ - onProgress?: (progress: TransferProgressEvent) => void; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileUploadStreamOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Option interface for File - Upload operations - * - * See: - * - {@link ShareFileClient.uploadFile} - * - {@link ShareFileClient.uploadSeekableStream} - * - * @export - * @interface FileParallelUploadOptions - */ -export interface FileParallelUploadOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileParallelUploadOptions - */ - abortSignal?: AbortSignalLike; - /** - * RangeSize specifies the range size to use in each parallel upload, - * the default (and maximum size) is FILE_RANGE_MAX_SIZE_BYTES. - * - * @type {number} - * @memberof FileParallelUploadOptions - */ - rangeSize?: number; - - /** - * Progress updater. - * - * @memberof FileParallelUploadOptions - */ - onProgress?: (progress: TransferProgressEvent) => void; - - /** - * File HTTP Headers. - * - * @type {FileHttpHeaders} - * @memberof FileParallelUploadOptions - */ - fileHttpHeaders?: FileHttpHeaders; - - /** - * Metadata of an Azure file. - * - * @type {Metadata} - * @memberof FileParallelUploadOptions - */ - metadata?: Metadata; - - /** - * Concurrency indicates the maximum number of ranges to upload in parallel. - * If not provided, 5 concurrency will be used by default. - * - * @type {number} - * @memberof FileParallelUploadOptions - */ - concurrency?: number; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileParallelUploadOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Option interface for the {@link ShareFileClient.downloadToBuffer} operation. - * - * @export - * @interface FileDownloadToBufferOptions - */ -export interface FileDownloadToBufferOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof FileDownloadToBufferOptions - */ - abortSignal?: AbortSignalLike; - /** - * When downloading Azure files, download method will try to split large file into small ranges. - * Every small range will be downloaded via a separate request. - * This option defines size data every small request trying to download. - * Must be > 0, will use the default value if undefined, - * - * @type {number} - * @memberof FileDownloadToBufferOptions - */ - rangeSize?: number; - - /** - * Optional. ONLY AVAILABLE IN NODE.JS. - * - * How many retries will perform when original range download stream unexpected ends. - * Above kind of ends will not trigger retry policy defined in a pipeline, - * because they doesn't emit network errors. - * - * With this option, every additional retry means an additional ShareFileClient.download() request will be made - * from the broken point, until the requested range has been successfully downloaded or - * maxRetryRequestsPerRange is reached. - * - * Default value is 5, please set a larger value when in poor network. - * - * @type {number} - * @memberof FileDownloadToBufferOptions - */ - maxRetryRequestsPerRange?: number; - - /** - * Progress updater. - * - * @memberof FileDownloadToBufferOptions - */ - onProgress?: (progress: TransferProgressEvent) => void; - - /** - * Concurrency indicates the maximum number of ranges to download in parallel. - * If not provided, 5 concurrency will be used by default. - * - * @type {number} - * @memberof FileDownloadToBufferOptions - */ - concurrency?: number; - /** - * Lease access conditions. - * - * @type {LeaseAccessConditions} - * @memberof FileDownloadToBufferOptions - */ - leaseAccessConditions?: LeaseAccessConditions; -} - -/** - * Contains response data for the {@link ShareFileClient.deleteIfExists} operation. - * - * @export - * @interface FileDeleteIfExistsResponse - */ -export interface FileDeleteIfExistsResponse extends FileDeleteResponse { - /** - * Indicate whether the file is successfully deleted. Is false if the file does not exist in the first place. - * - * @type {boolean} - * @memberof FileDeleteIfExistsResponse - */ - succeeded: boolean; -} - -/** - * A ShareFileClient represents a URL to an Azure Storage file. - * - * @export - * @class ShareFileClient - */ -export class ShareFileClient extends StorageClient { - /** - * context provided by protocol layer. - * - * @private - * @type {File} - * @memberof ShareFileClient - */ - private context: File; - - private _shareName: string; - private _path: string; - private _name: string; - - /** - * The share name corresponding to this file client - * - * @type {string} - * @memberof ShareFileClient - */ - public get shareName(): string { - return this._shareName; - } - - /** - * The full path of the file - * - * @type {string} - * @memberof ShareFileClient - */ - public get path(): string { - return this._path; - } - - /** - * The name of the file - * - * @type {string} - * @memberof ShareFileClient - */ - public get name(): string { - return this._name; - } - - /** - * Creates an instance of ShareFileClient. - * - * @param {string} url A URL string pointing to Azure Storage file, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString". - * This method accepts an encoded URL or non-encoded URL pointing to a file. - * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. - * However, if a file or directory name includes %, file or directory name must be encoded in the URL. - * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25". - * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential. - * If not specified, AnonymousCredential is used. - * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline. - * @memberof ShareFileClient - */ - constructor(url: string, credential?: Credential, options?: StoragePipelineOptions); - /** - * Creates an instance of ShareFileClient. - * - * @param {string} url A URL string pointing to Azure Storage file, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can - * append a SAS if using AnonymousCredential, such as - * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString". - * This method accepts an encoded URL or non-encoded URL pointing to a file. - * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped. - * However, if a file or directory name includes %, file or directory name must be encoded in the URL. - * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25". - * @param {Pipeline} pipeline Call newPipeline() to create a default - * pipeline, or provide a customized pipeline. - * @memberof ShareFileClient - */ - constructor(url: string, pipeline: Pipeline); - constructor( - url: string, - credentialOrPipeline?: Credential | Pipeline, - options?: StoragePipelineOptions - ) { - let pipeline: Pipeline; - if (credentialOrPipeline instanceof Pipeline) { - pipeline = credentialOrPipeline; - } else if (credentialOrPipeline instanceof Credential) { - pipeline = newPipeline(credentialOrPipeline, options); - } else { - // The second parameter is undefined. Use anonymous credential. - pipeline = newPipeline(new AnonymousCredential(), options); - } - - super(url, pipeline); - ({ - baseName: this._name, - shareName: this._shareName, - path: this._path - } = getShareNameAndPathFromUrl(this.url)); - this.context = new File(this.storageClientContext); - } - - /** - * Creates a new file or replaces a file. Note it only initializes the file with no content. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file - * - * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB. - * @param {FileCreateOptions} [options] Options to File Create operation. - * @returns {Promise} Response data for the File Create operation. - * @memberof ShareFileClient - * - * Example usage: - * - * ```js - * const content = "Hello world!"; - * - * // Create the file - * await fileClient.create(content.length); - * console.log("Created file successfully!"); - * - * // Then upload data to the file - * await fileClient.uploadRange(content, 0, content.length); - * console.log("Updated file successfully!") - * ``` - */ - public async create(size: number, options: FileCreateOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-create", options.tracingOptions); - try { - if (size < 0 || size > FILE_MAX_SIZE_BYTES) { - throw new RangeError(`File size must >= 0 and < ${FILE_MAX_SIZE_BYTES}.`); - } - options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options); - - if (!options.fileAttributes) { - // Note: It would be Archive in service side if None is set. - const attributes: FileSystemAttributes = new FileSystemAttributes(); - attributes.none = true; - options.fileAttributes = attributes; - } - - options.fileHttpHeaders = options.fileHttpHeaders || {}; - - return await this.context.create( - size, - fileAttributesToString(options.fileAttributes!), - fileCreationTimeToString(options.creationTime!), - fileLastWriteTimeToString(options.lastWriteTime!), - { - abortSignal: options.abortSignal, - fileHttpHeaders: options.fileHttpHeaders, - metadata: options.metadata, - filePermission: options.filePermission, - filePermissionKey: options.filePermissionKey, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Reads or downloads a file from the system, including its metadata and properties. - * - * * In Node.js, data returns in a Readable stream `readableStreamBody` - * * In browsers, data returns in a promise `contentAsBlob` - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file - * - * @param {number} [offset] From which position of the file to download, >= 0 - * @param {number} [count] How much data to be downloaded, > 0. Will download to the end when undefined - * @param {FileDownloadOptions} [options] Options to File Download operation. - * @returns {Promise} Response data for the File Download operation. - * @memberof ShareFileClient - * - * Example usage (Node.js): - * - * ```js - * // Download a file to a string - * const downloadFileResponse = await fileClient.download(); - * console.log( - * "Downloaded file content:", - * (await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()} - * ); - * - * // A helper method used to read a Node.js readable stream into string - * async function streamToBuffer(readableStream) { - * return new Promise((resolve, reject) => { - * const chunks = []; - * readableStream.on("data", (data) => { - * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - * }); - * readableStream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * readableStream.on("error", reject); - * }); - * } - * ``` - * - * Example usage (browsers): - * - * ```js - * // Download a file to a string - * const downloadFileResponse = await fileClient.download(0); - * console.log( - * "Downloaded file content:", - * await blobToString(await downloadFileResponse.blobBody)} - * ); - * - * // A helper method used to convert a browser Blob into string. - * export async function blobToString(blob: Blob): Promise { - * const fileReader = new FileReader(); - * return new Promise((resolve, reject) => { - * fileReader.onloadend = (ev: any) => { - * resolve(ev.target!.result); - * }; - * fileReader.onerror = reject; - * fileReader.readAsText(blob); - * }); - * } - * ``` - */ - public async download( - offset: number = 0, - count?: number, - options: FileDownloadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-download", options.tracingOptions); - try { - if (options.rangeGetContentMD5 && offset === 0 && count === undefined) { - throw new RangeError(`rangeGetContentMD5 only works with partial data downloading`); - } - - const downloadFullFile = offset === 0 && !count; - const res = await this.context.download({ - abortSignal: options.abortSignal, - onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream - range: downloadFullFile ? undefined : rangeToString({ offset, count }), - rangeGetContentMD5: options.rangeGetContentMD5, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - - // Return browser response immediately - if (!isNode) { - return res; - } - - // We support retrying when download stream unexpected ends in Node.js runtime - // Following code shouldn't be bundled into browser build, however some - // bundlers may try to bundle following code and "FileReadResponse.ts". - // In this case, "FileDownloadResponse.browser.ts" will be used as a shim of "FileDownloadResponse.ts" - // The config is in package.json "browser" field - if (options.maxRetryRequests === undefined || options.maxRetryRequests < 0) { - // TODO: Default value or make it a required parameter? - options.maxRetryRequests = DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS; - } - - if (res.contentLength === undefined) { - throw new RangeError(`File download response doesn't contain valid content length header`); - } - - return new FileDownloadResponse( - res, - async (start: number): Promise => { - const updatedOptions: FileDownloadOptionalParams = { - range: rangeToString({ - count: offset + res.contentLength! - start, - offset: start - }) - }; - - // Debug purpose only - // console.log( - // `Read from internal stream, range: ${ - // updatedOptions.range - // }, options: ${JSON.stringify(updatedOptions)}` - // ); - - return ( - await this.context.download({ - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - ...updatedOptions, - spanOptions - }) - ).readableStreamBody!; - }, - offset, - res.contentLength!, - { - abortSignal: options.abortSignal, - maxRetryRequests: options.maxRetryRequests, - onProgress: options.onProgress - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns true if the specified file exists; false otherwise. - * - * NOTE: use this function with care since an existing file might be deleted by other clients or - * applications. Vice versa new files might be added by other clients or applications after this - * function completes. - * - * @param {FileExistsOptions} [options] options to Exists operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async exists(options: FileExistsOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-exists", options.tracingOptions); - try { - await this.getProperties({ - abortSignal: options.abortSignal, - tracingOptions: { - ...options.tracingOptions, - spanOptions - } - }); - return true; - } catch (e) { - if (e.statusCode === 404) { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when checking file existence" - }); - return false; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns all user-defined metadata, standard HTTP properties, and system properties - * for the file. It does not return the content of the file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file-properties - * - * @param {FileGetPropertiesOptions} [options] Options to File Get Properties operation. - * @returns {Promise} Response data for the File Get Properties operation. - * @memberof ShareFileClient - */ - public async getProperties( - options: FileGetPropertiesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-getProperties", - options.tracingOptions - ); - try { - return this.context.getProperties({ - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets properties on the file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties - * - * @param {FileProperties} [properties] File properties. For file HTTP headers(e.g. Content-Type), - * if no values are provided, existing HTTP headers will be removed. - * For other file properties(e.g. fileAttributes), if no values are provided, - * existing values will be preserved. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async setProperties(properties: FileProperties = {}): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-setProperties", - properties.tracingOptions - ); - try { - properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties); - - properties.fileHttpHeaders = properties.fileHttpHeaders || {}; - - return await this.context.setHTTPHeaders( - fileAttributesToString(properties.fileAttributes!), - fileCreationTimeToString(properties.creationTime!), - fileLastWriteTimeToString(properties.lastWriteTime!), - { - abortSignal: properties.abortSignal, - fileHttpHeaders: properties.fileHttpHeaders, - filePermission: properties.filePermission, - filePermissionKey: properties.filePermissionKey, - leaseAccessConditions: properties.leaseAccessConditions, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the file from the storage account. - * When a file is successfully deleted, it is immediately removed from the storage - * account's index and is no longer accessible to clients. The file's data is later - * removed from the service during garbage collection. - * - * Delete File will fail with status code 409 (Conflict) and error code SharingViolation - * if the file is open on an SMB client. - * - * Delete File is not supported on a share snapshot, which is a read-only copy of - * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 - * - * @param {FileDeleteOptions} [options] Options to File Delete operation. - * @returns {Promise} Response data for the File Delete operation. - * @memberof ShareFileClient - */ - public async delete(options: FileDeleteOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-delete", options.tracingOptions); - try { - return await this.context.deleteMethod({ - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Removes the file from the storage account if it exists. - * When a file is successfully deleted, it is immediately removed from the storage - * account's index and is no longer accessible to clients. The file's data is later - * removed from the service during garbage collection. - * - * Delete File will fail with status code 409 (Conflict) and error code SharingViolation - * if the file is open on an SMB client. - * - * Delete File is not supported on a share snapshot, which is a read-only copy of - * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue) - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2 - * - * @param {FileDeleteOptions} [options] - * @returns {Promise} - * @memberof ShareFileClient - */ - public async deleteIfExists( - options: FileDeleteOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-deleteIfExists", - options.tracingOptions - ); - try { - const res = await this.delete({ - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - return { - succeeded: true, - ...res - }; - } catch (e) { - if (e.details?.errorCode === "ResourceNotFound") { - span.setStatus({ - code: CanonicalCode.NOT_FOUND, - message: "Expected exception when deleting a file only if it exists." - }); - return { - succeeded: false, - ...e.response?.parsedHeaders, - _response: e.response - }; - } - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Sets HTTP headers on the file. - * - * If no option provided, or no value provided for the file HTTP headers in the options, - * these file HTTP headers without a value will be cleared. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties - * - * @param {fileHttpHeaders} [FileHttpHeaders] File HTTP headers like Content-Type. - * Provide undefined will remove existing HTTP headers. - * @param {FileSetHttpHeadersOptions} [options] Options to File Set HTTP Headers operation. - * @returns {Promise} Response data for the File Set HTTP Headers operation. - * @memberof ShareFileClient - */ - public async setHttpHeaders( - fileHttpHeaders: FileHttpHeaders = {}, - options: FileSetHttpHeadersOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-setHTTPHeaders", - options.tracingOptions - ); - try { - // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved - options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options); - return await this.context.setHTTPHeaders( - fileAttributesToString(options.fileAttributes!), - fileCreationTimeToString(options.creationTime!), - fileLastWriteTimeToString(options.lastWriteTime!), - { - abortSignal: options.abortSignal, - fileHttpHeaders, - filePermission: options.filePermission, - filePermissionKey: options.filePermissionKey, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Resize file. - * - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties - * - * @param {number} length Resizes a file to the specified size in bytes. - * If the specified byte value is less than the current size of the file, - * then all ranges above the specified byte value are cleared. - * @param {FileResizeOptions} [options] Options to File Resize operation. - * @returns {Promise} Response data for the File Set HTTP Headers operation. - * @memberof ShareFileClient - */ - public async resize( - length: number, - options: FileResizeOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-resize", options.tracingOptions); - try { - if (length < 0) { - throw new RangeError(`Size cannot less than 0 when resizing file.`); - } - // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved. - options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options); - - return await this.context.setHTTPHeaders( - fileAttributesToString(options.fileAttributes!), - fileCreationTimeToString(options.creationTime!), - fileLastWriteTimeToString(options.lastWriteTime!), - { - abortSignal: options.abortSignal, - fileContentLength: length, - filePermission: options.filePermission, - filePermissionKey: options.filePermissionKey, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Updates user-defined metadata for the specified file. - * - * If no metadata defined in the option parameter, the file - * metadata will be removed. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-metadata - * - * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed - * @param {FileSetMetadataOptions} [options] Options to File Set Metadata operation. - * @returns {Promise} Response data for the File Set Metadata operation. - * @memberof ShareFileClient - */ - public async setMetadata( - metadata: Metadata = {}, - options: FileSetMetadataOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-setMetadata", options.tracingOptions); - try { - return await this.context.setMetadata({ - abortSignal: options.abortSignal, - metadata, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Upload a range of bytes to a file. Both the start and count of the - * range must be specified. The range can be up to 4 MB in size. - * - * @param {HttpRequestBody} body Blob, string, ArrayBuffer, ArrayBufferView or a function - * which returns a new Readable stream whose offset is from data source beginning. - * @param {number} offset Offset position of the destination Azure File to upload. - * @param {number} contentLength Length of body in bytes. Use Buffer.byteLength() to calculate body length for a - * string including non non-Base64/Hex-encoded characters. - * @param {FileUploadRangeOptions} [options={}] Options to File Upload Range operation. - * @returns {Promise} Response data for the File Upload Range operation. - * @memberof ShareFileClient - * - * Example usage: - * - * ```js - * const content = "Hello world!"; - * - * // Create the file - * await fileClient.create(content.length); - * console.log("Created file successfully!"); - * - * // Then upload data to the file - * await fileClient.uploadRange(content, 0, content.length); - * console.log("Updated file successfully!") - * ``` - */ - public async uploadRange( - body: HttpRequestBody, - offset: number, - contentLength: number, - options: FileUploadRangeOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-uploadRange", options.tracingOptions); - try { - if (offset < 0) { - throw new RangeError(`offset must be >= 0`); - } - - if (contentLength <= 0 || contentLength > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`contentLength must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); - } - - if (contentLength > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`offset must be < ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); - } - - return await this.context.uploadRange( - rangeToString({ count: contentLength, offset }), - "update", - contentLength, - { - abortSignal: options.abortSignal, - contentMD5: options.contentMD5, - onUploadProgress: options.onProgress, - body: body, - spanOptions, - leaseAccessConditions: options.leaseAccessConditions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Upload a range of bytes to a file where the contents are read from a another file's URL. - * The range can be up to 4 MB in size. - * - * @param {string} sourceURL Specify a URL to the copy source, Shared Access Signature(SAS) maybe needed for authentication. - * @param {number} sourceOffset The source offset to copy from. Pass 0 to copy from the beginning of source file. - * @param {number} destOffset Offset of destination file. - * @param {number} count Number of bytes to be uploaded from source file. - * @param {FileUploadRangeFromURLOptions} [options={}] Options to configure File - Upload Range from URL operation. - * @returns {Promise} - * @memberof FileURL - */ - public async uploadRangeFromURL( - sourceURL: string, - sourceOffset: number, - destOffset: number, - count: number, - options: FileUploadRangeFromURLOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-uploadRangeFromURL", - options.tracingOptions - ); - try { - if (sourceOffset < 0 || destOffset < 0) { - throw new RangeError(`sourceOffset and destOffset must be >= 0`); - } - - if (count <= 0 || count > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`count must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`); - } - - return await this.context.uploadRangeFromURL( - rangeToString({ offset: destOffset, count }), - sourceURL, - 0, - { - abortSignal: options.abortSignal, - sourceRange: rangeToString({ offset: sourceOffset, count }), - sourceModifiedAccessConditions: options.sourceConditions, - ...options, - spanOptions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - /** - * Clears the specified range and - * releases the space used in storage for that range. - * - * @param {number} offset - * @param {number} contentLength - * @param {FileClearRangeOptions} [options] Options to File Clear Range operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async clearRange( - offset: number, - contentLength: number, - options: FileClearRangeOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-clearRange", options.tracingOptions); - try { - if (offset < 0 || contentLength <= 0) { - throw new RangeError(`offset must >= 0 and contentLength must be > 0`); - } - - return await this.context.uploadRange( - rangeToString({ count: contentLength, offset }), - "clear", - 0, - { - abortSignal: options.abortSignal, - spanOptions, - leaseAccessConditions: options.leaseAccessConditions - } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns the list of valid ranges for a file. - * - * @param {FileGetRangeListOptions} [options] Options to File Get range List operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async getRangeList( - options: FileGetRangeListOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-getRangeList", - options.tracingOptions - ); - try { - const originalResponse = await this.context.getRangeList({ - abortSignal: options.abortSignal, - range: options.range ? rangeToString(options.range) : undefined, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - return { - _response: originalResponse._response, - date: originalResponse.date, - etag: originalResponse.etag, - errorCode: originalResponse.errorCode, - fileContentLength: originalResponse.fileContentLength, - lastModified: originalResponse.lastModified, - rangeList: originalResponse.filter(() => { - return true; - }), - requestId: originalResponse.requestId, - version: originalResponse.version - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Copies a blob or file to a destination file within the storage account. - * - * @param {string} copySource Specifies the URL of the source file or blob, up to 2 KB in length. - * To copy a file to another file within the same storage account, you may use Shared Key to - * authenticate the source file. If you are copying a file from another storage account, or if you - * are copying a blob from the same storage account or another storage account, then you must - * authenticate the source file or blob using a shared access signature. If the source is a public - * blob, no authentication is required to perform the copy operation. A file in a share snapshot - * can also be specified as a copy source. - * @param {FileStartCopyOptions} [options] Options to File Start Copy operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async startCopyFromURL( - copySource: string, - options: FileStartCopyOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-startCopyFromURL", - options.tracingOptions - ); - try { - return await this.context.startCopy(copySource, { - abortSignal: options.abortSignal, - metadata: options.metadata, - leaseAccessConditions: options.leaseAccessConditions, - filePermission: options.filePermission, - filePermissionKey: options.filePermissionKey, - copyFileSmbInfo: options.copyFileSmbInfo, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Aborts a pending Copy File operation, and leaves a destination file with zero length and full - * metadata. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/abort-copy-file - * - * @param {string} copyId Id of the Copy File operation to abort. - * @param {FileAbortCopyFromURLOptions} [options] Options to File Abort Copy From URL operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async abortCopyFromURL( - copyId: string, - options: FileAbortCopyFromURLOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-abortCopyFromURL", - options.tracingOptions - ); - try { - return await this.context.abortCopy(copyId, { - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - // High Level functions - - /** - * Uploads a Buffer(Node)/Blob/ArrayBuffer/ArrayBufferView to an Azure File. - * - * @param {Buffer | Blob | ArrayBuffer | ArrayBufferView} data Buffer(Node), Blob, ArrayBuffer or ArrayBufferView - * @param {FileParallelUploadOptions} [options] - * @returns {Promise} - */ - public async uploadData( - data: Buffer | Blob | ArrayBuffer | ArrayBufferView, - options: FileParallelUploadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-uploadData", options.tracingOptions); - try { - if (isNode && data instanceof Buffer) { - return this.uploadBuffer( - (offset, count) => data.slice(offset, offset + count), - data.byteLength, - { - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - } - ); - } else { - const browserBlob = new Blob([data]); - return this.uploadSeekableBlob( - (offset: number, size: number): Blob => { - return browserBlob.slice(offset, offset + size); - }, - browserBlob.size, - { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } - ); - } - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN BROWSERS. - * - * Uploads a browser Blob object to an Azure file. Requires a blobFactory as the data source, - * which need to return a Blob object with the offset and size provided. - * - * @param {(offset: number, size: number) => Blob} blobFactory - * @param {number} size - * @param {FileParallelUploadOptions} [options] - * @returns {Promise} - */ - async uploadSeekableBlob( - blobFactory: (offset: number, size: number) => Blob, - size: number, - options: FileParallelUploadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-UploadSeekableBlob", - options.tracingOptions - ); - try { - if (!options.rangeSize) { - options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; - } - if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); - } - - if (!options.fileHttpHeaders) { - options.fileHttpHeaders = {}; - } - - if (!options.concurrency) { - options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; - } - if (options.concurrency < 0) { - throw new RangeError(`options.concurrency cannot less than 0.`); - } - - // Create the file - await this.create(size, { - abortSignal: options.abortSignal, - fileHttpHeaders: options.fileHttpHeaders, - metadata: options.metadata, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - - const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; - let transferProgress: number = 0; - - const batch = new Batch(options.concurrency); - for (let i = 0; i < numBlocks; i++) { - batch.addOperation( - async (): Promise => { - const start = options.rangeSize! * i; - const end = i === numBlocks - 1 ? size : start + options.rangeSize!; - const contentLength = end - start; - await this.uploadRange(blobFactory(start, contentLength), start, contentLength, { - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - // Update progress after block is successfully uploaded to server, in case of block trying - // TODO: Hook with convenience layer progress event in finer level - transferProgress += contentLength; - if (options.onProgress) { - options.onProgress({ loadedBytes: transferProgress }); - } - } - ); - } - return await batch.do(); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * Uploads a local file to an Azure file. - * - * @param {string} filePath Full path of local file - * @param {ShareFileClient} fileClient ShareFileClient - * @param {FileParallelUploadOptions} [options] - * @returns {(Promise)} - */ - public async uploadFile( - filePath: string, - options: FileParallelUploadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan("ShareFileClient-uploadFile", options.tracingOptions); - try { - const size = (await fsStat(filePath)).size; - return await this.uploadResetableStream( - (offset, count) => - fsCreateReadStream(filePath, { - autoClose: true, - end: count ? offset + count - 1 : Infinity, - start: offset - }), - size, - { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } } - ); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * Accepts a Node.js Readable stream factory, and uploads in blocks to an Azure File. - * The Readable stream factory must returns a Node.js Readable stream starting from the offset defined. The offset - * is the offset in the Azure file to be uploaded. - * - * @export - * @param {(offset: number) => NodeJS.ReadableStream} streamFactory Returns a Node.js Readable stream starting - * from the offset defined - * @param {number} size Size of the Azure file - * @param {ShareFileClient} fileClient ShareFileClient - * @param {FileParallelUploadOptions} [options] - * @returns {(Promise)} - */ - async uploadResetableStream( - streamFactory: (offset: number, count?: number) => NodeJS.ReadableStream, - size: number, - options: FileParallelUploadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-uploadResetableStream", - options.tracingOptions - ); - try { - if (!options.rangeSize) { - options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; - } - if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); - } - - if (!options.fileHttpHeaders) { - options.fileHttpHeaders = {}; - } - - if (!options.concurrency) { - options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; - } - if (options.concurrency < 0) { - throw new RangeError(`options.concurrency cannot less than 0.`); - } - - // Create the file - await this.create(size, { - abortSignal: options.abortSignal, - fileHttpHeaders: options.fileHttpHeaders, - metadata: options.metadata, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - - const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; - let transferProgress: number = 0; - const batch = new Batch(options.concurrency); - - for (let i = 0; i < numBlocks; i++) { - batch.addOperation( - async (): Promise => { - const start = options.rangeSize! * i; - const end = i === numBlocks - 1 ? size : start + options.rangeSize!; - const contentLength = end - start; - await this.uploadRange( - () => streamFactory(start, contentLength), - start, - contentLength, - { - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - } - ); - // Update progress after block is successfully uploaded to server, in case of block trying - transferProgress += contentLength; - if (options.onProgress) { - options.onProgress({ loadedBytes: transferProgress }); - } - } - ); - } - return await batch.do(); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * @export - * @param {(offset: number, count: number) => Buffer} bufferChunk Returns a Node.js Buffer chunk starting - * from the offset defined till the count - * @param {number} size Size of the Azure file - * @param {ShareFileClient} fileClient ShareFileClient - * @param {FileParallelUploadOptions} [options] - * @returns {(Promise)} - */ - private async uploadBuffer( - bufferChunk: (offset: number, count: number) => Buffer, - size: number, - options: FileParallelUploadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-uploadBuffer", - options.tracingOptions - ); - try { - if (!options.rangeSize) { - options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; - } - if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); - } - - if (!options.fileHttpHeaders) { - options.fileHttpHeaders = {}; - } - - if (!options.concurrency) { - options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; - } - if (options.concurrency < 0) { - throw new RangeError(`options.concurrency cannot less than 0.`); - } - - // Create the file - await this.create(size, { - abortSignal: options.abortSignal, - fileHttpHeaders: options.fileHttpHeaders, - metadata: options.metadata, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - - const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1; - let transferProgress: number = 0; - const batch = new Batch(options.concurrency); - - for (let i = 0; i < numBlocks; i++) { - batch.addOperation( - async (): Promise => { - const start = options.rangeSize! * i; - const end = i === numBlocks - 1 ? size : start + options.rangeSize!; - const contentLength = end - start; - await this.uploadRange(bufferChunk(start, contentLength), start, contentLength, { - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - // Update progress after block is successfully uploaded to server, in case of block trying - transferProgress += contentLength; - if (options.onProgress) { - options.onProgress({ loadedBytes: transferProgress }); - } - } - ); - } - return await batch.do(); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * Downloads an Azure file in parallel to a buffer. - * Offset and count are optional, pass 0 for both to download the entire file. - * - * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two - * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size, - * consider {@link downloadToFile}. - * - * @param {Buffer} buffer Buffer to be fill, must have length larger than count - * @param {number} offset From which position of the Azure File to download - * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined - * @param {FileDownloadToBufferOptions} [options] - * @returns {Promise} - */ - public async downloadToBuffer( - buffer: Buffer, - offset?: number, - count?: number, - options?: FileDownloadToBufferOptions - ): Promise; - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME - * - * Downloads an Azure file in parallel to a buffer. - * Offset and count are optional, pass 0 for both to download the entire file - * - * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two - * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size, - * consider {@link downloadToFile}. - * - * @param {number} offset From which position of the Azure file to download - * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined - * @param {FileDownloadToBufferOptions} [options] - * @returns {Promise} - */ - public async downloadToBuffer( - offset?: number, - count?: number, - options?: FileDownloadToBufferOptions - ): Promise; - - public async downloadToBuffer( - bufferOrOffset?: Buffer | number, - offsetOrCount?: number, - countOrOptions?: FileDownloadToBufferOptions | number, - optOptions: FileDownloadToBufferOptions = {} - ): Promise { - let buffer: Buffer | undefined = undefined; - let offset: number; - let count: number; - let options: FileDownloadToBufferOptions = optOptions; - - if (bufferOrOffset instanceof Buffer) { - buffer = bufferOrOffset; - offset = offsetOrCount || 0; - count = typeof countOrOptions === "number" ? countOrOptions : 0; - } else { - offset = typeof bufferOrOffset === "number" ? bufferOrOffset : 0; - count = typeof offsetOrCount === "number" ? offsetOrCount : 0; - options = (countOrOptions as FileDownloadToBufferOptions) || {}; - } - - const { span, spanOptions } = createSpan( - "ShareFileClient-downloadToBuffer", - options.tracingOptions - ); - - try { - if (!options.rangeSize) { - options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES; - } - if (options.rangeSize < 0) { - throw new RangeError("rangeSize option must be > 0"); - } - - if (offset < 0) { - throw new RangeError("offset option must be >= 0"); - } - - if (count && count <= 0) { - throw new RangeError("count option must be > 0"); - } - - if (!options.concurrency) { - options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY; - } - if (options.concurrency < 0) { - throw new RangeError(`options.concurrency cannot less than 0.`); - } - - // Customer doesn't specify length, get it - if (!count) { - const response = await this.getProperties({ - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - count = response.contentLength! - offset; - if (count < 0) { - throw new RangeError( - `offset ${offset} shouldn't be larger than file size ${response.contentLength!}` - ); - } - } - - if (!buffer) { - try { - buffer = Buffer.alloc(count); - } catch (error) { - throw new Error( - `Unable to allocate a buffer of size: ${count} bytes. Please try passing your own Buffer to ` + - 'the "downloadToBuffer method or try using other methods like "download" or "downloadToFile".' + - `\t ${error.message}` - ); - } - } - - if (buffer.length < count) { - throw new RangeError( - `The buffer's size should be equal to or larger than the request count of bytes: ${count}` - ); - } - - let transferProgress: number = 0; - const batch = new Batch(options.concurrency); - for (let off = offset; off < offset + count; off = off + options.rangeSize) { - batch.addOperation(async () => { - // Exclusive chunk end position - let chunkEnd = offset + count!; - if (off + options.rangeSize! < chunkEnd) { - chunkEnd = off + options.rangeSize!; - } - const response = await this.download(off, chunkEnd - off, { - abortSignal: options.abortSignal, - maxRetryRequests: options.maxRetryRequestsPerRange, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - const stream = response.readableStreamBody!; - await streamToBuffer(stream, buffer!, off - offset, chunkEnd - offset); - // Update progress after block is downloaded, in case of block trying - // Could provide finer grained progress updating inside HTTP requests, - // only if convenience layer download try is enabled - transferProgress += chunkEnd - off; - if (options.onProgress) { - options.onProgress({ loadedBytes: transferProgress }); - } - }); - } - await batch.do(); - return buffer; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * Uploads a Node.js Readable stream into an Azure file. - * This method will try to create an Azure, then starts uploading chunk by chunk. - * Size of chunk is defined by `bufferSize` parameter. - * Please make sure potential size of stream doesn't exceed file size. - * - * PERFORMANCE IMPROVEMENT TIPS: - * * Input stream highWaterMark is better to set a same value with bufferSize - * parameter, which will avoid Buffer.concat() operations. - * - * @param {Readable} stream Node.js Readable stream. Must be less or equal than file size. - * @param {number} size Size of file to be created. Maximum size allowed is 1TB. - * If this value is larger than stream size, there will be empty bytes in file tail. - * @param {number} bufferSize Size of every buffer allocated in bytes, also the chunk/range size during - * the uploaded file. Size must be > 0 and <= 4 * 1024 * 1024 (4MB) - * @param {number} maxBuffers Max buffers will allocate during uploading, positive correlation - * with max uploading concurrency - * @param {FileUploadStreamOptions} [options] - * @returns {Promise} - */ - public async uploadStream( - stream: Readable, - size: number, - bufferSize: number, - maxBuffers: number, - options: FileUploadStreamOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-uploadStream", - options.tracingOptions - ); - try { - if (!options.fileHttpHeaders) { - options.fileHttpHeaders = {}; - } - - if (bufferSize <= 0 || bufferSize > FILE_RANGE_MAX_SIZE_BYTES) { - throw new RangeError(`bufferSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`); - } - - if (maxBuffers < 0) { - throw new RangeError(`maxBuffers must be > 0.`); - } - - // Create the file - await this.create(size, { - abortSignal: options.abortSignal, - fileHttpHeaders: options.fileHttpHeaders, - metadata: options.metadata, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - - let transferProgress: number = 0; - const scheduler = new BufferScheduler( - stream, - bufferSize, - maxBuffers, - async (buffer: Buffer, offset?: number) => { - if (transferProgress + buffer.length > size) { - throw new RangeError( - `Stream size is larger than file size ${size} bytes, uploading failed. ` + - `Please make sure stream length is less or equal than file size.` - ); - } - - await this.uploadRange(buffer, offset!, buffer.length, { - abortSignal: options.abortSignal, - leaseAccessConditions: options.leaseAccessConditions, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - - // Update progress after block is successfully uploaded to server, in case of block trying - transferProgress += buffer.length; - if (options.onProgress) { - options.onProgress({ loadedBytes: transferProgress }); - } - }, - // Concurrency should set a smaller value than maxBuffers, which is helpful to - // reduce the possibility when a outgoing handler waits for stream data, in - // this situation, outgoing handlers are blocked. - // Outgoing queue shouldn't be empty. - Math.ceil((maxBuffers / 4) * 3) - ); - return await scheduler.do(); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * ONLY AVAILABLE IN NODE.JS RUNTIME. - * - * Downloads an Azure Blob to a local file. - * Fails if the the given file path already exits. - * Offset and count are optional, pass 0 and undefined respectively to download the entire blob. - * - * @param {string} filePath - * @param {number} [offset] From which position of the block blob to download. - * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined. - * @param {BlobDownloadOptions} [options] Options to Blob download options. - * @returns {Promise} The response data for blob download operation, - * but with readableStreamBody set to undefined since its - * content is already read and written into a local file - * at the specified path. - * @memberof BlobClient - */ - public async downloadToFile( - filePath: string, - offset: number = 0, - count?: number, - options: FileDownloadOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-downloadToFile", - options.tracingOptions - ); - try { - const response = await this.download(offset, count, { - ...options, - tracingOptions: { ...options!.tracingOptions, spanOptions } - }); - if (response.readableStreamBody) { - await readStreamToLocalFile(response.readableStreamBody, filePath); - } - - // The stream is no longer accessible so setting it to undefined. - (response as any).fileDownloadStream = undefined; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Lists handles for a file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles - * - * @param {string} [marker] Optional. A string value that identifies the portion of the list to be - * returned with the next list handles operation. The operation returns a - * marker value within the response body if the list returned was not complete. - * The marker value may then be used in a subsequent call to request the next - * set of list items. - * @param {FileListHandlesSegmentOptions} [options={}] - * @returns {Promise} - * @memberof FileURL - */ - private async listHandlesSegment( - marker?: string, - options: FileListHandlesSegmentOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-listHandlesSegment", - options.tracingOptions - ); - try { - marker = marker === "" ? undefined : marker; - const response = await this.context.listHandles({ - abortSignal: options.abortSignal, - marker, - ...options, - spanOptions - }); - - // TODO: Protocol layer issue that when handle list is in returned XML - // response.handleList is an empty string - if ((response.handleList as any) === "") { - response.handleList = undefined; - } - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Returns an AsyncIterableIterator for FileListHandlesResponse - * - * @private - * @param {string} [marker] A string value that identifies the portion of the list to be - * returned with the next list handles operation. The operation returns a - * marker value within the response body if the list returned was not complete. - * The marker value may then be used in a subsequent call to request the next - * set of list items. - * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation. - * @returns {AsyncIterableIterator} - * @memberof ShareFileClient - */ - private async *iterateHandleSegments( - marker?: string, - options: FileListHandlesSegmentOptions = {} - ): AsyncIterableIterator { - let listHandlesResponse; - if (!!marker || marker === undefined) { - do { - listHandlesResponse = await this.listHandlesSegment(marker, options); - marker = listHandlesResponse.continuationToken; - yield listHandlesResponse; - } while (marker); - } - } - - /** - * Returns an AsyncIterableIterator for handles - * - * @private - * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation. - * @returns {AsyncIterableIterator} - * @memberof ShareFileClient - */ - private async *listHandleItems( - options: FileListHandlesSegmentOptions = {} - ): AsyncIterableIterator { - let marker: string | undefined; - for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) { - if (listHandlesResponse.handleList) { - for (const handle of listHandlesResponse.handleList) { - yield handle; - } - } - } - } - - /** - * Returns an async iterable iterator to list all the handles. - * under the specified account. - * - * .byPage() returns an async iterable iterator to list the handles in pages. - * - * @param {FileListHandlesOptions} [options] Options to list handles operation. - * @memberof ShareFileClient - * @returns {PagedAsyncIterableIterator} - * An asyncIterableIterator that supports paging. - */ - public listHandles( - options: FileListHandlesOptions = {} - ): PagedAsyncIterableIterator { - // an AsyncIterableIterator to iterate over handles - const iter = this.listHandleItems(options); - return { - /** - * @member {Promise} [next] The next method, part of the iteration protocol - */ - async next() { - return iter.next(); - }, - /** - * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol - */ - [Symbol.asyncIterator]() { - return this; - }, - /** - * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time - */ - byPage: (settings: PageSettings = {}) => { - return this.iterateHandleSegments(settings.continuationToken, { - maxPageSize: settings.maxPageSize, - ...options - }); - } - }; - } - - /** - * Force close all handles for a file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {string} [marker] Optional. A string value that identifies the position of handles that will - * be closed with the next force close handles operation. - * The operation returns a marker value within the response - * body if there are more handles to close. The marker value - * may then be used in a subsequent call to close the next set of handles. - * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - private async forceCloseHandlesSegment( - marker?: string, - options: FileForceCloseHandlesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-forceCloseHandlesSegment", - options.tracingOptions - ); - try { - marker = marker === "" ? undefined : marker; - const rawResponse = await this.context.forceCloseHandles("*", { - abortSignal: options.abortSignal, - marker, - spanOptions - }); - const response = rawResponse as FileForceCloseHandlesResponse; - response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; - response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Force close all handles for a file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async forceCloseAllHandles( - options: FileForceCloseHandlesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-forceCloseAllHandles", - options.tracingOptions - ); - try { - let handlesClosed = 0; - let numberOfHandlesFailedToClose = 0; - let marker: string | undefined = ""; - - do { - const response: FileForceCloseHandlesResponse = await this.forceCloseHandlesSegment( - marker, - { tracingOptions: { ...options!.tracingOptions, spanOptions } } - ); - marker = response.marker; - response.closedHandlesCount && (handlesClosed += response.closedHandlesCount); - response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount); - } while (marker); - - return { - closedHandlesCount: handlesClosed, - closeFailureCount: numberOfHandlesFailedToClose - }; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Force close a specific handle for a file. - * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles - * - * @param {string} handleId Specific handle ID, cannot be asterisk "*". - * Use forceCloseAllHandles() to close all handles. - * @param FileForceCloseHandlesOptions} [options] Options to force close handles operation. - * @returns {Promise} - * @memberof ShareFileClient - */ - public async forceCloseHandle( - handleId: string, - options: FileForceCloseHandlesOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareFileClient-forceCloseHandle", - options.tracingOptions - ); - try { - if (handleId === "*") { - throw new RangeError( - `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.` - ); - } - - const rawResponse = await this.context.forceCloseHandles(handleId, { - abortSignal: options.abortSignal, - spanOptions - }); - const response = rawResponse as FileForceCloseHandlesResponse; - response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0; - response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * Get a {@link ShareLeaseClient} that manages leases on the file. - * - * @param {string} [proposeLeaseId] Initial proposed lease Id. - * @returns {ShareLeaseClient} A new ShareLeaseClient object for managing leases on the file. - * @memberof ShareFileClient - */ - public getShareLeaseClient(proposeLeaseId?: string): ShareLeaseClient { - return new ShareLeaseClient(this, proposeLeaseId); - } -} - -/** - * The details of the response for a specific lease operation. - */ -export interface LeaseOperationResponseHeaders { - /** - * The ETag contains a value that you can use to perform operations conditionally. If the request - * version is 2011-08-18 or newer, the ETag value will be in quotes. - */ - etag?: string; - /** - * Returns the date and time the file was last modified. Any operation that modifies the file, - * including an update of the file's metadata or properties, changes the last-modified time of - * the file. - */ - lastModified?: Date; - /** - * Uniquely identifies a file's lease, won't be set when returned by releaseLease. - */ - leaseId?: string; - /** - * This header uniquely identifies the request that was made and can be used for troubleshooting - * the request. - */ - requestId?: string; - /** - * Indicates the version of the Blob service used to execute the request. This header is returned - * for requests made against version 2009-09-19 and above. - */ - version?: string; - /** - * UTC date/time value generated by the service that indicates the time at which the response was - * initiated - */ - date?: Date; - errorCode?: string; -} - -/** - * Contains the response data for operations that acquire, change, break or release a lease. - * - * See {@link ShareLeaseClient}. - */ -export type LeaseOperationResponse = LeaseOperationResponseHeaders & { - /** - * The underlying HTTP response. - */ - _response: HttpResponse & { - /** - * The parsed HTTP response headers. - */ - parsedHeaders: LeaseOperationResponseHeaders; - }; -}; - -/** - * lease operations options. - * - * @export - * @interface LeaseOperationOptions - */ -export interface LeaseOperationOptions extends CommonOptions { - /** - * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation. - * For example, use the @azure/abort-controller to create an `AbortSignal`. - * - * @type {AbortSignalLike} - * @memberof LeaseOperationOptions - */ - abortSignal?: AbortSignalLike; -} - -/** - * A client that manages leases for a {@link ShareFileClient}. - * - * @export - * @class ShareLeaseClient - */ -export class ShareLeaseClient { - private _leaseId: string; - private _url: string; - private _file: File; - /** - * Gets the lease Id. - * - * @readonly - * @memberof ShareLeaseClient - * @type {string} - */ - public get leaseId(): string { - return this._leaseId; - } - - /** - * Gets the url. - * - * @readonly - * @memberof ShareLeaseClient - * @type {string} - */ - public get url(): string { - return this._url; - } - - /** - * Creates an instance of ShareLeaseClient. - * @param {ShareFileClient} client The client to make the lease operation requests. - * @param {string} leaseId Initial proposed lease id. - * @memberof ShareLeaseClient - */ - constructor(client: ShareFileClient, leaseId?: string) { - const clientContext = new StorageClientContext( - SERVICE_VERSION, - client.url, - (client as any).pipeline.toServiceClientOptions() - ); - this._file = new File(clientContext); - - this._url = client.url; - - if (!leaseId) { - leaseId = generateUuid(); - } - this._leaseId = leaseId; - } - - /** - * The Lease File operation establishes and manages a lock on a file for write and delete operations. - * - * @param {number} duration Specifies the duration of lease. The only allowed value is -1, for a lease that never expires. - * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. - * @returns {Promise} Response data for acquire lease operation. - * @memberof ShareLeaseClient - */ - public async acquireLease( - duration = -1, - options: LeaseOperationOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareLeaseClient-acquireLease", - options.tracingOptions - ); - try { - return await this._file.acquireLease({ - abortSignal: options.abortSignal, - duration, - proposedLeaseId: this._leaseId, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * To change the ID of an existing lease. - * - * @param {string} proposedLeaseId the proposed new lease Id. - * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. - * @returns {Promise} Response data for change lease operation. - * @memberof ShareLeaseClient - */ - public async changeLease( - proposedLeaseId: string, - options: LeaseOperationOptions = {} - ): Promise { - const { span, spanOptions } = createSpan( - "ShareLeaseClient-changeLease", - options.tracingOptions - ); - try { - const response = await this._file.changeLease(this._leaseId, { - proposedLeaseId, - abortSignal: options.abortSignal, - spanOptions - }); - this._leaseId = proposedLeaseId; - return response; - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * To free the lease if it is no longer needed so that another client may - * immediately acquire a lease against the file. - * - * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. - * @returns {Promise} Response data for release lease operation. - * @memberof ShareLeaseClient - */ - public async releaseLease(options: LeaseOperationOptions = {}): Promise { - const { span, spanOptions } = createSpan( - "ShareLeaseClient-releaseLease", - options.tracingOptions - ); - try { - return await this._file.releaseLease(this._leaseId, { - abortSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } - - /** - * To force end the lease. - * - * @param {LeaseOperationOptions} [options={}] Options for the lease management operation. - * @returns {Promise} Response data for break lease operation. - * @memberof ShareLeaseClient - */ - public async breakLease(options: LeaseOperationOptions = {}): Promise { - const { span, spanOptions } = createSpan("ShareLeaseClient-breakLease", options.tracingOptions); - try { - return await this._file.breakLease({ - abortSignal: options.abortSignal, - spanOptions - }); - } catch (e) { - span.setStatus({ - code: CanonicalCode.UNKNOWN, - message: e.message - }); - throw e; - } finally { - span.end(); - } - } -} diff --git a/sdk/storage/storage-file-share/src/ShareServiceClient.ts b/sdk/storage/storage-file-share/src/ShareServiceClient.ts index e63a4e40032d..97e9a434566f 100644 --- a/sdk/storage/storage-file-share/src/ShareServiceClient.ts +++ b/sdk/storage/storage-file-share/src/ShareServiceClient.ts @@ -16,7 +16,7 @@ import { Service } from "./generated/src/operations"; import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline"; import { StorageClient, CommonOptions } from "./StorageClient"; import { ShareClientInternal } from "./ShareClientInternal"; -import { ShareClient, ShareCreateOptions, ShareDeleteMethodOptions } from "./ShareClient"; +import { ShareClient, ShareCreateOptions, ShareDeleteMethodOptions } from "./Clients"; import { appendToURLPath, extractConnectionStringParts } from "./utils/utils.common"; import { Credential } from "./credentials/Credential"; import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential"; diff --git a/sdk/storage/storage-file-share/src/generated/src/models/fileMappers.ts b/sdk/storage/storage-file-share/src/generated/src/models/fileMappers.ts index 990e34bab617..f14167017a5c 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/fileMappers.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/fileMappers.ts @@ -7,6 +7,7 @@ */ export { + ClearRange, FileAbortCopyHeaders, FileAcquireLeaseHeaders, FileBreakLeaseHeaders, @@ -18,6 +19,7 @@ export { FileGetPropertiesHeaders, FileGetRangeListHeaders, FileListHandlesHeaders, + FileRange, FileReleaseLeaseHeaders, FileSetHTTPHeadersHeaders, FileSetMetadataHeaders, @@ -26,6 +28,6 @@ export { FileUploadRangeHeaders, HandleItem, ListHandlesResponse, - Range, + ShareFileRangeList, StorageError } from "../models/mappers"; diff --git a/sdk/storage/storage-file-share/src/generated/src/models/index.ts b/sdk/storage/storage-file-share/src/generated/src/models/index.ts index 7fb1d5c868d2..abedbd788e9c 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/index.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/index.ts @@ -175,6 +175,21 @@ export interface ShareProperties { nextAllowedQuotaDowngradeTime?: Date; deletedTime?: Date; remainingRetentionDays?: number; + accessTier?: string; + accessTierChangeTime?: Date; + accessTierTransitionState?: string; + /** + * Possible values include: 'locked', 'unlocked' + */ + leaseStatus?: LeaseStatusType; + /** + * Possible values include: 'available', 'leased', 'expired', 'breaking', 'broken' + */ + leaseState?: LeaseStateType; + /** + * Possible values include: 'infinite', 'fixed' + */ + leaseDuration?: LeaseDurationType; } /** @@ -237,10 +252,20 @@ export interface Metrics { retentionPolicy?: RetentionPolicy; } +/** + * Settings for SMB multichannel + */ +export interface SmbMultichannel { + /** + * If SMB multichannel is enabled. + */ + enabled?: boolean; +} + /** * An Azure Storage file range. */ -export interface Range { +export interface FileRange { /** * Start of the range. */ @@ -251,6 +276,42 @@ export interface Range { end: number; } +/** + * An interface representing ClearRange. + */ +export interface ClearRange { + start: number; + end: number; +} + +/** + * Settings for SMB protocol. + */ +export interface ShareSmbSettings { + /** + * Settings for SMB Multichannel. + */ + multichannel?: SmbMultichannel; +} + +/** + * Protocol settings + */ +export interface ShareProtocolSettings { + /** + * Settings for SMB protocol. + */ + smb?: ShareSmbSettings; +} + +/** + * The list of file ranges + */ +export interface ShareFileRangeList { + ranges?: FileRange[]; + clearRanges?: ClearRange[]; +} + /** * An interface representing StorageError. */ @@ -309,6 +370,21 @@ export interface FileServiceProperties { * The set of CORS rules. */ cors?: CorsRule[]; + /** + * Protocol settings + */ + protocol?: ShareProtocolSettings; +} + +/** + * Additional parameters for a set of operations. + */ +export interface LeaseAccessConditions { + /** + * If specified, the operation only succeeds if the resource's lease is active and matches this + * ID. + */ + leaseId?: string; } /** @@ -342,17 +418,6 @@ export interface FileHttpHeaders { fileContentDisposition?: string; } -/** - * Additional parameters for a set of operations. - */ -export interface LeaseAccessConditions { - /** - * If specified, the operation only succeeds if the resource's lease is active and matches this - * ID. - */ - leaseId?: string; -} - /** * Additional parameters for uploadRangeFromURL operation. */ @@ -478,6 +543,11 @@ export interface ShareCreateOptionalParams extends coreHttp.RequestOptionsBase { * Specifies the maximum size of the share, in gigabytes. */ quota?: number; + /** + * Specifies the access tier of the share. Possible values include: 'TransactionOptimized', + * 'Hot', 'Cool' + */ + accessTier?: ShareAccessTier; } /** @@ -495,6 +565,10 @@ export interface ShareGetPropertiesOptionalParams extends coreHttp.RequestOption * Timeouts for File Service Operations. */ timeoutInSeconds?: number; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -514,9 +588,155 @@ export interface ShareDeleteMethodOptionalParams extends coreHttp.RequestOptions timeoutInSeconds?: number; /** * Specifies the option include to delete the base share and all of its snapshots. Possible - * values include: 'include' + * values include: 'include', 'include-leased' */ deleteSnapshots?: DeleteSnapshotsOptionType; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; +} + +/** + * Optional Parameters. + */ +export interface ShareAcquireLeaseOptionalParams extends coreHttp.RequestOptionsBase { + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never + * expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be + * changed using renew or change. + */ + duration?: number; + /** + * Proposed lease ID, in a GUID string format. The File service returns 400 (Invalid request) if + * the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list + * of valid GUID string formats. + */ + proposedLeaseId?: string; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; + /** + * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the + * analytics logs when storage analytics logging is enabled. + */ + requestId?: string; +} + +/** + * Optional Parameters. + */ +export interface ShareReleaseLeaseOptionalParams extends coreHttp.RequestOptionsBase { + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; + /** + * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the + * analytics logs when storage analytics logging is enabled. + */ + requestId?: string; +} + +/** + * Optional Parameters. + */ +export interface ShareChangeLeaseOptionalParams extends coreHttp.RequestOptionsBase { + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * Proposed lease ID, in a GUID string format. The File service returns 400 (Invalid request) if + * the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list + * of valid GUID string formats. + */ + proposedLeaseId?: string; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; + /** + * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the + * analytics logs when storage analytics logging is enabled. + */ + requestId?: string; +} + +/** + * Optional Parameters. + */ +export interface ShareRenewLeaseOptionalParams extends coreHttp.RequestOptionsBase { + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; + /** + * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the + * analytics logs when storage analytics logging is enabled. + */ + requestId?: string; +} + +/** + * Optional Parameters. + */ +export interface ShareBreakLeaseOptionalParams extends coreHttp.RequestOptionsBase { + /** + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * For a break operation, proposed duration the lease should continue before it is broken, in + * seconds, between 0 and 60. This break period is only used if it is shorter than the time + * remaining on the lease. If longer, the time remaining on the lease is used. A new lease will + * not be available before the break period has expired, but the lease may be held for longer + * than the break period. If this header does not appear with a break operation, a fixed-duration + * lease breaks after the remaining lease period elapses, and an infinite lease breaks + * immediately. + */ + breakPeriod?: number; + /** + * Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the + * analytics logs when storage analytics logging is enabled. + */ + requestId?: string; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -562,7 +782,7 @@ export interface ShareGetPermissionOptionalParams extends coreHttp.RequestOption /** * Optional Parameters. */ -export interface ShareSetQuotaOptionalParams extends coreHttp.RequestOptionsBase { +export interface ShareSetPropertiesOptionalParams extends coreHttp.RequestOptionsBase { /** * The timeout parameter is expressed in seconds. For more information, see Setting @@ -573,6 +793,15 @@ export interface ShareSetQuotaOptionalParams extends coreHttp.RequestOptionsBase * Specifies the maximum size of the share, in gigabytes. */ quota?: number; + /** + * Specifies the access tier of the share. Possible values include: 'TransactionOptimized', + * 'Hot', 'Cool' + */ + accessTier?: ShareAccessTier; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -589,6 +818,10 @@ export interface ShareSetMetadataOptionalParams extends coreHttp.RequestOptionsB * A name-value pair to associate with a file storage object. */ metadata?: { [propertyName: string]: string }; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -601,6 +834,10 @@ export interface ShareGetAccessPolicyOptionalParams extends coreHttp.RequestOpti * Timeouts for File Service Operations. */ timeoutInSeconds?: number; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -617,6 +854,10 @@ export interface ShareSetAccessPolicyOptionalParams extends coreHttp.RequestOpti * Timeouts for File Service Operations. */ timeoutInSeconds?: number; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -629,6 +870,10 @@ export interface ShareGetStatisticsOptionalParams extends coreHttp.RequestOption * Timeouts for File Service Operations. */ timeoutInSeconds?: number; + /** + * Additional parameters for the operation + */ + leaseAccessConditions?: LeaseAccessConditions; } /** @@ -1163,6 +1408,11 @@ export interface FileGetRangeListOptionalParams extends coreHttp.RequestOptionsB * snapshot to query. */ shareSnapshot?: string; + /** + * The previous snapshot parameter is an opaque DateTime value that, when present, specifies the + * previous snapshot. + */ + prevsharesnapshot?: string; /** * The timeout parameter is expressed in seconds. For more information, see Setting @@ -1266,29 +1516,186 @@ export interface FileListHandlesOptionalParams extends coreHttp.RequestOptionsBa */ export interface FileForceCloseHandlesOptionalParams extends coreHttp.RequestOptionsBase { /** - * The timeout parameter is expressed in seconds. For more information, see Setting - * Timeouts for File Service Operations. + * The timeout parameter is expressed in seconds. For more information, see Setting + * Timeouts for File Service Operations. + */ + timeoutInSeconds?: number; + /** + * A string value that identifies the portion of the list to be returned with the next list + * operation. The operation returns a marker value within the response body if the list returned + * was not complete. The marker value may then be used in a subsequent call to request the next + * set of list items. The marker value is opaque to the client. + */ + marker?: string; + /** + * The snapshot parameter is an opaque DateTime value that, when present, specifies the share + * snapshot to query. + */ + shareSnapshot?: string; +} + +/** + * Defines headers for SetProperties operation. + */ +export interface ServiceSetPropertiesHeaders { + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + errorCode?: string; +} + +/** + * Defines headers for GetProperties operation. + */ +export interface ServiceGetPropertiesHeaders { + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + errorCode?: string; +} + +/** + * Defines headers for ListSharesSegment operation. + */ +export interface ServiceListSharesSegmentHeaders { + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + errorCode?: string; +} + +/** + * Defines headers for Create operation. + */ +export interface ShareCreateHeaders { + /** + * The ETag contains a value which represents the version of the share, in quotes. + */ + etag?: string; + /** + * Returns the date and time the share was last modified. Any operation that modifies the share + * or its properties or metadata updates the last modified time. Operations on files do not + * affect the last modified time of the share. + */ + lastModified?: Date; + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + /** + * A UTC date/time value generated by the service that indicates the time at which the response + * was initiated. + */ + date?: Date; + errorCode?: string; +} + +/** + * Defines headers for GetProperties operation. + */ +export interface ShareGetPropertiesHeaders { + metadata?: { [propertyName: string]: string }; + /** + * The ETag contains a value that you can use to perform operations conditionally, in quotes. + */ + etag?: string; + /** + * Returns the date and time the share was last modified. Any operation that modifies the share + * or its properties updates the last modified time. Operations on files do not affect the last + * modified time of the share. + */ + lastModified?: Date; + /** + * This header uniquely identifies the request that was made and can be used for troubleshooting + * the request. + */ + requestId?: string; + /** + * Indicates the version of the File service used to execute the request. + */ + version?: string; + /** + * A UTC date/time value generated by the service that indicates the time at which the response + * was initiated. + */ + date?: Date; + /** + * Returns the current share quota in GB. + */ + quota?: number; + /** + * Returns the current share provisioned ipos. + */ + provisionedIops?: number; + /** + * Returns the current share provisioned ingress in megabytes per second. + */ + provisionedIngressMBps?: number; + /** + * Returns the current share provisioned egress in megabytes per second. + */ + provisionedEgressMBps?: number; + /** + * Returns the current share next allowed quota downgrade time. + */ + nextAllowedQuotaDowngradeTime?: Date; + /** + * When a share is leased, specifies whether the lease is of infinite or fixed duration. Possible + * values include: 'infinite', 'fixed' + */ + leaseDuration?: LeaseDurationType; + /** + * Lease state of the share. Possible values include: 'available', 'leased', 'expired', + * 'breaking', 'broken' + */ + leaseState?: LeaseStateType; + /** + * The current lease status of the share. Possible values include: 'locked', 'unlocked' */ - timeoutInSeconds?: number; + leaseStatus?: LeaseStatusType; /** - * A string value that identifies the portion of the list to be returned with the next list - * operation. The operation returns a marker value within the response body if the list returned - * was not complete. The marker value may then be used in a subsequent call to request the next - * set of list items. The marker value is opaque to the client. + * Returns the access tier set on the share. */ - marker?: string; + accessTier?: string; /** - * The snapshot parameter is an opaque DateTime value that, when present, specifies the share - * snapshot to query. + * Returns the last modified time (in UTC) of the access tier of the share. */ - shareSnapshot?: string; + accessTierChangeTime?: Date; + /** + * Returns the transition state betweeen access tiers, when present. + */ + accessTierTransitionState?: string; + errorCode?: string; } /** - * Defines headers for SetProperties operation. + * Defines headers for Delete operation. */ -export interface ServiceSetPropertiesHeaders { +export interface ShareDeleteHeaders { /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1298,13 +1705,37 @@ export interface ServiceSetPropertiesHeaders { * Indicates the version of the File service used to execute the request. */ version?: string; + /** + * A UTC date/time value generated by the service that indicates the time at which the response + * was initiated. + */ + date?: Date; errorCode?: string; } /** - * Defines headers for GetProperties operation. + * Defines headers for AcquireLease operation. */ -export interface ServiceGetPropertiesHeaders { +export interface ShareAcquireLeaseHeaders { + /** + * The ETag contains a value that you can use to perform operations conditionally, in quotes. + */ + etag?: string; + /** + * Returns the date and time the share was last modified. Any operation that modifies the share + * or its properties updates the last modified time. Operations on files do not affect the last + * modified time of the share. + */ + lastModified?: Date; + /** + * Uniquely identifies a share's lease + */ + leaseId?: string; + /** + * If a client request id header is sent in the request, this header will be present in the + * response with the same value. + */ + clientRequestId?: string; /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1314,13 +1745,33 @@ export interface ServiceGetPropertiesHeaders { * Indicates the version of the File service used to execute the request. */ version?: string; + /** + * UTC date/time value generated by the service that indicates the time at which the response was + * initiated + */ + date?: Date; errorCode?: string; } /** - * Defines headers for ListSharesSegment operation. + * Defines headers for ReleaseLease operation. */ -export interface ServiceListSharesSegmentHeaders { +export interface ShareReleaseLeaseHeaders { + /** + * The ETag contains a value that you can use to perform operations conditionally, in quotes. + */ + etag?: string; + /** + * Returns the date and time the share was last modified. Any operation that modifies the share + * or its properties updates the last modified time. Operations on files do not affect the last + * modified time of the share. + */ + lastModified?: Date; + /** + * If a client request id header is sent in the request, this header will be present in the + * response with the same value. + */ + clientRequestId?: string; /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1330,23 +1781,37 @@ export interface ServiceListSharesSegmentHeaders { * Indicates the version of the File service used to execute the request. */ version?: string; + /** + * UTC date/time value generated by the service that indicates the time at which the response was + * initiated + */ + date?: Date; errorCode?: string; } /** - * Defines headers for Create operation. + * Defines headers for ChangeLease operation. */ -export interface ShareCreateHeaders { +export interface ShareChangeLeaseHeaders { /** - * The ETag contains a value which represents the version of the share, in quotes. + * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ etag?: string; /** * Returns the date and time the share was last modified. Any operation that modifies the share - * or its properties or metadata updates the last modified time. Operations on files do not - * affect the last modified time of the share. + * or its properties updates the last modified time. Operations on files do not affect the last + * modified time of the share. */ lastModified?: Date; + /** + * Uniquely identifies a share's lease + */ + leaseId?: string; + /** + * If a client request id header is sent in the request, this header will be present in the + * response with the same value. + */ + clientRequestId?: string; /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1357,18 +1822,17 @@ export interface ShareCreateHeaders { */ version?: string; /** - * A UTC date/time value generated by the service that indicates the time at which the response - * was initiated. + * UTC date/time value generated by the service that indicates the time at which the response was + * initiated */ date?: Date; errorCode?: string; } /** - * Defines headers for GetProperties operation. + * Defines headers for RenewLease operation. */ -export interface ShareGetPropertiesHeaders { - metadata?: { [propertyName: string]: string }; +export interface ShareRenewLeaseHeaders { /** * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ @@ -1379,6 +1843,15 @@ export interface ShareGetPropertiesHeaders { * modified time of the share. */ lastModified?: Date; + /** + * Uniquely identifies a share's lease + */ + leaseId?: string; + /** + * If a client request id header is sent in the request, this header will be present in the + * response with the same value. + */ + clientRequestId?: string; /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1389,37 +1862,39 @@ export interface ShareGetPropertiesHeaders { */ version?: string; /** - * A UTC date/time value generated by the service that indicates the time at which the response - * was initiated. + * Returns the current share next allowed quota downgrade time. */ date?: Date; + errorCode?: string; +} + +/** + * Defines headers for BreakLease operation. + */ +export interface ShareBreakLeaseHeaders { /** - * Returns the current share quota in GB. + * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ - quota?: number; + etag?: string; /** - * Returns the current share provisioned ipos. + * Returns the date and time the share was last modified. Any operation that modifies the share + * or its properties updates the last modified time. Operations on files do not affect the last + * modified time of the share. */ - provisionedIops?: number; + lastModified?: Date; /** - * Returns the current share provisioned ingress in megabytes per second. + * Approximate time remaining in the lease period, in seconds. */ - provisionedIngressMBps?: number; + leaseTimeInSeconds?: number; /** - * Returns the current share provisioned egress in megabytes per second. + * Uniquely identifies a share's lease */ - provisionedEgressMBps?: number; + leaseId?: string; /** - * Returns the current share next allowed quota downgrade time. + * If a client request id header is sent in the request, this header will be present in the + * response with the same value. */ - nextAllowedQuotaDowngradeTime?: Date; - errorCode?: string; -} - -/** - * Defines headers for Delete operation. - */ -export interface ShareDeleteHeaders { + clientRequestId?: string; /** * This header uniquely identifies the request that was made and can be used for troubleshooting * the request. @@ -1430,8 +1905,8 @@ export interface ShareDeleteHeaders { */ version?: string; /** - * A UTC date/time value generated by the service that indicates the time at which the response - * was initiated. + * UTC date/time value generated by the service that indicates the time at which the response was + * initiated */ date?: Date; errorCode?: string; @@ -1528,9 +2003,9 @@ export interface ShareGetPermissionHeaders { } /** - * Defines headers for SetQuota operation. + * Defines headers for SetProperties operation. */ -export interface ShareSetQuotaHeaders { +export interface ShareSetPropertiesHeaders { /** * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ @@ -2961,60 +3436,68 @@ export interface FileForceCloseHandlesHeaders { export type StorageErrorCode = 'AccountAlreadyExists' | 'AccountBeingCreated' | 'AccountIsDisabled' | 'AuthenticationFailed' | 'AuthorizationFailure' | 'ConditionHeadersNotSupported' | 'ConditionNotMet' | 'EmptyMetadataKey' | 'InsufficientAccountPermissions' | 'InternalError' | 'InvalidAuthenticationInfo' | 'InvalidHeaderValue' | 'InvalidHttpVerb' | 'InvalidInput' | 'InvalidMd5' | 'InvalidMetadata' | 'InvalidQueryParameterValue' | 'InvalidRange' | 'InvalidResourceName' | 'InvalidUri' | 'InvalidXmlDocument' | 'InvalidXmlNodeValue' | 'Md5Mismatch' | 'MetadataTooLarge' | 'MissingContentLengthHeader' | 'MissingRequiredQueryParameter' | 'MissingRequiredHeader' | 'MissingRequiredXmlNode' | 'MultipleConditionHeadersNotSupported' | 'OperationTimedOut' | 'OutOfRangeInput' | 'OutOfRangeQueryParameterValue' | 'RequestBodyTooLarge' | 'ResourceTypeMismatch' | 'RequestUrlFailedToParse' | 'ResourceAlreadyExists' | 'ResourceNotFound' | 'ServerBusy' | 'UnsupportedHeader' | 'UnsupportedXmlNode' | 'UnsupportedQueryParameter' | 'UnsupportedHttpVerb' | 'CannotDeleteFileOrDirectory' | 'ClientCacheFlushDelay' | 'DeletePending' | 'DirectoryNotEmpty' | 'FileLockConflict' | 'InvalidFileOrDirectoryPathName' | 'ParentNotFound' | 'ReadOnlyAttribute' | 'ShareAlreadyExists' | 'ShareBeingDeleted' | 'ShareDisabled' | 'ShareNotFound' | 'SharingViolation' | 'ShareSnapshotInProgress' | 'ShareSnapshotCountExceeded' | 'ShareSnapshotOperationNotSupported' | 'ShareHasSnapshots' | 'ContainerQuotaDowngradeNotAllowed' | 'AuthorizationSourceIPMismatch' | 'AuthorizationProtocolMismatch' | 'AuthorizationPermissionMismatch' | 'AuthorizationServiceMismatch' | 'AuthorizationResourceTypeMismatch' | 'FeatureVersionMismatch'; /** - * Defines values for PermissionCopyModeType. - * Possible values include: 'source', 'override' + * Defines values for LeaseDurationType. + * Possible values include: 'infinite', 'fixed' * @readonly * @enum {string} */ -export type PermissionCopyModeType = 'source' | 'override'; +export type LeaseDurationType = 'infinite' | 'fixed'; /** - * Defines values for DeleteSnapshotsOptionType. - * Possible values include: 'include' + * Defines values for LeaseStateType. + * Possible values include: 'available', 'leased', 'expired', 'breaking', 'broken' * @readonly * @enum {string} */ -export type DeleteSnapshotsOptionType = 'include'; +export type LeaseStateType = 'available' | 'leased' | 'expired' | 'breaking' | 'broken'; /** - * Defines values for ListSharesIncludeType. - * Possible values include: 'snapshots', 'metadata', 'deleted' + * Defines values for LeaseStatusType. + * Possible values include: 'locked', 'unlocked' * @readonly * @enum {string} */ -export type ListSharesIncludeType = 'snapshots' | 'metadata' | 'deleted'; +export type LeaseStatusType = 'locked' | 'unlocked'; /** - * Defines values for CopyStatusType. - * Possible values include: 'pending', 'success', 'aborted', 'failed' + * Defines values for ShareAccessTier. + * Possible values include: 'TransactionOptimized', 'Hot', 'Cool' * @readonly * @enum {string} */ -export type CopyStatusType = 'pending' | 'success' | 'aborted' | 'failed'; +export type ShareAccessTier = 'TransactionOptimized' | 'Hot' | 'Cool'; /** - * Defines values for LeaseDurationType. - * Possible values include: 'infinite', 'fixed' + * Defines values for PermissionCopyModeType. + * Possible values include: 'source', 'override' * @readonly * @enum {string} */ -export type LeaseDurationType = 'infinite' | 'fixed'; +export type PermissionCopyModeType = 'source' | 'override'; /** - * Defines values for LeaseStateType. - * Possible values include: 'available', 'leased', 'expired', 'breaking', 'broken' + * Defines values for DeleteSnapshotsOptionType. + * Possible values include: 'include', 'include-leased' * @readonly * @enum {string} */ -export type LeaseStateType = 'available' | 'leased' | 'expired' | 'breaking' | 'broken'; +export type DeleteSnapshotsOptionType = 'include' | 'include-leased'; /** - * Defines values for LeaseStatusType. - * Possible values include: 'locked', 'unlocked' + * Defines values for ListSharesIncludeType. + * Possible values include: 'snapshots', 'metadata', 'deleted' * @readonly * @enum {string} */ -export type LeaseStatusType = 'locked' | 'unlocked'; +export type ListSharesIncludeType = 'snapshots' | 'metadata' | 'deleted'; + +/** + * Defines values for CopyStatusType. + * Possible values include: 'pending', 'success', 'aborted', 'failed' + * @readonly + * @enum {string} + */ +export type CopyStatusType = 'pending' | 'success' | 'aborted' | 'failed'; /** * Defines values for FileRangeWriteType. @@ -3142,6 +3625,81 @@ export type ShareDeleteResponse = ShareDeleteHeaders & { }; }; +/** + * Contains response data for the acquireLease operation. + */ +export type ShareAcquireLeaseResponse = ShareAcquireLeaseHeaders & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareAcquireLeaseHeaders; + }; +}; + +/** + * Contains response data for the releaseLease operation. + */ +export type ShareReleaseLeaseResponse = ShareReleaseLeaseHeaders & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareReleaseLeaseHeaders; + }; +}; + +/** + * Contains response data for the changeLease operation. + */ +export type ShareChangeLeaseResponse = ShareChangeLeaseHeaders & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareChangeLeaseHeaders; + }; +}; + +/** + * Contains response data for the renewLease operation. + */ +export type ShareRenewLeaseResponse = ShareRenewLeaseHeaders & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareRenewLeaseHeaders; + }; +}; + +/** + * Contains response data for the breakLease operation. + */ +export type ShareBreakLeaseResponse = ShareBreakLeaseHeaders & { + /** + * The underlying HTTP response. + */ + _response: coreHttp.HttpResponse & { + /** + * The parsed HTTP response headers. + */ + parsedHeaders: ShareBreakLeaseHeaders; + }; +}; + /** * Contains response data for the createSnapshot operation. */ @@ -3198,9 +3756,9 @@ export type ShareGetPermissionResponse = SharePermission & ShareGetPermissionHea }; /** - * Contains response data for the setQuota operation. + * Contains response data for the setProperties operation. */ -export type ShareSetQuotaResponse = ShareSetQuotaHeaders & { +export type ShareSetPropertiesResponse = ShareSetPropertiesHeaders & { /** * The underlying HTTP response. */ @@ -3208,7 +3766,7 @@ export type ShareSetQuotaResponse = ShareSetQuotaHeaders & { /** * The parsed HTTP response headers. */ - parsedHeaders: ShareSetQuotaHeaders; + parsedHeaders: ShareSetPropertiesHeaders; }; }; @@ -3646,7 +4204,7 @@ export type FileUploadRangeFromURLResponse = FileUploadRangeFromURLHeaders & { /** * Contains response data for the getRangeList operation. */ -export type FileGetRangeListResponse = Array & FileGetRangeListHeaders & { +export type FileGetRangeListResponse = ShareFileRangeList & FileGetRangeListHeaders & { /** * The underlying HTTP response. */ @@ -3664,7 +4222,7 @@ export type FileGetRangeListResponse = Array & FileGetRangeListHeaders & /** * The response body as parsed JSON or XML */ - parsedBody: Range[]; + parsedBody: ShareFileRangeList; }; }; diff --git a/sdk/storage/storage-file-share/src/generated/src/models/mappers.ts b/sdk/storage/storage-file-share/src/generated/src/models/mappers.ts index a4f07c09825b..c5b8fb1b0bd9 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/mappers.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/mappers.ts @@ -462,6 +462,63 @@ export const ShareProperties: coreHttp.CompositeMapper = { type: { name: "Number" } + }, + accessTier: { + xmlName: "AccessTier", + serializedName: "AccessTier", + type: { + name: "String" + } + }, + accessTierChangeTime: { + xmlName: "AccessTierChangeTime", + serializedName: "AccessTierChangeTime", + type: { + name: "DateTimeRfc1123" + } + }, + accessTierTransitionState: { + xmlName: "AccessTierTransitionState", + serializedName: "AccessTierTransitionState", + type: { + name: "String" + } + }, + leaseStatus: { + xmlName: "LeaseStatus", + serializedName: "LeaseStatus", + type: { + name: "Enum", + allowedValues: [ + "locked", + "unlocked" + ] + } + }, + leaseState: { + xmlName: "LeaseState", + serializedName: "LeaseState", + type: { + name: "Enum", + allowedValues: [ + "available", + "leased", + "expired", + "breaking", + "broken" + ] + } + }, + leaseDuration: { + xmlName: "LeaseDuration", + serializedName: "LeaseDuration", + type: { + name: "Enum", + allowedValues: [ + "infinite", + "fixed" + ] + } } } } @@ -662,11 +719,56 @@ export const Metrics: coreHttp.CompositeMapper = { } }; -export const Range: coreHttp.CompositeMapper = { - serializedName: "Range", +export const SmbMultichannel: coreHttp.CompositeMapper = { + xmlName: "Multichannel", + serializedName: "SmbMultichannel", + type: { + name: "Composite", + className: "SmbMultichannel", + modelProperties: { + enabled: { + xmlName: "Enabled", + serializedName: "Enabled", + type: { + name: "Boolean" + } + } + } + } +}; + +export const FileRange: coreHttp.CompositeMapper = { + xmlName: "Range", + serializedName: "FileRange", + type: { + name: "Composite", + className: "FileRange", + modelProperties: { + start: { + xmlName: "Start", + required: true, + serializedName: "Start", + type: { + name: "Number" + } + }, + end: { + xmlName: "End", + required: true, + serializedName: "End", + type: { + name: "Number" + } + } + } + } +}; + +export const ClearRange: coreHttp.CompositeMapper = { + serializedName: "ClearRange", type: { name: "Composite", - className: "Range", + className: "ClearRange", modelProperties: { start: { xmlName: "Start", @@ -688,6 +790,80 @@ export const Range: coreHttp.CompositeMapper = { } }; +export const ShareSmbSettings: coreHttp.CompositeMapper = { + serializedName: "ShareSmbSettings", + type: { + name: "Composite", + className: "ShareSmbSettings", + modelProperties: { + multichannel: { + xmlName: "Multichannel", + serializedName: "Multichannel", + type: { + name: "Composite", + className: "SmbMultichannel" + } + } + } + } +}; + +export const ShareProtocolSettings: coreHttp.CompositeMapper = { + serializedName: "ShareProtocolSettings", + type: { + name: "Composite", + className: "ShareProtocolSettings", + modelProperties: { + smb: { + xmlName: "SMB", + serializedName: "Smb", + type: { + name: "Composite", + className: "ShareSmbSettings" + } + } + } + } +}; + +export const ShareFileRangeList: coreHttp.CompositeMapper = { + serializedName: "ShareFileRangeList", + type: { + name: "Composite", + className: "ShareFileRangeList", + modelProperties: { + ranges: { + xmlName: "Ranges", + xmlElementName: "Range", + serializedName: "Ranges", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "FileRange" + } + } + } + }, + clearRanges: { + xmlName: "ClearRanges", + xmlElementName: "ClearRange", + serializedName: "ClearRanges", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ClearRange" + } + } + } + } + } + } +}; + export const StorageError: coreHttp.CompositeMapper = { serializedName: "StorageError", type: { @@ -804,6 +980,30 @@ export const FileServiceProperties: coreHttp.CompositeMapper = { } } } + }, + protocol: { + xmlName: "ProtocolSettings", + serializedName: "Protocol", + type: { + name: "Composite", + className: "ShareProtocolSettings" + } + } + } + } +}; + +export const LeaseAccessConditions: coreHttp.CompositeMapper = { + xmlName: "lease-access-conditions", + type: { + name: "Composite", + className: "LeaseAccessConditions", + modelProperties: { + leaseId: { + xmlName: "leaseId", + type: { + name: "String" + } } } } @@ -855,22 +1055,6 @@ export const FileHttpHeaders: coreHttp.CompositeMapper = { } }; -export const LeaseAccessConditions: coreHttp.CompositeMapper = { - xmlName: "lease-access-conditions", - type: { - name: "Composite", - className: "LeaseAccessConditions", - modelProperties: { - leaseId: { - xmlName: "leaseId", - type: { - name: "String" - } - } - } - } -}; - export const SourceModifiedAccessConditions: coreHttp.CompositeMapper = { xmlName: "source-modified-access-conditions", type: { @@ -1151,6 +1335,57 @@ export const ShareGetPropertiesHeaders: coreHttp.CompositeMapper = { name: "DateTimeRfc1123" } }, + leaseDuration: { + serializedName: "x-ms-lease-duration", + type: { + name: "Enum", + allowedValues: [ + "infinite", + "fixed" + ] + } + }, + leaseState: { + serializedName: "x-ms-lease-state", + type: { + name: "Enum", + allowedValues: [ + "available", + "leased", + "expired", + "breaking", + "broken" + ] + } + }, + leaseStatus: { + serializedName: "x-ms-lease-status", + type: { + name: "Enum", + allowedValues: [ + "locked", + "unlocked" + ] + } + }, + accessTier: { + serializedName: "x-ms-access-tier", + type: { + name: "String" + } + }, + accessTierChangeTime: { + serializedName: "x-ms-access-tier-change-time", + type: { + name: "DateTimeRfc1123" + } + }, + accessTierTransitionState: { + serializedName: "x-ms-access-tier-transition-state", + type: { + name: "String" + } + }, errorCode: { serializedName: "x-ms-error-code", type: { @@ -1195,6 +1430,296 @@ export const ShareDeleteHeaders: coreHttp.CompositeMapper = { } }; +export const ShareAcquireLeaseHeaders: coreHttp.CompositeMapper = { + serializedName: "share-acquirelease-headers", + type: { + name: "Composite", + className: "ShareAcquireLeaseHeaders", + modelProperties: { + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "DateTimeRfc1123" + } + }, + leaseId: { + serializedName: "x-ms-lease-id", + type: { + name: "String" + } + }, + clientRequestId: { + serializedName: "x-ms-client-request-id", + type: { + name: "String" + } + }, + requestId: { + serializedName: "x-ms-request-id", + type: { + name: "String" + } + }, + version: { + serializedName: "x-ms-version", + type: { + name: "String" + } + }, + date: { + serializedName: "date", + type: { + name: "DateTimeRfc1123" + } + }, + errorCode: { + serializedName: "x-ms-error-code", + type: { + name: "String" + } + } + } + } +}; + +export const ShareReleaseLeaseHeaders: coreHttp.CompositeMapper = { + serializedName: "share-releaselease-headers", + type: { + name: "Composite", + className: "ShareReleaseLeaseHeaders", + modelProperties: { + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "DateTimeRfc1123" + } + }, + clientRequestId: { + serializedName: "x-ms-client-request-id", + type: { + name: "String" + } + }, + requestId: { + serializedName: "x-ms-request-id", + type: { + name: "String" + } + }, + version: { + serializedName: "x-ms-version", + type: { + name: "String" + } + }, + date: { + serializedName: "date", + type: { + name: "DateTimeRfc1123" + } + }, + errorCode: { + serializedName: "x-ms-error-code", + type: { + name: "String" + } + } + } + } +}; + +export const ShareChangeLeaseHeaders: coreHttp.CompositeMapper = { + serializedName: "share-changelease-headers", + type: { + name: "Composite", + className: "ShareChangeLeaseHeaders", + modelProperties: { + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "DateTimeRfc1123" + } + }, + leaseId: { + serializedName: "x-ms-lease-id", + type: { + name: "String" + } + }, + clientRequestId: { + serializedName: "x-ms-client-request-id", + type: { + name: "String" + } + }, + requestId: { + serializedName: "x-ms-request-id", + type: { + name: "String" + } + }, + version: { + serializedName: "x-ms-version", + type: { + name: "String" + } + }, + date: { + serializedName: "date", + type: { + name: "DateTimeRfc1123" + } + }, + errorCode: { + serializedName: "x-ms-error-code", + type: { + name: "String" + } + } + } + } +}; + +export const ShareRenewLeaseHeaders: coreHttp.CompositeMapper = { + serializedName: "share-renewlease-headers", + type: { + name: "Composite", + className: "ShareRenewLeaseHeaders", + modelProperties: { + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "DateTimeRfc1123" + } + }, + leaseId: { + serializedName: "x-ms-lease-id", + type: { + name: "String" + } + }, + clientRequestId: { + serializedName: "x-ms-client-request-id", + type: { + name: "String" + } + }, + requestId: { + serializedName: "x-ms-request-id", + type: { + name: "String" + } + }, + version: { + serializedName: "x-ms-version", + type: { + name: "String" + } + }, + date: { + serializedName: "date", + type: { + name: "DateTimeRfc1123" + } + }, + errorCode: { + serializedName: "x-ms-error-code", + type: { + name: "String" + } + } + } + } +}; + +export const ShareBreakLeaseHeaders: coreHttp.CompositeMapper = { + serializedName: "share-breaklease-headers", + type: { + name: "Composite", + className: "ShareBreakLeaseHeaders", + modelProperties: { + etag: { + serializedName: "etag", + type: { + name: "String" + } + }, + lastModified: { + serializedName: "last-modified", + type: { + name: "DateTimeRfc1123" + } + }, + leaseTimeInSeconds: { + serializedName: "x-ms-lease-time", + type: { + name: "Number" + } + }, + leaseId: { + serializedName: "x-ms-lease-id", + type: { + name: "String" + } + }, + clientRequestId: { + serializedName: "x-ms-client-request-id", + type: { + name: "String" + } + }, + requestId: { + serializedName: "x-ms-request-id", + type: { + name: "String" + } + }, + version: { + serializedName: "x-ms-version", + type: { + name: "String" + } + }, + date: { + serializedName: "date", + type: { + name: "DateTimeRfc1123" + } + }, + errorCode: { + serializedName: "x-ms-error-code", + type: { + name: "String" + } + } + } + } +}; + export const ShareCreateSnapshotHeaders: coreHttp.CompositeMapper = { serializedName: "share-createsnapshot-headers", type: { @@ -1321,11 +1846,11 @@ export const ShareGetPermissionHeaders: coreHttp.CompositeMapper = { } }; -export const ShareSetQuotaHeaders: coreHttp.CompositeMapper = { - serializedName: "share-setquota-headers", +export const ShareSetPropertiesHeaders: coreHttp.CompositeMapper = { + serializedName: "share-setproperties-headers", type: { name: "Composite", - className: "ShareSetQuotaHeaders", + className: "ShareSetPropertiesHeaders", modelProperties: { etag: { serializedName: "etag", diff --git a/sdk/storage/storage-file-share/src/generated/src/models/parameters.ts b/sdk/storage/storage-file-share/src/generated/src/models/parameters.ts index 5a93cbfde140..4c989c972f46 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/parameters.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/parameters.ts @@ -10,6 +10,18 @@ import * as coreHttp from "@azure/core-http"; +export const accessTier: coreHttp.OperationParameter = { + parameterPath: [ + "options", + "accessTier" + ], + mapper: { + serializedName: "x-ms-access-tier", + type: { + name: "String" + } + } +}; export const action0: coreHttp.OperationParameter = { parameterPath: "action", mapper: { @@ -47,6 +59,18 @@ export const action2: coreHttp.OperationParameter = { } }; export const action3: coreHttp.OperationParameter = { + parameterPath: "action", + mapper: { + required: true, + isConstant: true, + serializedName: "x-ms-lease-action", + defaultValue: 'renew', + type: { + name: "String" + } + } +}; +export const action4: coreHttp.OperationParameter = { parameterPath: "action", mapper: { required: true, @@ -58,6 +82,18 @@ export const action3: coreHttp.OperationParameter = { } } }; +export const breakPeriod: coreHttp.OperationParameter = { + parameterPath: [ + "options", + "breakPeriod" + ], + mapper: { + serializedName: "x-ms-lease-break-period", + type: { + name: "Number" + } + } +}; export const comp0: coreHttp.OperationQueryParameter = { parameterPath: "comp", mapper: { @@ -88,7 +124,7 @@ export const comp10: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'lease', + defaultValue: 'forceclosehandles', type: { name: "String" } @@ -136,7 +172,7 @@ export const comp2: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'snapshot', + defaultValue: 'lease', type: { name: "String" } @@ -148,7 +184,7 @@ export const comp3: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'filepermission', + defaultValue: 'snapshot', type: { name: "String" } @@ -160,7 +196,7 @@ export const comp4: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'metadata', + defaultValue: 'filepermission', type: { name: "String" } @@ -172,7 +208,7 @@ export const comp5: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'acl', + defaultValue: 'metadata', type: { name: "String" } @@ -184,7 +220,7 @@ export const comp6: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'stats', + defaultValue: 'acl', type: { name: "String" } @@ -196,7 +232,7 @@ export const comp7: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'undelete', + defaultValue: 'stats', type: { name: "String" } @@ -208,7 +244,7 @@ export const comp8: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'listhandles', + defaultValue: 'undelete', type: { name: "String" } @@ -220,7 +256,7 @@ export const comp9: coreHttp.OperationQueryParameter = { required: true, isConstant: true, serializedName: "comp", - defaultValue: 'forceclosehandles', + defaultValue: 'listhandles', type: { name: "String" } @@ -314,7 +350,8 @@ export const deleteSnapshots: coreHttp.OperationParameter = { type: { name: "Enum", allowedValues: [ - "include" + "include", + "include-leased" ] } } @@ -716,6 +753,18 @@ export const prefix: coreHttp.OperationQueryParameter = { } } }; +export const prevsharesnapshot: coreHttp.OperationQueryParameter = { + parameterPath: [ + "options", + "prevsharesnapshot" + ], + mapper: { + serializedName: "prevsharesnapshot", + type: { + name: "String" + } + } +}; export const proposedLeaseId: coreHttp.OperationParameter = { parameterPath: [ "options", diff --git a/sdk/storage/storage-file-share/src/generated/src/models/serviceMappers.ts b/sdk/storage/storage-file-share/src/generated/src/models/serviceMappers.ts index ac1f53f0ddeb..655468b6880d 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/serviceMappers.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/serviceMappers.ts @@ -17,5 +17,8 @@ export { ServiceSetPropertiesHeaders, ShareItem, ShareProperties, + ShareProtocolSettings, + ShareSmbSettings, + SmbMultichannel, StorageError } from "../models/mappers"; diff --git a/sdk/storage/storage-file-share/src/generated/src/models/shareMappers.ts b/sdk/storage/storage-file-share/src/generated/src/models/shareMappers.ts index 452568ab51aa..e21c713360e1 100644 --- a/sdk/storage/storage-file-share/src/generated/src/models/shareMappers.ts +++ b/sdk/storage/storage-file-share/src/generated/src/models/shareMappers.ts @@ -8,6 +8,9 @@ export { AccessPolicy, + ShareAcquireLeaseHeaders, + ShareBreakLeaseHeaders, + ShareChangeLeaseHeaders, ShareCreateHeaders, ShareCreatePermissionHeaders, ShareCreateSnapshotHeaders, @@ -17,10 +20,12 @@ export { ShareGetPropertiesHeaders, ShareGetStatisticsHeaders, SharePermission, + ShareReleaseLeaseHeaders, + ShareRenewLeaseHeaders, ShareRestoreHeaders, ShareSetAccessPolicyHeaders, ShareSetMetadataHeaders, - ShareSetQuotaHeaders, + ShareSetPropertiesHeaders, ShareStats, SignedIdentifier, StorageError diff --git a/sdk/storage/storage-file-share/src/generated/src/operations/directory.ts b/sdk/storage/storage-file-share/src/generated/src/operations/directory.ts index 1746b39274c7..0c60814582fb 100644 --- a/sdk/storage/storage-file-share/src/generated/src/operations/directory.ts +++ b/sdk/storage/storage-file-share/src/generated/src/operations/directory.ts @@ -388,7 +388,7 @@ const setMetadataOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype2, - Parameters.comp4 + Parameters.comp5 ], headerParameters: [ Parameters.metadata, @@ -450,7 +450,7 @@ const listHandlesOperationSpec: coreHttp.OperationSpec = { Parameters.maxResults, Parameters.timeoutInSeconds, Parameters.shareSnapshot, - Parameters.comp8 + Parameters.comp9 ], headerParameters: [ Parameters.recursive, @@ -480,7 +480,7 @@ const forceCloseHandlesOperationSpec: coreHttp.OperationSpec = { Parameters.timeoutInSeconds, Parameters.marker, Parameters.shareSnapshot, - Parameters.comp9 + Parameters.comp10 ], headerParameters: [ Parameters.handleId, diff --git a/sdk/storage/storage-file-share/src/generated/src/operations/file.ts b/sdk/storage/storage-file-share/src/generated/src/operations/file.ts index 92c1d2f88001..eaf552a359ec 100644 --- a/sdk/storage/storage-file-share/src/generated/src/operations/file.ts +++ b/sdk/storage/storage-file-share/src/generated/src/operations/file.ts @@ -28,7 +28,7 @@ export class File { /** * Creates a new file or replaces a file. Note it only initializes the file with no content. - * @param fileContentLength Specifies the maximum size for the file, up to 1 TB. + * @param fileContentLength Specifies the maximum size for the file, up to 4 TB. * @param fileAttributes If specified, the provided file attributes shall be set. Default value: * ‘Archive’ for file and ‘Directory’ for directory. ‘None’ can also be specified as default. * @param fileCreatedOn Creation time for the file/directory. Default value: Now. @@ -38,7 +38,7 @@ export class File { */ create(fileContentLength: number, fileAttributes: string, fileCreatedOn: string, fileLastWriteOn: string, options?: Models.FileCreateOptionalParams): Promise; /** - * @param fileContentLength Specifies the maximum size for the file, up to 1 TB. + * @param fileContentLength Specifies the maximum size for the file, up to 4 TB. * @param fileAttributes If specified, the provided file attributes shall be set. Default value: * ‘Archive’ for file and ‘Directory’ for directory. ‘None’ can also be specified as default. * @param fileCreatedOn Creation time for the file/directory. Default value: Now. @@ -47,7 +47,7 @@ export class File { */ create(fileContentLength: number, fileAttributes: string, fileCreatedOn: string, fileLastWriteOn: string, callback: coreHttp.ServiceCallback): void; /** - * @param fileContentLength Specifies the maximum size for the file, up to 1 TB. + * @param fileContentLength Specifies the maximum size for the file, up to 4 TB. * @param fileAttributes If specified, the provided file attributes shall be set. Default value: * ‘Archive’ for file and ‘Directory’ for directory. ‘None’ can also be specified as default. * @param fileCreatedOn Creation time for the file/directory. Default value: Now. @@ -445,13 +445,13 @@ export class File { /** * @param callback The callback */ - getRangeList(callback: coreHttp.ServiceCallback): void; + getRangeList(callback: coreHttp.ServiceCallback): void; /** * @param options The optional parameters * @param callback The callback */ - getRangeList(options: Models.FileGetRangeListOptionalParams, callback: coreHttp.ServiceCallback): void; - getRangeList(options?: Models.FileGetRangeListOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + getRangeList(options: Models.FileGetRangeListOptionalParams, callback: coreHttp.ServiceCallback): void; + getRangeList(options?: Models.FileGetRangeListOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.client.sendOperationRequest( { options @@ -779,7 +779,7 @@ const setMetadataOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.timeoutInSeconds, - Parameters.comp4 + Parameters.comp5 ], headerParameters: [ Parameters.metadata, @@ -807,7 +807,7 @@ const acquireLeaseOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.timeoutInSeconds, - Parameters.comp10 + Parameters.comp2 ], headerParameters: [ Parameters.duration, @@ -837,7 +837,7 @@ const releaseLeaseOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.timeoutInSeconds, - Parameters.comp10 + Parameters.comp2 ], headerParameters: [ Parameters.leaseId1, @@ -866,7 +866,7 @@ const changeLeaseOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.timeoutInSeconds, - Parameters.comp10 + Parameters.comp2 ], headerParameters: [ Parameters.leaseId1, @@ -896,12 +896,12 @@ const breakLeaseOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.timeoutInSeconds, - Parameters.comp10 + Parameters.comp2 ], headerParameters: [ Parameters.version, Parameters.requestId, - Parameters.action3, + Parameters.action4, Parameters.leaseId0 ], responses: { @@ -1004,6 +1004,7 @@ const getRangeListOperationSpec: coreHttp.OperationSpec = { ], queryParameters: [ Parameters.shareSnapshot, + Parameters.prevsharesnapshot, Parameters.timeoutInSeconds, Parameters.comp12 ], @@ -1014,19 +1015,7 @@ const getRangeListOperationSpec: coreHttp.OperationSpec = { ], responses: { 200: { - bodyMapper: { - xmlElementName: "Range", - serializedName: "parsedResponse", - type: { - name: "Sequence", - element: { - type: { - name: "Composite", - className: "Range" - } - } - } - }, + bodyMapper: Mappers.ShareFileRangeList, headersMapper: Mappers.FileGetRangeListHeaders }, default: { @@ -1114,7 +1103,7 @@ const listHandlesOperationSpec: coreHttp.OperationSpec = { Parameters.maxResults, Parameters.timeoutInSeconds, Parameters.shareSnapshot, - Parameters.comp8 + Parameters.comp9 ], headerParameters: [ Parameters.version @@ -1143,7 +1132,7 @@ const forceCloseHandlesOperationSpec: coreHttp.OperationSpec = { Parameters.timeoutInSeconds, Parameters.marker, Parameters.shareSnapshot, - Parameters.comp9 + Parameters.comp10 ], headerParameters: [ Parameters.handleId, diff --git a/sdk/storage/storage-file-share/src/generated/src/operations/share.ts b/sdk/storage/storage-file-share/src/generated/src/operations/share.ts index 5cc5179f048f..4459f676cd01 100644 --- a/sdk/storage/storage-file-share/src/generated/src/operations/share.ts +++ b/sdk/storage/storage-file-share/src/generated/src/operations/share.ts @@ -101,6 +101,143 @@ export class Share { callback) as Promise; } + /** + * The Lease Share operation establishes and manages a lock on a share, or the specified snapshot + * for set and delete share operations. + * @param [options] The optional parameters + * @returns Promise + */ + acquireLease(options?: Models.ShareAcquireLeaseOptionalParams): Promise; + /** + * @param callback The callback + */ + acquireLease(callback: coreHttp.ServiceCallback): void; + /** + * @param options The optional parameters + * @param callback The callback + */ + acquireLease(options: Models.ShareAcquireLeaseOptionalParams, callback: coreHttp.ServiceCallback): void; + acquireLease(options?: Models.ShareAcquireLeaseOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + options + }, + acquireLeaseOperationSpec, + callback) as Promise; + } + + /** + * The Lease Share operation establishes and manages a lock on a share, or the specified snapshot + * for set and delete share operations. + * @param leaseId Specifies the current lease ID on the resource. + * @param [options] The optional parameters + * @returns Promise + */ + releaseLease(leaseId: string, options?: Models.ShareReleaseLeaseOptionalParams): Promise; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param callback The callback + */ + releaseLease(leaseId: string, callback: coreHttp.ServiceCallback): void; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param options The optional parameters + * @param callback The callback + */ + releaseLease(leaseId: string, options: Models.ShareReleaseLeaseOptionalParams, callback: coreHttp.ServiceCallback): void; + releaseLease(leaseId: string, options?: Models.ShareReleaseLeaseOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + leaseId, + options + }, + releaseLeaseOperationSpec, + callback) as Promise; + } + + /** + * The Lease Share operation establishes and manages a lock on a share, or the specified snapshot + * for set and delete share operations. + * @param leaseId Specifies the current lease ID on the resource. + * @param [options] The optional parameters + * @returns Promise + */ + changeLease(leaseId: string, options?: Models.ShareChangeLeaseOptionalParams): Promise; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param callback The callback + */ + changeLease(leaseId: string, callback: coreHttp.ServiceCallback): void; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param options The optional parameters + * @param callback The callback + */ + changeLease(leaseId: string, options: Models.ShareChangeLeaseOptionalParams, callback: coreHttp.ServiceCallback): void; + changeLease(leaseId: string, options?: Models.ShareChangeLeaseOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + leaseId, + options + }, + changeLeaseOperationSpec, + callback) as Promise; + } + + /** + * The Lease Share operation establishes and manages a lock on a share, or the specified snapshot + * for set and delete share operations. + * @param leaseId Specifies the current lease ID on the resource. + * @param [options] The optional parameters + * @returns Promise + */ + renewLease(leaseId: string, options?: Models.ShareRenewLeaseOptionalParams): Promise; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param callback The callback + */ + renewLease(leaseId: string, callback: coreHttp.ServiceCallback): void; + /** + * @param leaseId Specifies the current lease ID on the resource. + * @param options The optional parameters + * @param callback The callback + */ + renewLease(leaseId: string, options: Models.ShareRenewLeaseOptionalParams, callback: coreHttp.ServiceCallback): void; + renewLease(leaseId: string, options?: Models.ShareRenewLeaseOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + leaseId, + options + }, + renewLeaseOperationSpec, + callback) as Promise; + } + + /** + * The Lease Share operation establishes and manages a lock on a share, or the specified snapshot + * for set and delete share operations. + * @param [options] The optional parameters + * @returns Promise + */ + breakLease(options?: Models.ShareBreakLeaseOptionalParams): Promise; + /** + * @param callback The callback + */ + breakLease(callback: coreHttp.ServiceCallback): void; + /** + * @param options The optional parameters + * @param callback The callback + */ + breakLease(options: Models.ShareBreakLeaseOptionalParams, callback: coreHttp.ServiceCallback): void; + breakLease(options?: Models.ShareBreakLeaseOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + options + }, + breakLeaseOperationSpec, + callback) as Promise; + } + /** * Creates a read-only snapshot of a share. * @param [options] The optional parameters @@ -182,27 +319,27 @@ export class Share { } /** - * Sets quota for the specified share. + * Sets properties for the specified share. * @param [options] The optional parameters - * @returns Promise + * @returns Promise */ - setQuota(options?: Models.ShareSetQuotaOptionalParams): Promise; + setProperties(options?: Models.ShareSetPropertiesOptionalParams): Promise; /** * @param callback The callback */ - setQuota(callback: coreHttp.ServiceCallback): void; + setProperties(callback: coreHttp.ServiceCallback): void; /** * @param options The optional parameters * @param callback The callback */ - setQuota(options: Models.ShareSetQuotaOptionalParams, callback: coreHttp.ServiceCallback): void; - setQuota(options?: Models.ShareSetQuotaOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + setProperties(options: Models.ShareSetPropertiesOptionalParams, callback: coreHttp.ServiceCallback): void; + setProperties(options?: Models.ShareSetPropertiesOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.client.sendOperationRequest( { options }, - setQuotaOperationSpec, - callback) as Promise; + setPropertiesOperationSpec, + callback) as Promise; } /** @@ -341,6 +478,7 @@ const createOperationSpec: coreHttp.OperationSpec = { headerParameters: [ Parameters.metadata, Parameters.quota, + Parameters.accessTier, Parameters.version ], responses: { @@ -368,7 +506,8 @@ const getPropertiesOperationSpec: coreHttp.OperationSpec = { Parameters.restype1 ], headerParameters: [ - Parameters.version + Parameters.version, + Parameters.leaseId0 ], responses: { 200: { @@ -396,7 +535,8 @@ const deleteMethodOperationSpec: coreHttp.OperationSpec = { ], headerParameters: [ Parameters.version, - Parameters.deleteSnapshots + Parameters.deleteSnapshots, + Parameters.leaseId0 ], responses: { 202: { @@ -411,6 +551,164 @@ const deleteMethodOperationSpec: coreHttp.OperationSpec = { serializer }; +const acquireLeaseOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PUT", + path: "{shareName}", + urlParameters: [ + Parameters.url + ], + queryParameters: [ + Parameters.timeoutInSeconds, + Parameters.shareSnapshot, + Parameters.comp2, + Parameters.restype1 + ], + headerParameters: [ + Parameters.duration, + Parameters.proposedLeaseId, + Parameters.version, + Parameters.requestId, + Parameters.action0 + ], + responses: { + 201: { + headersMapper: Mappers.ShareAcquireLeaseHeaders + }, + default: { + bodyMapper: Mappers.StorageError, + headersMapper: Mappers.ShareAcquireLeaseHeaders + } + }, + isXML: true, + serializer +}; + +const releaseLeaseOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PUT", + path: "{shareName}", + urlParameters: [ + Parameters.url + ], + queryParameters: [ + Parameters.timeoutInSeconds, + Parameters.shareSnapshot, + Parameters.comp2, + Parameters.restype1 + ], + headerParameters: [ + Parameters.leaseId1, + Parameters.version, + Parameters.requestId, + Parameters.action1 + ], + responses: { + 200: { + headersMapper: Mappers.ShareReleaseLeaseHeaders + }, + default: { + bodyMapper: Mappers.StorageError, + headersMapper: Mappers.ShareReleaseLeaseHeaders + } + }, + isXML: true, + serializer +}; + +const changeLeaseOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PUT", + path: "{shareName}", + urlParameters: [ + Parameters.url + ], + queryParameters: [ + Parameters.timeoutInSeconds, + Parameters.shareSnapshot, + Parameters.comp2, + Parameters.restype1 + ], + headerParameters: [ + Parameters.leaseId1, + Parameters.proposedLeaseId, + Parameters.version, + Parameters.requestId, + Parameters.action2 + ], + responses: { + 200: { + headersMapper: Mappers.ShareChangeLeaseHeaders + }, + default: { + bodyMapper: Mappers.StorageError, + headersMapper: Mappers.ShareChangeLeaseHeaders + } + }, + isXML: true, + serializer +}; + +const renewLeaseOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PUT", + path: "{shareName}", + urlParameters: [ + Parameters.url + ], + queryParameters: [ + Parameters.timeoutInSeconds, + Parameters.shareSnapshot, + Parameters.comp2, + Parameters.restype1 + ], + headerParameters: [ + Parameters.leaseId1, + Parameters.version, + Parameters.requestId, + Parameters.action3 + ], + responses: { + 200: { + headersMapper: Mappers.ShareRenewLeaseHeaders + }, + default: { + bodyMapper: Mappers.StorageError, + headersMapper: Mappers.ShareRenewLeaseHeaders + } + }, + isXML: true, + serializer +}; + +const breakLeaseOperationSpec: coreHttp.OperationSpec = { + httpMethod: "PUT", + path: "{shareName}", + urlParameters: [ + Parameters.url + ], + queryParameters: [ + Parameters.timeoutInSeconds, + Parameters.shareSnapshot, + Parameters.comp2, + Parameters.restype1 + ], + headerParameters: [ + Parameters.breakPeriod, + Parameters.version, + Parameters.requestId, + Parameters.action4, + Parameters.leaseId0 + ], + responses: { + 202: { + headersMapper: Mappers.ShareBreakLeaseHeaders + }, + default: { + bodyMapper: Mappers.StorageError, + headersMapper: Mappers.ShareBreakLeaseHeaders + } + }, + isXML: true, + serializer +}; + const createSnapshotOperationSpec: coreHttp.OperationSpec = { httpMethod: "PUT", path: "{shareName}", @@ -420,7 +718,7 @@ const createSnapshotOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp2 + Parameters.comp3 ], headerParameters: [ Parameters.metadata, @@ -448,7 +746,7 @@ const createPermissionOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp3 + Parameters.comp4 ], headerParameters: [ Parameters.version @@ -483,7 +781,7 @@ const getPermissionOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp3 + Parameters.comp4 ], headerParameters: [ Parameters.filePermissionKey0, @@ -503,7 +801,7 @@ const getPermissionOperationSpec: coreHttp.OperationSpec = { serializer }; -const setQuotaOperationSpec: coreHttp.OperationSpec = { +const setPropertiesOperationSpec: coreHttp.OperationSpec = { httpMethod: "PUT", path: "{shareName}", urlParameters: [ @@ -516,15 +814,17 @@ const setQuotaOperationSpec: coreHttp.OperationSpec = { ], headerParameters: [ Parameters.version, - Parameters.quota + Parameters.quota, + Parameters.accessTier, + Parameters.leaseId0 ], responses: { 200: { - headersMapper: Mappers.ShareSetQuotaHeaders + headersMapper: Mappers.ShareSetPropertiesHeaders }, default: { bodyMapper: Mappers.StorageError, - headersMapper: Mappers.ShareSetQuotaHeaders + headersMapper: Mappers.ShareSetPropertiesHeaders } }, isXML: true, @@ -540,11 +840,12 @@ const setMetadataOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp4 + Parameters.comp5 ], headerParameters: [ Parameters.metadata, - Parameters.version + Parameters.version, + Parameters.leaseId0 ], responses: { 200: { @@ -568,10 +869,11 @@ const getAccessPolicyOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp5 + Parameters.comp6 ], headerParameters: [ - Parameters.version + Parameters.version, + Parameters.leaseId0 ], responses: { 200: { @@ -608,10 +910,11 @@ const setAccessPolicyOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp5 + Parameters.comp6 ], headerParameters: [ - Parameters.version + Parameters.version, + Parameters.leaseId0 ], requestBody: { parameterPath: [ @@ -656,10 +959,11 @@ const getStatisticsOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp6 + Parameters.comp7 ], headerParameters: [ - Parameters.version + Parameters.version, + Parameters.leaseId0 ], responses: { 200: { @@ -684,7 +988,7 @@ const restoreOperationSpec: coreHttp.OperationSpec = { queryParameters: [ Parameters.timeoutInSeconds, Parameters.restype1, - Parameters.comp7 + Parameters.comp8 ], headerParameters: [ Parameters.version, diff --git a/sdk/storage/storage-file-share/src/generated/src/storageClientContext.ts b/sdk/storage/storage-file-share/src/generated/src/storageClientContext.ts index 2bbf3ec564f3..adab378c137e 100644 --- a/sdk/storage/storage-file-share/src/generated/src/storageClientContext.ts +++ b/sdk/storage/storage-file-share/src/generated/src/storageClientContext.ts @@ -11,7 +11,7 @@ import * as coreHttp from "@azure/core-http"; const packageName = "azure-storage-file-share"; -const packageVersion = "12.2.1"; +const packageVersion = "12.3.0-beta.1"; export class StorageClientContext extends coreHttp.ServiceClient { version: string; diff --git a/sdk/storage/storage-file-share/src/generatedModels.ts b/sdk/storage/storage-file-share/src/generatedModels.ts index efcf6bf8e15b..9a08c0661536 100644 --- a/sdk/storage/storage-file-share/src/generatedModels.ts +++ b/sdk/storage/storage-file-share/src/generatedModels.ts @@ -33,7 +33,7 @@ export { FileUploadRangeResponse, HandleItem, ListSharesIncludeType, - Range as RangeModel, + FileRange as RangeModel, ServiceGetPropertiesResponse, ServiceListSharesSegmentResponse, ServiceSetPropertiesResponse, @@ -48,7 +48,7 @@ export { ShareItem, ShareSetAccessPolicyResponse, ShareSetMetadataResponse, - ShareSetQuotaResponse, + ShareSetPropertiesResponse, SignedIdentifier as SignedIdentifierModel, SourceModifiedAccessConditions, FileForceCloseHandlesHeaders, @@ -94,11 +94,30 @@ export { ShareProperties, ShareSetAccessPolicyHeaders, ShareSetMetadataHeaders, - ShareSetQuotaHeaders, + ShareSetPropertiesHeaders, AccessPolicy, LeaseAccessConditions, LeaseDurationType, LeaseStateType, LeaseStatusType, - CopyFileSmbInfo + CopyFileSmbInfo, + ShareProtocolSettings, + ShareSmbSettings, + SmbMultichannel, + FileGetRangeListResponse as FileGetRangeListDiffResponse, + ShareFileRangeList, + ClearRange, + ShareAccessTier } from "./generated/src/models"; + +import { ShareSetPropertiesResponse, ShareSetPropertiesHeaders } from "./generated/src/models"; + +/** + * Contains response data for the setQuota operation. + */ +export type ShareSetQuotaResponse = ShareSetPropertiesResponse; + +/** + * Defines headers for setQuota operation. + */ +export type ShareSetQuotaHeaders = ShareSetPropertiesHeaders; diff --git a/sdk/storage/storage-file-share/src/index.browser.ts b/sdk/storage/storage-file-share/src/index.browser.ts index 1bd59d37bc5c..98ae86f914af 100644 --- a/sdk/storage/storage-file-share/src/index.browser.ts +++ b/sdk/storage/storage-file-share/src/index.browser.ts @@ -3,9 +3,7 @@ import { RestError } from "@azure/core-http"; -export * from "./ShareClient"; -export * from "./ShareDirectoryClient"; -export * from "./ShareFileClient"; +export * from "./Clients"; export * from "./credentials/AnonymousCredential"; export * from "./credentials/Credential"; export { SasIPRange } from "./SasIPRange"; diff --git a/sdk/storage/storage-file-share/src/index.ts b/sdk/storage/storage-file-share/src/index.ts index c6cfeb777863..36bd9362ba11 100644 --- a/sdk/storage/storage-file-share/src/index.ts +++ b/sdk/storage/storage-file-share/src/index.ts @@ -9,10 +9,8 @@ export * from "./AccountSASServices"; export * from "./AccountSASSignatureValues"; export * from "./FileSASPermissions"; export * from "./FileSASSignatureValues"; -export * from "./ShareDirectoryClient"; -export * from "./ShareFileClient"; +export * from "./Clients"; export * from "./ShareSASPermissions"; -export * from "./ShareClient"; export * from "./credentials/AnonymousCredential"; export * from "./credentials/Credential"; export * from "./credentials/StorageSharedKeyCredential"; diff --git a/sdk/storage/storage-file-share/src/utils/constants.ts b/sdk/storage/storage-file-share/src/utils/constants.ts index 469039012392..0c26d3215ecb 100644 --- a/sdk/storage/storage-file-share/src/utils/constants.ts +++ b/sdk/storage/storage-file-share/src/utils/constants.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export const SDK_VERSION: string = "12.2.1"; -export const SERVICE_VERSION: string = "2019-12-12"; +export const SDK_VERSION: string = "12.3.0-beta.1"; +export const SERVICE_VERSION: string = "2020-02-10"; export const FILE_MAX_SIZE_BYTES: number = 4 * 1024 * 1024 * 1024 * 1024; // 4TB export const FILE_RANGE_MAX_SIZE_BYTES: number = 4 * 1024 * 1024; // 4MB diff --git a/sdk/storage/storage-file-share/swagger/README.md b/sdk/storage/storage-file-share/swagger/README.md index 92acff2933e5..c64f40ad2f33 100644 --- a/sdk/storage/storage-file-share/swagger/README.md +++ b/sdk/storage/storage-file-share/swagger/README.md @@ -12,7 +12,7 @@ enable-xml: true generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../src/generated -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.FileStorage/preview/2019-12-12/file.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-dataplane-preview/specification/storage/data-plane/Microsoft.FileStorage/preview/2020-02-10/file.json model-date-time-as-string: true optional-response-headers: true ``` @@ -282,4 +282,14 @@ directive: $["x-ms-client-name"] = "body"; ``` +### Rename leaseTime -> leaseTimeInSeconds + +```yaml +directive: + - from: swagger-document + where: $["x-ms-paths"]["/{shareName}?restype=share&comp=lease&break"]..responses..headers["x-ms-lease-time"] + transform: > + $["x-ms-client-name"] = "LeaseTimeInSeconds"; +``` + ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fstorage%2Fstorage-file-share%2Fswagger%2FREADME.png) diff --git a/sdk/storage/storage-file-share/test/fileclient.spec.ts b/sdk/storage/storage-file-share/test/fileclient.spec.ts index f490c036a128..e57ebbcf8ef4 100644 --- a/sdk/storage/storage-file-share/test/fileclient.spec.ts +++ b/sdk/storage/storage-file-share/test/fileclient.spec.ts @@ -4,7 +4,7 @@ import * as dotenv from "dotenv"; import { AbortController } from "@azure/abort-controller"; import { isNode, URLBuilder, URLQuery } from "@azure/core-http"; import { setTracer, SpanGraph, TestTracer } from "@azure/core-tracing"; -import { delay, record, Recorder, isPlaybackMode } from "@azure/test-utils-recorder"; +import { delay, isLiveMode, record, Recorder } from "@azure/test-utils-recorder"; import { FileStartCopyOptions, ShareClient, ShareDirectoryClient, ShareFileClient } from "../src"; import { FileSystemAttributes } from "../src/FileSystemAttributes"; @@ -60,7 +60,7 @@ describe("FileClient", () => { afterEach(async function() { if (!this.currentTest?.isPending()) { - await shareClient.delete(); + await shareClient.delete({ deleteSnapshots: "include" }); await recorder.stop(); } }); @@ -149,24 +149,24 @@ describe("FileClient", () => { assert.ok(properties.fileParentId!); }); - // need to skip this test in live as it requires Premium_LRS SKU for 2019-12-12. it("create largest file", async function() { // IE complains about "Arithmetic result exceeded 32 bits". - if (!isPlaybackMode() || (!isNode && isIE())) { + if (!isNode && isIE()) { this.skip(); } - const GB = 1024 * 1024 * 1024; - await shareClient.setQuota(FILE_MAX_SIZE_BYTES / GB); - const cResp = await fileClient.create(FILE_MAX_SIZE_BYTES); + const fileSize = FILE_MAX_SIZE_BYTES; + const cResp = await fileClient.create(fileSize); assert.equal(cResp.errorCode, undefined); - await fileClient.resize(FILE_MAX_SIZE_BYTES); + await fileClient.resize(fileSize); const updatedProperties = await fileClient.getProperties(); - assert.deepStrictEqual(updatedProperties.contentLength, FILE_MAX_SIZE_BYTES); + assert.deepStrictEqual(updatedProperties.contentLength, fileSize); + + await fileClient.uploadRange(content, fileSize - content.length, content.length); }); - it("setProperties with default parameters", async () => { + it("setProperties with default parameters", async function() { await fileClient.create(content.length); await fileClient.setProperties(); @@ -181,7 +181,12 @@ describe("FileClient", () => { assert.ok(result.fileParentId!); assert.ok(result.lastModified); assert.deepStrictEqual(result.metadata, {}); - assert.ok(!result.cacheControl); + // IE11 sends "cache-control: no-cache"/"cache-control:max-age=0" for every requests + if (!isNode && isIE()) { + assert.ok(result.cacheControl); + } else { + assert.ok(!result.cacheControl); + } assert.ok(!result.contentType); assert.ok(!result.contentMD5); assert.ok(!result.contentEncoding); @@ -538,6 +543,86 @@ describe("FileClient", () => { assert.deepStrictEqual(result.rangeList[0], { start: 0, end: 9 }); }); + it("getRangeList with share snapshot", async () => { + await fileClient.create(513); // 512-byte aligned + await fileClient.uploadRange("Hello", 0, 5); + await fileClient.uploadRange("World", 5, 5); + await fileClient.clearRange(0, 513); + + const snapshotRes = await shareClient.createSnapshot(); + assert.ok(snapshotRes.snapshot); + + await fileClient.uploadRange("Hello", 0, 5); + + const fileClientWithShareSnapShot = fileClient.withShareSnapshot(snapshotRes.snapshot!); + const result = await fileClientWithShareSnapShot.getRangeList(); + + assert.deepStrictEqual(result.rangeList.length, 1); + assert.deepStrictEqual(result.rangeList[0], { start: 512, end: 512 }); + }); + + it("getRangeListDiff", async function() { + if (isLiveMode()) { + // Skipped for now as the result is not stable. + this.skip(); + } + await fileClient.create(512 * 4 + 1); + await fileClient.uploadRange("Hello", 0, 5); + + const snapshotRes = await shareClient.createSnapshot(); + assert.ok(snapshotRes.snapshot); + + await fileClient.clearRange(0, 1024); + await fileClient.uploadRange("World", 1023, 5); + + const result = await fileClient.getRangeListDiff(snapshotRes.snapshot!); + console.log(result.clearRanges); + console.log(result.ranges); + console.log(result.requestId); + + assert.ok(result.clearRanges); + assert.deepStrictEqual(result.clearRanges!.length, 1); + assert.deepStrictEqual(result.clearRanges![0], { start: 0, end: 511 }); + + assert.ok(result.ranges); + assert.deepStrictEqual(result.ranges!.length, 1); + assert.deepStrictEqual(result.ranges![0], { start: 512, end: 1535 }); + }); + + it("getRangeListDiff with share snapshot", async function() { + if (isLiveMode()) { + // Skipped for now as the result is not stable. + this.skip(); + } + await fileClient.create(512 * 4 + 1); + await fileClient.uploadRange("Hello", 0, 5); + + const snapshotRes = await shareClient.createSnapshot(); + assert.ok(snapshotRes.snapshot); + + await fileClient.clearRange(0, 1024); + await fileClient.uploadRange("World", 1023, 5); + + const snapshotRes2 = await shareClient.createSnapshot(); + assert.ok(snapshotRes2.snapshot); + + await fileClient.uploadRange("Hello", 0, 5); + + const fileClientWithShareSnapShot = fileClient.withShareSnapshot(snapshotRes2.snapshot!); + const result = await fileClientWithShareSnapShot.getRangeListDiff(snapshotRes.snapshot!); + console.log(result.clearRanges); + console.log(result.ranges); + console.log(result.requestId); + + assert.ok(result.clearRanges); + assert.deepStrictEqual(result.clearRanges!.length, 1); + assert.deepStrictEqual(result.clearRanges![0], { start: 0, end: 511 }); + + assert.ok(result.ranges); + assert.deepStrictEqual(result.ranges!.length, 1); + assert.deepStrictEqual(result.ranges![0], { start: 512, end: 1535 }); + }); + it("download with with default parameters", async () => { await fileClient.create(content.length); await fileClient.uploadRange(content, 0, content.length); diff --git a/sdk/storage/storage-file-share/test/fileserviceclient.spec.ts b/sdk/storage/storage-file-share/test/fileserviceclient.spec.ts index 685ad6ac56d6..439d4636a33b 100644 --- a/sdk/storage/storage-file-share/test/fileserviceclient.spec.ts +++ b/sdk/storage/storage-file-share/test/fileserviceclient.spec.ts @@ -4,9 +4,10 @@ import { getBSU, getSASConnectionStringFromEnvironment, recorderEnvSetup, - getSoftDeleteBSU + getSoftDeleteBSU, + getGenericBSU } from "./utils"; -import { record, delay, Recorder } from "@azure/test-utils-recorder"; +import { record, delay, Recorder, isLiveMode } from "@azure/test-utils-recorder"; import * as dotenv from "dotenv"; import { ShareServiceClient, ShareItem } from "../src"; dotenv.config(); @@ -328,7 +329,14 @@ describe("FileServiceClient", () => { serviceProperties.cors.push(newCORS); } - await serviceClient.setProperties(serviceProperties); + // SMB multi-channel is returned by getProperties() even when the feature is not supproted on the account. + const newServiceProperties = { + cors: serviceProperties.cors, + minuteMetrics: serviceProperties.minuteMetrics, + hourMetrics: serviceProperties.hourMetrics + }; + + await serviceClient.setProperties(newServiceProperties); await delay(5 * 1000); const result = await serviceClient.getProperties(); @@ -466,3 +474,33 @@ describe("FileServiceClient", () => { } }); }); + +describe("FileServiceClient Premium", () => { + let recorder: Recorder; + let serviceClient: ShareServiceClient; + + beforeEach(function() { + recorder = record(this, recorderEnvSetup); + try { + serviceClient = getGenericBSU("PREMIUM_FILE_"); + } catch (error) { + this.skip(); + } + }); + + afterEach(async function() { + await recorder.stop(); + }); + + it("SMB Multichannel", async function() { + if (isLiveMode()) { + // Skipped for now as it needs be enabled on the account. + this.skip(); + } + await serviceClient.setProperties({ + protocol: { smb: { multichannel: { enabled: true } } } + }); + const propertiesSet = await serviceClient.getProperties(); + assert.ok(propertiesSet.protocol?.smb?.multichannel); + }); +}); diff --git a/sdk/storage/storage-file-share/test/leaseclient.spec.ts b/sdk/storage/storage-file-share/test/leaseclient.spec.ts index 58111ff8ce92..45aecbd394c8 100644 --- a/sdk/storage/storage-file-share/test/leaseclient.spec.ts +++ b/sdk/storage/storage-file-share/test/leaseclient.spec.ts @@ -1,12 +1,17 @@ import * as assert from "assert"; -import * as dotenv from "dotenv"; import { getBSU, recorderEnvSetup, bodyToString } from "./utils"; import { record, Recorder } from "@azure/test-utils-recorder"; -import { ShareClient, ShareDirectoryClient, ShareFileClient } from "../src"; -import { FileSystemAttributes } from "../src/FileSystemAttributes"; - +import { + ShareClient, + ShareDirectoryClient, + ShareFileClient, + ShareLeaseClient, + ShareServiceClient +} from "../src"; +import * as dotenv from "dotenv"; dotenv.config(); +// for file describe("LeaseClient", () => { let shareName: string; let shareClient: ShareClient; @@ -20,16 +25,6 @@ describe("LeaseClient", () => { let recorder: Recorder; - let fullFileAttributes = new FileSystemAttributes(); - fullFileAttributes.readonly = true; - fullFileAttributes.hidden = true; - fullFileAttributes.system = true; - fullFileAttributes.archive = true; - fullFileAttributes.temporary = true; - fullFileAttributes.offline = true; - fullFileAttributes.notContentIndexed = true; - fullFileAttributes.noScrubData = true; - beforeEach(async function() { recorder = record(this, recorderEnvSetup); const serviceClient = getBSU(); @@ -96,11 +91,12 @@ describe("LeaseClient", () => { }); it("invalid duration for acquireLease", async () => { - const invalid_duration = 2; + // only -1 for infinite is allowed. + const invalid_duration = 20; const leaseClient = fileClient.getShareLeaseClient(); try { await leaseClient.acquireLease(invalid_duration); - assert.fail("acquireLease should fail for an invalid duration: -2"); + assert.fail(`acquireLease should fail for an invalid duration: ${invalid_duration}`); } catch (err) { assert.equal(err.statusCode, 400); } @@ -141,7 +137,9 @@ describe("LeaseClient", () => { let result = await fileClient.getProperties(); assert.equal(result.leaseState, "leased"); - await leaseClient.breakLease(); + const res = await leaseClient.breakLease(); + assert.equal(res.leaseTimeInSeconds, undefined); + result = await fileClient.getProperties(); assert.equal(result.leaseState, "broken"); @@ -335,3 +333,267 @@ describe("LeaseClient", () => { await fileClient.getProperties({ leaseAccessConditions: { leaseId: leaseClient.leaseId } }); }); }); + +describe("LeaseClient for share", () => { + let serviceClient: ShareServiceClient; + let shareName: string; + let shareClient: ShareClient; + const infiniteDuration = -1; + const finiteDuration = 15; + const guid = "e9890485-bf47-4d9a-b3d0-aceb18506124"; + + let recorder: Recorder; + beforeEach(async function() { + recorder = record(this, recorderEnvSetup); + serviceClient = getBSU(); + shareName = recorder.getUniqueName("share"); + shareClient = serviceClient.getShareClient(shareName); + await shareClient.create(); + }); + + afterEach(async function() { + await shareClient.deleteIfExists({ deleteSnapshots: "include-leased" }); + await recorder.stop(); + }); + + // lease management: + it("acquireLease", async () => { + const leaseClient = shareClient.getShareLeaseClient(guid); + + const acquireResp = await leaseClient.acquireLease(infiniteDuration); + assert.equal(acquireResp.leaseId, guid); + + const result = await shareClient.getProperties(); + assert.equal(result.leaseDuration, "infinite"); + assert.equal(result.leaseState, "leased"); + assert.equal(result.leaseStatus, "locked"); + + await leaseClient.releaseLease(); + }); + + it("acquireLease for snapshot", async () => { + const snapshotRes = await shareClient.createSnapshot(); + assert.ok(snapshotRes.snapshot); + const snapshotShareClient = shareClient.withSnapshot(snapshotRes.snapshot!); + + const leaseClient = snapshotShareClient.getShareLeaseClient(guid); + const acquireResp = await leaseClient.acquireLease(infiniteDuration); + assert.equal(acquireResp.leaseId, guid); + + const snapshotResult = await snapshotShareClient.getProperties(); + assert.equal(snapshotResult.leaseDuration, "infinite"); + assert.equal(snapshotResult.leaseState, "leased"); + assert.equal(snapshotResult.leaseStatus, "locked"); + + const result = await shareClient.getProperties(); + assert.equal(result.leaseDuration, undefined); + assert.equal(result.leaseState, "available"); + assert.equal(result.leaseStatus, "unlocked"); + }); + + it("acquireLease without proposed lease id, with a finite duration", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(finiteDuration); + + const result = await shareClient.getProperties(); + assert.equal(result.leaseDuration, "fixed"); + assert.equal(result.leaseState, "leased"); + assert.equal(result.leaseStatus, "locked"); + + await leaseClient.releaseLease(); + }); + + it("acquireLease again with another lease id", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(infiniteDuration); + + const anotherLeaseClient = shareClient.getShareLeaseClient(guid); + try { + await anotherLeaseClient.acquireLease(infiniteDuration); + assert.fail("acquireLease a leased lease should fail with a different lease id"); + } catch (err) { + assert.equal(err.statusCode, 409); + } + + await leaseClient.releaseLease(); + }); + + it("acquireLease again with same lease id", async () => { + const leaseClient = shareClient.getShareLeaseClient(guid); + await leaseClient.acquireLease(); + await leaseClient.acquireLease(infiniteDuration); + + await leaseClient.releaseLease(); + }); + + it("invalid duration for acquireLease", async () => { + // only -1 for infinite is allowed. + const invalidDuration = 1; + const leaseClient = shareClient.getShareLeaseClient(); + try { + await leaseClient.acquireLease(invalidDuration); + assert.fail(`acquireLease should fail for an invalid duration: ${invalidDuration}`); + } catch (err) { + assert.equal(err.statusCode, 400); + } + }); + + it("changeLease", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(infiniteDuration); + const changeResp = await leaseClient.changeLease(guid); + assert.equal(changeResp.leaseId, guid); + + await leaseClient.releaseLease(); + }); + + it("changeLease before acquiring a lease", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + try { + const changeResp = await leaseClient.changeLease(guid); + assert.equal(changeResp.leaseId, guid); + await leaseClient.releaseLease(); + } catch (err) { + assert.equal(err.statusCode, 409); + } + }); + + it("release lease", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(); + await leaseClient.releaseLease(); + + const result = await shareClient.getProperties(); + assert.equal(result.leaseDuration, undefined); + assert.equal(result.leaseState, "available"); + assert.equal(result.leaseStatus, "unlocked"); + }); + + it("break lease and then release it", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(); + let result = await shareClient.getProperties(); + assert.equal(result.leaseState, "leased"); + + const breakRes = await leaseClient.breakLease(); + // infinite lease broken immediately + assert.equal(breakRes.leaseTimeInSeconds, 0); + + result = await shareClient.getProperties(); + assert.equal(result.leaseState, "broken"); + + await leaseClient.releaseLease(); + }); + + it("break a broken lease", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(finiteDuration); + const breakRes = await leaseClient.breakLease(); + assert.ok(breakRes.leaseTimeInSeconds); + await leaseClient.breakLease(); + + await leaseClient.releaseLease(); + }); + + it("acquire a broken lease", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(); + await leaseClient.breakLease(); + let result = await shareClient.getProperties(); + assert.equal(result.leaseState, "broken"); + + await leaseClient.acquireLease(); + result = await shareClient.getProperties(); + assert.equal(result.leaseState, "leased"); + + await leaseClient.releaseLease(); + }); + + it("renew a lease", async () => { + const leaseClient = shareClient.getShareLeaseClient(guid); + await leaseClient.acquireLease(); + await leaseClient.renewLease(); + + await leaseClient.releaseLease(); + }); + + it("lease properties properly returned", async () => { + const leaseClient = shareClient.getShareLeaseClient(); + await leaseClient.acquireLease(); + + const getPropertiesRes = await shareClient.getProperties(); + assert.equal(getPropertiesRes.leaseDuration, "infinite"); + assert.equal(getPropertiesRes.leaseState, "leased"); + assert.equal(getPropertiesRes.leaseStatus, "locked"); + + for await (const shareItem of serviceClient.listShares()) { + if (shareItem.name === shareName) { + assert.equal(shareItem.properties.leaseDuration, "infinite"); + assert.equal(shareItem.properties.leaseState, "leased"); + assert.equal(shareItem.properties.leaseStatus, "locked"); + } + } + + await leaseClient.releaseLease(); + }); + + // lease conditions + it("lease condition for delete", async () => { + const leaseClient = new ShareLeaseClient(shareClient, guid); + await leaseClient.acquireLease(); + + try { + await shareClient.delete(); + assert.fail("Delete without lease condition should have failed."); + } catch (err) { + assert.equal(err.details.errorCode, "LeaseIdMissing"); + } + + await shareClient.delete({ leaseAccessConditions: { leaseId: guid } }); + }); + + it("lease condition for get operations", async () => { + const leaseClient = new ShareLeaseClient(shareClient); + await leaseClient.acquireLease(); + + await shareClient.getProperties(); + + try { + await shareClient.getProperties({ leaseAccessConditions: { leaseId: guid } }); + assert.fail("get with miss-match lease ID should have failed."); + } catch (err) { + assert.equal(err.details.errorCode, "LeaseIdMismatchWithContainerOperation"); + } + + await shareClient.getProperties({ leaseAccessConditions: { leaseId: leaseClient.leaseId } }); + + await leaseClient.releaseLease(); + }); + + it("lease condition for write operations", async () => { + const leaseClient = new ShareLeaseClient(shareClient); + await leaseClient.acquireLease(); + + const meta = { key: "val" }; + + try { + await shareClient.setMetadata(meta); + assert.fail("write without lease ID should have failed."); + } catch (err) { + assert.equal(err.details.errorCode, "LeaseIdMissing"); + } + + try { + await shareClient.setMetadata(meta, { leaseAccessConditions: { leaseId: guid } }); + assert.fail("write with miss-match lease ID should have failed."); + } catch (err) { + assert.equal(err.details.errorCode, "LeaseIdMismatchWithContainerOperation"); + } + + await shareClient.setMetadata(meta, { + leaseAccessConditions: { leaseId: leaseClient.leaseId } + }); + + await leaseClient.releaseLease(); + }); +}); diff --git a/sdk/storage/storage-file-share/test/node/sas.spec.ts b/sdk/storage/storage-file-share/test/node/sas.spec.ts index d5fb5b58c26a..4bb84154e0bf 100644 --- a/sdk/storage/storage-file-share/test/node/sas.spec.ts +++ b/sdk/storage/storage-file-share/test/node/sas.spec.ts @@ -10,11 +10,10 @@ import { SASProtocol, StorageSharedKeyCredential } from "../../src"; -import { ShareFileClient } from "../../src/ShareFileClient"; +import { ShareFileClient, ShareClient } from "../../src"; import { FileSASPermissions } from "../../src/FileSASPermissions"; import { generateFileSASQueryParameters } from "../../src/FileSASSignatureValues"; import { newPipeline } from "../../src/Pipeline"; -import { ShareClient } from "../../src/ShareClient"; import { ShareSASPermissions } from "../../src/ShareSASPermissions"; import { getBSU, recorderEnvSetup } from "../utils"; import { delay, record, Recorder } from "@azure/test-utils-recorder"; diff --git a/sdk/storage/storage-file-share/test/node/shareclient.spec.ts b/sdk/storage/storage-file-share/test/node/shareclient.spec.ts index 2018cc066817..773be116b382 100644 --- a/sdk/storage/storage-file-share/test/node/shareclient.spec.ts +++ b/sdk/storage/storage-file-share/test/node/shareclient.spec.ts @@ -62,6 +62,20 @@ describe("ShareClient Node.js only", () => { done(); }); + it("setAccessPolicy and getAccessPolicy with empty SignedIdentifier", async () => { + const identifiers: any = [ + { + id: "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=" + } + ]; + + await shareClient.setAccessPolicy(identifiers); + const getAccessPolicyResponse = await shareClient.getAccessPolicy(); + + assert.equal(getAccessPolicyResponse.signedIdentifiers[0].id, identifiers[0].id); + assert.deepStrictEqual(getAccessPolicyResponse.signedIdentifiers[0].accessPolicy, undefined); + }); + it("can be created with a url and a credential", async () => { const factories = (shareClient as any).pipeline.factories; const credential = factories[factories.length - 1] as StorageSharedKeyCredential; diff --git a/sdk/storage/storage-file-share/test/shareclient.spec.ts b/sdk/storage/storage-file-share/test/shareclient.spec.ts index f2ca19df128c..09b188256e29 100644 --- a/sdk/storage/storage-file-share/test/shareclient.spec.ts +++ b/sdk/storage/storage-file-share/test/shareclient.spec.ts @@ -229,6 +229,31 @@ describe("ShareClient", () => { assert.ok(createPermResp.requestId!); assert.ok(createPermResp.version!); }); + + it("create share specifying accessTier and listShare", async () => { + const newShareName = recorder.getUniqueName("newshare"); + const newShareClient = serviceClient.getShareClient(newShareName); + await newShareClient.create({ accessTier: "Hot" }); + + for await (const shareItem of serviceClient.listShares({ prefix: newShareName })) { + if (shareItem.name === newShareName) { + assert.deepStrictEqual(shareItem.properties.accessTier, "Hot"); + assert.ok(shareItem.properties.accessTierChangeTime); + break; + } + } + + await newShareClient.delete(); + }); + + it("setAccessTier", async () => { + await shareClient.setAccessTier("Hot"); + const getRes = await shareClient.getProperties(); + + assert.deepStrictEqual(getRes.accessTier, "Hot"); + assert.ok(getRes.accessTierChangeTime); + assert.deepStrictEqual(getRes.accessTierTransitionState, "pending-from-transactionOptimized"); + }); }); describe("ShareDirectoryClient - Verify Name Properties", () => { diff --git a/sdk/storage/storage-file-share/test/specialnaming.spec.ts b/sdk/storage/storage-file-share/test/specialnaming.spec.ts index b687cd121e68..8c26b698e940 100644 --- a/sdk/storage/storage-file-share/test/specialnaming.spec.ts +++ b/sdk/storage/storage-file-share/test/specialnaming.spec.ts @@ -1,11 +1,9 @@ -import { ShareFileClient } from "../src/ShareFileClient"; +import { ShareClient, ShareFileClient, ShareDirectoryClient } from "../src"; import { getBSU, recorderEnvSetup } from "./utils/index"; import * as assert from "assert"; import { appendToURLPath } from "../src/utils/utils.common"; -import { ShareDirectoryClient } from "../src/ShareDirectoryClient"; import { record, Recorder } from "@azure/test-utils-recorder"; import * as dotenv from "dotenv"; -import { ShareClient } from "../src"; dotenv.config(); describe("Special Naming Tests", () => { diff --git a/sdk/storage/storage-file-share/test/utils/testutils.common.ts b/sdk/storage/storage-file-share/test/utils/testutils.common.ts index 2df6e9465eb3..84209f2c11bb 100644 --- a/sdk/storage/storage-file-share/test/utils/testutils.common.ts +++ b/sdk/storage/storage-file-share/test/utils/testutils.common.ts @@ -23,7 +23,11 @@ export const recorderEnvSetup: RecorderEnvironmentSetup = { SOFT_DELETE_ACCOUNT_NAME: `${mockSDAccountName}`, SOFT_DELETE_ACCOUNT_KEY: `${mockAccountKey}`, SOFT_DELETE_ACCOUNT_SAS: `${mockAccountKey}`, - SOFT_DELETE_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockSDAccountName};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net` + SOFT_DELETE_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockSDAccountName};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net`, + PREMIUM_FILE_ACCOUNT_NAME: `${mockAccountName}`, + PREMIUM_FILE_ACCOUNT_KEY: `${mockAccountKey}`, + PREMIUM_FILE_ACCOUNT_SAS: `${mockAccountKey}`, + PREMIUM_FILE_STORAGE_CONNECTION_STRING: `DefaultEndpointsProtocol=https;AccountName=${mockSDAccountName};AccountKey=${mockAccountKey};EndpointSuffix=core.windows.net` }, customizationsOnRecordings: [ // Used in record mode diff --git a/sdk/storage/storage-file-share/tests.yml b/sdk/storage/storage-file-share/tests.yml index adb6bce8f675..f674802b22b2 100644 --- a/sdk/storage/storage-file-share/tests.yml +++ b/sdk/storage/storage-file-share/tests.yml @@ -6,6 +6,8 @@ extends: PackageName: "@azure/storage-file-share" ResourceServiceDirectory: storage TimeoutInMinutes: 90 + ResourceGroupLocation: canadacentral + SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources-preview) EnvVars: AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) diff --git a/sdk/storage/storage-queue/CHANGELOG.md b/sdk/storage/storage-queue/CHANGELOG.md index db4f7574a2a5..ab9daca4cdf0 100644 --- a/sdk/storage/storage-queue/CHANGELOG.md +++ b/sdk/storage/storage-queue/CHANGELOG.md @@ -1,7 +1,8 @@ # Release History -## 12.1.1 (Unreleased) +## 12.2.0 (Unreleased) +- Updated Azure Storage Service API version to 2020-02-10. ## 12.1.0 (2020-09-08) diff --git a/sdk/storage/storage-queue/package.json b/sdk/storage/storage-queue/package.json index 46035454be54..07708daa261e 100644 --- a/sdk/storage/storage-queue/package.json +++ b/sdk/storage/storage-queue/package.json @@ -1,7 +1,7 @@ { "name": "@azure/storage-queue", "sdk-type": "client", - "version": "12.1.1", + "version": "12.2.0", "description": "Microsoft Azure Storage SDK for JavaScript - Queue", "main": "./dist/index.js", "module": "./dist-esm/src/index.js", @@ -25,7 +25,7 @@ }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", - "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.1.0 --use=@microsoft.azure/autorest.typescript@5.0.1", + "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.2.0 --use=@microsoft.azure/autorest.typescript@5.0.1", "build:es6": "tsc -p tsconfig.json", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", diff --git a/sdk/storage/storage-queue/recordings/browsers/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.json b/sdk/storage/storage-queue/recordings/browsers/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.json new file mode 100644 index 000000000000..6f34c8b84fee --- /dev/null +++ b/sdk/storage/storage-queue/recordings/browsers/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.json @@ -0,0 +1,109 @@ +{ + "recordings": [ + { + "method": "PUT", + "url": "https://fakestorageaccount.queue.core.windows.net/queue160015813770703540", + "query": { + "timeout": "30" + }, + "requestBody": null, + "status": 201, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 15 Sep 2020 08:22:18 GMT", + "server": "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f4a8c0d7-254b-4a9a-bcba-a84695fa1804", + "x-ms-request-id": "59bd2c3b-2003-0066-5839-8bed2f000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "POST", + "url": "https://fakestorageaccount.queue.core.windows.net/queue160015813770703540/messages", + "query": { + "visibilitytimeout": "10", + "timeout": "30" + }, + "requestBody": "foo", + "status": 201, + "response": "56947312-751e-4eda-8024-ad7da71ba8b7Tue, 15 Sep 2020 08:22:19 GMTTue, 22 Sep 2020 08:22:19 GMTAgAAAAMAAAAAAAAAi/40WjmL1gE=Tue, 15 Sep 2020 08:22:29 GMT", + "responseHeaders": { + "content-type": "application/xml", + "date": "Tue, 15 Sep 2020 08:22:18 GMT", + "server": "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "d960f306-0c71-4a7a-9df2-62c1430af19b", + "x-ms-request-id": "59bd31c8-2003-0066-4c39-8bed2f000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "PUT", + "url": "https://fakestorageaccount.queue.core.windows.net/queue160015813770703540/messages/56947312-751e-4eda-8024-ad7da71ba8b7", + "query": { + "popreceipt": "AgAAAAMAAAAAAAAAi/40WjmL1gE=", + "visibilitytimeout": "0", + "timeout": "30" + }, + "requestBody": null, + "status": 204, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 15 Sep 2020 08:22:19 GMT", + "server": "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "cbbb8c81-d74d-43b5-b10b-6653888b4a87", + "x-ms-popreceipt": "AwAAAAMAAAAAAAAALjGbVDmL1gEAAAAA", + "x-ms-request-id": "59bd373d-2003-0066-2a39-8bed2f000000", + "x-ms-time-next-visible": "Tue, 15 Sep 2020 08:22:20 GMT", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "GET", + "url": "https://fakestorageaccount.queue.core.windows.net/queue160015813770703540/messages", + "query": { + "timeout": "30" + }, + "requestBody": null, + "status": 200, + "response": "56947312-751e-4eda-8024-ad7da71ba8b7Tue, 15 Sep 2020 08:22:19 GMTTue, 22 Sep 2020 08:22:19 GMTAgAAAAMAAAAAAAAATSTYZjmL1gE=Tue, 15 Sep 2020 08:22:50 GMT1foo", + "responseHeaders": { + "cache-control": "no-cache", + "content-type": "application/xml", + "date": "Tue, 15 Sep 2020 08:22:20 GMT", + "server": "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "05f0472a-ac7a-4f51-a804-13f6e3cb4229", + "x-ms-request-id": "59bd3c34-2003-0066-6539-8bed2f000000", + "x-ms-version": "2020-02-10" + } + }, + { + "method": "DELETE", + "url": "https://fakestorageaccount.queue.core.windows.net/queue160015813770703540", + "query": { + "timeout": "30" + }, + "requestBody": null, + "status": 204, + "response": "", + "responseHeaders": { + "content-length": "0", + "date": "Tue, 15 Sep 2020 08:22:20 GMT", + "server": "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "78d4e21d-c50d-4de0-afa0-9e71c060b65f", + "x-ms-request-id": "59bd4256-2003-0066-5239-8bed2f000000", + "x-ms-version": "2020-02-10" + } + } + ], + "uniqueTestInfo": { + "uniqueName": { + "queue": "queue160015813770703540" + }, + "newDate": {} + }, + "hash": "c97a331f5a4027e071f910b9d305ee79" +} \ No newline at end of file diff --git a/sdk/storage/storage-queue/recordings/node/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.js b/sdk/storage/storage-queue/recordings/node/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.js new file mode 100644 index 000000000000..e380815a6e55 --- /dev/null +++ b/sdk/storage/storage-queue/recordings/node/queueclient_messageid_methods/recording_update_visibility_timeout_only_preserve_content.js @@ -0,0 +1,109 @@ +let nock = require('nock'); + +module.exports.hash = "e43fe88599f94bda7bb7c36a7c88b62f"; + +module.exports.testInfo = {"uniqueName":{"queue":"queue160015809428209607"},"newDate":{}} + +nock('https://fakestorageaccount.queue.core.windows.net:443', {"encodedQueryParams":true}) + .put('/queue160015809428209607') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2248f401-9003-003e-1b39-8b3570000000', + 'x-ms-client-request-id', + '243c19b3-a611-47c4-bb86-6f342d4f2ae3', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 15 Sep 2020 08:21:35 GMT' +]); + +nock('https://fakestorageaccount.queue.core.windows.net:443', {"encodedQueryParams":true}) + .post('/queue160015809428209607/messages', "foo") + .query(true) + .reply(201, "a340c68f-fd60-484d-bf95-14ce7ec15614Tue, 15 Sep 2020 08:21:35 GMTTue, 22 Sep 2020 08:21:35 GMTAgAAAAMAAAAAAAAAPV0YQDmL1gE=Tue, 15 Sep 2020 08:21:45 GMT", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2248f4d8-9003-003e-5839-8b3570000000', + 'x-ms-client-request-id', + '9e7e431a-ac04-4522-8322-fe56a306f5a0', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 15 Sep 2020 08:21:35 GMT' +]); + +nock('https://fakestorageaccount.queue.core.windows.net:443', {"encodedQueryParams":true}) + .put('/queue160015809428209607/messages/a340c68f-fd60-484d-bf95-14ce7ec15614') + .query(true) + .reply(204, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2248f5af-9003-003e-1c39-8b3570000000', + 'x-ms-client-request-id', + '08bc98dd-c44f-4b4b-a4ab-47f81b0ae7fc', + 'x-ms-version', + '2020-02-10', + 'x-ms-popreceipt', + 'AwAAAAMAAAAAAAAAyudQOjmL1gEAAAAA', + 'x-ms-time-next-visible', + 'Tue, 15 Sep 2020 08:21:36 GMT', + 'Date', + 'Tue, 15 Sep 2020 08:21:36 GMT' +]); + +nock('https://fakestorageaccount.queue.core.windows.net:443', {"encodedQueryParams":true}) + .get('/queue160015809428209607/messages') + .query(true) + .reply(200, "a340c68f-fd60-484d-bf95-14ce7ec15614Tue, 15 Sep 2020 08:21:35 GMTTue, 22 Sep 2020 08:21:35 GMTAgAAAAMAAAAAAAAAywtgTDmL1gE=Tue, 15 Sep 2020 08:22:06 GMT1foo", [ + 'Cache-Control', + 'no-cache', + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2248f673-9003-003e-4f39-8b3570000000', + 'x-ms-client-request-id', + '61f2ddc4-b4dd-47bc-9af2-4d587dafe80a', + 'x-ms-version', + '2020-02-10', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Cache-Control,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Tue, 15 Sep 2020 08:21:36 GMT' +]); + +nock('https://fakestorageaccount.queue.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/queue160015809428209607') + .query(true) + .reply(204, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '2248f71b-9003-003e-6e39-8b3570000000', + 'x-ms-client-request-id', + 'c084add0-1a55-4435-aff2-cd8c2298deaf', + 'x-ms-version', + '2020-02-10', + 'Date', + 'Tue, 15 Sep 2020 08:21:36 GMT' +]); diff --git a/sdk/storage/storage-queue/review/storage-queue.api.md b/sdk/storage/storage-queue/review/storage-queue.api.md index 6a23acf8805e..57ec1be8fcbf 100644 --- a/sdk/storage/storage-queue/review/storage-queue.api.md +++ b/sdk/storage/storage-queue/review/storage-queue.api.md @@ -370,7 +370,7 @@ export class QueueClient extends StorageClient { sendMessage(messageText: string, options?: QueueSendMessageOptions): Promise; setAccessPolicy(queueAcl?: SignedIdentifier[], options?: QueueSetAccessPolicyOptions): Promise; setMetadata(metadata?: Metadata, options?: QueueSetMetadataOptions): Promise; - updateMessage(messageId: string, popReceipt: string, message: string, visibilityTimeout?: number, options?: QueueUpdateMessageOptions): Promise; + updateMessage(messageId: string, popReceipt: string, message?: string, visibilityTimeout?: number, options?: QueueUpdateMessageOptions): Promise; } // @public diff --git a/sdk/storage/storage-queue/src/QueueClient.ts b/sdk/storage/storage-queue/src/QueueClient.ts index bec226efbd58..57f831a98496 100644 --- a/sdk/storage/storage-queue/src/QueueClient.ts +++ b/sdk/storage/storage-queue/src/QueueClient.ts @@ -1258,7 +1258,7 @@ export class QueueClient extends StorageClient { * * @param {string} messageId Id of the message * @param {string} popReceipt A valid pop receipt value returned from an earlier call to the receive messages or update message operation. - * @param {string} message Message to update. + * @param {string} message Message to update. If this parameter is undefined, then the content of the message won't be updated. * @param {number} visibilityTimeout Specifies the new visibility timeout value, in seconds, * relative to server time. The new value must be larger than or equal to 0, * and cannot be larger than 7 days. The visibility timeout of a message cannot @@ -1271,23 +1271,22 @@ export class QueueClient extends StorageClient { public async updateMessage( messageId: string, popReceipt: string, - message: string, + message?: string, visibilityTimeout?: number, options: QueueUpdateMessageOptions = {} ): Promise { const { span, spanOptions } = createSpan("QueueClient-updateMessage", options.tracingOptions); + let queueMessage = undefined; + if (message !== undefined) { + queueMessage = { messageText: message }; + } + try { - return await this.getMessageIdContext(messageId).update( - { - messageText: message - }, - popReceipt, - visibilityTimeout || 0, - { - abortSignal: options.abortSignal, - spanOptions - } - ); + return await this.getMessageIdContext(messageId).update(popReceipt, visibilityTimeout || 0, { + abortSignal: options.abortSignal, + spanOptions, + queueMessage + }); } catch (e) { span.setStatus({ code: CanonicalCode.UNKNOWN, diff --git a/sdk/storage/storage-queue/src/generated/src/models/index.ts b/sdk/storage/storage-queue/src/generated/src/models/index.ts index 53ba26d102ed..10ba47b8028c 100644 --- a/sdk/storage/storage-queue/src/generated/src/models/index.ts +++ b/sdk/storage/storage-queue/src/generated/src/models/index.ts @@ -637,6 +637,10 @@ export interface MessagesPeekOptionalParams extends coreHttp.RequestOptionsBase * Optional Parameters. */ export interface MessageIdUpdateOptionalParams extends coreHttp.RequestOptionsBase { + /** + * A Message object which can be stored in a Queue + */ + queueMessage?: QueueMessage; /** * The The timeout parameter is expressed in seconds. For more information, see */ - update(queueMessage: Models.QueueMessage, popReceipt: string, visibilityTimeout: number, options?: Models.MessageIdUpdateOptionalParams): Promise; + update(popReceipt: string, visibilityTimeout: number, options?: Models.MessageIdUpdateOptionalParams): Promise; /** - * @param queueMessage A Message object which can be stored in a Queue * @param popReceipt Required. Specifies the valid pop receipt value returned from an earlier call * to the Get Messages or Update Message operation. * @param visibilityTimeout Optional. Specifies the new visibility timeout value, in seconds, @@ -54,9 +52,8 @@ export class MessageId { * later than the expiry time. * @param callback The callback */ - update(queueMessage: Models.QueueMessage, popReceipt: string, visibilityTimeout: number, callback: coreHttp.ServiceCallback): void; + update(popReceipt: string, visibilityTimeout: number, callback: coreHttp.ServiceCallback): void; /** - * @param queueMessage A Message object which can be stored in a Queue * @param popReceipt Required. Specifies the valid pop receipt value returned from an earlier call * to the Get Messages or Update Message operation. * @param visibilityTimeout Optional. Specifies the new visibility timeout value, in seconds, @@ -67,11 +64,10 @@ export class MessageId { * @param options The optional parameters * @param callback The callback */ - update(queueMessage: Models.QueueMessage, popReceipt: string, visibilityTimeout: number, options: Models.MessageIdUpdateOptionalParams, callback: coreHttp.ServiceCallback): void; - update(queueMessage: Models.QueueMessage, popReceipt: string, visibilityTimeout: number, options?: Models.MessageIdUpdateOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { + update(popReceipt: string, visibilityTimeout: number, options: Models.MessageIdUpdateOptionalParams, callback: coreHttp.ServiceCallback): void; + update(popReceipt: string, visibilityTimeout: number, options?: Models.MessageIdUpdateOptionalParams | coreHttp.ServiceCallback, callback?: coreHttp.ServiceCallback): Promise { return this.client.sendOperationRequest( { - queueMessage, popReceipt, visibilityTimeout, options @@ -130,11 +126,11 @@ const updateOperationSpec: coreHttp.OperationSpec = { Parameters.requestId ], requestBody: { - parameterPath: "queueMessage", - mapper: { - ...Mappers.QueueMessage, - required: true - } + parameterPath: [ + "options", + "queueMessage" + ], + mapper: Mappers.QueueMessage }, contentType: "application/xml; charset=utf-8", responses: { diff --git a/sdk/storage/storage-queue/src/generated/src/storageClientContext.ts b/sdk/storage/storage-queue/src/generated/src/storageClientContext.ts index 41f81787658a..9c08aed48f22 100644 --- a/sdk/storage/storage-queue/src/generated/src/storageClientContext.ts +++ b/sdk/storage/storage-queue/src/generated/src/storageClientContext.ts @@ -11,7 +11,7 @@ import * as coreHttp from "@azure/core-http"; const packageName = "azure-storage-queue"; -const packageVersion = "12.1.1"; +const packageVersion = "12.2.0"; export class StorageClientContext extends coreHttp.ServiceClient { url: string; @@ -39,7 +39,7 @@ export class StorageClientContext extends coreHttp.ServiceClient { super(undefined, options); - this.version = "2019-12-12"; + this.version = '2020-02-10'; this.baseUri = "{url}"; this.requestContentType = "application/json; charset=utf-8"; this.url = url; diff --git a/sdk/storage/storage-queue/src/utils/constants.ts b/sdk/storage/storage-queue/src/utils/constants.ts index 8792cc6188b6..52cda480d73e 100644 --- a/sdk/storage/storage-queue/src/utils/constants.ts +++ b/sdk/storage/storage-queue/src/utils/constants.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -export const SDK_VERSION: string = "12.1.1"; -export const SERVICE_VERSION: string = "2019-12-12"; +export const SDK_VERSION: string = "12.2.0"; +export const SERVICE_VERSION: string = "2020-02-10"; /** * The OAuth scope to use with Azure Storage. diff --git a/sdk/storage/storage-queue/swagger/README.md b/sdk/storage/storage-queue/swagger/README.md index 29e77ebe4675..4ca17841a072 100644 --- a/sdk/storage/storage-queue/swagger/README.md +++ b/sdk/storage/storage-queue/swagger/README.md @@ -196,13 +196,13 @@ directive: $["x-ms-client-name"] = "queueAnalyticsLogging" ``` -### Update service version from "2018-03-28" to "2019-12-12" +### Update service version from "2018-03-28" to "2020-02-10" ```yaml directive: - from: swagger-document where: $.parameters.ApiVersionParameter - transform: $.enum = [ "2019-12-12" ]; + transform: $.enum = [ "2020-02-10" ]; ``` ### Rename AccessPolicy start -> startsOn @@ -231,5 +231,4 @@ directive: } ``` - ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fstorage%2Fstorage-queue%2Fswagger%2FREADME.png) diff --git a/sdk/storage/storage-queue/test/messageidclient.spec.ts b/sdk/storage/storage-queue/test/messageidclient.spec.ts index eae5d21d32b2..d27d268afffe 100644 --- a/sdk/storage/storage-queue/test/messageidclient.spec.ts +++ b/sdk/storage/storage-queue/test/messageidclient.spec.ts @@ -206,4 +206,13 @@ describe("QueueClient messageId methods", () => { ); assert.equal(newClient.name, queueName, "Queue name is not the same as the one provided."); }); + + it("update visibility timeout only preserve content", async () => { + const message = "foo"; + const enqueueRes = await queueClient.sendMessage(message, { visibilityTimeout: 10 }); + await queueClient.updateMessage(enqueueRes.messageId, enqueueRes.popReceipt); + const receiveMessage = (await queueClient.receiveMessages()).receivedMessageItems[0]; + assert.equal(enqueueRes.messageId, receiveMessage.messageId); + assert.equal(message, receiveMessage.messageText); + }); }); diff --git a/sdk/storage/storage-queue/tests.yml b/sdk/storage/storage-queue/tests.yml index 8fd7a8bc31f4..c32dceb5f56d 100644 --- a/sdk/storage/storage-queue/tests.yml +++ b/sdk/storage/storage-queue/tests.yml @@ -5,3 +5,5 @@ extends: parameters: PackageName: "@azure/storage-queue" ResourceServiceDirectory: storage + ResourceGroupLocation: canadacentral + SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources-preview) diff --git a/sdk/storage/test-resources-post.ps1 b/sdk/storage/test-resources-post.ps1 index c2604c770827..3e61bc86c32d 100644 --- a/sdk/storage/test-resources-post.ps1 +++ b/sdk/storage/test-resources-post.ps1 @@ -62,6 +62,12 @@ $storageContext = New-AzStorageContext -StorageAccountName $datalakeStorageAccou $storageSas = New-AzStorageAccountSASToken -ResourceType Service, Container, Object -Service Blob, File, Queue, Table -Permission "rwdxftlacup" -Context $storageContext $AdditionalEnvKeys["DFS_ACCOUNT_SAS"] = $storageSas +$fullStorageAccount = $DeploymentOutputs['FULL_ACCOUNT_NAME'] +Write-Host "Creating SAS for full storage account $fullStorageAccount" +$storageContext = New-AzStorageContext -StorageAccountName $fullStorageAccount -StorageAccountKey $DeploymentOutputs['FULL_ACCOUNT_KEY'] +$storageSas = New-AzStorageAccountSASToken -ResourceType Service, Container, Object -Service Blob, File, Queue, Table -Permission "rwdxftlacup" -Context $storageContext +$AdditionalEnvKeys["FULL_ACCOUNT_SAS"] = $storageSas +$AdditionalEnvKeys["SOFT_DELETE_ACCOUNT_SAS"] = $storageSas # Try to detect the shell based on the parent process name (e.g. launch via shebang). $shell, $shellExportFormat = if (($parentProcessName = (Get-Process -Id $PID).Parent.ProcessName) -and $parentProcessName -eq 'cmd') { diff --git a/sdk/storage/test-resources.json b/sdk/storage/test-resources.json index 9fa750ddbf86..184d91d5aebe 100644 --- a/sdk/storage/test-resources.json +++ b/sdk/storage/test-resources.json @@ -32,8 +32,8 @@ "metadata": { "description": "The application client secret used to run tests." } - }, - "enableVersioning": { + }, + "enableVersioning": { "type": "bool", "defaultValue": false }, @@ -49,9 +49,13 @@ "storageApiVersion": "2019-04-01", "location": "[resourceGroup().location]", "accountName": "[parameters('baseName')]", - "datalakeAccountName": "[concat('d', parameters('baseName'))]", + "datalakeAccountName": "[concat('dl', parameters('baseName'))]", + "fullAccountName": "[concat('f', parameters('baseName'))]", + "premiumFileAccountName": "[concat('pf', parameters('baseName'))]", "accountNameTidy": "[toLower(trim(variables('accountName')))]", - "datalakeaccountNameTidy": "[toLower(trim(variables('datalakeAccountName')))]", + "datalakeAccountNameTidy": "[toLower(trim(variables('datalakeAccountName')))]", + "fullAccountNameTidy": "[toLower(trim(variables('fullAccountName')))]", + "premiumFileAccountNameTidy": "[toLower(trim(variables('premiumFileAccountName')))]", "blobEndPoint": "[concat('https://',variables('accountNameTidy'),'.blob.', parameters('storageEndpointSuffix'))]", "accountSasProperties": { "signedServices": "bfqt", @@ -61,21 +65,47 @@ "signedExpiry": "2022-01-01T23:59:00Z" }, "authorizationApiVersion": "2018-01-01-preview", - "blobDataContributorRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe')]" + "blobDataContributorRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "blobDataOwnerRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", + "encryption": { + "services": { + "file": { + "enabled": true + }, + "blob": { + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + }, + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + } }, "resources": [ { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "[variables('authorizationApiVersion')]", "name": "[guid(concat('blobDataContributorRoleId', variables('accountName')))]", - "dependsOn": [ - "[variables('accountName')]" - ], + "dependsOn": ["[variables('accountName')]"], "properties": { "roleDefinitionId": "[variables('blobDataContributorRoleId')]", "principalId": "[parameters('testApplicationOid')]" } }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "[variables('authorizationApiVersion')]", + "name": "[guid(concat('blobDataOwnerRoleId', variables('accountName')))]", + "dependsOn": ["[variables('accountName')]"], + "properties": { + "roleDefinitionId": "[variables('blobDataOwnerRoleId')]", + "principalId": "[parameters('testApplicationOid')]" + } + }, { "type": "Microsoft.Storage/storageAccounts", "apiVersion": "[variables('storageApiVersion')]", @@ -87,26 +117,9 @@ }, "kind": "StorageV2", "properties": { - "networkAcls": { - "bypass": "AzureServices", - "virtualNetworkRules": [ - ], - "ipRules": [ - ], - "defaultAction": "Allow" - }, + "networkAcls": "[variables('networkAcls')]", "supportsHttpsTrafficOnly": true, - "encryption": { - "services": { - "file": { - "enabled": true - }, - "blob": { - "enabled": true - } - }, - "keySource": "Microsoft.Storage" - }, + "encryption": "[variables('encryption')]", "accessTier": "Hot" }, "resources": [ @@ -114,17 +127,13 @@ "name": "default", "type": "blobServices", "apiVersion": "[variables('storageApiVersion')]", - "dependsOn": [ - "[variables('accountName')]" - ], + "dependsOn": ["[variables('accountName')]"], "properties": { "isVersioningEnabled": "[parameters('enableVersioning')]", "cors": { "corsRules": [ { - "allowedOrigins": [ - "*" - ], + "allowedOrigins": ["*"], "allowedMethods": [ "DELETE", "GET", @@ -136,57 +145,40 @@ "PATCH" ], "maxAgeInSeconds": 86400, - "exposedHeaders": [ - "*" - ], - "allowedHeaders": [ - "*" - ] + "exposedHeaders": ["*"], + "allowedHeaders": ["*"] } ] + }, + "lastAccessTimeTrackingPolicy": { + "enable": true, + "name": "AccessTimeTracking", + "trackingGranularityInDays": 1, + "blobType": ["blockBlob"] } }, - "resources": [ - ] + "resources": [] }, { "name": "default", "type": "fileServices", "apiVersion": "[variables('storageApiVersion')]", - "dependsOn": [ - "[variables('accountName')]" - ], + "dependsOn": ["[variables('accountName')]"], "properties": { "cors": { "corsRules": [ { - "allowedOrigins": [ - "*" - ], - "allowedMethods": [ - "DELETE", - "GET", - "HEAD", - "MERGE", - "POST", - "OPTIONS", - "PUT" - ], + "allowedOrigins": ["*"], + "allowedMethods": ["DELETE", "GET", "HEAD", "MERGE", "POST", "OPTIONS", "PUT"], "maxAgeInSeconds": 86400, - "exposedHeaders": [ - "*" - ], - "allowedHeaders": [ - "*" - ] + "exposedHeaders": ["*"], + "allowedHeaders": ["*"] } ] } }, - "resources": [ - ] + "resources": [] } - ] }, { @@ -201,54 +193,135 @@ "kind": "StorageV2", "properties": { "isHnsEnabled": true, - "cors": { - "corsRules": [ - { - "allowedOrigins": [ - "*" - ], - "allowedMethods": [ - "DELETE", - "GET", - "HEAD", - "MERGE", - "POST", - "OPTIONS", - "PUT", - "PATCH" - ], - "maxAgeInSeconds": 86400, - "exposedHeaders": [ - "*" - ], - "allowedHeaders": [ - "*" - ] - } - ] - }, - "networkAcls": { - "bypass": "AzureServices", - "virtualNetworkRules": [ - ], - "ipRules": [ - ], - "defaultAction": "Allow" - }, + "networkAcls": "[variables('networkAcls')]", "supportsHttpsTrafficOnly": true, - "encryption": { - "services": { - "file": { - "enabled": true + "encryption": "[variables('encryption')]", + "accessTier": "Hot" + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "[variables('storageApiVersion')]", + "name": "[variables('fullAccountName')]", + "location": "[variables('location')]", + "sku": { + "name": "Standard_RAGRS", + "tier": "Standard" + }, + "kind": "StorageV2", + "properties": { + "networkAcls": "[variables('networkAcls')]", + "supportsHttpsTrafficOnly": true, + "encryption": "[variables('encryption')]", + "accessTier": "Hot" + }, + "resources": [ + { + "name": "default", + "type": "blobServices", + "apiVersion": "[variables('storageApiVersion')]", + "properties": { + "restorePolicy": { + "enabled": true, + "days": 6 + }, + "deleteRetentionPolicy": { + "enabled": true, + "days": 7 }, - "blob": { + "containerDeleteRetentionPolicy": { + "enabled": true, + "days": 7 + }, + "changeFeed": { "enabled": true + }, + "isVersioningEnabled": true, + "cors": { + "corsRules": [ + { + "allowedOrigins": ["*"], + "allowedMethods": [ + "DELETE", + "GET", + "HEAD", + "MERGE", + "POST", + "OPTIONS", + "PUT", + "PATCH" + ], + "maxAgeInSeconds": 86400, + "exposedHeaders": ["*"], + "allowedHeaders": ["*"] + } + ] } }, - "keySource": "Microsoft.Storage" + "dependsOn": ["[variables('fullAccountName')]"] }, + { + "name": "default", + "type": "fileservices", + "apiVersion": "[variables('storageApiVersion')]", + "properties": { + "shareDeleteRetentionPolicy": { + "enabled": true, + "days": 7 + }, + "cors": { + "corsRules": [ + { + "allowedOrigins": ["*"], + "allowedMethods": ["DELETE", "GET", "HEAD", "MERGE", "POST", "OPTIONS", "PUT"], + "maxAgeInSeconds": 86400, + "exposedHeaders": ["*"], + "allowedHeaders": ["*"] + } + ] + } + }, + "dependsOn": ["[variables('fullAccountName')]"] + } + ] + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "[variables('storageApiVersion')]", + "name": "[variables('premiumFileAccountName')]", + "location": "[variables('location')]", + "sku": { + "name": "Premium_LRS", + "tier": "Premium" + }, + "kind": "FileStorage", + "properties": { + "networkAcls": "[variables('networkAcls')]", + "supportsHttpsTrafficOnly": true, + "encryption": "[variables('encryption')]", "accessTier": "Hot" - } + }, + "resources": [ + { + "name": "default", + "type": "fileservices", + "apiVersion": "[variables('storageApiVersion')]", + "properties": { + "cors": { + "corsRules": [ + { + "allowedOrigins": ["*"], + "allowedMethods": ["DELETE", "GET", "HEAD", "MERGE", "POST", "OPTIONS", "PUT"], + "maxAgeInSeconds": 86400, + "exposedHeaders": ["*"], + "allowedHeaders": ["*"] + } + ] + } + }, + "dependsOn": ["[variables('premiumFileAccountName')]"] + } + ] } ], "outputs": { @@ -290,7 +363,55 @@ }, "DFS_ACCOUNT_SAS": { "type": "string", - "value": "[concat('?', listAccountSas(variables('datalakeaccountNameTidy'), variables('storageApiVersion'), variables('accountSasProperties')).accountSasToken)]" + "value": "[concat('?', listAccountSas(variables('datalakeAccountNameTidy'), variables('storageApiVersion'), variables('accountSasProperties')).accountSasToken)]" + }, + "FULL_ACCOUNT_NAME": { + "type": "string", + "value": "[variables('fullAccountName')]" + }, + "FULL_ACCOUNT_KEY": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value]" + }, + "FULL_ACCOUNT_SAS": { + "type": "string", + "value": "[concat('?', listAccountSas(variables('fullAccountNameTidy'), variables('storageApiVersion'), variables('accountSasProperties')).accountSasToken)]" + }, + "FULL_STORAGE_CONNECTION_STRING": { + "type": "string", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('fullAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value, ';EndpointSuffix=', parameters('storageEndpointSuffix'))]" + }, + "SOFT_DELETE_ACCOUNT_NAME": { + "type": "string", + "value": "[variables('fullAccountName')]" + }, + "SOFT_DELETE_ACCOUNT_KEY": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value]" + }, + "SOFT_DELETE_ACCOUNT_SAS": { + "type": "string", + "value": "[concat('?', listAccountSas(variables('fullAccountNameTidy'), variables('storageApiVersion'), variables('accountSasProperties')).accountSasToken)]" + }, + "SOFT_DELETE_STORAGE_CONNECTION_STRING": { + "type": "string", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('fullAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value, ';EndpointSuffix=', parameters('storageEndpointSuffix'))]" + }, + "PREMIUM_FILE_ACCOUNT_NAME": { + "type": "string", + "value": "[variables('fullAccountName')]" + }, + "PREMIUM_FILE_ACCOUNT_KEY": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value]" + }, + "PREMIUM_FILE_ACCOUNT_SAS": { + "type": "string", + "value": "[concat('?', listAccountSas(variables('fullAccountNameTidy'), variables('storageApiVersion'), variables('accountSasProperties')).accountSasToken)]" + }, + "PREMIUM_FILE_STORAGE_CONNECTION_STRING": { + "type": "string", + "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('fullAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('fullAccountName')), variables('storageApiVersion')).keys[0].value, ';EndpointSuffix=', parameters('storageEndpointSuffix'))]" } } }