Skip to content

Added Exists, CreateIfNotExists, and DeleteIfExists to Data Lake#9996

Merged
seanmcc-msft merged 2 commits intoAzure:masterfrom
seanmcc-msft:feature/storage/dataLakeExists2
Feb 18, 2020
Merged

Added Exists, CreateIfNotExists, and DeleteIfExists to Data Lake#9996
seanmcc-msft merged 2 commits intoAzure:masterfrom
seanmcc-msft:feature/storage/dataLakeExists2

Conversation

@seanmcc-msft
Copy link
Copy Markdown
Member

@seanmcc-msft seanmcc-msft commented Feb 15, 2020

@seanmcc-msft seanmcc-msft marked this pull request as ready for review February 15, 2020 01:35
try
{
scope.Start();
Response<BlobContainerInfo> containerResponse = await _containerClient.CreateIfNotExistsAsync(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit - this is getting close to enough logic that it might be nice to share a sync/async implementation with a CreateIfNotExistsInternal(..., bool async).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

DataLakeFileSystemClient.CreateIfNotExists() and DataLakeFileSystemClient.CreateIfNotExistsAsync() call BlobContainerClient.CreateIfNotExists() and BlobContainerClient.CreateIfNotExistsAsync(), respectively. BlobContainerClient.CreateIfNotExistsInternal() is private. I think creating a shared DataLakeFileSystemClient.CreateIfNotExistsInternal() would require duplicated most of the logic in BlobContainerClient.CreateIfNotExistsInternal(), so it would be a wash in terms of duplicate code.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it could just be the following in a shared method without exposing the internal blob method:

Response<BlobContainerInfo> containerResponse = async ?
    await _containerClient.CreateIfNotExistsAsync(...).ConfigureAwait(false) :
    _containerClient.CreateIfNotExists(...);

Again though, it doesn't matter as much for this one but it would be nice if/when you're adding other helpers with more complicated logic.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

cancellationToken).ConfigureAwait(false);
}
catch (RequestFailedException storageRequestFailedException)
when (storageRequestFailedException.ErrorCode == "PathAlreadyExists")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should have a DataLakeErrorCode.PathAlreadyExists to use instead of a hard-coded string, but I just noticed that none exists. We should file a bug and get that included before GA.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

try
{
scope.Start();
DataLakeRequestConditions conditions = new DataLakeRequestConditions { IfNoneMatch = new ETag("*") };
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit - I think we've got something like Constants.Wildcard for this string.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed.

scope.Start();

return _blockBlobClient.Exists(
cancellationToken);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit - not sure the extra line buys much for a single parameter, but we should at least indent

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed.

scope.Start();

return await _blockBlobClient.ExistsAsync(
cancellationToken).ConfigureAwait(false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit - indent here too

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed.

/// a failure occurs.
/// </remarks>
public virtual Response<bool> DeleteIfExists(
bool? recursive = default,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it worth making this a regular bool with a default of false or true? I don't have any good intuition what null would mean here as a customer.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is by design. recursive isn't a valid parameter when deleting a File, so when it is set to default, it is not included.

// Act
await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
unauthorizedDirecotry.CreateIfNotExistsAsync(),
e => Assert.AreEqual("AuthenticationFailed", e.ErrorCode.Split('\n')[0]));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the Split doing anything meaningful? Does the ErrorCode property return multiple lines of text?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It does not. I've removed it from all our Storage unit tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE REQ] Exists/CreateIfNotExists/DeleteIfExists for DataLake

2 participants