Azure/azure-storage-cpplite

API given error incorrectly even though it could connect and download blob

prasanthrgb opened this issue · 11 comments

I tried the sample.cpp provided with a little modification for logging and error checking. Please see below code. I gave correct credentials, the container and blob which i am trying to download exist and i could successfully download blob from blob storage.

But, i get error while creating storage_account, blob_client, blob client wrapper though my credentials are correct. I checked 'errno' variable. Please see the code and guide me if i am using it in a wrong way.

void checkstatus()
{
    if(errno == 0)
    {
        printf("Success\n");
    }
    else
    {
        printf("Failure\n");
    }
}

int main()
{
    std::shared_ptr<storage_credential> cred = nullptr;
    cred = std::make_shared<shared_key_credential>(account_name, account_key);


    printf("\nCreating account : ");
    std::shared_ptr<storage_account> account = std::make_shared<storage_account>(account_name, cred, /* use_https */ true);
    checkstatus();

    if(NULL != account)
    {
    	printf("\nCreating blob client : ");
    	auto bC = std::make_shared<blob_client>(account, 2);
    	checkstatus();

		std::string containerName = "con1";
		std::string blobName = "1.txt";

		bool exists = true;
		printf("\nCreating blob client wrapper : ");
		blob_client_wrapper bc(bC);
		checkstatus();

		printf("\nGet blob property: ");
		bc.get_blob_property(containerName, blobName);
		checkstatus();

		printf("\nChecking does container exist: ");
		exists = bc.container_exists(containerName);
		checkstatus();


		printf("\nChecking does blob exist: ");
		exists = bc.blob_exists(containerName, "1.txt");
		checkstatus();
		if(!exists)
		{
			printf("\n Blob name does not exist");
		}

		time_t last_modified;
		printf("\nDownloading file");
		bc.download_blob_to_file(containerName, blobName, "./13.txt", last_modified);
		std::cout <<"Download Blob done: " << errno << std::endl;
    }
    else
    {
    	std::cout <<"Download Error: " << errno << std::endl;
    }

    return 0;
    
}

@prasanthrgb Please try the code below

printf("\nCreating blob client : ");
auto bC = std::make_shared<blob_client>(account, 2);
printf("%s\n", bC ? "Success" : "Failure");
//checkstatus();

std::string containerName = "con1";
std::string blobName = "1.txt";

bool exists = true;
printf("\nCreating blob client wrapper : ");
blob_client_wrapper bc(bC);
printf("%s\n", bc.is_valid() ? "Success" : "Failure");
//checkstatus();

I strongly recommend you stay clear of blob_client_wrapper and always stick to blob_client, unless you have special requirements.

Thank you for the reply.

The below code worked for correct credentials. It gave success if correct credential is given.
auto bC = std::make_shared<blob_client>(account, 2);
printf("%s\n", bC ? "Success" : "Failure");

But with incorrect account name, it does not show 'Failure'. Also if invalid key is given the following crash occurs in the sample.cpp app.

"terminate called after throwing an instance of 'std::runtime_error'
what(): length of base64 string is not an even multiple of 4
Aborted (core dumped)"

Any help would be really appreciated.

Hi @prasanthrgb ,

There's no way for this sdk to verify whether an account name is valid or not. The endpoint is ACCOUNT_NAME.blob.core.windows.net. So if an invalid account name is given, the dns lookup would fail, and what would happen next totally depend on underlying HTTP client.

Key must be a valid base64-encoded string. You cannot use any random string to pretend an invalid key.

Ok Thanks!

I am planning to use blob_client as per suggestion.

But, #68 mention about a gap of blob_client with respect to blob client wrapper
"There is also a feature gap, where blob_client_wrapper supports concurrent upload, which needs to be ported to blob_client."

I hope that would not be a problem for me to use blob_client to use it for download operation. Please comments on this.

@prasanthrgb Yes, blob_client doesn't support that feature yet, it only supports single-thread operation for now. So if you want to upload a big blob in parallel, you cannot do it with blob_client. An workaround is to break the file into parts, and upload each part in parallel with upload_block_from_stream or upload_block_from_buffer.

Or you can formally request this feature, so that I can prioritize it.

Thank you very much for the reply.

I only want download operation now.
Just to check couple of this using blob client.
#1 . Does this support checking credential are correct or not?
#2. Does it suport parallel download ?

#1 . Does this support checking credential are correct or not?

Regarding this, the behavior of blob_client is pretty much the same as blob_client_wrapper. If the storage account exists but doesn't match the key, it will return HTTP 403. If the account name doesn't exist, usually the DNS lookup will fail, it should also return an error.

#2. Does it suport parallel download ?

Nope, neither parallel upload nor download is supported.

OK, thanks!
I hope blob client shall not throw exception.
May i know when we can expect sample which uses blob_client?

Meantime, Is there any documentation available to use blob_client?

I hope blob client shall not throw exception.

It actually doesn't throw exceptions, except when there's a bug in the SDK and when the storage account key isn't base64-encoded string.

May i know when we can expect sample which uses blob_client?

Maybe next week, I don't have too much time this week.

Meantime, Is there any documentation available to use blob_client?

It's quite easy actually, and there isn't any documentation except the sample that is coming.

Hi, Please let me know did u get enough time to look into this

@prasanthrgb Hi, please have a look at this PR #63, it's going to be released in no time.