examples: add storage-blob examples (#56)
This commit is contained in:
Родитель
f86645637a
Коммит
5c0337f03c
|
@ -0,0 +1,71 @@
|
|||
# Getting started with samples
|
||||
|
||||
Cloned from [azure-sdk-for-js/storage-blob/samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples).
|
||||
|
||||
## `@azure/monitor-opentelemetry-exporter`
|
||||
|
||||
All changes required to enable exporting trace data to Azure Monitor were made in `tracing.ts` / `tracing.js`.
|
||||
|
||||
In order for auto-instrumentation to take effect, `tracing` must be imported **before** you `import` or `require` any other module into your application!.
|
||||
|
||||
## Get account credentials of your storage account
|
||||
|
||||
- In the [Azure Portal](https://portal.azure.com), go to **Dashboard > Storage > _your-storage-account_**.
|
||||
- Note down the "AccountName", "AccountKey" obtained at **Access keys** and "AccountSAS" from **Shared access signature** under **Settings** tab.
|
||||
Before running any of the samples, update with the credentials you have noted down above.
|
||||
|
||||
### Authenticating with Azure Active Directory
|
||||
|
||||
If you have [registered an application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) with an Azure Active Directory tenant, you can [assign it to an RBAC role](https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad) in your Azure Storage account. This enables you to use the Azure.Identity library to authenticate with Azure Storage as shown in the [azureAdAuth.ts sample](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/storage/storage-blob/samples/typescript/src/azureAdAuth.ts).
|
||||
|
||||
## Javascript sample
|
||||
|
||||
Copy the sample to your samples folder and use `node` to run it.
|
||||
|
||||
```bash
|
||||
node sample.js
|
||||
```
|
||||
|
||||
## Typescript sample
|
||||
|
||||
If you don't have Typescript installed, then use `npm` to install it first.
|
||||
|
||||
```bash
|
||||
npm install -g typescript
|
||||
```
|
||||
|
||||
One way to run Typescript samples is to use `ts-node`. To install `ts-node`, run the below in your sample folder
|
||||
|
||||
```bash
|
||||
npm install -g ts-node
|
||||
```
|
||||
|
||||
Copy the sample to your samples folder and use `ts-node` to run it.
|
||||
|
||||
```bash
|
||||
ts-node sample.ts
|
||||
```
|
||||
|
||||
## Browser sample
|
||||
|
||||
Running these samples in the browser requires a bundler. While we give examples using Webpack, any bundler will do!
|
||||
|
||||
First, install webpack and webpack-cli.
|
||||
|
||||
```bash
|
||||
npm install --save-dev webpack webpack-cli
|
||||
```
|
||||
|
||||
Next, run webpack on the sample code to produce an optimized browser bundle.
|
||||
|
||||
```bash
|
||||
npx webpack sample.js
|
||||
```
|
||||
|
||||
This will produce `dist/main.js`. Reference this file in an HTML file script tag and open the file in a browser to run the sample.
|
||||
|
||||
```html
|
||||
<script src="./dist/main.js"></script>
|
||||
```
|
||||
|
||||
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fstorage%2Fstorage-blob%2Fsamples%2FREADME.png)
|
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
page_type: sample
|
||||
languages:
|
||||
- javascript
|
||||
products:
|
||||
- azure
|
||||
- azure-storage
|
||||
urlFragment: storage-blob-javascript
|
||||
---
|
||||
|
||||
# Azure Storage Blob client library samples for JavaScript
|
||||
|
||||
These sample programs show how to use the JavaScript client libraries for Azure Storage Blobs in some common scenarios.
|
||||
|
||||
| **File Name** | **Description** |
|
||||
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [basic.js][basic] | authenticate with the service using an account name & key (or anonymously with a SAS URL); create and delete containers; create, list, and download a blob |
|
||||
| [withConnString.js][withconnstring] | connect to and authenticate with the service using a connection string |
|
||||
| [sharedKeyCred.js][sharedkeycred] | authenticate with the service using an account name and a shared key |
|
||||
| [anonymousCred.js][anonymouscred] | authenticate with the service anonymously using a SAS URL |
|
||||
| [azureAdAuth.js][azureadauth] | authenticate with the service using Azure Active Directory |
|
||||
| [proxyAuth.js][proxyauth] | connect to the service using a proxy and authenticate with an account name & key |
|
||||
| [iterators-blobs.js][iterators-blobs] | different methods for iterating over blobs in a container, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-containers.js][iterators-containers] | different methods for iterating over containers in an account, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-blobs-hierarchy.js][iterators-blobs-hierarchy] | iterating over blobs by hierarchy, using separators in the blob names, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-without-await.js][iterators-without-await] | iterating over blobs in a container without using `for await` syntax |
|
||||
| [customPipeline.js][custompipeline] | use custom HTTP pipeline options when connecting to the service |
|
||||
| [customizedClientHeaders.js][customizedclientheaders] | use a custom request policy to add metadata to requests, in this case through the custom x-ms-client-request-id header |
|
||||
| [errorsAndResponses.js][errorsandresponses] | demonstrate various errors and responses |
|
||||
| [readingSnapshot.js][readingsnapshot] | create a blob snapshot and read from that snapshot |
|
||||
| [advanced.js][advanced] | use custom logging and pipeline options, then shows some example advanced options when creating containers, listing and downloading blobs, etc. |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The sample are compatible with Node.js >= 8.0.0, except for the samples that use the async `for await` syntax, which require Node.js >= 10.0.0.
|
||||
|
||||
You need [an Azure subscription][freesub] and [an Azure Storage account][azstorage] to run these sample programs. Samples retrieve credentials to access the storage account from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
|
||||
|
||||
Adapting the samples to run in the browser requires some additional consideration. For details, please see the [package README][package].
|
||||
|
||||
## Setup
|
||||
|
||||
To run the samples using the published version of the package:
|
||||
|
||||
1. Install the dependencies using `npm`:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
|
||||
|
||||
3. Run whichever samples you like (note that some samples may require additional setup, see the table above):
|
||||
|
||||
```bash
|
||||
node basic.js
|
||||
```
|
||||
|
||||
Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform):
|
||||
|
||||
```bash
|
||||
npx cross-env ACCOUNT_NAME="<account name>" ACCOUNT_KEY="<account key>" node basic.js
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
|
||||
|
||||
[advanced]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/advanced.js
|
||||
[anonymouscred]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/anonymousCred.js
|
||||
[azureadauth]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/azureAdAuth.js
|
||||
[basic]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/basic.js
|
||||
[customizedclientheaders]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/customizedClientHeaders.js
|
||||
[custompipeline]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/customPipeline.js
|
||||
[errorsandresponses]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/errorsAndResponses.js
|
||||
[iterators-blobs-hierarchy]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/iterators-blobs-hierarchy.js
|
||||
[iterators-blobs]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/iterators-blobs.js
|
||||
[iterators-containers]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/iterators-containers.js
|
||||
[iterators-without-await]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/iterators-without-await.js
|
||||
[proxyauth]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/proxyAuth.js
|
||||
[readingsnapshot]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/readingSnapshot.js
|
||||
[sharedkeycred]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/sharedKeyCred.js
|
||||
[withconnstring]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/javascript/withConnString.js
|
||||
[apiref]: https://docs.microsoft.com/javascript/api/@azure/storage-blob
|
||||
[azstorage]: https://docs.microsoft.com/azure/storage/common/storage-account-overview
|
||||
[freesub]: https://azure.microsoft.com/free/
|
||||
[package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/README.md
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name, SAS and a path pointing to local file in main()
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
const { AbortController } = require("@azure/abort-controller");
|
||||
const { AnonymousCredential, BlobServiceClient, newPipeline } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
// Enabling logging may help uncover useful information about failures.
|
||||
// In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`.
|
||||
// Alternatively, logging can be enabled at runtime by calling `setLogLevel("info");`
|
||||
// `setLogLevel` can be imported from the `@azure/logger` package
|
||||
const { setLogLevel } = require("@azure/logger");
|
||||
setLogLevel("info");
|
||||
|
||||
async function main() {
|
||||
// Fill in following settings before running this sample
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
const localFilePath = "README.md";
|
||||
|
||||
const pipeline = newPipeline(new AnonymousCredential(), {
|
||||
// httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface
|
||||
retryOptions: { maxTries: 4 }, // Retry options
|
||||
userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string
|
||||
keepAliveOptions: {
|
||||
// Keep alive is enabled by default, disable keep alive by setting false
|
||||
enable: false
|
||||
}
|
||||
});
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
pipeline
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
try {
|
||||
await containerClient.create();
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Creating a container fails, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Create a blob
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
|
||||
// Parallel uploading with BlockBlobClient.uploadFile() in Node.js runtime
|
||||
// BlockBlobClient.uploadFile() is only available in Node.js
|
||||
try {
|
||||
await blockBlobClient.uploadFile(localFilePath, {
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("uploadFile succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`uploadFile failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Parallel uploading a Readable stream with BlockBlobClient.uploadStream() in Node.js runtime
|
||||
// BlockBlobClient.uploadStream() is only available in Node.js
|
||||
try {
|
||||
await blockBlobClient.uploadStream(fs.createReadStream(localFilePath), 4 * 1024 * 1024, 20, {
|
||||
abortSignal: AbortController.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("uploadStream succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`uploadStream failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Parallel uploading a browser File/Blob/ArrayBuffer in browsers with BlockBlobClient.uploadBrowserData()
|
||||
// Uncomment following code in browsers because BlockBlobClient.uploadBrowserData() is only available in browsers
|
||||
/*
|
||||
const browserFile = document.getElementById("fileinput").files[0];
|
||||
await blockBlobClient.uploadBrowserData(browserFile, {
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: ev => console.log(ev)
|
||||
});
|
||||
*/
|
||||
|
||||
// Parallel downloading a block blob into Node.js buffer
|
||||
// downloadToBuffer is only available in Node.js
|
||||
const fileSize = fs.statSync(localFilePath).size;
|
||||
const buffer = Buffer.alloc(fileSize);
|
||||
try {
|
||||
await blockBlobClient.downloadToBuffer(buffer, 0, undefined, {
|
||||
abortSignal: AbortController.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("downloadToBuffer succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`downloadToBuffer failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Archive the blob - Log the error codes
|
||||
await blockBlobClient.setAccessTier("Archive");
|
||||
try {
|
||||
// Downloading an archived blockBlob fails
|
||||
console.log("// Downloading an archived blockBlob fails...");
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
// BlobArchived Conflict (409) This operation is not permitted on an archived blob.
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - ${err.details.message}\n`);
|
||||
}
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and SAS in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient, AnonymousCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and SAS
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
|
||||
// Use AnonymousCredential when url already includes a SAS signature
|
||||
const anonymousCredential = new AnonymousCredential();
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
// When using AnonymousCredential, following url should include a valid SAS or support public access
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
anonymousCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
|
||||
Setup :
|
||||
- Reference - Authorize access to blobs and queues with Azure Active Directory from a client application
|
||||
- https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app
|
||||
|
||||
- Register a new AAD application and give permissions to access Azure Storage on behalf of the signed-in user
|
||||
- Register a new application in the Azure Active Directory(in the azure-portal) - https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
|
||||
- In the `API permissions` section, select `Add a permission` and choose `Microsoft APIs`.
|
||||
- Pick `Azure Storage` and select the checkbox next to `user_impersonation` and then click `Add permissions`. This would allow the application to access Azure Storage on behalf of the signed-in user.
|
||||
- Grant access to Azure Blob data with RBAC in the Azure Portal
|
||||
- RBAC roles for blobs and queues - https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-rbac-portal.
|
||||
- In the azure portal, go to your storage-account and assign **Storage Blob Data Contributor** role to the registered AAD application from `Access control (IAM)` tab (in the left-side-navbar of your storage account in the azure-portal).
|
||||
|
||||
- Environment setup for the sample
|
||||
- From the overview page of your AAD Application, note down the `CLIENT ID` and `TENANT ID`. In the "Certificates & Secrets" tab, create a secret and note that down.
|
||||
- Make sure you have AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET as environment variables to successfully execute the sample(Can leverage process.env).
|
||||
*/
|
||||
|
||||
const { BlobServiceClient } = require("@azure/storage-blob");
|
||||
const { DefaultAzureCredential } = require("@azure/identity");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
|
||||
// Azure AD Credential information is required to run this sample:
|
||||
if (
|
||||
!process.env.AZURE_TENANT_ID ||
|
||||
!process.env.AZURE_CLIENT_ID ||
|
||||
!process.env.AZURE_CLIENT_SECRET
|
||||
) {
|
||||
console.warn(
|
||||
"Azure AD authentication information not provided, but it is required to run this sample. Exiting."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
// DefaultAzureCredential will first look for Azure Active Directory (AAD)
|
||||
// client secret credentials in the following environment variables:
|
||||
//
|
||||
// - AZURE_TENANT_ID: The ID of your AAD tenant
|
||||
// - AZURE_CLIENT_ID: The ID of your AAD app registration (client)
|
||||
// - AZURE_CLIENT_SECRET: The client secret for your AAD app registration
|
||||
//
|
||||
// If those environment variables aren't found and your application is deployed
|
||||
// to an Azure VM or App Service instance, the managed service identity endpoint
|
||||
// will be used as a fallback authentication source.
|
||||
const defaultAzureCredential = new DefaultAzureCredential();
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
defaultAzureCredential
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const createContainerResponse = await blobServiceClient
|
||||
.getContainerClient(containerName)
|
||||
.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only avaiable in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
// DefaultAzureCredential will first look for Azure Active Directory (AAD)
|
||||
// client secret credentials in the following environment variables:
|
||||
//
|
||||
// - AZURE_TENANT_ID: The ID of your AAD tenant
|
||||
// - AZURE_CLIENT_ID: The ID of your AAD app registration (client)
|
||||
// - AZURE_CLIENT_SECRET: The client secret for your AAD app registration
|
||||
//
|
||||
// If those environment variables aren't found and your application is deployed
|
||||
// to an Azure VM or App Service instance, the managed service identity endpoint
|
||||
// will be used as a fallback authentication source.
|
||||
// const defaultAzureCredential = new DefaultAzureCredential();
|
||||
|
||||
// You can find more TokenCredential implementations in the [@azure/identity](https://www.npmjs.com/package/@azure/identity) library
|
||||
// to use client secrets, certificates, or managed identities for authentication.
|
||||
|
||||
// Use AnonymousCredential when url already includes a SAS signature
|
||||
// const anonymousCredential = new AnonymousCredential();
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
// When using AnonymousCredential, following url should include a valid SAS or support public access
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// List blobs
|
||||
i = 1;
|
||||
for await (const blob of containerClient.listBlobsFlat()) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// Get blob content from position 0 to the end
|
||||
// In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody
|
||||
// In browsers, get downloaded data by accessing downloadBlockBlobResponse.blobBody
|
||||
const downloadBlockBlobResponse = await blockBlobClient.download(0);
|
||||
console.log(
|
||||
"Downloaded blob content",
|
||||
await streamToString(downloadBlockBlobResponse.readableStreamBody)
|
||||
);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
// A helper method used to read a Node.js readable stream into string
|
||||
async function streamToString(readableStream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
readableStream.on("data", (data) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const {
|
||||
BlobServiceClient,
|
||||
StorageSharedKeyCredential,
|
||||
newPipeline
|
||||
} = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Use sharedKeyCredential, tokenCredential or anonymousCredential to create a pipeline
|
||||
const pipeline = newPipeline(sharedKeyCredential, {
|
||||
// httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface
|
||||
retryOptions: { maxTries: 4 }, // Retry options
|
||||
userAgentOptions: { userAgentPrefix: "Sample V1.0.0" } // Customized telemetry string
|
||||
});
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
pipeline
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
You can create your own policy and inject it into the default pipeline, or create your own Pipeline.
|
||||
A request policy is a filter triggered before and after a HTTP request. With a filter, we can tweak HTTP requests and responses.
|
||||
For example, add a customized header, update URL or create logs. A HTTP pipeline is a group of policy factories.
|
||||
|
||||
Here we provide a sample to demonstrate how to customize the x-ms-client-request-id header for all outgoing HTTP requests.
|
||||
This sample is just to demo the feature. Feel free to move the classes into one file in your code.
|
||||
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const {
|
||||
newPipeline,
|
||||
AnonymousCredential,
|
||||
BlobServiceClient,
|
||||
BaseRequestPolicy
|
||||
} = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
// Create a policy factory with create() method provided
|
||||
class RequestIDPolicyFactory {
|
||||
// Constructor to accept parameters
|
||||
constructor(prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
// create() method needs to create a new RequestIDPolicy object
|
||||
create(nextPolicy, options) {
|
||||
return new RequestIDPolicy(nextPolicy, options, this.prefix);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a policy by extending from BaseRequestPolicy
|
||||
class RequestIDPolicy extends BaseRequestPolicy {
|
||||
constructor(nextPolicy, options, prefix) {
|
||||
super(nextPolicy, options);
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
// Customize HTTP requests and responses by overriding sendRequest
|
||||
// Parameter request is WebResource type
|
||||
async sendRequest(request) {
|
||||
// Customize client request ID header
|
||||
request.headers.set(
|
||||
"x-ms-client-request-id",
|
||||
`${this.prefix}_SOME_PATTERN_${new Date().getTime()}`
|
||||
);
|
||||
|
||||
// response is HttpOperationResponse type
|
||||
const response = await this._nextPolicy.sendRequest(request);
|
||||
|
||||
// Modify response here if needed
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
|
||||
// Create a default pipeline with newPipeline
|
||||
const pipeline = newPipeline(new AnonymousCredential());
|
||||
|
||||
// Inject customized factory into default pipeline
|
||||
pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix"));
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
pipeline
|
||||
);
|
||||
const response = (
|
||||
await blobServiceClient
|
||||
.listContainers()
|
||||
.byPage()
|
||||
.next()
|
||||
).value;
|
||||
|
||||
// Check customized client request ID
|
||||
console.log(response._response.request.headers.get("x-ms-client-request-id"));
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Create Blob Service Client from Account connection string or SAS connection string
|
||||
// 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`
|
||||
const STORAGE_CONNECTION_STRING = process.env.STORAGE_CONNECTION_STRING || "";
|
||||
// Note - Account connection string can only be used in node.
|
||||
const blobServiceClient = BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING);
|
||||
|
||||
// Create a container
|
||||
console.log("// Create a new container..");
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
let containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
let createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully,`);
|
||||
console.log(
|
||||
`requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n`
|
||||
);
|
||||
|
||||
try {
|
||||
// Creating an existing container fails...
|
||||
console.log("// Creating an existing container fails...");
|
||||
createContainerResponse = await containerClient.create();
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
}
|
||||
|
||||
// Create a blockBlobClient
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
let blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
|
||||
try {
|
||||
// Invoke getProperties() on a non existing blob
|
||||
console.log("// Invoke getProperties() on a non existing blob...");
|
||||
await blockBlobClient.getProperties();
|
||||
} catch (err) {
|
||||
console.log(`getProperties() failed as expected,`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
|
||||
// Create a new block blob
|
||||
console.log("// Create a new block blob...");
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully,`);
|
||||
console.log(
|
||||
`requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
|
||||
// Invoke getProperties() on an existing blob
|
||||
console.log("// Invoke getProperties() on an existing blob...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const blobProperties = await blockBlobClient.getProperties();
|
||||
console.log(
|
||||
`getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} `
|
||||
);
|
||||
console.log(
|
||||
`requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n`
|
||||
);
|
||||
|
||||
try {
|
||||
// Downloading from a non existing blob
|
||||
console.log("// Downloading from a non existing blob...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient("invalid" + blobName);
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
console.log(`download() failed as expected,`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
|
||||
// Download blob content
|
||||
console.log("// Download blob content...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const downloadBlockBlobResponse = await blockBlobClient.download();
|
||||
console.log(
|
||||
`Downloaded blob content - ${await streamToString(
|
||||
downloadBlockBlobResponse.readableStreamBody
|
||||
)},`
|
||||
);
|
||||
console.log(
|
||||
`requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Archive the blob
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
await blockBlobClient.setAccessTier("Archive");
|
||||
// Downloading an archived blockBlob fails
|
||||
console.log("// Downloading an archived blockBlob fails...");
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
// BlobArchived Conflict (409) This operation is not permitted on an archived blob.
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - ${err.details.message}\n`);
|
||||
}
|
||||
|
||||
// Delete container
|
||||
try {
|
||||
// Deleting a non-existing container
|
||||
console.log("// Deleting a non-existing container...");
|
||||
containerClient = blobServiceClient.getContainerClient("invalid" + containerName);
|
||||
await containerClient.delete();
|
||||
} catch (err) {
|
||||
console.log(`Deleting a non-existing container fails as expected`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - \n${err.details.message}\n`);
|
||||
|
||||
// Delete container
|
||||
containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
const deleteContainerResponse = await containerClient.delete();
|
||||
console.log("Deleted container successfully -");
|
||||
console.log(
|
||||
`requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// A helper method used to read a Node.js readable stream into string
|
||||
async function streamToString(readableStream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
readableStream.on("data", (data) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,144 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// create some blobs with delimiters in names
|
||||
const content = "hello";
|
||||
const contentByteLength = Buffer.byteLength(content);
|
||||
let blobName = "a1";
|
||||
let blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
let uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "a2";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix1/b1";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix1/b2";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/c";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/d";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/e";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// 1. List blobs by hierarchy
|
||||
console.log("Listing blobs by hierarchy");
|
||||
let iter = containerClient.listBlobsByHierarchy("/");
|
||||
for await (const item of iter) {
|
||||
if (item.kind === "prefix") {
|
||||
console.log(`\tBlobPrefix: ${item.name}`);
|
||||
} else {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Generator syntax .next() and passing a prefix
|
||||
console.log("Listing blobs by hierarchy, specifying a prefix");
|
||||
iter = containerClient.listBlobsByHierarchy("/", { prefix: "prefix1/" });
|
||||
let entity = await iter.next();
|
||||
while (!entity.done) {
|
||||
let item = entity.value;
|
||||
if (item.kind === "prefix") {
|
||||
console.log(`\tBlobPrefix: ${item.name}`);
|
||||
} else {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
entity = await iter.next();
|
||||
}
|
||||
|
||||
// 3. byPage()
|
||||
console.log("Listing blobs by hierarchy by page");
|
||||
for await (const response of containerClient.listBlobsByHierarchy("/").byPage()) {
|
||||
const segment = response.segment;
|
||||
if (segment.blobPrefixes) {
|
||||
for (const prefix of segment.blobPrefixes) {
|
||||
console.log(`\tBlobPrefix: ${prefix.name}`);
|
||||
}
|
||||
}
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. byPage() and passing a prefix and max page size
|
||||
console.log("Listing blobs by hierarchy by page, specifying a prefix and a max page size");
|
||||
let i = 1;
|
||||
for await (const response of containerClient
|
||||
.listBlobsByHierarchy("/", { prefix: "prefix2/sub1/" })
|
||||
.byPage({ maxPageSize: 2 })) {
|
||||
console.log(`Page ${i++}`);
|
||||
const segment = response.segment;
|
||||
if (segment.blobPrefixes) {
|
||||
for (const prefix of segment.blobPrefixes) {
|
||||
console.log(`\tBlobPrefix: ${prefix.name}`);
|
||||
}
|
||||
}
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
for (let index = 0; index < 7; index++) {
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
}
|
||||
|
||||
// 1. List blobs
|
||||
console.log("Listing all blobs using iter");
|
||||
let i = 1;
|
||||
let iter = containerClient.listBlobsFlat();
|
||||
for await (const blob of iter) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// 2. Same as the previous example
|
||||
console.log("Listing all blobs");
|
||||
i = 1;
|
||||
for await (const blob of containerClient.listBlobsFlat()) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// 3. Generator syntax .next()
|
||||
console.log("Listing all blobs using iter.next()");
|
||||
i = 1;
|
||||
iter = containerClient.listBlobsFlat();
|
||||
let blobItem = await iter.next();
|
||||
while (!blobItem.done) {
|
||||
console.log(`Blob ${i++}: ${blobItem.value.name}`);
|
||||
blobItem = await iter.next();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/////////////// Examples for .byPage() ///////////////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
// 4. list containers by page
|
||||
console.log("Listing all blobs by page");
|
||||
i = 1;
|
||||
for await (const response of containerClient.listBlobsFlat().byPage()) {
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Same as the previous example - passing maxPageSize in the page settings
|
||||
console.log("Listing all blobs by page, passing maxPageSize in the page settings");
|
||||
i = 1;
|
||||
for await (const response of containerClient.listBlobsFlat().byPage({ maxPageSize: 20 })) {
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Generator syntax .next()
|
||||
console.log("Listing all blobs by page using iterator.next()");
|
||||
i = 1;
|
||||
let iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 20 });
|
||||
let response = await iterator.next();
|
||||
while (!response.done) {
|
||||
const segment = response.value.segment;
|
||||
for (const blob of segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
response = await iterator.next();
|
||||
}
|
||||
|
||||
// 7. Passing marker as an argument (similar to the previous example)
|
||||
console.log("Listing all blobs by page, using iterator.next() and continuation token");
|
||||
i = 1;
|
||||
iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 20 });
|
||||
response = await iterator.next();
|
||||
let segment = response.value.segment;
|
||||
// Prints 2 blob names
|
||||
for (const blob of segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
// Gets next marker
|
||||
console.log("\tContinuation");
|
||||
let marker = response.value.nextMarker;
|
||||
// Passing next marker as continuationToken
|
||||
iterator = containerClient.listBlobsFlat().byPage({ continuationToken: marker, maxPageSize: 10 });
|
||||
response = await iterator.next();
|
||||
// Prints 5 blob names
|
||||
if (!response.done) {
|
||||
for (const blob of response.value.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
// 1. List Containers
|
||||
console.log("Listing all containers using iter");
|
||||
let i = 1;
|
||||
let iter = blobServiceClient.listContainers();
|
||||
for await (const container of iter) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// 2. Same as the previous example
|
||||
console.log("Listing all containers without iter");
|
||||
i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// 3. Generator syntax .next()
|
||||
console.log("Listing all containers using iter.next()");
|
||||
i = 1;
|
||||
iter = blobServiceClient.listContainers();
|
||||
let containerItem = await iter.next();
|
||||
while (!containerItem.done) {
|
||||
console.log(`Container ${i++}: ${containerItem.value.name}`);
|
||||
containerItem = await iter.next();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/////////////// Examples for .byPage() ///////////////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
// 4. list containers by page
|
||||
console.log("Listing all containers byPage()");
|
||||
i = 1;
|
||||
for await (const response of blobServiceClient.listContainers().byPage()) {
|
||||
if (response.containerItems) {
|
||||
for (const container of response.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Same as the previous example - passing maxPageSize in the page settings
|
||||
console.log("Listing all containers byPage(), passing maxPageSize in the page settings");
|
||||
i = 1;
|
||||
for await (const response of blobServiceClient.listContainers().byPage({ maxPageSize: 20 })) {
|
||||
if (response.containerItems) {
|
||||
for (const container of response.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Generator syntax .next()
|
||||
console.log("Listing all containers byPage(), using iterator.next()");
|
||||
i = 1;
|
||||
let iterator = blobServiceClient.listContainers().byPage({ maxPageSize: 20 });
|
||||
let response = await iterator.next();
|
||||
while (!response.done) {
|
||||
if (response.value.containerItems) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
response = await iterator.next();
|
||||
}
|
||||
|
||||
// 7. Passing marker as an argument (similar to the previous example)
|
||||
console.log("Listing all containers byPage(), using iterator.next() and continuation token");
|
||||
i = 1;
|
||||
iterator = blobServiceClient.listContainers().byPage({ maxPageSize: 2 });
|
||||
response = await iterator.next();
|
||||
// Prints 2 container names
|
||||
if (response.value.containerItems) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
// Gets next marker
|
||||
console.log("\tContinuation");
|
||||
let marker = response.value.nextMarker;
|
||||
// Passing next marker as continuationToken
|
||||
iterator = blobServiceClient
|
||||
.listContainers()
|
||||
.byPage({ continuationToken: marker, maxPageSize: 10 });
|
||||
response = await iterator.next();
|
||||
// Prints 10 container names
|
||||
if (!response.done) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
const numberOfBlobs = 7;
|
||||
for (let i = 0; i < numberOfBlobs; i++) {
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
}
|
||||
|
||||
console.log("Listing all blobs without await");
|
||||
let index = 1;
|
||||
let asyncIter = containerClient.listBlobsFlat();
|
||||
|
||||
function printBlob(result) {
|
||||
if (!result.done) {
|
||||
console.log("Blob " + index++ + ": " + result.value.name);
|
||||
asyncIter.next().then(printBlob);
|
||||
} else {
|
||||
containerClient.delete().then(() => console.log("deleted container"));
|
||||
}
|
||||
}
|
||||
|
||||
asyncIter.next().then(printBlob);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.log(err.message);
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "azure-storage-blob-samples-js",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "Azure Storage Blob client library samples for TypeScript",
|
||||
"engine": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Azure/azure-sdk-for-js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Azure",
|
||||
"Storage",
|
||||
"Blob",
|
||||
"Node.js",
|
||||
"JavaScript"
|
||||
],
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Azure/azure-sdk-for-js#readme",
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "latest",
|
||||
"@azure/identity": "latest",
|
||||
"@azure/storage-blob": "latest",
|
||||
"@azure/monitor-opentelemetry-exporter": "latest",
|
||||
"@opentelemetry/node": "latest",
|
||||
"dotenv": "^8.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^3.0.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// To use the manual proxyOptions below, remove this block
|
||||
if (!process.env.HTTP_PROXY || !process.env.HTTPS_PROXY) {
|
||||
console.warn("Proxy information not provided, but it is required to run this sample. Exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential,
|
||||
// The library tries to load the proxy settings from the environment variables like HTTP_PROXY
|
||||
// Alternatively, the service client accepts the following `proxyOptions` as part of its options:
|
||||
{
|
||||
/*
|
||||
proxyOptions : {
|
||||
// To use these options, remove the section above that checks for HTTP_PROXY or HTTPS_PROXY
|
||||
host: "http://localhost",
|
||||
port: 3128,
|
||||
username: "<username>",
|
||||
password: "<password>"
|
||||
}
|
||||
*/
|
||||
}
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const createContainerResponse = await blobServiceClient
|
||||
.getContainerClient(containerName)
|
||||
.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
If you use BlobClient.download() to download an append blob which is being actively appended,
|
||||
you may get a 412 HTTP error, just like this issue: https://github.com/Azure/azure-storage-js/issues/51
|
||||
|
||||
Recommend solution is to snapshot the append blob, and read from the snapshot blob.
|
||||
|
||||
Reason
|
||||
- blobClient.download() will try to download a blob with a HTTP Get request into a stream.
|
||||
- When a stream unexpectedly ends because of an unreliable network, retry will resume the stream read
|
||||
from that broken point with a new HTTP Get request.
|
||||
- The second HTTP request will use conditional header `IfMatch` with the blob's `ETag`
|
||||
returned in first request to make sure the blob doesn't change when the 2nd retry happens.
|
||||
Otherwise, a 412 conditional header doesn't match error will be returned.
|
||||
- This strict strategy is used to avoid data integrity issues, such as the blob maybe totally over written by someone others.
|
||||
However, this strategy seems avoiding reading from reading a constantly updated log file when a retry happens.
|
||||
|
||||
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blobClient = containerClient.getBlobClient(blobName);
|
||||
const blockBlobClient = blobClient.getBlockBlobClient();
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// Downloading blob from the snapshot
|
||||
console.log("Downloading blob...");
|
||||
const snapshotResponse = await blobClient.createSnapshot();
|
||||
const blobSnapshotClient = blobClient.withSnapshot(snapshotResponse.snapshot);
|
||||
|
||||
const response = await blobSnapshotClient.download(0);
|
||||
console.log(
|
||||
"Reading response to string...",
|
||||
(await blobSnapshotClient.getProperties()).contentLength
|
||||
);
|
||||
|
||||
console.log("Downloaded blob content", await streamToString(response.readableStreamBody));
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
// A helper method used to read a Node.js readable stream into string
|
||||
async function streamToString(readableStream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
readableStream.on("data", (data) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
# Used in most samples. Retrieve these values from a storage account in the Azure Portal.
|
||||
ACCOUNT_NAME=<storage-account-name>
|
||||
ACCOUNT_KEY=<storage-account-key>
|
||||
|
||||
# Used for withConnString
|
||||
STORAGE_CONNECTION_STRING=<storage-account-connection-string>
|
||||
|
||||
# Used for the advanced and anonymousCred tests. Create a SAS token for a storage account in the Azure Portal.
|
||||
ACCOUNT_SAS=<shared-access-signature>
|
||||
|
||||
# Used to authenticate using Azure AD as a service principal for role-based authentication.
|
||||
#
|
||||
# See the documentation for `EnvironmentCredential` at the following link:
|
||||
# https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential
|
||||
AZURE_TENANT_ID=<AD tenant id or name>
|
||||
AZURE_CLIENT_ID=<ID of the user/service principal to authenticate as>
|
||||
AZURE_CLIENT_SECRET=<client secret used to authenticate to Azure AD>
|
||||
|
||||
# To run the proxyAuth sample, set up an HTTP proxy and enter your information:
|
||||
# HTTP_PROXY=http://localhost:3128
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter";
|
||||
import { NodeTracerProvider } from "@opentelemetry/node";
|
||||
import { BatchSpanProcessor } from "@opentelemetry/tracing";
|
||||
import * as azureSdkTracing from "@azure/core-tracing";
|
||||
|
||||
const provider = new NodeTracerProvider();
|
||||
|
||||
const azureExporter = new AzureMonitorTraceExporter({
|
||||
instrumentationKey: "ikey",
|
||||
logger: provider.logger,
|
||||
});
|
||||
|
||||
provider.addSpanProcessor(new BatchSpanProcessor(azureExporter, {
|
||||
bufferSize: 1000, // 1000 spans
|
||||
bufferTimeout: 15000, // 15 seconds
|
||||
}));
|
||||
|
||||
provider.register();
|
||||
|
||||
azureSdkTracing.setTracer(
|
||||
provider.getTracer("example tracer")
|
||||
);
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
const { BlobServiceClient } = require("@azure/storage-blob");
|
||||
|
||||
// Load the .env file if it exists
|
||||
require("dotenv").config();
|
||||
|
||||
async function main() {
|
||||
// Create Blob Service Client from Account connection string or SAS connection string
|
||||
// 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`
|
||||
const STORAGE_CONNECTION_STRING = process.env.STORAGE_CONNECTION_STRING || "";
|
||||
// Note - Account connection string can only be used in node.
|
||||
const blobServiceClient = BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
dist
|
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
page_type: sample
|
||||
languages:
|
||||
- typescript
|
||||
products:
|
||||
- azure
|
||||
- azure-storage
|
||||
urlFragment: storage-blob-typescript
|
||||
---
|
||||
|
||||
# Azure Storage Blob client library samples for TypeScript
|
||||
|
||||
These sample programs show how to use the TypeScript client libraries for Azure Storage Blobs in some common scenarios.
|
||||
|
||||
| **File Name** | **Description** |
|
||||
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [basic.ts][basic] | authenticate with the service using an account name & key (or anonymously with a SAS URL); create and delete containers; create, list, and download a blob |
|
||||
| [withConnString.ts][withconnstring] | connect to and authenticate with the service using a connection string |
|
||||
| [sharedKeyCred.ts][sharedkeycred] | authenticate with the service using an account name and a shared key |
|
||||
| [anonymousCred.ts][anonymouscred] | authenticate with the service anonymously using a SAS URL |
|
||||
| [azureAdAuth.ts][azureadauth] | authenticate with the service using Azure Active Directory |
|
||||
| [proxyAuth.ts][proxyauth] | connect to the service using a proxy and authenticate with an account name & key |
|
||||
| [iterators-blobs.ts][iterators-blobs] | different methods for iterating over blobs in a container, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-containers.ts][iterators-containers] | different methods for iterating over containers in an account, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-blobs-hierarchy.ts][iterators-blobs-hierarchy] | iterating over blobs by hierarchy, using separators in the blob names, showing options for paging, resuming paging, etc. |
|
||||
| [iterators-without-await.ts][iterators-without-await] | iterating over blobs in a container without using `for await` syntax |
|
||||
| [customPipeline.ts][custompipeline] | use custom HTTP pipeline options when connecting to the service |
|
||||
| [customizedClientHeaders.ts][customizedclientheaders] | use a custom request policy to add metadata to requests, in this case through the custom x-ms-client-request-id header |
|
||||
| [errorsAndResponses.ts][errorsandresponses] | demonstrate various errors and responses |
|
||||
| [readingSnapshot.ts][readingsnapshot] | create a blob snapshot and read from that snapshot |
|
||||
| [advanced.ts][advanced] | use custom logging and pipeline options, then shows some example advanced options when creating containers, listing and downloading blobs, etc. |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The samples are compatible with Node.js >= 8.0.0, except for the samples that use the async `for await` syntax, which require a Node.js >= 10.0.0.
|
||||
|
||||
Before running the samples in Node, they must be compiled to JavaScript using the TypeScript compiler. For more information on TypeScript, see the [TypeScript documentation][typescript]. Install the TypeScript compiler using
|
||||
|
||||
```bash
|
||||
npm install -g typescript
|
||||
```
|
||||
|
||||
You need [an Azure subscription][freesub] and [an Azure Storage account][azstorage] to run these sample programs. Samples retrieve credentials to access the storage account from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
|
||||
|
||||
Adapting the samples to run in the browser requires some additional consideration. For details, please see the [package README][package].
|
||||
|
||||
## Setup
|
||||
|
||||
To run the samples using the published version of the package:
|
||||
|
||||
1. Install the dependencies using `npm`:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Compile the samples
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
|
||||
|
||||
4. Run whichever samples you like (note that some samples may require additional setup, see the table above):
|
||||
|
||||
```bash
|
||||
node dist/basic.js
|
||||
```
|
||||
|
||||
Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform):
|
||||
|
||||
```bash
|
||||
npx cross-env ACCOUNT_NAME="<account name>" ACCOUNT_KEY="<account key>" node dist/basic.js
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
|
||||
|
||||
[advanced]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/advanced.ts
|
||||
[anonymouscred]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/anonymousCred.ts
|
||||
[azureadauth]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/azureAdAuth.ts
|
||||
[basic]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/basic.ts
|
||||
[customizedclientheaders]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/customizedClientHeaders.ts
|
||||
[custompipeline]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/customPipeline.ts
|
||||
[errorsandresponses]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/errorsAndResponses.ts
|
||||
[iterators-blobs-hierarchy]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/iterators-blobs-hierarchy.ts
|
||||
[iterators-blobs]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/iterators-blobs.ts
|
||||
[iterators-containers]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/iterators-containers.ts
|
||||
[iterators-without-await]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/iterators-without-await.ts
|
||||
[proxyauth]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/proxyAuth.ts
|
||||
[readingsnapshot]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/readingSnapshot.ts
|
||||
[sharedkeycred]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/sharedKeyCred.ts
|
||||
[withconnstring]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/samples/typescript/src/withConnString.ts
|
||||
[apiref]: https://docs.microsoft.com/javascript/api/@azure/storage-blob
|
||||
[azstorage]: https://docs.microsoft.com/azure/storage/common/storage-account-overview
|
||||
[freesub]: https://azure.microsoft.com/free/
|
||||
[package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob/README.md
|
||||
[typescript]: https://www.typescriptlang.org/docs/home.html
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "azure-storage-blob-samples-ts",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "Azure Storage Blob client library samples for TypeScript",
|
||||
"engine": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prebuild": "rimraf dist/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Azure/azure-sdk-for-js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Azure",
|
||||
"Storage",
|
||||
"Blob",
|
||||
"Node.js",
|
||||
"TypeScript"
|
||||
],
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Azure/azure-sdk-for-js#readme",
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "latest",
|
||||
"@azure/identity": "latest",
|
||||
"@azure/storage-blob": "latest",
|
||||
"@azure/monitor-opentelemetry-exporter": "latest",
|
||||
"@opentelemetry/node": "latest",
|
||||
"dotenv": "^8.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^3.9.6"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# Used in most samples. Retrieve these values from a storage account in the Azure Portal.
|
||||
ACCOUNT_NAME=<storage-account-name>
|
||||
ACCOUNT_KEY=<storage-account-key>
|
||||
|
||||
# Used for withConnString
|
||||
STORAGE_CONNECTION_STRING=<storage-account-connection-string>
|
||||
|
||||
# Used for the advanced and anonymousCred tests. Create a SAS token for a storage account in the Azure Portal.
|
||||
ACCOUNT_SAS=<shared-access-signature>
|
||||
|
||||
# Used to authenticate using Azure AD as a service principal for role-based authentication.
|
||||
#
|
||||
# See the documentation for `EnvironmentCredential` at the following link:
|
||||
# https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential
|
||||
AZURE_TENANT_ID=<AD tenant id or name>
|
||||
AZURE_CLIENT_ID=<ID of the user/service principal to authenticate as>
|
||||
AZURE_CLIENT_SECRET=<client secret used to authenticate to Azure AD>
|
||||
|
||||
# To run the proxyAuth sample, set up an HTTP proxy and enter your information:
|
||||
# HTTP_PROXY=http://localhost:3128
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name, SAS and a path pointing to local file in main()
|
||||
*/
|
||||
|
||||
import * as fs from "fs";
|
||||
import { AbortController } from "@azure/abort-controller";
|
||||
import { AnonymousCredential, BlobServiceClient, newPipeline } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
// Enabling logging may help uncover useful information about failures.
|
||||
// In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`.
|
||||
// Alternatively, logging can be enabled at runtime by calling `setLogLevel("info");`
|
||||
// `setLogLevel` can be imported from the `@azure/logger` package
|
||||
import { setLogLevel } from "@azure/logger";
|
||||
setLogLevel("info");
|
||||
|
||||
export async function main() {
|
||||
// Fill in following settings before running this sample
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
const localFilePath = "README.md";
|
||||
|
||||
const pipeline = newPipeline(new AnonymousCredential(), {
|
||||
// httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface
|
||||
retryOptions: { maxTries: 4 }, // Retry options
|
||||
userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string
|
||||
keepAliveOptions: {
|
||||
// Keep alive is enabled by default, disable keep alive by setting false
|
||||
enable: false
|
||||
}
|
||||
});
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
pipeline
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
try {
|
||||
await containerClient.create();
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Creating a container fails, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Create a blob
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
|
||||
// Parallel uploading with BlockBlobClient.uploadFile() in Node.js runtime
|
||||
// BlockBlobClient.uploadFile() is only available in Node.js
|
||||
try {
|
||||
await blockBlobClient.uploadFile(localFilePath, {
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("uploadFile succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`uploadFile failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Parallel uploading a Readable stream with BlockBlobClient.uploadStream() in Node.js runtime
|
||||
// BlockBlobClient.uploadStream() is only available in Node.js
|
||||
try {
|
||||
await blockBlobClient.uploadStream(fs.createReadStream(localFilePath), 4 * 1024 * 1024, 20, {
|
||||
abortSignal: AbortController.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("uploadStream succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`uploadStream failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Parallel uploading a browser File/Blob/ArrayBuffer in browsers with BlockBlobClient.uploadBrowserData()
|
||||
// Uncomment following code in browsers because BlockBlobClient.uploadBrowserData() is only available in browsers
|
||||
/*
|
||||
const browserFile = document.getElementById("fileinput").files[0];
|
||||
await blockBlobClient.uploadBrowserData(browserFile, {
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: ev => console.log(ev)
|
||||
});
|
||||
*/
|
||||
|
||||
// Parallel downloading a block blob into Node.js buffer
|
||||
// downloadToBuffer is only available in Node.js
|
||||
const fileSize = fs.statSync(localFilePath).size;
|
||||
const buffer = Buffer.alloc(fileSize);
|
||||
try {
|
||||
await blockBlobClient.downloadToBuffer(buffer, 0, undefined, {
|
||||
abortSignal: AbortController.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins
|
||||
blockSize: 4 * 1024 * 1024, // 4MB block size
|
||||
concurrency: 20, // 20 concurrency
|
||||
onProgress: (ev) => console.log(ev)
|
||||
});
|
||||
console.log("downloadToBuffer succeeds");
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`downloadToBuffer failed, requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
}
|
||||
|
||||
// Archive the blob - Log the error codes
|
||||
await blockBlobClient.setAccessTier("Archive");
|
||||
try {
|
||||
// Downloading an archived blockBlob fails
|
||||
console.log("// Downloading an archived blockBlob fails...");
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
// BlobArchived Conflict (409) This operation is not permitted on an archived blob.
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - ${err.details.message}\n`);
|
||||
}
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and SAS in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient, AnonymousCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and SAS
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
|
||||
// Use AnonymousCredential when url already includes a SAS signature
|
||||
const anonymousCredential = new AnonymousCredential();
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
// When using AnonymousCredential, following url should include a valid SAS or support public access
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
anonymousCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
|
||||
Setup :
|
||||
- Reference - Authorize access to blobs and queues with Azure Active Directory from a client application
|
||||
- https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app
|
||||
|
||||
- Register a new AAD application and give permissions to access Azure Storage on behalf of the signed-in user
|
||||
- Register a new application in the Azure Active Directory(in the azure-portal) - https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
|
||||
- In the `API permissions` section, select `Add a permission` and choose `Microsoft APIs`.
|
||||
- Pick `Azure Storage` and select the checkbox next to `user_impersonation` and then click `Add permissions`. This would allow the application to access Azure Storage on behalf of the signed-in user.
|
||||
- Grant access to Azure Blob data with RBAC in the Azure Portal
|
||||
- RBAC roles for blobs and queues - https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-rbac-portal.
|
||||
- In the azure portal, go to your storage-account and assign **Storage Blob Data Contributor** role to the registered AAD application from `Access control (IAM)` tab (in the left-side-navbar of your storage account in the azure-portal).
|
||||
|
||||
- Environment setup for the sample
|
||||
- From the overview page of your AAD Application, note down the `CLIENT ID` and `TENANT ID`. In the "Certificates & Secrets" tab, create a secret and note that down.
|
||||
- Make sure you have AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET as environment variables to successfully execute the sample(Can leverage process.env).
|
||||
*/
|
||||
|
||||
import { BlobServiceClient } from "@azure/storage-blob";
|
||||
import { DefaultAzureCredential } from "@azure/identity";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
|
||||
// Azure AD Credential information is required to run this sample:
|
||||
if (
|
||||
!process.env.AZURE_TENANT_ID ||
|
||||
!process.env.AZURE_CLIENT_ID ||
|
||||
!process.env.AZURE_CLIENT_SECRET
|
||||
) {
|
||||
console.warn(
|
||||
"Azure AD authentication information not provided, but it is required to run this sample. Exiting."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
// DefaultAzureCredential will first look for Azure Active Directory (AAD)
|
||||
// client secret credentials in the following environment variables:
|
||||
//
|
||||
// - AZURE_TENANT_ID: The ID of your AAD tenant
|
||||
// - AZURE_CLIENT_ID: The ID of your AAD app registration (client)
|
||||
// - AZURE_CLIENT_SECRET: The client secret for your AAD app registration
|
||||
//
|
||||
// If those environment variables aren't found and your application is deployed
|
||||
// to an Azure VM or App Service instance, the managed service identity endpoint
|
||||
// will be used as a fallback authentication source.
|
||||
const defaultAzureCredential = new DefaultAzureCredential();
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
defaultAzureCredential
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const createContainerResponse = await blobServiceClient
|
||||
.getContainerClient(containerName)
|
||||
.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
import {
|
||||
BlobServiceClient,
|
||||
StorageSharedKeyCredential,
|
||||
BlobDownloadResponseModel
|
||||
} from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// ONLY AVAILABLE IN NODE.JS RUNTIME
|
||||
// DefaultAzureCredential will first look for Azure Active Directory (AAD)
|
||||
// client secret credentials in the following environment variables:
|
||||
//
|
||||
// - AZURE_TENANT_ID: The ID of your AAD tenant
|
||||
// - AZURE_CLIENT_ID: The ID of your AAD app registration (client)
|
||||
// - AZURE_CLIENT_SECRET: The client secret for your AAD app registration
|
||||
//
|
||||
// If those environment variables aren't found and your application is deployed
|
||||
// to an Azure VM or App Service instance, the managed service identity endpoint
|
||||
// will be used as a fallback authentication source.
|
||||
// const defaultAzureCredential = new DefaultAzureCredential();
|
||||
|
||||
// You can find more TokenCredential implementations in the [@azure/identity](https://www.npmjs.com/package/@azure/identity) library
|
||||
// to use client secrets, certificates, or managed identities for authentication.
|
||||
|
||||
// Use AnonymousCredential when url already includes a SAS signature
|
||||
// const anonymousCredential = new AnonymousCredential();
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
// When using AnonymousCredential, following url should include a valid SAS or support public access
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Create a blob
|
||||
const content = "hello, 你好";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// List blobs
|
||||
i = 1;
|
||||
for await (const blob of containerClient.listBlobsFlat()) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// Get blob content from position 0 to the end
|
||||
// In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody
|
||||
// In browsers, get downloaded data by accessing downloadBlockBlobResponse.blobBody
|
||||
const downloadBlockBlobResponse: BlobDownloadResponseModel = await blockBlobClient.download(0);
|
||||
console.log(
|
||||
"Downloaded blob content",
|
||||
await streamToString(downloadBlockBlobResponse.readableStreamBody!)
|
||||
);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient, StorageSharedKeyCredential, newPipeline } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Use sharedKeyCredential, tokenCredential or anonymousCredential to create a pipeline
|
||||
const pipeline = newPipeline(sharedKeyCredential, {
|
||||
// httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface
|
||||
retryOptions: { maxTries: 4 }, // Retry options
|
||||
userAgentOptions: { userAgentPrefix: "Sample V1.0.0" } // Customized telemetry string
|
||||
});
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
pipeline
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
You can create your own policy and inject it into the default pipeline, or create your own Pipeline.
|
||||
A request policy is a filter triggered before and after a HTTP request. With a filter, we can tweak HTTP requests and responses.
|
||||
For example, add a customized header, update URL or create logs. A HTTP pipeline is a group of policy factories.
|
||||
|
||||
Here we provide a sample to demonstrate how to customize the x-ms-client-request-id header for all outgoing HTTP requests.
|
||||
This sample is just to demo the feature. Feel free to move the classes into one file in your code.
|
||||
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import {
|
||||
newPipeline,
|
||||
AnonymousCredential,
|
||||
BlobServiceClient,
|
||||
BaseRequestPolicy,
|
||||
WebResource,
|
||||
RequestPolicy,
|
||||
RequestPolicyOptions
|
||||
} from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
// Create a policy factory with create() method provided
|
||||
class RequestIDPolicyFactory {
|
||||
prefix: string;
|
||||
// Constructor to accept parameters
|
||||
constructor(prefix: string) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
// create() method needs to create a new RequestIDPolicy object
|
||||
create(nextPolicy: RequestPolicy, options: RequestPolicyOptions) {
|
||||
return new RequestIDPolicy(nextPolicy, options, this.prefix);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a policy by extending from BaseRequestPolicy
|
||||
class RequestIDPolicy extends BaseRequestPolicy {
|
||||
prefix: string;
|
||||
constructor(nextPolicy: RequestPolicy, options: RequestPolicyOptions, prefix: string) {
|
||||
super(nextPolicy, options);
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
// Customize HTTP requests and responses by overriding sendRequest
|
||||
// Parameter request is WebResource type
|
||||
async sendRequest(request: WebResource) {
|
||||
// Customize client request ID header
|
||||
request.headers.set(
|
||||
"x-ms-client-request-id",
|
||||
`${this.prefix}_SOME_PATTERN_${new Date().getTime()}`
|
||||
);
|
||||
|
||||
// response is HttpOperationResponse type
|
||||
const response = await this._nextPolicy.sendRequest(request);
|
||||
|
||||
// Modify response here if needed
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// Main function
|
||||
export async function main() {
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountSas = process.env.ACCOUNT_SAS || "";
|
||||
|
||||
// Create a default pipeline with newPipeline
|
||||
const pipeline = newPipeline(new AnonymousCredential());
|
||||
|
||||
// Inject customized factory into default pipeline
|
||||
pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix"));
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net${accountSas}`,
|
||||
pipeline
|
||||
);
|
||||
const response = (
|
||||
await blobServiceClient
|
||||
.listContainers()
|
||||
.byPage()
|
||||
.next()
|
||||
).value;
|
||||
|
||||
// Check customized client request ID
|
||||
console.log(response._response.request.headers.get("x-ms-client-request-id"));
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,160 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Create Blob Service Client from Account connection string or SAS connection string
|
||||
// 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`
|
||||
const STORAGE_CONNECTION_STRING = process.env.STORAGE_CONNECTION_STRING || "";
|
||||
// Note - Account connection string can only be used in node.
|
||||
const blobServiceClient = BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING);
|
||||
|
||||
// Create a container
|
||||
console.log("// Create a new container..");
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
let containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
let createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully,`);
|
||||
console.log(
|
||||
`requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n`
|
||||
);
|
||||
|
||||
try {
|
||||
// Creating an existing container fails...
|
||||
console.log("// Creating an existing container fails...");
|
||||
createContainerResponse = await containerClient.create();
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
}
|
||||
|
||||
// Create a blockBlobClient
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
let blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
|
||||
try {
|
||||
// Invoke getProperties() on a non existing blob
|
||||
console.log("// Invoke getProperties() on a non existing blob...");
|
||||
await blockBlobClient.getProperties();
|
||||
} catch (err) {
|
||||
console.log(`getProperties() failed as expected,`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
|
||||
// Create a new block blob
|
||||
console.log("// Create a new block blob...");
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully,`);
|
||||
console.log(
|
||||
`requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
|
||||
// Invoke getProperties() on an existing blob
|
||||
console.log("// Invoke getProperties() on an existing blob...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const blobProperties = await blockBlobClient.getProperties();
|
||||
console.log(
|
||||
`getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} `
|
||||
);
|
||||
console.log(
|
||||
`requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n`
|
||||
);
|
||||
|
||||
try {
|
||||
// Downloading from a non existing blob
|
||||
console.log("// Downloading from a non existing blob...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient("invalid" + blobName);
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
console.log(`download() failed as expected,`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`
|
||||
);
|
||||
|
||||
// Download blob content
|
||||
console.log("// Download blob content...");
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const downloadBlockBlobResponse = await blockBlobClient.download();
|
||||
console.log(
|
||||
`Downloaded blob content - ${await streamToString(
|
||||
downloadBlockBlobResponse.readableStreamBody!
|
||||
)},`
|
||||
);
|
||||
console.log(
|
||||
`requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Archive the blob
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
await blockBlobClient.setAccessTier("Archive");
|
||||
// Downloading an archived blockBlob fails
|
||||
console.log("// Downloading an archived blockBlob fails...");
|
||||
await blockBlobClient.download();
|
||||
} catch (err) {
|
||||
// BlobArchived Conflict (409) This operation is not permitted on an archived blob.
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - ${err.details.message}\n`);
|
||||
}
|
||||
|
||||
// Delete container
|
||||
try {
|
||||
// Deleting a non-existing container
|
||||
console.log("// Deleting a non-existing container...");
|
||||
containerClient = blobServiceClient.getContainerClient("invalid" + containerName);
|
||||
await containerClient.delete();
|
||||
} catch (err) {
|
||||
console.log(`Deleting a non-existing container fails as expected`);
|
||||
console.log(
|
||||
`requestId - ${err.details.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`
|
||||
);
|
||||
console.log(`error message - \n${err.details.message}\n`);
|
||||
|
||||
// Delete container
|
||||
containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
const deleteContainerResponse = await containerClient.delete();
|
||||
console.log("Deleted container successfully -");
|
||||
console.log(
|
||||
`requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
import { ContainerClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// create some blobs with delimiters in names
|
||||
const content = "hello";
|
||||
const contentByteLength = Buffer.byteLength(content);
|
||||
let blobName = "a1";
|
||||
let blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
let uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "a2";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix1/b1";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix1/b2";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/c";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/d";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
blobName = "prefix2/sub1/e";
|
||||
blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
uploadBlobResponse = await blockBlobClient.upload(content, contentByteLength);
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// 1. List blobs by hierarchy
|
||||
console.log("Listing blobs by hierarchy");
|
||||
let iter = containerClient.listBlobsByHierarchy("/");
|
||||
for await (const item of iter) {
|
||||
if (item.kind === "prefix") {
|
||||
console.log(`\tBlobPrefix: ${item.name}`);
|
||||
} else {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Generator syntax .next() and passing a prefix
|
||||
console.log("Listing blobs by hierarchy, specifying a prefix");
|
||||
iter = containerClient.listBlobsByHierarchy("/", { prefix: "prefix1/" });
|
||||
let entity = await iter.next();
|
||||
while (!entity.done) {
|
||||
let item = entity.value;
|
||||
if (item.kind === "prefix") {
|
||||
console.log(`\tBlobPrefix: ${item.name}`);
|
||||
} else {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
entity = await iter.next();
|
||||
}
|
||||
|
||||
// 3. byPage()
|
||||
console.log("Listing blobs by hierarchy by page");
|
||||
for await (const response of containerClient.listBlobsByHierarchy("/").byPage()) {
|
||||
const segment = response.segment;
|
||||
if (segment.blobPrefixes) {
|
||||
for (const prefix of segment.blobPrefixes) {
|
||||
console.log(`\tBlobPrefix: ${prefix.name}`);
|
||||
}
|
||||
}
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. byPage() and passing a prefix and max page size
|
||||
console.log("Listing blobs by hierarchy by page, specifying a prefix and a max page size");
|
||||
let i = 1;
|
||||
for await (const response of containerClient
|
||||
.listBlobsByHierarchy("/", { prefix: "prefix2/sub1/" })
|
||||
.byPage({ maxPageSize: 2 })) {
|
||||
console.log(`Page ${i++}`);
|
||||
const segment = response.segment;
|
||||
if (segment.blobPrefixes) {
|
||||
for (const prefix of segment.blobPrefixes) {
|
||||
console.log(`\tBlobPrefix: ${prefix.name}`);
|
||||
}
|
||||
}
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(
|
||||
`\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter connection string of your storage account name in main()
|
||||
*/
|
||||
|
||||
import { ContainerClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
for (let index = 0; index < 7; index++) {
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
}
|
||||
|
||||
// 1. List blobs
|
||||
console.log("Listing all blobs using iter");
|
||||
let i = 1;
|
||||
let iter = containerClient.listBlobsFlat();
|
||||
for await (const blob of iter) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// 2. Same as the previous example
|
||||
console.log("Listing all blobs");
|
||||
i = 1;
|
||||
for await (const blob of containerClient.listBlobsFlat()) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
|
||||
// 3. Generator syntax .next()
|
||||
console.log("Listing all blobs using iter.next()");
|
||||
i = 1;
|
||||
iter = containerClient.listBlobsFlat();
|
||||
let blobItem = await iter.next();
|
||||
while (!blobItem.done) {
|
||||
console.log(`Blob ${i++}: ${blobItem.value.name}`);
|
||||
blobItem = await iter.next();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/////////////// Examples for .byPage() ///////////////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
// 4. list containers by page
|
||||
console.log("Listing all blobs by page");
|
||||
i = 1;
|
||||
for await (const response of containerClient.listBlobsFlat().byPage()) {
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Same as the previous example - passing maxPageSize in the page settings
|
||||
console.log("Listing all blobs by page, passing maxPageSize in the page settings");
|
||||
i = 1;
|
||||
for await (const response of containerClient.listBlobsFlat().byPage({ maxPageSize: 20 })) {
|
||||
for (const blob of response.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Generator syntax .next()
|
||||
console.log("Listing all blobs by page using iterator.next()");
|
||||
i = 1;
|
||||
let iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 20 });
|
||||
let response = await iterator.next();
|
||||
while (!response.done) {
|
||||
const segment = response.value.segment;
|
||||
for (const blob of segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
response = await iterator.next();
|
||||
}
|
||||
|
||||
// 7. Passing marker as an argument (similar to the previous example)
|
||||
console.log("Listing all blobs by page, using iterator.next() and continuation token");
|
||||
i = 1;
|
||||
iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 2 });
|
||||
response = await iterator.next();
|
||||
let segment = response.value.segment;
|
||||
// Prints 2 blob names
|
||||
for (const blob of segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
// Gets next marker
|
||||
console.log("\tContinuation");
|
||||
let marker = response.value.continuationToken;
|
||||
// Passing next marker as continuationToken
|
||||
iterator = containerClient.listBlobsFlat().byPage({ continuationToken: marker, maxPageSize: 10 });
|
||||
response = await iterator.next();
|
||||
// Prints 5 blob names
|
||||
if (!response.done) {
|
||||
for (const blob of response.value.segment.blobItems) {
|
||||
console.log(`Blob ${i++}: ${blob.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
await containerClient.delete();
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
// 1. List Containers
|
||||
let i = 1;
|
||||
let iter = blobServiceClient.listContainers();
|
||||
for await (const container of iter) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// 2. Same as the previous example
|
||||
i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// 3. Generator syntax .next()
|
||||
i = 1;
|
||||
iter = blobServiceClient.listContainers();
|
||||
let containerItem = await iter.next();
|
||||
while (!containerItem.done) {
|
||||
console.log(`Container ${i++}: ${containerItem.value.name}`);
|
||||
containerItem = await iter.next();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/////////////// Examples for .byPage() ///////////////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
// 4. list containers by page
|
||||
i = 1;
|
||||
for await (const response of blobServiceClient.listContainers().byPage()) {
|
||||
if (response.containerItems) {
|
||||
for (const container of response.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Same as the previous example - passing maxPageSize in the page settings
|
||||
i = 1;
|
||||
for await (const response of blobServiceClient.listContainers().byPage({ maxPageSize: 20 })) {
|
||||
if (response.containerItems) {
|
||||
for (const container of response.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Generator syntax .next()
|
||||
i = 1;
|
||||
let iterator = blobServiceClient.listContainers().byPage({ maxPageSize: 20 });
|
||||
let response = await iterator.next();
|
||||
while (!response.done) {
|
||||
if (response.value.containerItems) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
response = await iterator.next();
|
||||
}
|
||||
|
||||
// 7. Passing marker as an argument (similar to the previous example)
|
||||
i = 1;
|
||||
iterator = blobServiceClient.listContainers().byPage({ maxPageSize: 2 });
|
||||
response = await iterator.next();
|
||||
// Prints 2 container names
|
||||
if (response.value.containerItems) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
// Gets next marker
|
||||
let marker = response.value.continuationToken;
|
||||
// Passing next marker as continuationToken
|
||||
iterator = blobServiceClient
|
||||
.listContainers()
|
||||
.byPage({ continuationToken: marker, maxPageSize: 10 });
|
||||
response = await iterator.next();
|
||||
// Prints 10 container names
|
||||
if (response.value.containerItems) {
|
||||
for (const container of response.value.containerItems) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
import { ContainerClient, StorageSharedKeyCredential, BlobItem } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
const numberOfBlobs = 7;
|
||||
for (let i = 0; i < numberOfBlobs; i++) {
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
}
|
||||
|
||||
console.log("Listing all blobs without await");
|
||||
let index = 1;
|
||||
let asyncIter = containerClient.listBlobsFlat();
|
||||
|
||||
function printBlob(result: { done?: boolean; value: BlobItem }) {
|
||||
if (!result.done) {
|
||||
console.log("Blob " + index++ + ": " + result.value.name);
|
||||
asyncIter.next().then(printBlob);
|
||||
} else {
|
||||
containerClient.delete().then(() => console.log("deleted container"));
|
||||
}
|
||||
}
|
||||
|
||||
asyncIter.next().then(printBlob);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.log(err.message);
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// To use the manual proxyOptions below, remove this block
|
||||
if (!process.env.HTTP_PROXY || !process.env.HTTPS_PROXY) {
|
||||
console.warn("Proxy information not provided, but it is required to run this sample. Exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential,
|
||||
// The library tries to load the proxy settings from the environment variables like HTTP_PROXY
|
||||
// Alternatively, the service client accepts the following `proxyOptions` as part of its options:
|
||||
{
|
||||
/*
|
||||
proxyOptions : {
|
||||
// To use these options, remove the section above that checks for HTTP_PROXY or HTTPS_PROXY
|
||||
host: "http://localhost",
|
||||
port: 3128,
|
||||
username: "<username>",
|
||||
password: "<password>"
|
||||
}
|
||||
*/
|
||||
}
|
||||
);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const createContainerResponse = await blobServiceClient
|
||||
.getContainerClient(containerName)
|
||||
.create();
|
||||
console.log(`Created container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/*
|
||||
If you use BlobClient.download() to download an append blob which is being actively appended,
|
||||
you may get a 412 HTTP error, just like this issue: https://github.com/Azure/azure-storage-js/issues/51
|
||||
|
||||
Recommend solution is to snapshot the append blob, and read from the snapshot blob.
|
||||
|
||||
Reason
|
||||
- blobClient.download() will try to download a blob with a HTTP Get request into a stream.
|
||||
- When a stream unexpectedly ends because of an unreliable network, retry will resume the stream read
|
||||
from that broken point with a new HTTP Get request.
|
||||
- The second HTTP request will use conditional header `IfMatch` with the blob's `ETag`
|
||||
returned in first request to make sure the blob doesn't change when the 2nd retry happens.
|
||||
Otherwise, a 412 conditional header doesn't match error will be returned.
|
||||
- This strict strategy is used to avoid data integrity issues, such as the blob maybe totally over written by someone others.
|
||||
However, this strategy seems avoiding reading from reading a constantly updated log file when a retry happens.
|
||||
|
||||
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { ContainerClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = new ContainerClient(
|
||||
`https://${account}.blob.core.windows.net/${containerName}`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Create a blob
|
||||
const content = "hello";
|
||||
const blobName = "newblob" + new Date().getTime();
|
||||
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
||||
const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content));
|
||||
console.log(`Uploaded block blob ${blobName} successfully`, uploadBlobResponse.requestId);
|
||||
|
||||
// Downloading blob from the snapshot
|
||||
console.log("Downloading blob...");
|
||||
const snapshotResponse = await blockBlobClient.createSnapshot();
|
||||
const blobSnapshotClient = blockBlobClient.withSnapshot(snapshotResponse.snapshot!);
|
||||
|
||||
const response = await blobSnapshotClient.download(0);
|
||||
console.log(
|
||||
"Reading response to string...",
|
||||
(await blobSnapshotClient.getProperties()).contentLength
|
||||
);
|
||||
|
||||
console.log("Downloaded blob content", await streamToString(response.readableStreamBody!));
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
chunks.push(data.toString());
|
||||
});
|
||||
readableStream.on("end", () => {
|
||||
resolve(chunks.join(""));
|
||||
});
|
||||
readableStream.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Enter your storage account name and shared key
|
||||
const account = process.env.ACCOUNT_NAME || "";
|
||||
const accountKey = process.env.ACCOUNT_KEY || "";
|
||||
|
||||
// Use StorageSharedKeyCredential with storage account and account key
|
||||
// StorageSharedKeyCredential is only available in Node.js runtime, not in browsers
|
||||
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
|
||||
|
||||
// List containers
|
||||
const blobServiceClient = new BlobServiceClient(
|
||||
`https://${account}.blob.core.windows.net`,
|
||||
sharedKeyCredential
|
||||
);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter";
|
||||
import { NodeTracerProvider } from "@opentelemetry/node";
|
||||
import { BatchSpanProcessor } from "@opentelemetry/tracing";
|
||||
import * as azureSdkTracing from "@azure/core-tracing";
|
||||
|
||||
const provider = new NodeTracerProvider();
|
||||
|
||||
const azureExporter = new AzureMonitorTraceExporter({
|
||||
instrumentationKey: "ikey",
|
||||
logger: provider.logger,
|
||||
});
|
||||
|
||||
provider.addSpanProcessor(new BatchSpanProcessor(azureExporter, {
|
||||
bufferSize: 1000, // 1000 spans
|
||||
bufferTimeout: 15000, // 15 seconds
|
||||
}));
|
||||
|
||||
provider.register();
|
||||
|
||||
azureSdkTracing.setTracer(
|
||||
provider.getTracer("example tracer") as any // cast to any until azure sdk uses latest types
|
||||
);
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Setup tracing before importing anything else
|
||||
require("./tracing");
|
||||
|
||||
/*
|
||||
Setup: Enter your storage account name and shared key in main()
|
||||
*/
|
||||
|
||||
import { BlobServiceClient } from "@azure/storage-blob";
|
||||
|
||||
// Load the .env file if it exists
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
export async function main() {
|
||||
// Create Blob Service Client from Account connection string or SAS connection string
|
||||
// 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`
|
||||
const STORAGE_CONNECTION_STRING = process.env.STORAGE_CONNECTION_STRING || "";
|
||||
// Note - Account connection string can only be used in node.
|
||||
const blobServiceClient = BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING);
|
||||
|
||||
let i = 1;
|
||||
for await (const container of blobServiceClient.listContainers()) {
|
||||
console.log(`Container ${i++}: ${container.name}`);
|
||||
}
|
||||
|
||||
// Create a container
|
||||
const containerName = `newcontainer${new Date().getTime()}`;
|
||||
const containerClient = blobServiceClient.getContainerClient(containerName);
|
||||
|
||||
const createContainerResponse = await containerClient.create();
|
||||
console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
|
||||
|
||||
// Delete container
|
||||
await containerClient.delete();
|
||||
|
||||
console.log("deleted container");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Error running sample:", err.message);
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
|
||||
"lib": ["dom", "dom.iterable", "esnext.asynciterable"],
|
||||
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src/**.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"packages": [
|
||||
"packages/*",
|
||||
"examples/*"
|
||||
"examples/**/*"
|
||||
],
|
||||
"version": "1.0.0-preview.4"
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче