Skip to content
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
36 changes: 15 additions & 21 deletions sdk/storage/storage-file/samples/typescript/advanced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ async function main() {
// Create a share
const shareName = `newshare${new Date().getTime()}`;
const shareClient = ShareClient.fromFileServiceClient(serviceClient, shareName);
await shareClient.create(Aborter.none);
await shareClient.create();
console.log(`Create share ${shareName} successfully`);

// Create a directory
const directoryName = `newdirectory${new Date().getTime()}`;
const directoryClient = DirectoryClient.fromShareClient(shareClient, directoryName);
await directoryClient.create(Aborter.none);
await directoryClient.create();
console.log(`Create directory ${directoryName} successfully`);

// Upload local file to Azure file parallelly
Expand All @@ -53,24 +53,24 @@ async function main() {

// Parallel uploading with uploadFileToAzureFile in Node.js runtime
// uploadFileToAzureFile is only available in Node.js
await uploadFileToAzureFile(Aborter.none, localFilePath, fileClient, {
await uploadFileToAzureFile(localFilePath, fileClient, {
rangeSize: 4 * 1024 * 1024, // 4MB range size
parallelism: 20, // 20 concurrency
progress: ev => console.log(ev)
progress: (ev) => console.log(ev)
Comment thread
HarshaNalluru marked this conversation as resolved.
});
console.log("uploadFileToAzureFile success");

// Parallel uploading a Readable stream with uploadStreamToAzureFile in Node.js runtime
// uploadStreamToAzureFile is only available in Node.js
await uploadStreamToAzureFile(
Aborter.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
fs.createReadStream(localFilePath),
fileSize,
fileClient,
4 * 1024 * 1024,
20,
{
progress: ev => console.log(ev)
abortSignal: Aborter.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
progress: (ev: any) => console.log(ev)
}
);
console.log("uploadStreamToAzureFile success");
Expand All @@ -79,7 +79,7 @@ async function main() {
// Uncomment following code in browsers because uploadBrowserDataToAzureFile is only available in browsers
/*
const browserFile = document.getElementById("fileinput").files[0];
await uploadBrowserDataToAzureFile(Aborter.none, browserFile, fileClient, {
await uploadBrowserDataToAzureFile(browserFile, fileClient, {
rangeSize: 4 * 1024 * 1024, // 4MB range size
parallelism: 20, // 20 concurrency
progress: ev => console.log(ev)
Expand All @@ -89,22 +89,16 @@ async function main() {
// Parallel downloading an Azure file into Node.js buffer
// downloadAzureFileToBuffer is only available in Node.js
const buffer = Buffer.alloc(fileSize);
await downloadAzureFileToBuffer(
Aborter.timeout(30 * 60 * 1000),
buffer,
fileClient,
0,
undefined,
{
rangeSize: 4 * 1024 * 1024, // 4MB range size
parallelism: 20, // 20 concurrency
progress: ev => console.log(ev)
}
);
await downloadAzureFileToBuffer(buffer, fileClient, 0, undefined, {
abortSignal: Aborter.timeout(30 * 60 * 1000),
rangeSize: 4 * 1024 * 1024, // 4MB range size
parallelism: 20, // 20 concurrency
progress: (ev) => console.log(ev)
});
console.log("downloadAzureFileToBuffer success");

// Delete share
await shareClient.delete(Aborter.none);
await shareClient.delete();
console.log("deleted share");
}

Expand All @@ -113,6 +107,6 @@ main()
.then(() => {
console.log("Successfully executed sample.");
})
.catch(err => {
.catch((err) => {
console.log(err.message);
});
32 changes: 13 additions & 19 deletions sdk/storage/storage-file/samples/typescript/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
*/

import {
Aborter,
StorageClient,
FileServiceClient,
SharedKeyCredential,
Models,
ShareClient,
DirectoryClient,
FileClient,
SharedKeyCredential,
Models
FileClient
} from "../.."; // Change to "@azure/storage-file" in your package

async function main() {
Expand Down Expand Up @@ -38,7 +37,6 @@ async function main() {
let marker;
do {
const listSharesResponse: Models.ServiceListSharesSegmentResponse = await serviceClient.listSharesSegment(
Aborter.none,
marker
);

Expand All @@ -51,65 +49,61 @@ async function main() {
// Create a share
const shareName = `newshare${new Date().getTime()}`;
const shareClient = ShareClient.fromFileServiceClient(serviceClient, shareName);
await shareClient.create(Aborter.none);
await shareClient.create();
console.log(`Create share ${shareName} successfully`);

// Create a directory
const directoryName = `newdirectory${new Date().getTime()}`;
const directoryClient = DirectoryClient.fromShareClient(shareClient, directoryName);
await directoryClient.create(Aborter.none);
await directoryClient.create();
console.log(`Create directory ${directoryName} successfully`);

// Create a file
const content = "Hello World!";
const fileName = "newfile" + new Date().getTime();
const fileClient = FileClient.fromDirectoryClient(directoryClient, fileName);
await fileClient.create(Aborter.none, content.length);
await fileClient.create(content.length);
console.log(`Create file ${fileName} successfully`);

// Upload file range
await fileClient.uploadRange(Aborter.none, content, 0, content.length);
await fileClient.uploadRange(content, 0, content.length);
console.log(`Upload file range "${content}" to ${fileName} successfully`);

// List directories and files
console.log(`List directories and files under directory ${directoryName}`);
marker = undefined;
do {
const listFilesAndDirectoriesResponse: Models.DirectoryListFilesAndDirectoriesSegmentResponse = await directoryClient.listFilesAndDirectoriesSegment(
Aborter.none,
marker
);

marker = listFilesAndDirectoriesResponse.nextMarker;
for (const file of listFilesAndDirectoriesResponse.segment.fileItems) {
console.log(`\tFile: ${file.name}`);
}
for (const directory of listFilesAndDirectoriesResponse.segment
.directoryItems) {
for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) {
console.log(`\tDirectory: ${directory.name}`);
}
} while (marker);

// Get file content from position 0 to the end
// In Node.js, get downloaded data by accessing downloadFileResponse.readableStreamBody
// In browsers, get downloaded data by accessing downloadFileResponse.blobBody
const downloadFileResponse = await fileClient.download(Aborter.none, 0);
const downloadFileResponse = await fileClient.download(0);
console.log(
`Downloaded file content${await streamToString(
downloadFileResponse.readableStreamBody!
)}`
`Downloaded file content${await streamToString(downloadFileResponse.readableStreamBody!)}`
);

// Delete share
await shareClient.delete(Aborter.none);
await shareClient.delete();
console.log(`deleted share ${shareName}`);
}

// A helper method used to read a Node.js readable stream into string
async function streamToString(readableStream: NodeJS.ReadableStream) {
return new Promise((resolve, reject) => {
const chunks: string[] = [];
readableStream.on("data", data => {
readableStream.on("data", (data) => {
chunks.push(data.toString());
});
readableStream.on("end", () => {
Expand All @@ -124,6 +118,6 @@ main()
.then(() => {
console.log("Successfully executed sample.");
})
.catch(err => {
.catch((err) => {
console.log(err.message);
});
12 changes: 6 additions & 6 deletions sdk/storage/storage-file/src/Aborter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ import { AbortSignalLike, isNode } from "@azure/ms-rest-js";
*
* @example
* // Abort without timeout
* await fileClient.uploadRange(Aborter.none, buf, 0, buf.length);
* await fileClient.uploadRange(buf, 0, buf.length);
*
* @example
* // Abort container create in 1000ms
* await fileClient.uploadRange(Aborter.timeout(1000), buf, 0, buf.length);
* await fileClient.uploadRange(buf, 0, buf.length, {abortSignal: Aborter.timeout(1000)});
*
* @example
* // Share aborter cross multiple operations in 30s
* // Upload the same data to 2 different data centers at the same time, abort another when any of them is finished
* const aborter = Aborter.timeout(30 * 1000);
* fileClient1.uploadRange(aborter, buf, 0, buf.length).then(aborter.abort);
* fileClient2.uploadRange(aborter, buf, 0, buf.length).then(aborter.abort);
* fileClient1.uploadRange(buf, 0, buf.length, {abortSignal: aborter}).then(aborter.abort);
* fileClient2.uploadRange(buf, 0, buf.length, {abortSignal: aborter}).then(aborter.abort);
*
* @example
* // Cascaded aborting
* // All operations can't take more than 30 seconds
* const aborter = Aborter.timeout(30 * 1000);
*
* // Following 2 operations can't take more than 25 seconds
* await fileClient.uploadRange(aborter.withTimeout(25 * 1000), buf, 0, buf.length);
* await fileClient.uploadRange(aborter.withTimeout(25 * 1000), buf, 0, buf.length);
* await fileClient.uploadRange(buf, 0, buf.length, {abortSignal: aborter.withTimeout(25 * 1000)});
* await fileClient.uploadRange(buf, 0, buf.length, {abortSignal: aborter.withTimeout(25 * 1000)});
*
* @export
* @class Aborter
Expand Down
43 changes: 27 additions & 16 deletions sdk/storage/storage-file/src/DirectoryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { StorageClient } from "./StorageClient";
import { appendToURLPath } from "./utils/utils.common";

export interface IDirectoryCreateOptions {
abortSignal?: Aborter;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to copy and paste some documentation for abortSignal

/**
* A name-value pair
* to associate with a file storage object.
Expand All @@ -19,6 +20,7 @@ export interface IDirectoryCreateOptions {
}

export interface IDirectoryListFilesAndDirectoriesSegmentOptions {
abortSignal?: Aborter;
/**
* Filters the results to return only entries whose
* name begins with the specified prefix.
Expand All @@ -39,6 +41,18 @@ export interface IDirectoryListFilesAndDirectoriesSegmentOptions {
maxresults?: number;
}

export interface IDirectoryDeleteOptions {
abortSignal?: Aborter;
}

export interface IDirectoryGetPropertiesOptions {
abortSignal?: Aborter;
}

export interface IDirectorySetMetadataOptions {
abortSignal?: Aborter;
}

/**
* A DirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories.
*
Expand Down Expand Up @@ -121,16 +135,14 @@ export class DirectoryClient extends StorageClient {
* Creates a new directory under the specified share or parent directory.
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
*
* @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 {IDirectoryCreateOptions} [options]
* @returns {Promise<Models.DirectoryCreateResponse>}
* @memberof DirectoryClient
*/
public async create(
aborter: Aborter,
options: IDirectoryCreateOptions = {}
): Promise<Models.DirectoryCreateResponse> {
const aborter = options.abortSignal || Aborter.none;
return this.context.create({
...options,
abortSignal: aborter
Expand All @@ -143,12 +155,13 @@ export class DirectoryClient extends StorageClient {
* subdirectories.
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-directory-properties
*
* @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(),
* goto documents of Aborter for more examples about request cancellation
* @returns {Promise<Models.DirectoryGetPropertiesResponse>}
* @memberof DirectoryClient
*/
public async getProperties(aborter: Aborter): Promise<Models.DirectoryGetPropertiesResponse> {
public async getProperties(
options: IDirectoryGetPropertiesOptions = {}
): Promise<Models.DirectoryGetPropertiesResponse> {
const aborter = options.abortSignal || Aborter.none;
return this.context.getProperties({
abortSignal: aborter
});
Expand All @@ -159,12 +172,13 @@ export class DirectoryClient extends StorageClient {
* deleted.
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
*
* @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(),
* goto documents of Aborter for more examples about request cancellation
* @returns {Promise<Models.DirectoryDeleteResponse>}
* @memberof DirectoryClient
*/
public async delete(aborter: Aborter): Promise<Models.DirectoryDeleteResponse> {
public async delete(
options: IDirectoryDeleteOptions = {}
): Promise<Models.DirectoryDeleteResponse> {
const aborter = options.abortSignal || Aborter.none;
return this.context.deleteMethod({
abortSignal: aborter
});
Expand All @@ -174,16 +188,15 @@ export class DirectoryClient extends StorageClient {
* Updates user defined metadata for the specified directory.
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata
*
* @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 {IMetadata} [metadata] If no metadata provided, all existing directory metadata will be removed
* @returns {Promise<Models.DirectorySetMetadataResponse>}
* @memberof DirectoryClient
*/
public async setMetadata(
aborter: Aborter,
metadata?: IMetadata
metadata?: IMetadata,
options: IDirectorySetMetadataOptions = {}
): Promise<Models.DirectorySetMetadataResponse> {
const aborter = options.abortSignal || Aborter.none;
return this.context.setMetadata({
abortSignal: aborter,
metadata
Expand All @@ -195,18 +208,16 @@ export class DirectoryClient extends StorageClient {
* 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 {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} [marker]
* @param {IDirectoryListFilesAndDirectoriesSegmentOptions} [options]
* @returns {Promise<Models.DirectoryListFilesAndDirectoriesSegmentResponse>}
* @memberof DirectoryClient
*/
public async listFilesAndDirectoriesSegment(
aborter: Aborter,
marker?: string,
options: IDirectoryListFilesAndDirectoriesSegmentOptions = {}
): Promise<Models.DirectoryListFilesAndDirectoriesSegmentResponse> {
const aborter = options.abortSignal || Aborter.none;
return this.context.listFilesAndDirectoriesSegment({
abortSignal: aborter,
marker,
Expand Down
Loading