Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppendBlobClient.getOutputStream(boolean) to overwrite correctly if set to true #33086

Merged
merged 15 commits into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/storage/azure-storage-blob/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Added support for 2021-12-02 service version.
- Added support for Blob Cold Tier `AccessTier.COLD`.
- Fixed bug where `BlobErrorCode.IncrementalCopyOfEarlierVersionSnapshotNotAllowed` was spelled incorrectly.
- Added new overload `AppendBlobClient.getBlobOutputStream(boolean)` that takes in a boolean for overwrite and appends to existing data if overwrite is specified `false`, or deletes and recreates a blob if overwrite is specified `true`.

### Breaking Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
*/
@ServiceClient(builder = SpecializedBlobClientBuilder.class)
public final class AppendBlobClient extends BlobClientBase {

private final AppendBlobAsyncClient appendBlobAsyncClient;

/**
Expand Down Expand Up @@ -99,7 +100,7 @@ public AppendBlobClient getCustomerProvidedKeyClient(CustomerProvidedKey custome

/**
* Creates and opens an output stream to write data to the append blob. If the blob already exists on the service,
* it will be overwritten.
* new data will get appended to the existing blob.
*
* @return A {@link BlobOutputStream} object used to write data to the blob.
* @throws BlobStorageException If a storage service error occurred.
Expand All @@ -109,8 +110,27 @@ public BlobOutputStream getBlobOutputStream() {
}

/**
* Creates and opens an output stream to write data to the append blob. If the blob already exists on the service,
* it will be overwritten.
* Creates and opens an output stream to write data to the append blob. If overwrite is specified {@code true},
* the existing blob will be deleted and recreated, should data exist on the blob. If overwrite is specified
* {@code false}, new data will get appended to the existing blob.
*
* @return A {@link BlobOutputStream} object used to write data to the blob.
* @param overwrite Whether an existing blob should be deleted and recreated, should data exist on the blob.
ibrahimrabab marked this conversation as resolved.
Show resolved Hide resolved
* @throws BlobStorageException If a storage service error occurred.
*/
public BlobOutputStream getBlobOutputStream(boolean overwrite) {
AppendBlobRequestConditions requestConditions = null;
if (!overwrite) {
requestConditions = new AppendBlobRequestConditions().setIfNoneMatch(Constants.HeaderConstants.ETAG_WILDCARD);
} else {
// creating new blob to overwrite existing blob
create(true);
}
return getBlobOutputStream(requestConditions);
}

/**
* Creates and opens an output stream to write data to the append blob.
*
* @param requestConditions A {@link BlobRequestConditions} object that represents the access conditions for the
* blob.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,61 @@ class BlobOutputStreamTest extends APISpec {
convertInputStreamToByteArray(appendBlobClient.openInputStream()) == data
}

@LiveOnly
def "AppendBlob output stream overwrite"() {
setup:
def data = getRandomByteArray(FOUR_MB)
def appendBlobClient = cc.getBlobClient(generateBlobName()).getAppendBlobClient()
appendBlobClient.create()

when:
def outputStream = appendBlobClient.getBlobOutputStream()
outputStream.write(data)
outputStream.close()

then:
convertInputStreamToByteArray(appendBlobClient.openInputStream()) == data

when:
def data2 = getRandomByteArray(FOUR_MB)

def outputStream2 = appendBlobClient.getBlobOutputStream(true)
outputStream2.write(data2)
outputStream2.close()

then:
appendBlobClient.getProperties().getBlobSize() == data2.length
convertInputStreamToByteArray(appendBlobClient.openInputStream()) == data2
}

@LiveOnly
def "AppendBlob output stream overwrite false"() {
setup:
def data = getRandomByteArray(Constants.MB)
def appendBlobClient = cc.getBlobClient(generateBlobName()).getAppendBlobClient()
appendBlobClient.create()

when:
def outputStream = appendBlobClient.getBlobOutputStream()
outputStream.write(data)
outputStream.close()

then:
convertInputStreamToByteArray(appendBlobClient.openInputStream()) == data

when:
def data2 = getRandomByteArray(Constants.MB)
outputStream = appendBlobClient.getBlobOutputStream(false)
outputStream.write(data2)
outputStream.close()

then:
def finalData = new byte[2 * Constants.MB]
System.arraycopy(data, 0, finalData, 0, data.length)
System.arraycopy(data2, 0, finalData, data.length, data2.length)
convertInputStreamToByteArray(appendBlobClient.openInputStream()) == finalData
}

def convertInputStreamToByteArray(InputStream inputStream) {
int b
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
Expand Down