Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
78996f1
update swagger file
browndav-msft May 13, 2026
e2225d6
fix linting
browndav-msft May 13, 2026
e33274c
add crc64 support for AppendBlock
browndav-msft May 14, 2026
59e195c
add crc64 support for PageBlob
browndav-msft May 18, 2026
dc5ef2c
add class header comment, add javadocs to constructorproxy
browndav-msft May 18, 2026
831042b
add support for crc64 for url upload, add tests
browndav-msft May 18, 2026
32ffdb1
add support for crc64 for blockblob
browndav-msft May 18, 2026
2be490c
Merge branch 'feature/storage/stg104base' into stg104/md5Crc64Merge
browndav-msft May 18, 2026
6ba8ad4
add service versions for tests, add recordings
browndav-msft May 18, 2026
7451e0d
remove added folder
browndav-msft May 18, 2026
dca4a80
remove changelog entry
browndav-msft May 18, 2026
b5f28d5
add tests for uploadUrl to BlockBlob and AppendBlob
browndav-msft May 19, 2026
d1a0f78
add recordings for uploadUrl for appendblob and blockblob
browndav-msft May 19, 2026
97396f4
change appendblob tests
browndav-msft May 20, 2026
342c745
change blockblobapi tests
browndav-msft May 20, 2026
1d7e404
change pageblob api tests
browndav-msft May 20, 2026
9334a0a
add recordings for new tests
browndav-msft May 20, 2026
bd80fd7
add separate upload from url tests for block blob api
browndav-msft May 20, 2026
a97b60b
add recordings for uploadFromUrlMaxReturnsCrc64
browndav-msft May 20, 2026
de43f67
add missing recordings
browndav-msft May 21, 2026
7d8e539
remove unneeded service version restrictions in test blockblob api test
browndav-msft May 22, 2026
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
2 changes: 1 addition & 1 deletion sdk/storage/azure-storage-blob/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/storage/azure-storage-blob",
"Tag": "java/storage/azure-storage-blob_47f4243e59"
"Tag": "java/storage/azure-storage-blob_48aa31792b"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.implementation.accesshelpers;

import com.azure.storage.blob.models.AppendBlobItem;

import java.time.OffsetDateTime;

/**
* Helper class to access private values of {@link AppendBlobItem} across package boundaries.
*/
public final class AppendBlobItemConstructorProxy {
private static AppendBlobItemConstructorAccessor accessor;

private AppendBlobItemConstructorProxy() {
}

/**
* Type defining the methods to set the non-public properties of an {@link AppendBlobItem}.
*/
public interface AppendBlobItemConstructorAccessor {
/**
* Creates a new instance of {@link AppendBlobItem}.
*
* @param eTag ETag of the append blob.
* @param lastModified Last modified time of the append blob.
* @param contentMd5 Content MD5 of the append blob.
* @param isServerEncrypted Flag indicating if the append blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the append blob.
* @param encryptionScope The encryption scope used to encrypt the append blob.
* @param blobAppendOffset The offset at which the block was committed to the append blob.
* @param blobCommittedBlockCount The number of committed blocks in the append blob.
* @param versionId The version identifier of the append blob.
* @param contentCrc64 Content CRC64 of the append blob.
* @return A new instance of {@link AppendBlobItem}.
*/
AppendBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5, boolean isServerEncrypted,
String encryptionKeySha256, String encryptionScope, String blobAppendOffset,
Integer blobCommittedBlockCount, String versionId, byte[] contentCrc64);
}

/**
* The method called from {@link AppendBlobItem} to set its accessor.
*
* @param accessor The accessor.
*/
public static void setAccessor(final AppendBlobItemConstructorAccessor accessor) {
AppendBlobItemConstructorProxy.accessor = accessor;
}

/**
* Creates a new instance of {@link AppendBlobItem}.
*
* @param eTag ETag of the append blob.
* @param lastModified Last modified time of the append blob.
* @param contentMd5 Content MD5 of the append blob.
* @param isServerEncrypted Flag indicating if the append blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the append blob.
* @param encryptionScope The encryption scope used to encrypt the append blob.
* @param blobAppendOffset The offset at which the block was committed to the append blob.
* @param blobCommittedBlockCount The number of committed blocks in the append blob.
* @param versionId The version identifier of the append blob.
* @param contentCrc64 Content CRC64 of the append blob.
* @return A new instance of {@link AppendBlobItem}.
*/
public static AppendBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5,
boolean isServerEncrypted, String encryptionKeySha256, String encryptionScope, String blobAppendOffset,
Integer blobCommittedBlockCount, String versionId, byte[] contentCrc64) {
// This looks odd but is necessary, it is possible to engage the access helper before anywhere else in the
// application accesses AppendBlobItem which triggers the accessor to be configured. So, if the accessor is null
// this effectively pokes the class to set up the accessor.
if (accessor == null) {
new AppendBlobItem(null, null, null, false, null, null, null, null, null);
}

assert accessor != null;
return accessor.create(eTag, lastModified, contentMd5, isServerEncrypted, encryptionKeySha256, encryptionScope,
blobAppendOffset, blobCommittedBlockCount, versionId, contentCrc64);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.implementation.accesshelpers;

import com.azure.storage.blob.models.BlockBlobItem;

import java.time.OffsetDateTime;

/**
* Helper class to access private values of {@link BlockBlobItem} across package boundaries.
*/
public final class BlockBlobItemConstructorProxy {
private static BlockBlobItemConstructorAccessor accessor;

private BlockBlobItemConstructorProxy() {
}

/**
* Type defining the methods to set the non-public properties of a {@link BlockBlobItem}.
*/
public interface BlockBlobItemConstructorAccessor {
/**
* Creates a new instance of {@link BlockBlobItem}.
*
* @param eTag ETag of the block blob.
* @param lastModified Last modified time of the block blob.
* @param contentMd5 Content MD5 of the block blob.
* @param isServerEncrypted Flag indicating if the block blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the block blob.
* @param encryptionScope The encryption scope used to encrypt the block blob.
* @param versionId The version identifier of the block blob.
* @param contentCrc64 Content CRC64 of the block blob.
* @return A new instance of {@link BlockBlobItem}.
*/
BlockBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5, Boolean isServerEncrypted,
String encryptionKeySha256, String encryptionScope, String versionId, byte[] contentCrc64);
}

/**
* The method called from {@link BlockBlobItem} to set its accessor.
*
* @param accessor The accessor.
*/
public static void setAccessor(final BlockBlobItemConstructorAccessor accessor) {
BlockBlobItemConstructorProxy.accessor = accessor;
}

/**
* Creates a new instance of {@link BlockBlobItem}.
*
* @param eTag ETag of the block blob.
* @param lastModified Last modified time of the block blob.
* @param contentMd5 Content MD5 of the block blob.
* @param isServerEncrypted Flag indicating if the block blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the block blob.
* @param encryptionScope The encryption scope used to encrypt the block blob.
* @param versionId The version identifier of the block blob.
* @param contentCrc64 Content CRC64 of the block blob.
* @return A new instance of {@link BlockBlobItem}.
*/
public static BlockBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5,
Boolean isServerEncrypted, String encryptionKeySha256, String encryptionScope, String versionId,
byte[] contentCrc64) {

if (accessor == null) {
new BlockBlobItem(null, null, null, (Boolean) null, null, null, null);
}

assert accessor != null;
return accessor.create(eTag, lastModified, contentMd5, isServerEncrypted, encryptionKeySha256, encryptionScope,
versionId, contentCrc64);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob.implementation.accesshelpers;

import com.azure.storage.blob.models.PageBlobItem;

import java.time.OffsetDateTime;

/**
* Helper class to access private values of {@link PageBlobItem} across package boundaries.
*/
public final class PageBlobItemConstructorProxy {
private static PageBlobItemConstructorAccessor accessor;

private PageBlobItemConstructorProxy() {
}

/**
* Type defining the methods to set the non-public properties of a {@link PageBlobItem}.
*/
public interface PageBlobItemConstructorAccessor {
/**
* Creates a new instance of {@link PageBlobItem}.
*
* @param eTag ETag of the page blob.
* @param lastModified Last modified time of the page blob.
* @param contentMd5 Content MD5 of the page blob.
* @param isServerEncrypted Flag indicating if the page blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the page blob.
* @param encryptionScope The encryption scope used to encrypt the page blob.
* @param blobSequenceNumber The current sequence number for the page blob.
* @param versionId The version identifier of the page blob.
* @param contentCrc64 Content CRC64 of the page blob.
* @return A new instance of {@link PageBlobItem}.
*/
PageBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5, Boolean isServerEncrypted,
String encryptionKeySha256, String encryptionScope, Long blobSequenceNumber, String versionId,
byte[] contentCrc64);
}

/**
* The method called from {@link PageBlobItem} to set its accessor.
*
* @param accessor The accessor.
*/
public static void setAccessor(final PageBlobItemConstructorAccessor accessor) {
PageBlobItemConstructorProxy.accessor = accessor;
}

/**
* Creates a new instance of {@link PageBlobItem}.
*
* @param eTag ETag of the page blob.
* @param lastModified Last modified time of the page blob.
* @param contentMd5 Content MD5 of the page blob.
* @param isServerEncrypted Flag indicating if the page blob is encrypted on the server.
* @param encryptionKeySha256 The encryption key used to encrypt the page blob.
* @param encryptionScope The encryption scope used to encrypt the page blob.
* @param blobSequenceNumber The current sequence number for the page blob.
* @param versionId The version identifier of the page blob.
* @param contentCrc64 Content CRC64 of the page blob.
* @return A new instance of {@link PageBlobItem}.
*/
public static PageBlobItem create(String eTag, OffsetDateTime lastModified, byte[] contentMd5,
Boolean isServerEncrypted, String encryptionKeySha256, String encryptionScope, Long blobSequenceNumber,
String versionId, byte[] contentCrc64) {

if (accessor == null) {
new PageBlobItem(null, null, null, false, null, null, null, null);
}

assert accessor != null;
return accessor.create(eTag, lastModified, contentMd5, isServerEncrypted, encryptionKeySha256, encryptionScope,
blobSequenceNumber, versionId, contentCrc64);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public final class BlockBlobsPutBlobFromUrlHeaders {
@Generated
private byte[] contentMD5;

/*
* The x-ms-content-crc64 property.
*/
@Generated
private byte[] xMsContentCrc64;

/*
* The x-ms-client-request-id property.
*/
Expand Down Expand Up @@ -84,6 +90,8 @@ public final class BlockBlobsPutBlobFromUrlHeaders {
@Generated
private String xMsEncryptionScope;

private static final HttpHeaderName X_MS_CONTENT_CRC64 = HttpHeaderName.fromString("x-ms-content-crc64");

private static final HttpHeaderName X_MS_VERSION = HttpHeaderName.fromString("x-ms-version");

private static final HttpHeaderName X_MS_VERSION_ID = HttpHeaderName.fromString("x-ms-version-id");
Expand Down Expand Up @@ -116,6 +124,12 @@ public BlockBlobsPutBlobFromUrlHeaders(HttpHeaders rawHeaders) {
} else {
this.contentMD5 = null;
}
String xMsContentCrc64 = rawHeaders.getValue(X_MS_CONTENT_CRC64);
if (xMsContentCrc64 != null) {
this.xMsContentCrc64 = Base64.getDecoder().decode(xMsContentCrc64);
} else {
this.xMsContentCrc64 = null;
}
this.xMsClientRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID);
this.xMsRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_REQUEST_ID);
this.xMsVersion = rawHeaders.getValue(X_MS_VERSION);
Expand Down Expand Up @@ -209,6 +223,28 @@ public BlockBlobsPutBlobFromUrlHeaders setContentMD5(byte[] contentMD5) {
return this;
}

/**
* Get the xMsContentCrc64 property: The x-ms-content-crc64 property.
*
* @return the xMsContentCrc64 value.
*/
@Generated
public byte[] getXMsContentCrc64() {
return CoreUtils.clone(this.xMsContentCrc64);
}

/**
* Set the xMsContentCrc64 property: The x-ms-content-crc64 property.
*
* @param xMsContentCrc64 the xMsContentCrc64 value to set.
* @return the BlockBlobsPutBlobFromUrlHeaders object itself.
*/
@Generated
public BlockBlobsPutBlobFromUrlHeaders setXMsContentCrc64(byte[] xMsContentCrc64) {
this.xMsContentCrc64 = CoreUtils.clone(xMsContentCrc64);
return this;
}

/**
* Get the xMsClientRequestId property: The x-ms-client-request-id property.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public final class BlockBlobsUploadHeaders {
@Generated
private byte[] contentMD5;

/*
* The x-ms-content-crc64 property.
*/
@Generated
private byte[] xMsContentCrc64;

/*
* The x-ms-client-request-id property.
*/
Expand Down Expand Up @@ -90,6 +96,8 @@ public final class BlockBlobsUploadHeaders {
@Generated
private String xMsStructuredBody;

private static final HttpHeaderName X_MS_CONTENT_CRC64 = HttpHeaderName.fromString("x-ms-content-crc64");

private static final HttpHeaderName X_MS_VERSION = HttpHeaderName.fromString("x-ms-version");

private static final HttpHeaderName X_MS_VERSION_ID = HttpHeaderName.fromString("x-ms-version-id");
Expand Down Expand Up @@ -124,6 +132,12 @@ public BlockBlobsUploadHeaders(HttpHeaders rawHeaders) {
} else {
this.contentMD5 = null;
}
String xMsContentCrc64 = rawHeaders.getValue(X_MS_CONTENT_CRC64);
if (xMsContentCrc64 != null) {
this.xMsContentCrc64 = Base64.getDecoder().decode(xMsContentCrc64);
} else {
this.xMsContentCrc64 = null;
}
this.xMsClientRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID);
this.xMsRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_REQUEST_ID);
this.xMsVersion = rawHeaders.getValue(X_MS_VERSION);
Expand Down Expand Up @@ -218,6 +232,28 @@ public BlockBlobsUploadHeaders setContentMD5(byte[] contentMD5) {
return this;
}

/**
* Get the xMsContentCrc64 property: The x-ms-content-crc64 property.
*
* @return the xMsContentCrc64 value.
*/
@Generated
public byte[] getXMsContentCrc64() {
return CoreUtils.clone(this.xMsContentCrc64);
}

/**
* Set the xMsContentCrc64 property: The x-ms-content-crc64 property.
*
* @param xMsContentCrc64 the xMsContentCrc64 value to set.
* @return the BlockBlobsUploadHeaders object itself.
*/
@Generated
public BlockBlobsUploadHeaders setXMsContentCrc64(byte[] xMsContentCrc64) {
this.xMsContentCrc64 = CoreUtils.clone(xMsContentCrc64);
return this;
}

/**
* Get the xMsClientRequestId property: The x-ms-client-request-id property.
*
Expand Down
Loading