From 0876ff4fd5ccfaf388d3d6cd2023474d371f6637 Mon Sep 17 00:00:00 2001 From: JinmingHu Date: Wed, 26 May 2021 02:08:17 +0800 Subject: [PATCH] Add samples (#2342) --- .../azure-storage-blobs/CMakeLists.txt | 2 + .../sample/blob_list_operation.cpp | 57 +++++++++++++++++ .../azure-storage-blobs/sample/blob_sas.cpp | 63 +++++++++++++++++++ .../storage/common/storage_credential.hpp | 2 + .../azure-storage-common/sample/main.cpp | 14 ++++- .../sample/samples_common.hpp | 4 +- .../src/storage_credential.cpp | 2 + 7 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 sdk/storage/azure-storage-blobs/sample/blob_list_operation.cpp create mode 100644 sdk/storage/azure-storage-blobs/sample/blob_sas.cpp diff --git a/sdk/storage/azure-storage-blobs/CMakeLists.txt b/sdk/storage/azure-storage-blobs/CMakeLists.txt index 797c9a499..6e3440736 100644 --- a/sdk/storage/azure-storage-blobs/CMakeLists.txt +++ b/sdk/storage/azure-storage-blobs/CMakeLists.txt @@ -113,6 +113,8 @@ if(BUILD_STORAGE_SAMPLES) azure-storage-sample PRIVATE sample/blob_getting_started.cpp + sample/blob_list_operation.cpp + sample/blob_sas.cpp ) target_link_libraries(azure-storage-sample PRIVATE azure-storage-blobs) diff --git a/sdk/storage/azure-storage-blobs/sample/blob_list_operation.cpp b/sdk/storage/azure-storage-blobs/sample/blob_list_operation.cpp new file mode 100644 index 000000000..694a8e13d --- /dev/null +++ b/sdk/storage/azure-storage-blobs/sample/blob_list_operation.cpp @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include "samples_common.hpp" + +SAMPLE(BlobListOperation, BlobListOperation) +void BlobListOperation() +{ + using namespace Azure::Storage::Blobs; + + std::string containerName = "sample-container"; + std::string blobName = "sample-blob"; + std::string blobContent = "Hello Azure!"; + + { + // Create some containers and blobs for test + for (int i = 0; i < 2; ++i) + { + auto containerClient = BlobContainerClient::CreateFromConnectionString( + GetConnectionString(), containerName + std::to_string(i)); + containerClient.CreateIfNotExists(); + for (int j = 0; j < 3; ++j) + { + BlockBlobClient blobClient + = containerClient.GetBlockBlobClient(blobName + std::to_string(j)); + blobClient.UploadFrom( + reinterpret_cast(blobContent.data()), blobContent.size()); + } + } + } + + auto serviceClient = BlobServiceClient::CreateFromConnectionString(GetConnectionString()); + + for (auto containerPage = serviceClient.ListBlobContainers(); containerPage.HasPage(); + containerPage.MoveToNextPage()) + { + for (auto& container : containerPage.BlobContainers) + { + // Below is what you want to do with each container + std::cout << "blob container: " << container.Name << std::endl; + for (auto blobPage = serviceClient.GetBlobContainerClient(container.Name).ListBlobs(); + blobPage.HasPage(); + blobPage.MoveToNextPage()) + { + for (auto& blob : blobPage.Blobs) + { + // Below is what you want to do with each blob + std::cout << " blob: " << blob.Name << std::endl; + } + } + } + } +} diff --git a/sdk/storage/azure-storage-blobs/sample/blob_sas.cpp b/sdk/storage/azure-storage-blobs/sample/blob_sas.cpp new file mode 100644 index 000000000..1a7fc7880 --- /dev/null +++ b/sdk/storage/azure-storage-blobs/sample/blob_sas.cpp @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include "samples_common.hpp" + +SAMPLE(BlobSas, BlobSas) +void BlobSas() +{ + using namespace Azure::Storage::Blobs; + + std::string accountName = GetAccountName(); + std::string accountKey = GetAccountKey(); + + std::string containerName = "sample-container"; + std::string blobName = "sample-blob"; + std::string blobContent = "Hello Azure!"; + + // Create a container and a blob for test + { + auto credential + = std::make_shared(accountName, accountKey); + auto containerClient = BlobContainerClient( + "https://" + accountName + ".blob.core.windows.net/" + containerName, credential); + containerClient.CreateIfNotExists(); + BlockBlobClient blobClient = containerClient.GetBlockBlobClient(blobName); + blobClient.UploadFrom(reinterpret_cast(blobContent.data()), blobContent.size()); + } + + Azure::Storage::Sas::BlobSasBuilder sasBuilder; + sasBuilder.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60); + sasBuilder.BlobContainerName = containerName; + sasBuilder.BlobName = blobName; + sasBuilder.Resource = Azure::Storage::Sas::BlobSasResource::Blob; + // Read permission only + sasBuilder.SetPermissions(Azure::Storage::Sas::BlobSasPermissions::Read); + + std::string sasToken = sasBuilder.GenerateSasToken( + Azure::Storage::StorageSharedKeyCredential(accountName, accountKey)); + + auto blobClient = BlobClient( + "https://" + accountName + ".blob.core.windows.net/" + containerName + "/" + blobName + + sasToken); + + // We can read the blob + auto properties = blobClient.GetProperties().Value; + + try + { + + Azure::Storage::Metadata metadata; + // But we cannot write, this will throw + blobClient.SetMetadata(metadata); + // Never reach here + std::abort(); + } + catch (Azure::Storage::StorageException&) + { + } +} diff --git a/sdk/storage/azure-storage-common/inc/azure/storage/common/storage_credential.hpp b/sdk/storage/azure-storage-common/inc/azure/storage/common/storage_credential.hpp index fce86bc26..3a5bd7f72 100644 --- a/sdk/storage/azure-storage-common/inc/azure/storage/common/storage_credential.hpp +++ b/sdk/storage/azure-storage-common/inc/azure/storage/common/storage_credential.hpp @@ -77,6 +77,8 @@ namespace Azure { namespace Storage { struct ConnectionStringParts { + std::string AccountName; + std::string AccountKey; Azure::Core::Url BlobServiceUrl; Azure::Core::Url FileServiceUrl; Azure::Core::Url QueueServiceUrl; diff --git a/sdk/storage/azure-storage-common/sample/main.cpp b/sdk/storage/azure-storage-common/sample/main.cpp index 4892de11d..7c3139905 100644 --- a/sdk/storage/azure-storage-common/sample/main.cpp +++ b/sdk/storage/azure-storage-common/sample/main.cpp @@ -9,9 +9,11 @@ #include #include +#include + #include "samples_common.hpp" -const std::string& GetConnectionString() +std::string GetConnectionString() { const static std::string ConnectionString = ""; @@ -27,6 +29,16 @@ const std::string& GetConnectionString() throw std::runtime_error("Cannot find connection string"); } +std::string GetAccountName() +{ + return Azure::Storage::_internal::ParseConnectionString(GetConnectionString()).AccountName; +} + +std::string GetAccountKey() +{ + return Azure::Storage::_internal::ParseConnectionString(GetConnectionString()).AccountKey; +} + int main(int argc, char** argv) { if (argc != 2) diff --git a/sdk/storage/azure-storage-common/sample/samples_common.hpp b/sdk/storage/azure-storage-common/sample/samples_common.hpp index f09f768ba..1bfafeab1 100644 --- a/sdk/storage/azure-storage-common/sample/samples_common.hpp +++ b/sdk/storage/azure-storage-common/sample/samples_common.hpp @@ -7,7 +7,9 @@ #include #include -const std::string& GetConnectionString(); +std::string GetConnectionString(); +std::string GetAccountName(); +std::string GetAccountKey(); class Sample { public: diff --git a/sdk/storage/azure-storage-common/src/storage_credential.cpp b/sdk/storage/azure-storage-common/src/storage_credential.cpp index e5b588273..2defb9bc3 100644 --- a/sdk/storage/azure-storage-common/src/storage_credential.cpp +++ b/sdk/storage/azure-storage-common/src/storage_credential.cpp @@ -53,6 +53,7 @@ namespace Azure { namespace Storage { namespace _internal { std::string EndpointSuffix = getWithDefault(connectionStringMap, "EndpointSuffix", "core.windows.net"); std::string accountName = getWithDefault(connectionStringMap, "AccountName"); + connectionStringParts.AccountName = accountName; std::string endpoint = getWithDefault(connectionStringMap, "BlobEndpoint"); if (endpoint.empty() && !accountName.empty()) @@ -83,6 +84,7 @@ namespace Azure { namespace Storage { namespace _internal { connectionStringParts.QueueServiceUrl = Azure::Core::Url(std::move(endpoint)); std::string accountKey = getWithDefault(connectionStringMap, "AccountKey"); + connectionStringParts.AccountKey = accountKey; if (!accountKey.empty()) { if (accountName.empty())