Unify all markup C++ code sections to use 'cpp' (#5138)

* Unify all markup C++ code sections to use 'cpp'

* Update broken link

---------

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
This commit is contained in:
Anton Kolesnyk 2023-11-08 20:42:59 -08:00 committed by GitHub
parent f816bb194b
commit 030ad9a6ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 82 additions and 82 deletions

View File

@ -162,7 +162,7 @@ Azure C++ SDK headers needed are located within the `<azure>` folder, with sub-f
Here's an example application to help you get started: Here's an example application to help you get started:
```C++ ```cpp
#include <iostream> #include <iostream>
// Include the necessary SDK headers // Include the necessary SDK headers
@ -231,7 +231,7 @@ The main shared concepts of `Azure Core` include:
Many client library operations **return** the templated `Azure::Core::Response<T>` type from the API calls. This type let's you get the raw HTTP response from the service request call the Azure service APIs make, along with the result of the operation to get more API specific details. This is the templated `T` operation result which can be extracted from the response, using the `Value` field. Many client library operations **return** the templated `Azure::Core::Response<T>` type from the API calls. This type let's you get the raw HTTP response from the service request call the Azure service APIs make, along with the result of the operation to get more API specific details. This is the templated `T` operation result which can be extracted from the response, using the `Value` field.
```C++ ```cpp
// Azure service operations return a Response<T> templated type. // Azure service operations return a Response<T> templated type.
Azure::Response<Models::BlobProperties> propertiesResponse = blockBlobClient.GetProperties(); Azure::Response<Models::BlobProperties> propertiesResponse = blockBlobClient.GetProperties();
@ -249,7 +249,7 @@ Some operations take a long time to complete and require polling for their statu
You can intermittently poll whether the operation has finished by using the `Poll()` method inside a loop on the returned `Operation<T>` and track progress of the operation using `Value()`, while the operation is not done (using `IsDone()`). Your per-polling custom logic can go in that loop, such as logging progress. Alternatively, if you just want to wait until the operation completes, you can use `PollUntilDone()`. You can intermittently poll whether the operation has finished by using the `Poll()` method inside a loop on the returned `Operation<T>` and track progress of the operation using `Value()`, while the operation is not done (using `IsDone()`). Your per-polling custom logic can go in that loop, such as logging progress. Alternatively, if you just want to wait until the operation completes, you can use `PollUntilDone()`.
```C++ ```cpp
std::string sourceUri = "<a uri to the source blob to copy>"; std::string sourceUri = "<a uri to the source blob to copy>";
// Typically, long running operation APIs have names that begin with Start. // Typically, long running operation APIs have names that begin with Start.

View File

@ -48,7 +48,7 @@ Following the examples from opentelemetry-cpp, the following can be used
to establish an OpenTelemetry exporter which logs to the console or to an to establish an OpenTelemetry exporter which logs to the console or to an
in-memory logger. in-memory logger.
```c++ ```cpp
opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider> opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider>
CreateOpenTelemetryProvider() CreateOpenTelemetryProvider()
{ {
@ -71,13 +71,13 @@ CreateOpenTelemetryProvider()
} }
``` ```
Other exporters exist to export to [Jaeger](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/exporters/jaeger), Other exporters exist to export to [Elasticsearch](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/exporters/elasticsearch),
[Windows ETW](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/exporters/etw) and others. [Windows ETW](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/exporters/etw) and others.
Once the `opentelemetry::trace::TracerProvider` has been created, The client needs to create a new `Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider` which Once the `opentelemetry::trace::TracerProvider` has been created, The client needs to create a new `Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider` which
functions as an abstract class integration between OpenTelemetry and Azure Core: functions as an abstract class integration between OpenTelemetry and Azure Core:
```c++ ```cpp
std::shared_ptr<Azure::Core::Tracing::TracerProvider> traceProvider std::shared_ptr<Azure::Core::Tracing::TracerProvider> traceProvider
= Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(CreateOpenTelemetryProvider()); = Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(CreateOpenTelemetryProvider());
``` ```
@ -92,7 +92,7 @@ While using the ApplicationContext is the simplest mechanism for integration Ope
To enable customers to further customize how tracing works, the application can set the `Telemetry.TracingProvider` field in the service client options, which will establish the tracer provider used by To enable customers to further customize how tracing works, the application can set the `Telemetry.TracingProvider` field in the service client options, which will establish the tracer provider used by
the service client. the service client.
```c++ ```cpp
auto tracerProvider(CreateOpenTelemetryProvider()); auto tracerProvider(CreateOpenTelemetryProvider());
auto provider(Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(tracerProvider)); auto provider(Azure::Core::Tracing::OpenTelemetry::OpenTelemetryProvider::Create(tracerProvider));
@ -116,13 +116,13 @@ There are two steps needed to integrate Distributed Tracing with a Service Clien
To add a new `DiagnosticTracingFactory` to the client, simply add the class as a member: To add a new `DiagnosticTracingFactory` to the client, simply add the class as a member:
```c++ ```cpp
Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory; Azure::Core::Tracing::_internal::TracingContextFactory m_tracingFactory;
``` ```
And construct the new tracing factory in the service constructor: And construct the new tracing factory in the service constructor:
```c++ ```cpp
explicit ServiceClient(ServiceClientOptions const& clientOptions = ServiceClientOptions{}) explicit ServiceClient(ServiceClientOptions const& clientOptions = ServiceClientOptions{})
: m_tracingFactory(clientOptions, "Azure.Core.OpenTelemetry.Test.Service", : m_tracingFactory(clientOptions, "Azure.Core.OpenTelemetry.Test.Service",
"azure-core-opentelemetry-test-service-cpp", PackageVersion::ToString()) "azure-core-opentelemetry-test-service-cpp", PackageVersion::ToString())
@ -139,7 +139,7 @@ And construct the new tracing factory in the service constructor:
1. `Span::AddEvent(std::exception&)` - This registers the exception with the distributed tracing infrastructure. 1. `Span::AddEvent(std::exception&)` - This registers the exception with the distributed tracing infrastructure.
1. `Span::SetStatus` - This sets the status of the operation in the trace. 1. `Span::SetStatus` - This sets the status of the operation in the trace.
```c++ ```cpp
Azure::Response<std::string> ServiceMethod( Azure::Response<std::string> ServiceMethod(
std::string const&, std::string const&,
Azure::Core::Context const& context = Azure::Core::Context{}) Azure::Core::Context const& context = Azure::Core::Context{})

View File

@ -96,7 +96,7 @@ For detailed samples please review the code provided.
### GetSettings ### GetSettings
To get all the available settings present on the Keyvault instance we will first create a client : To get all the available settings present on the Keyvault instance we will first create a client :
```CPP ```cpp
auto tenantId = std::getenv("AZURE_TENANT_ID"); auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID"); auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET"); auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
@ -110,7 +110,7 @@ Please note that we are using the HSM URL, not the keyvault URL.
To get the settings we will call the GetSettings API To get the settings we will call the GetSettings API
```CPP ```cpp
// Get all settings // Get all settings
SettingsListResult settingsList = settingsClient.GetSettings().Value; SettingsListResult settingsList = settingsClient.GetSettings().Value;
``` ```
@ -119,14 +119,14 @@ To get the settings we will call the GetSettings API
To get a specific setting we will call the GetSetting API bassing the setting name as a string parameter. To get a specific setting we will call the GetSetting API bassing the setting name as a string parameter.
```CPP ```cpp
Setting setting = settingsClient.GetSetting(settingsList.Value[0].Name).Value; Setting setting = settingsClient.GetSetting(settingsList.Value[0].Name).Value;
``` ```
### UpdateSetting ### UpdateSetting
To update the value of any of the the available settings, we will call the UpdateSettings API as follows: To update the value of any of the the available settings, we will call the UpdateSettings API as follows:
```CPP ```cpp
UpdateSettingOptions options; UpdateSettingOptions options;
options.Value = <setting value>; options.Value = <setting value>;

View File

@ -64,7 +64,7 @@ v12
A `TokenCredential` abstract class (different API surface than v7.5) exists in the [Azure Core](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core) package that all libraries of the new Azure SDK family depend on, and can be used to construct Storage clients. Implementations of this class can be found separately in the [Azure Identity](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/identity/azure-identity) package. A `TokenCredential` abstract class (different API surface than v7.5) exists in the [Azure Core](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/core/azure-core) package that all libraries of the new Azure SDK family depend on, and can be used to construct Storage clients. Implementations of this class can be found separately in the [Azure Identity](https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/identity/azure-identity) package.
```C++ ```cpp
BlobServiceClient serviceClient(serviceUrl, std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret)); BlobServiceClient serviceClient(serviceUrl, std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret));
``` ```
@ -76,11 +76,11 @@ v7.5
In general, SAS tokens can be provided on their own to be applied as needed, or as a complete, self-authenticating URL. The legacy library allowed providing a SAS through `storage_credentials` as well as constructing with a complete URL. In general, SAS tokens can be provided on their own to be applied as needed, or as a complete, self-authenticating URL. The legacy library allowed providing a SAS through `storage_credentials` as well as constructing with a complete URL.
```C++ ```cpp
cloud_blob_client blob_client(storage_uri(blob_url), storage_credentials(sas_token)); cloud_blob_client blob_client(storage_uri(blob_url), storage_credentials(sas_token));
``` ```
```C++ ```cpp
cloud_blob_client blob_client(storage_uri(blob_url_with_sas)); cloud_blob_client blob_client(storage_uri(blob_url_with_sas));
``` ```
@ -88,7 +88,7 @@ v12
The new library only supports constructing a client with a fully constructed SAS URI. Note that since client URIs are immutable once created, a new client instance with a new SAS must be created in order to rotate a SAS. The new library only supports constructing a client with a fully constructed SAS URI. Note that since client URIs are immutable once created, a new client instance with a new SAS must be created in order to rotate a SAS.
```C++ ```cpp
BlobClient blobClient(blobUrlWithSas); BlobClient blobClient(blobUrlWithSas);
``` ```
@ -98,19 +98,19 @@ The following code assumes you have acquired your connection string (you can do
v7.5 v7.5
```C++ ```cpp
cloud_storage_account storage_account = cloud_storage_account::parse(storage_connection_string); cloud_storage_account storage_account = cloud_storage_account::parse(storage_connection_string);
cloud_blob_client service_client = storage_account.create_cloud_blob_client(); cloud_blob_client service_client = storage_account.create_cloud_blob_client();
``` ```
v12 v12
```C++ ```cpp
BlobServiceClient serviceClient = BlobServiceClient::CreateFromConnectionString(connectionString); BlobServiceClient serviceClient = BlobServiceClient::CreateFromConnectionString(connectionString);
``` ```
You can also directly get a blob client with your connection string, instead of going through a service and container client to get to your desired blob. You just need to provide the container and blob names alongside the connection string. You can also directly get a blob client with your connection string, instead of going through a service and container client to get to your desired blob. You just need to provide the container and blob names alongside the connection string.
```C++ ```cpp
BlobClient blobClient = BlobClient::CreateFromConnectionString(connectionString, containerName, blobName); BlobClient blobClient = BlobClient::CreateFromConnectionString(connectionString, containerName, blobName);
``` ```
@ -121,12 +121,12 @@ Shared key authentication requires the URI to the storage endpoint, the storage
Note that the URI to your storage account can generally be derived from the account name (though some exceptions exist), and so you can track only the account name and key. These examples will assume that is the case, though you can substitute your specific account URI if you do not follow this pattern. Note that the URI to your storage account can generally be derived from the account name (though some exceptions exist), and so you can track only the account name and key. These examples will assume that is the case, though you can substitute your specific account URI if you do not follow this pattern.
v7.5 v7.5
```C++ ```cpp
cloud_blob_client blob_client(storage_uri(blob_service_url), storage_credentials(account_name, account_key)); cloud_blob_client blob_client(storage_uri(blob_service_url), storage_credentials(account_name, account_key));
``` ```
v12 v12
```C++ ```cpp
auto credential = std::make_shared<StorageSharedKeyCredential>(accountName, accountKey); auto credential = std::make_shared<StorageSharedKeyCredential>(accountName, accountKey);
BlobServiceClient serviceClient(blobServiceUrl, credential); BlobServiceClient serviceClient(blobServiceUrl, credential);
``` ```
@ -169,20 +169,20 @@ The following table lists v7.5 classes and their v12 equivalents for quick refer
### Creating a Container ### Creating a Container
v7.5 v7.5
```C++ ```cpp
auto container_client = service_client.get_container_reference(container_name); auto container_client = service_client.get_container_reference(container_name);
container_client.create(); container_client.create();
``` ```
v12 v12
```C++ ```cpp
auto containerClient = serviceClient.GetBlobContainerClient(containerName); auto containerClient = serviceClient.GetBlobContainerClient(containerName);
containerClient.Create(); containerClient.Create();
``` ```
Or you can use the `BlobServiceClient.CreateBlobContainer()` method. Or you can use the `BlobServiceClient.CreateBlobContainer()` method.
```C++ ```cpp
serviceClient.CreateBlobContainer(containerName); serviceClient.CreateBlobContainer(containerName);
``` ```
@ -191,13 +191,13 @@ serviceClient.CreateBlobContainer(containerName);
#### Uploading from a file #### Uploading from a file
v7.5 v7.5
```C++ ```cpp
cloud_block_blob block_blob_client = container_client.get_block_blob_reference(blob_name); cloud_block_blob block_blob_client = container_client.get_block_blob_reference(blob_name);
block_blob_client.upload_from_file(local_file_path); block_blob_client.upload_from_file(local_file_path);
``` ```
v12 v12
```C++ ```cpp
BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(blobName); BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(blobName);
blockBlobClient.UploadFrom(localFilePath); blockBlobClient.UploadFrom(localFilePath);
``` ```
@ -205,24 +205,24 @@ blockBlobClient.UploadFrom(localFilePath);
#### Uploading from a stream #### Uploading from a stream
v7.5 v7.5
```C++ ```cpp
block_blob_client.upload_from_stream(stream); block_blob_client.upload_from_stream(stream);
``` ```
v12 v12
```C++ ```cpp
blockBlobClient.Upload(stream); blockBlobClient.Upload(stream);
``` ```
#### Uploading text #### Uploading text
v7.5 v7.5
```C++ ```cpp
block_blob_client.upload_text("Hello Azure!"); block_blob_client.upload_text("Hello Azure!");
``` ```
v12 v12
```C++ ```cpp
uint8_t text[] = "Hello Azure!"; uint8_t text[] = "Hello Azure!";
blockBlobClient.UploadFrom(text, sizeof(text) - 1); blockBlobClient.UploadFrom(text, sizeof(text) - 1);
``` ```
@ -232,13 +232,13 @@ blockBlobClient.UploadFrom(text, sizeof(text) - 1);
#### Downloading to a file #### Downloading to a file
v7.5 v7.5
```C++ ```cpp
auto blob_client = container_client.get_blob_reference(blob_name); auto blob_client = container_client.get_blob_reference(blob_name);
blob_client.download_to_file(local_file_path); blob_client.download_to_file(local_file_path);
``` ```
v12 v12
```C++ ```cpp
auto blobClient = containerClient.GetBlobClient(blobName); auto blobClient = containerClient.GetBlobClient(blobName);
blobClient.DownloadTo(localFilePath); blobClient.DownloadTo(localFilePath);
``` ```
@ -246,12 +246,12 @@ blobClient.DownloadTo(localFilePath);
#### Downloading to a stream #### Downloading to a stream
v7.5 v7.5
```C++ ```cpp
blob_client.download_to_stream(stream); blob_client.download_to_stream(stream);
``` ```
v12 v12
```C++ ```cpp
auto response = blobClient.Download(); auto response = blobClient.Download();
BodyStream& stream = *response.Value.BodyStream; BodyStream& stream = *response.Value.BodyStream;
``` ```
@ -259,12 +259,12 @@ BodyStream& stream = *response.Value.BodyStream;
#### Downloading text #### Downloading text
v7.5 v7.5
```C++ ```cpp
auto text = blob_client.download_text(); auto text = blob_client.download_text();
``` ```
v12 v12
```C++ ```cpp
auto response = blobClient.Download(); auto response = blobClient.Download();
std::vector<uint8_t> blobContent = response.Value.BodyStream->ReadToEnd(); std::vector<uint8_t> blobContent = response.Value.BodyStream->ReadToEnd();
std::string text(blobContent.begin(), blobContent.end()); std::string text(blobContent.begin(), blobContent.end());
@ -275,7 +275,7 @@ std::string text(blobContent.begin(), blobContent.end());
#### Flat Listing #### Flat Listing
v7.5 v7.5
```C++ ```cpp
for (auto iter = container_client.list_blobs(); iter != list_blob_item_iterator(); ++iter) { for (auto iter = container_client.list_blobs(); iter != list_blob_item_iterator(); ++iter) {
if (iter->is_blob()) { if (iter->is_blob()) {
auto blob_client = iter->as_blob(); auto blob_client = iter->as_blob();
@ -284,7 +284,7 @@ for (auto iter = container_client.list_blobs(); iter != list_blob_item_iterator(
``` ```
v12 v12
```C++ ```cpp
for (auto blobPage = containerClient.ListBlobs(); blobPage.HasPage(); blobPage.MoveToNextPage()) { for (auto blobPage = containerClient.ListBlobs(); blobPage.HasPage(); blobPage.MoveToNextPage()) {
for (auto& blob : blobPage.Blobs) { for (auto& blob : blobPage.Blobs) {
@ -300,7 +300,7 @@ v7.5
`list_blobs()` and `list_blobs_segmented()` that were used in a flat listing contain overloads with a boolean parameter `use_flat_blob_listing`, which results in a flat listing when `true`. Provide `false` to perform a hierarchical listing. `list_blobs()` and `list_blobs_segmented()` that were used in a flat listing contain overloads with a boolean parameter `use_flat_blob_listing`, which results in a flat listing when `true`. Provide `false` to perform a hierarchical listing.
```C++ ```cpp
for (auto iter = container_client.list_blobs(prefix, false, blob_listing_details::none, 0, blob_request_options, operation_context)) { for (auto iter = container_client.list_blobs(prefix, false, blob_listing_details::none, 0, blob_request_options, operation_context)) {
if (iter->is_blob()) { if (iter->is_blob()) {
auto blob_client = iter->as_blob(); auto blob_client = iter->as_blob();
@ -315,7 +315,7 @@ v12
v12 has explicit methods for listing by hierarchy. v12 has explicit methods for listing by hierarchy.
```C++ ```cpp
for (auto blobPage = containerClient.ListBlobsByHierarchy("/"); blobPage.HasPage(); blobPage.MoveToNextPage()) { for (auto blobPage = containerClient.ListBlobsByHierarchy("/"); blobPage.HasPage(); blobPage.MoveToNextPage()) {
for (auto& blob : blobPage.Blobs) { for (auto& blob : blobPage.Blobs) {
@ -336,7 +336,7 @@ v7.5 samples:
The legacy SDK maintained a metadata cache, allowing you to modify metadata on the `cloud_blob` and invoke `upload_metadata()`. Calling `download_attributes()` beforehand refreshed the metadata cache to avoid undoing recent changes. The legacy SDK maintained a metadata cache, allowing you to modify metadata on the `cloud_blob` and invoke `upload_metadata()`. Calling `download_attributes()` beforehand refreshed the metadata cache to avoid undoing recent changes.
```C++ ```cpp
blob_client.download_attributes(); blob_client.download_attributes();
blob_client.metadata()["foo"] = "bar"; blob_client.metadata()["foo"] = "bar";
blob_client.upload_metadata(); blob_client.upload_metadata();
@ -344,7 +344,7 @@ blob_client.upload_metadata();
The legacy SDK maintained internal state for blob content uploads. Calling `download_attributes()` beforehand refreshed the metadata cache to avoid undoing recent changes. The legacy SDK maintained internal state for blob content uploads. Calling `download_attributes()` beforehand refreshed the metadata cache to avoid undoing recent changes.
```C++ ```cpp
// download blob content. blob metadata is fetched and cached on download // download blob content. blob metadata is fetched and cached on download
blob_client.download_to_file(local_file_path); blob_client.download_to_file(local_file_path);
@ -358,7 +358,7 @@ v12 samples:
The modern SDK requires you to hold onto metadata and update it appropriately before sending off. You cannot just add a new key-value pair, you must update the collection and send the collection. The modern SDK requires you to hold onto metadata and update it appropriately before sending off. You cannot just add a new key-value pair, you must update the collection and send the collection.
```C++ ```cpp
auto metadata = blobClient.GetProperties().Value.Metadata; auto metadata = blobClient.GetProperties().Value.Metadata;
metadata["foo"] = "bar"; metadata["foo"] = "bar";
blobClient.SetMetadata(metadata); blobClient.SetMetadata(metadata);
@ -366,7 +366,7 @@ blobClient.SetMetadata(metadata);
Additionally with blob content edits, if your blobs have metadata you need to get the metadata and re-upload with that metadata, telling the service what metadata goes with this new blob state. Additionally with blob content edits, if your blobs have metadata you need to get the metadata and re-upload with that metadata, telling the service what metadata goes with this new blob state.
```C++ ```cpp
// download blob content and metadata // download blob content and metadata
auto response = blobClient.DownloadTo(localFilePath); auto response = blobClient.DownloadTo(localFilePath);
auto metadata = response.Value.Metadata; auto metadata = response.Value.Metadata;
@ -387,7 +387,7 @@ blobClient.UploadFrom(localFilePath, uploadOptions);
v7.5 calculated blob content MD5 for validation on download by default, assuming there was a stored MD5 in the blob properties. Calculation and storage on upload was opt-in. Note that this value is not generated or validated by the service, and is only retained for the client to validate against. v7.5 calculated blob content MD5 for validation on download by default, assuming there was a stored MD5 in the blob properties. Calculation and storage on upload was opt-in. Note that this value is not generated or validated by the service, and is only retained for the client to validate against.
v7.5 v7.5
```C++ ```cpp
blob_request_options options; blob_request_options options;
options.set_store_blob_content_md5(false); // true to calculate content MD5 on upload and store property options.set_store_blob_content_md5(false); // true to calculate content MD5 on upload and store property
options.set_disable_content_md5_validation(false); // true to disable download content validation options.set_disable_content_md5_validation(false); // true to disable download content validation
@ -396,7 +396,7 @@ options.set_disable_content_md5_validation(false); // true to disable download
v12 does not have an automated mechanism for blob content validation. It must be done per-request by the user. v12 does not have an automated mechanism for blob content validation. It must be done per-request by the user.
v12 v12
```C++ ```cpp
// upload with blob content hash property // upload with blob content hash property
UploadBlockBlobOptions uploadOptions; UploadBlockBlobOptions uploadOptions;
uploadOptions.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5; uploadOptions.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5;
@ -419,7 +419,7 @@ v7.5 provided transactional hashing on uploads and downloads through opt-in requ
v7.5 v7.5
```C++ ```cpp
blob_request_options options; blob_request_options options;
options.set_use_transactional_md5(false); // true to use MD5 on all blob content transactions. options.set_use_transactional_md5(false); // true to use MD5 on all blob content transactions.
options.set_use_transactional_crc64(false); // true to use CRC64 on all blob content transactions. options.set_use_transactional_crc64(false); // true to use CRC64 on all blob content transactions.
@ -427,7 +427,7 @@ options.set_use_transactional_crc64(false); // true to use CRC64 on all blob co
v12 does not currently provide this functionality. Users who manage their own individual upload and download HTTP requests can provide a precalculated MD5 on upload and access the MD5 in the response object. v12 currently offers no API to request a transactional CRC64. v12 does not currently provide this functionality. Users who manage their own individual upload and download HTTP requests can provide a precalculated MD5 on upload and access the MD5 in the response object. v12 currently offers no API to request a transactional CRC64.
```C++ ```cpp
// upload a block with transactional hash calculated by user // upload a block with transactional hash calculated by user
StageBlockOptions stageBlockOptions; StageBlockOptions stageBlockOptions;
stageBlockOptions.TransactionalContentHash = ContentHash(); stageBlockOptions.TransactionalContentHash = ContentHash();
@ -454,13 +454,13 @@ auto hashValue = response.Value.Details.HttpHeaders.ContentHash.Value;
#### Retry policy #### Retry policy
v7.5 v7.5
```C++ ```cpp
blob_request_options options; blob_request_options options;
options.set_retry_policy(exponential_retry_policy(delta_backoff, max_attempts)); options.set_retry_policy(exponential_retry_policy(delta_backoff, max_attempts));
``` ```
v12 v12
```C++ ```cpp
Blobs::BlobClientOptions options; Blobs::BlobClientOptions options;
// The only supported mode is exponential. // The only supported mode is exponential.
options.Retry.RetryDelay = std::chrono::milliseconds(delta_backoff); options.Retry.RetryDelay = std::chrono::milliseconds(delta_backoff);
@ -472,7 +472,7 @@ options.Retry.MaxRetries = maxAttempts;
Unfortunately, we don't support asynchronous interface in v12 SDK. You could wrap synchronous functions into asynchronous with some async framework like `std::async`. But note that I/O operations are still performed synchronously under the hood. There's no performance gain with this method. Unfortunately, we don't support asynchronous interface in v12 SDK. You could wrap synchronous functions into asynchronous with some async framework like `std::async`. But note that I/O operations are still performed synchronously under the hood. There's no performance gain with this method.
v7.5 v7.5
```C++ ```cpp
auto task = blob_client.download_text_async().then([](utility::string_t blob_content) { auto task = blob_client.download_text_async().then([](utility::string_t blob_content) {
std::wcout << "blob content:" << blob_content << std::endl; std::wcout << "blob content:" << blob_content << std::endl;
}); });
@ -481,7 +481,7 @@ task.wait();
``` ```
v12 v12
```C++ ```cpp
auto task = std::async([blobClient]() { auto task = std::async([blobClient]() {
auto response = blobClient.Download(); auto response = blobClient.Download();
std::vector<uint8_t> blobContent = response.Value.BodyStream->ReadToEnd(); std::vector<uint8_t> blobContent = response.Value.BodyStream->ReadToEnd();

View File

@ -82,7 +82,7 @@ Client Options | [Accessing the response](https://github.com/Azure/azure-sdk-for
### Uploading a blob ### Uploading a blob
```C++ ```cpp
const std::string connectionString = "<connection_string>"; const std::string connectionString = "<connection_string>";
const std::string containerName = "sample-container"; const std::string containerName = "sample-container";
const std::string blobName = "sample-blob"; const std::string blobName = "sample-blob";
@ -99,7 +99,7 @@ blobClinet.UploadFrom(bufferPtr, bufferLength);
### Downloading a blob ### Downloading a blob
```C++ ```cpp
// download to local file // download to local file
blobClient.DownloadTo(localFilePath); blobClient.DownloadTo(localFilePath);
// or download to memory buffer // or download to memory buffer
@ -108,7 +108,7 @@ blobClinet.DownloadTo(bufferPtr, bufferLength);
### Enumerating blobs ### Enumerating blobs
```C++ ```cpp
for (auto blobPage = containerClient.ListBlobs(); blobPage.HasPage(); blobPage.MoveToNextPage()) { for (auto blobPage = containerClient.ListBlobs(); blobPage.HasPage(); blobPage.MoveToNextPage()) {
for (auto& blob : blobPage.Blobs) { for (auto& blob : blobPage.Blobs) {
// Below is what you want to do with each blob // Below is what you want to do with each blob
@ -123,7 +123,7 @@ All Blob service operations will throw a [StorageException](https://github.com/A
on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/blob-service-error-codes)s. on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/blob-service-error-codes)s.
Many of these errors are recoverable. Many of these errors are recoverable.
```C++ ```cpp
try try
{ {
containerClient.Delete(); containerClient.Delete();

View File

@ -97,7 +97,7 @@ Client Options | [Accessing the response](https://github.com/Azure/azure-sdk-for
### Appending Data to a DataLake File ### Appending Data to a DataLake File
```C++ ```cpp
const std::string connectionString = "<connection_string>"; const std::string connectionString = "<connection_string>";
const std::string fileSystemName = "sample-filesystem"; const std::string fileSystemName = "sample-filesystem";
const std::string directoryName = "sample-directory"; const std::string directoryName = "sample-directory";
@ -125,12 +125,12 @@ fileClient.Append(fileStream, 0);
fileClient.Flush(fileStream.Length()); fileClient.Flush(fileStream.Length());
``` ```
### Reading Data from a DataLake File ### Reading Data from a DataLake File
```C++ ```cpp
Response<DownloadFileResult> fileContents = fileClient.Download(); Response<DownloadFileResult> fileContents = fileClient.Download();
``` ```
### Enumerating DataLake Paths ### Enumerating DataLake Paths
```C++ ```cpp
for (auto pathPage = client.ListPaths(false); pathPage.HasPage(); pathPage.MoveToNextPage()) for (auto pathPage = client.ListPaths(false); pathPage.HasPage(); pathPage.MoveToNextPage())
{ {
for (auto& path : pathPage.Paths) for (auto& path : pathPage.Paths)
@ -147,7 +147,7 @@ All File DataLake service operations will throw a [StorageException](https://git
on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/blob-service-error-codes)s. on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/blob-service-error-codes)s.
Many of these errors are recoverable. Many of these errors are recoverable.
```C++ ```cpp
try try
{ {
fileSystemClient.Delete(); fileSystemClient.Delete();

View File

@ -73,7 +73,7 @@ Client Options | [Accessing the response](https://github.com/Azure/azure-sdk-for
### Create a share and upload a file ### Create a share and upload a file
```C++ ```cpp
const std::string shareName = "sample-share"; const std::string shareName = "sample-share";
const std::string directoryName = "sample-directory"; const std::string directoryName = "sample-directory";
const std::string fileName = "sample-file"; const std::string fileName = "sample-file";
@ -97,7 +97,7 @@ fileClient.UploadFrom(bufferPtr, bufferLength);
### Download a file ### Download a file
```C++ ```cpp
// download to local file // download to local file
fileClient.DownloadTo(localFilePath); fileClient.DownloadTo(localFilePath);
// or download to memory buffer // or download to memory buffer
@ -106,7 +106,7 @@ fileClient.DownloadTo(bufferPtr, bufferLength);
### Traverse a share ### Traverse a share
```C++ ```cpp
std::vector<ShareDirectoryClient> remaining; std::vector<ShareDirectoryClient> remaining;
remaining.push_back(shareClient.GetRootDirectoryClient()); remaining.push_back(shareClient.GetRootDirectoryClient());
while (remaining.size() > 0) while (remaining.size() > 0)
@ -135,7 +135,7 @@ All Azure Storage File Shares service operations will throw a [StorageException]
on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/file-service-error-codes)s. on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/file-service-error-codes)s.
Many of these errors are recoverable. Many of these errors are recoverable.
```C++ ```cpp
try try
{ {
shareClient.Delete(); shareClient.Delete();

View File

@ -72,7 +72,7 @@ Client Options | [Accessing the response](https://github.com/Azure/azure-sdk-for
### Send messages ### Send messages
```C++ ```cpp
const std::string connectionString = "<connection_string>"; const std::string connectionString = "<connection_string>";
const std::string queueName = "sample-queue"; const std::string queueName = "sample-queue";
@ -86,7 +86,7 @@ queueClient.EnqueueMessage("Hello, Azure2!");
queueClient.EnqueueMessage("Hello, Azure3!"); queueClient.EnqueueMessage("Hello, Azure3!");
``` ```
### Receive messages ### Receive messages
```C++ ```cpp
ReceiveMessagesOptions receiveOptions; ReceiveMessagesOptions receiveOptions;
receiveOptions.MaxMessages = 3; receiveOptions.MaxMessages = 3;
auto receiveMessagesResult = queueClient.ReceiveMessages(receiveOptions).Value; auto receiveMessagesResult = queueClient.ReceiveMessages(receiveOptions).Value;
@ -103,7 +103,7 @@ All Azure Storage Queue service operations will throw a [StorageException](http
on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/queue-service-error-codes)s. on failure with helpful [ErrorCode](https://learn.microsoft.com/rest/api/storageservices/queue-service-error-codes)s.
Many of these errors are recoverable. Many of these errors are recoverable.
```C++ ```cpp
try try
{ {
queueClient.Delete(); queueClient.Delete();

View File

@ -43,7 +43,7 @@ The inner loop gets called for every paged result and doesn't do I/O.
Below is an example of listing all blobs in a blob container. Below is an example of listing all blobs in a blob container.
```C++ ```cpp
for (auto page = blobContainerClient.ListBlobs(); page.HasPage(); page.MoveToNextPage()) { for (auto page = blobContainerClient.ListBlobs(); page.HasPage(); page.MoveToNextPage()) {
for (auto& blob : page.Blobs) { for (auto& blob : page.Blobs) {
std::cout << blob.Name << std::endl; std::cout << blob.Name << std::endl;
@ -53,7 +53,7 @@ for (auto page = blobContainerClient.ListBlobs(); page.HasPage(); page.MoveToNex
Sometimes a paged result may contain multiple collections and you may want to iterate over all of them. Sometimes a paged result may contain multiple collections and you may want to iterate over all of them.
```C++ ```cpp
for (auto page = directoryClient.ListFilesAndDirectories(); page.HasPage(); page.MoveToNextPage()) for (auto page = directoryClient.ListFilesAndDirectories(); page.HasPage(); page.MoveToNextPage())
{ {
for (const auto& d : page.Directories) for (const auto& d : page.Directories)
@ -72,7 +72,7 @@ for (auto page = directoryClient.ListFilesAndDirectories(); page.HasPage(); page
Yes, each client options takes an `ApiVersion` as an optional parameter, with which you can specify an API-version used for all the HTTP requests from this client. Yes, each client options takes an `ApiVersion` as an optional parameter, with which you can specify an API-version used for all the HTTP requests from this client.
Clients spawned from another client instance will inherit the settings. Clients spawned from another client instance will inherit the settings.
```C++ ```cpp
// serviceClient sends HTTP requests with default API-version, which will change as version evolves. // serviceClient sends HTTP requests with default API-version, which will change as version evolves.
auto serviceClient = BlobServiceClient::CreateFromConnectionString(GetConnectionString()); auto serviceClient = BlobServiceClient::CreateFromConnectionString(GetConnectionString());
@ -94,7 +94,7 @@ Furthermore, this scenario is not covered by testing, although most of the APIs
We recommend you set an application ID with the code below, so that it can be identified from which application, SDK, and platform the request was sent. The information could be useful for troubleshooting and telemetry purposes. We recommend you set an application ID with the code below, so that it can be identified from which application, SDK, and platform the request was sent. The information could be useful for troubleshooting and telemetry purposes.
```C++ ```cpp
BlobClientOptions clientOptions; BlobClientOptions clientOptions;
clientOptions.Telemetry.ApplicationId = "SomeApplication v1.2.3"; clientOptions.Telemetry.ApplicationId = "SomeApplication v1.2.3";
@ -109,7 +109,7 @@ This applies to both input variables and output.
If your code runs in an environment where the default locale and encoding is not UTF-8, you should encode before passing variables into the SDK and decode variables returned from the SDK. If your code runs in an environment where the default locale and encoding is not UTF-8, you should encode before passing variables into the SDK and decode variables returned from the SDK.
In the blow code snippet, we'd like to create a blob named <code>ol&#225;</code>. In the blow code snippet, we'd like to create a blob named <code>ol&#225;</code>.
```C++ ```cpp
// If the blob client is created from a container client, the blob name should be UTF-8 encoded. // If the blob client is created from a container client, the blob name should be UTF-8 encoded.
auto blobClient = containerClient.GetBlobClient("ol\xC3\xA1"); auto blobClient = containerClient.GetBlobClient("ol\xC3\xA1");
// If the blob client is built from URL, it should be URL-encoded // If the blob client is built from URL, it should be URL-encoded
@ -130,7 +130,7 @@ for (auto page = blobContainerClient.ListBlobs(); page.HasPage(); page.MoveToNex
You can check whether a blob exists or not by writing a convenience method on top of getting blob properties, as follows: You can check whether a blob exists or not by writing a convenience method on top of getting blob properties, as follows:
```C++ ```cpp
bool BlobExists(const Azure::Storage::Blobs::BlobClient& client) { bool BlobExists(const Azure::Storage::Blobs::BlobClient& client) {
try { try {
client.GetProperties(); client.GetProperties();
@ -152,7 +152,7 @@ In this case, it's more recommended to:
1. Use `CreateIfNotExists()`, `DeleteIfExists()` functions whenever possible. These functions internally use access conditions and can help you catch unexpected exceptions caused by resending PUT/DELETE requests on network errors. 1. Use `CreateIfNotExists()`, `DeleteIfExists()` functions whenever possible. These functions internally use access conditions and can help you catch unexpected exceptions caused by resending PUT/DELETE requests on network errors.
1. Use access conditions for other operations. The code below only sends one HTTP request, check-and-write is performed atomically. It only succeeds if the blob doesn't exist. 1. Use access conditions for other operations. The code below only sends one HTTP request, check-and-write is performed atomically. It only succeeds if the blob doesn't exist.
```C++ ```cpp
UploadBlockBlobOptions options; UploadBlockBlobOptions options;
options.AccessConditions.IfNoneMatch = Azure::ETag::Any(); options.AccessConditions.IfNoneMatch = Azure::ETag::Any();
blobClient.Upload(stream, options); blobClient.Upload(stream, options);
@ -174,7 +174,7 @@ This one is suitable in most cases. You can expect higher throughput because the
Unfortunately, this SDK doesn't provide a convenient way to upload many blobs or directory contents (files and sub-directories) with just one function call. Unfortunately, this SDK doesn't provide a convenient way to upload many blobs or directory contents (files and sub-directories) with just one function call.
You have to create multiple threads, traverse the directories by yourself and upload blobs one by one in each thread to speed up the transfer. Below is a skeleton example. You have to create multiple threads, traverse the directories by yourself and upload blobs one by one in each thread to speed up the transfer. Below is a skeleton example.
```C++ ```cpp
const std::vector<std::string> paths; // Files to be uploaded const std::vector<std::string> paths; // Files to be uploaded
std::atomic<size_t> curr{0}; std::atomic<size_t> curr{0};
auto upload_func = [&]() { auto upload_func = [&]() {
@ -224,7 +224,7 @@ Make sure you calculate the checksum as early as possible so that potential corr
This functionality also works for download operations. This functionality also works for download operations.
Below is a code sample to use this feature. Below is a code sample to use this feature.
```C++ ```cpp
// upload data with pre-calculated checksum // upload data with pre-calculated checksum
Blobs::UploadBlockBlobOptions options; Blobs::UploadBlockBlobOptions options;
auto checksum = ContentHash(); auto checksum = ContentHash();
@ -296,7 +296,7 @@ Below is an example of adding a custom header into each HTTP request.
The header value is static and doesn't change over time, so we make it a per-operation policy. The header value is static and doesn't change over time, so we make it a per-operation policy.
If you want to add some time-variant headers like authentication, you should use a per-retry policy. If you want to add some time-variant headers like authentication, you should use a per-retry policy.
```C++ ```cpp
class NewPolicy final : public Azure::Core::Http::Policies::HttpPolicy { class NewPolicy final : public Azure::Core::Http::Policies::HttpPolicy {
public: public:
~NewPolicy() override {} ~NewPolicy() override {}
@ -326,7 +326,7 @@ options.PerRetryPolicies.push_back(std::make_unique<NewPolicy>());
Requests failed due to network errors or HTTP status code 408, 500, 502, 503, 504 will be retried at most 3 times (4 attempts in total) using exponential backoff with jitter. Requests failed due to network errors or HTTP status code 408, 500, 502, 503, 504 will be retried at most 3 times (4 attempts in total) using exponential backoff with jitter.
These parameters can be customized with `RetryOptions`. Below is an example. These parameters can be customized with `RetryOptions`. Below is an example.
```C++ ```cpp
BlobClientOptions options; BlobClientOptions options;
options.Retry.RetryDelay = std::chrono::milliseconds(800); options.Retry.RetryDelay = std::chrono::milliseconds(800);
options.Retry.MaxRetryDelay = std::chrono::seconds(60); options.Retry.MaxRetryDelay = std::chrono::seconds(60);
@ -346,7 +346,7 @@ Here are a few things you can do to minimize the impact of this kind of error.
1. Increase the retry count. 1. Increase the retry count.
1. Identify the throttling type and reduce the traffic sent from client side. 1. Identify the throttling type and reduce the traffic sent from client side.
You can check the exception thrown from storage function calls with the below code. The error message will indicate which scalability target was exceeded. You can check the exception thrown from storage function calls with the below code. The error message will indicate which scalability target was exceeded.
```C++ ```cpp
try try
{ {
// storage function goes here // storage function goes here
@ -383,7 +383,7 @@ If you're using SAS authentication, you should:
1. SAS token has its own scope, for example it may be scoped to a storage account, a container or a blob/file. Make sure you don't access a resource out of the SAS token's scope. 1. SAS token has its own scope, for example it may be scoped to a storage account, a container or a blob/file. Make sure you don't access a resource out of the SAS token's scope.
1. Check the message in the exception. 1. Check the message in the exception.
You could print the information in the exception with the code below. You could print the information in the exception with the code below.
```C++ ```cpp
try try
{ {
// storage function goes here // storage function goes here