Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage][File] Add async iterator for listing handles in DirectoryClient #5133

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,92 @@
"recordings": [
{
"method": "PUT",
"url": "https://fakestorageaccount.file.core.windows.net/share156816861416402421",
"url": "https://fakestorageaccount.file.core.windows.net/share156874149465507289",
"query": {
"restype": "share"
},
"requestBody": null,
"status": 201,
"response": "",
"responseHeaders": {
"date": "Wed, 11 Sep 2019 02:23:33 GMT",
"last-modified": "Wed, 11 Sep 2019 02:23:34 GMT",
"date": "Tue, 17 Sep 2019 17:31:34 GMT",
"last-modified": "Tue, 17 Sep 2019 17:31:34 GMT",
"server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
"etag": "\"0x8D7365F0BBD78FF\"",
"x-ms-request-id": "252c6a6d-d01a-0019-1847-684a94000000",
"etag": "\"0x8D73B94E30469F1\"",
"x-ms-request-id": "d2f2ae7e-c01a-006f-6c7d-6d98a2000000",
"x-ms-version": "2019-02-02",
"x-ms-client-request-id": "b83b56c6-a1f9-4207-86cb-005e4b1ff10d",
"x-ms-client-request-id": "829bcb3e-d115-460f-a5fd-7c139b90cf94",
"content-length": "0"
}
},
{
"method": "PUT",
"url": "https://fakestorageaccount.file.core.windows.net/share156816861416402421/dir156816861436804907",
"url": "https://fakestorageaccount.file.core.windows.net/share156874149465507289/dir156874149501008806",
"query": {
"restype": "directory"
},
"requestBody": null,
"status": 201,
"response": "",
"responseHeaders": {
"date": "Wed, 11 Sep 2019 02:23:34 GMT",
"x-ms-file-change-time": "2019-09-11T02:23:34.5012677Z",
"date": "Tue, 17 Sep 2019 17:31:34 GMT",
"x-ms-file-change-time": "2019-09-17T17:31:34.7770317Z",
"x-ms-file-attributes": "Directory",
"x-ms-file-id": "13835128424026341376",
"x-ms-request-server-encrypted": "true",
"x-ms-file-creation-time": "2019-09-11T02:23:34.5012677Z",
"x-ms-file-creation-time": "2019-09-17T17:31:34.7770317Z",
"x-ms-file-parent-id": "0",
"x-ms-file-permission-key": "15292852142319295125*13609941760923454748",
"x-ms-client-request-id": "f9d838a6-7c85-4607-89c4-7228d9966834",
"x-ms-file-permission-key": "15246684120248489204*13496228697838683005",
"x-ms-client-request-id": "4cc2f1db-2416-4b34-bea7-d6588b7c1a06",
"content-length": "0",
"last-modified": "Wed, 11 Sep 2019 02:23:34 GMT",
"last-modified": "Tue, 17 Sep 2019 17:31:34 GMT",
"server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
"etag": "\"0x8D7365F0BDC93C5\"",
"x-ms-request-id": "252c6a70-d01a-0019-1a47-684a94000000",
"x-ms-file-last-write-time": "2019-09-11T02:23:34.5012677Z",
"etag": "\"0x8D73B94E31D6FCD\"",
"x-ms-request-id": "d2f2ae84-c01a-006f-717d-6d98a2000000",
"x-ms-file-last-write-time": "2019-09-17T17:31:34.7770317Z",
"x-ms-version": "2019-02-02"
}
},
{
"method": "GET",
"url": "https://fakestorageaccount.file.core.windows.net/share156816861416402421/dir156816861436804907",
"url": "https://fakestorageaccount.file.core.windows.net/share156830612406803206/dir156830612568607181",
"query": {
"comp": "listhandles"
},
"requestBody": null,
"status": 200,
"response": "<?xml version=\"1.0\" encoding=\"utf-8\"?><EnumerationResults><Entries /><NextMarker /></EnumerationResults>",
"responseHeaders": {
"date": "Wed, 11 Sep 2019 02:23:34 GMT",
"date": "Tue, 17 Sep 2019 17:31:34 GMT",
"server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
"transfer-encoding": "chunked",
"content-type": "application/xml",
"x-ms-request-id": "252c6a72-d01a-0019-1c47-684a94000000",
"x-ms-request-id": "d2f2ae88-c01a-006f-757d-6d98a2000000",
"x-ms-version": "2019-02-02",
"x-ms-client-request-id": "a6b8afa9-69d3-4582-a164-f86c0627c090"
"x-ms-client-request-id": "736f8ef2-6561-4baa-9a73-d9bafce1768f"
}
},
{
"method": "DELETE",
"url": "https://fakestorageaccount.file.core.windows.net/share156816861416402421",
"url": "https://fakestorageaccount.file.core.windows.net/share156874149465507289",
"query": {
"restype": "share"
},
"requestBody": null,
"status": 202,
"response": "",
"responseHeaders": {
"date": "Wed, 11 Sep 2019 02:23:34 GMT",
"date": "Tue, 17 Sep 2019 17:31:35 GMT",
"server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-request-id": "252c6a74-d01a-0019-1e47-684a94000000",
"x-ms-request-id": "d2f2ae8e-c01a-006f-7a7d-6d98a2000000",
"x-ms-version": "2019-02-02",
"x-ms-client-request-id": "159b3b0c-6f95-4378-be4d-0063b26a0e01",
"x-ms-client-request-id": "4c9ae987-f5b9-4400-8673-4c9abb6fd8c2",
"content-length": "0"
}
}
],
"uniqueTestInfo": {
"share": "share156816861416402421",
"dir": "dir156816861436804907"
"share": "share156874149465507289",
"dir": "dir156874149501008806"
}
}
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
let nock = require('nock');

module.exports.testInfo = {"share":"share156816834591106357","dir":"dir156816834643308154"}
module.exports.testInfo = {"share":"share156874146595505350","dir":"dir156874146640309836"}

nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
.put('/share156816834591106357')
.put('/share156874146595505350')
.query(true)
.reply(201, "", [ 'Content-Length',
'0',
'Last-Modified',
'Wed, 11 Sep 2019 02:19:06 GMT',
'Tue, 17 Sep 2019 17:31:05 GMT',
'ETag',
'"0x8D7365E6C084D6C"',
'"0x8D73B94D1F2A754"',
'Server',
'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
'x-ms-request-id',
'8ca535fe-e01a-0033-7447-683fd1000000',
'dd8a603a-301a-0094-0e7d-6d50b8000000',
'x-ms-client-request-id',
'322f17a3-8b10-4cbb-8b42-058f02e9c9a8',
'faa21ea1-6582-476c-aea4-3138a3587106',
'x-ms-version',
'2019-02-02',
'Date',
'Wed, 11 Sep 2019 02:19:06 GMT' ]);
'Tue, 17 Sep 2019 17:31:05 GMT' ]);


nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
.put('/share156816834591106357/dir156816834643308154')
.put('/share156874146595505350/dir156874146640309836')
.query(true)
.reply(201, "", [ 'Content-Length',
'0',
'Last-Modified',
'Wed, 11 Sep 2019 02:19:06 GMT',
'Tue, 17 Sep 2019 17:31:06 GMT',
'ETag',
'"0x8D7365E6C48F294"',
'"0x8D73B94D223E34B"',
'Server',
'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
'x-ms-request-id',
'2515c7fd-701a-0036-4c47-68cbae000000',
'8e38c1f0-901a-005e-477d-6dc375000000',
'x-ms-client-request-id',
'e7a0ede0-42b0-4379-ace2-133300d1d951',
'be2ab265-67d2-48e9-8a6d-64d6457fe217',
'x-ms-version',
'2019-02-02',
'x-ms-file-change-time',
'2019-09-11T02:19:06.7760276Z',
'2019-09-17T17:31:06.2980427Z',
'x-ms-file-last-write-time',
'2019-09-11T02:19:06.7760276Z',
'2019-09-17T17:31:06.2980427Z',
'x-ms-file-creation-time',
'2019-09-11T02:19:06.7760276Z',
'2019-09-17T17:31:06.2980427Z',
'x-ms-file-permission-key',
'15292852142319295125*13609941760923454748',
'15246684120248489204*13496228697838683005',
'x-ms-file-attributes',
'Directory',
'x-ms-file-id',
Expand All @@ -57,11 +57,11 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam
'x-ms-request-server-encrypted',
'true',
'Date',
'Wed, 11 Sep 2019 02:19:06 GMT' ]);
'Tue, 17 Sep 2019 17:31:05 GMT' ]);


nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
.get('/share156816834591106357/dir156816834643308154')
.get('/share156830612406803206/dir156830612568607181')
.query(true)
.reply(200, "<?xml version=\"1.0\" encoding=\"utf-8\"?><EnumerationResults><Entries /><NextMarker /></EnumerationResults>", [ 'Transfer-Encoding',
'chunked',
Expand All @@ -70,32 +70,32 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam
'Server',
'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
'x-ms-request-id',
'ddf4b2fa-701a-003d-2047-68d3da000000',
'7ae875a4-e01a-00d9-637d-6d965a000000',
'x-ms-client-request-id',
'b1121ace-1f29-4fc7-86fe-eac3bd78e88a',
'bc8ea878-a50f-401d-b326-a26813ec5fd8',
'x-ms-version',
'2019-02-02',
'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:19:06 GMT' ]);
'Tue, 17 Sep 2019 17:31:06 GMT' ]);


nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
.delete('/share156816834591106357')
.delete('/share156874146595505350')
.query(true)
.reply(202, "", [ 'Content-Length',
'0',
'Server',
'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
'x-ms-request-id',
'3f32e87c-d01a-0012-7047-6852e0000000',
'd31cdd80-401a-007e-027d-6dafb9000000',
'x-ms-client-request-id',
'034deb60-725a-4361-a0e5-1858f0b3705a',
'2a48d8e8-82a3-444a-9976-2e866be27006',
'x-ms-version',
'2019-02-02',
'Date',
'Wed, 11 Sep 2019 02:19:07 GMT' ]);
'Tue, 17 Sep 2019 17:31:08 GMT' ]);

134 changes: 134 additions & 0 deletions sdk/storage/storage-file/samples/javascript/iterators-handles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
Setup: Enter your storage account name and shared key in main()
*/

const { FileServiceClient, SharedKeyCredential } = require("../.."); // Change to "@azure/storage-file" in your package

async function main() {
// Enter your storage account name, shared key, share name, and directory name.
// Please ensure your directory is mounted
// https://docs.microsoft.com/en-us/azure/storage/files/storage-how-to-use-files-windows
// https://docs.microsoft.com/en-us/azure/storage/files/storage-how-to-use-files-linux
// https://docs.microsoft.com/en-us/azure/storage/files/storage-how-to-use-files-mac
const account = "";
const accountKey = "";
const shareName = "";
const dirName = "";

// Use SharedKeyCredential with storage account and account key
// SharedKeyCredential is only avaiable in Node.js runtime, not in browsers
const sharedKeyCredential = new SharedKeyCredential(account, accountKey);

const serviceClient = new FileServiceClient(
`https://${account}.file.core.windows.net`,
sharedKeyCredential
);

const shareClient = serviceClient.getShareClient(shareName);
const dirClient = shareClient.getDirectoryClient(dirName);

console.log(`List handles`);

// 1. List handles
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}`);
}

console.log(`List handles directly without using iter`);

// 2. Same as the previous example
i = 1;
for await (const handle of dirClient.listHandles()) {
console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
}

console.log(`List handles using iter.next()`);

// 3. Generator syntax .next()
i = 1;
iter = await 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();
}

////////////////////////////////////////////////////////
/////////////// Examples for .byPage() ///////////////
////////////////////////////////////////////////////////

console.log(`List handles by pages`);

// 4. list handles by page
i = 1;
for await (const response of dirClient.listHandles().byPage()) {
if (response.handleList) {
for (const handle of response.handleList) {
console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
}
}
}

console.log(`List handles by pages recursively with max page size`);

// 5. Same as the previous example - passing maxPageSize in the page settings
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}`);
}
}
}

console.log(`List handles by pages using next()`);

// 6. Generator syntax .next()
i = 1;
let iterator = dirClient.listHandles().byPage({ maxPageSize: 2 });
let response = await iterator.next();
while (!response.done) {
if (response.value.handleList) {
for (const handle of response.value.handleList) {
console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
}
}
response = await iterator.next();
}

console.log(`List handles by pages with continuation`);

// 7. Passing marker as an argument (similar to the previous example)
i = 1;
iterator = dirClient.listHandles().byPage({ maxPageSize: 2 });
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.nextMarker;
// Passing next marker as continuationToken
console.log(` continuation`);
iterator = dirClient.listHandles().byPage({ continuationToken: marker, maxPageSize: 2 });
response = await iterator.next();
// Prints 2 more handles assuming you have more than four handles
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}`);
}
}
}

// An async method returns a Promise object, which is compatible with then().catch() coding style.
main()
.then(() => {
console.log("Successfully executed sample.");
})
.catch((err) => {
console.log(err.message);
});
Loading