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

Reapply "Blobs Sync Stack Migration (#40812)" (#41819) #41968

Merged
merged 34 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1aee530
Reapply "Blobs Sync Stack Migration (#40812)" (#41819)
ibrahimrabab Sep 20, 2024
8530117
removing wrapTimeoutServiceCallWithExceptionMapping instances everywh…
ibrahimrabab Sep 24, 2024
20c6640
fixing tests related to copyDestAC
ibrahimrabab Sep 25, 2024
b7fda35
adding test recordings since copyDestAC has sanitized headers
ibrahimrabab Sep 25, 2024
5443186
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Sep 25, 2024
5dd12c7
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Sep 25, 2024
d98a1fb
updating test recording since values are sanitized now
ibrahimrabab Sep 25, 2024
c3f4c28
added back wrapTimeoutServiceCallWithExceptionMapping
ibrahimrabab Sep 25, 2024
8be924c
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Sep 26, 2024
6b363ee
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Sep 26, 2024
684a2b3
adding swagger changes to the impl files
ibrahimrabab Sep 26, 2024
454e572
removing wrapTimeoutServiceCallWithExceptionMapping
ibrahimrabab Sep 26, 2024
9117b8b
removing unused imports
ibrahimrabab Sep 26, 2024
ca3ef41
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Oct 2, 2024
4410f29
updating core-http-vertx dependency
ibrahimrabab Oct 2, 2024
c2e0bc6
removing extra imports in datalake pom file
ibrahimrabab Oct 2, 2024
0bd8485
removing unreleased versions since they've been released from version…
ibrahimrabab Oct 2, 2024
edb3cd4
removing okhttp and vertx
ibrahimrabab Oct 2, 2024
a824f81
reverted changes done to queryWithResponse and queryInputStream
ibrahimrabab Oct 8, 2024
31f8525
removing unused imports
ibrahimrabab Oct 8, 2024
8100fbf
removing unused constructors
ibrahimrabab Oct 8, 2024
13cf877
reverting changes in FileApiTest
ibrahimrabab Oct 8, 2024
b186468
removing unnecessary comments
ibrahimrabab Oct 9, 2024
2cc1565
removing blob error code checks to match async implementation
ibrahimrabab Oct 10, 2024
635211d
adding BlobConstants, resolving comments
ibrahimrabab Oct 15, 2024
c5f5645
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Oct 15, 2024
6cc9752
adding exception handling in spotbugs for beginCopy in BlobClientBase
ibrahimrabab Oct 15, 2024
fdda684
removing spotbugs-exclude from overall code quality package, removed …
ibrahimrabab Oct 16, 2024
b879bb9
removing commented out code
ibrahimrabab Oct 16, 2024
61d6e3d
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Oct 16, 2024
4fda2e1
removing extra methods from ModelHelper, avoiding mutating options in…
ibrahimrabab Oct 16, 2024
124f1f8
removing HttpResponseException and using BlobStorageException for con…
ibrahimrabab Oct 16, 2024
14f2f7b
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-java in…
ibrahimrabab Oct 17, 2024
325f26a
adding mock service version to get nullQueryResponse test working
ibrahimrabab Oct 17, 2024
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
7 changes: 7 additions & 0 deletions sdk/storage/azure-storage-blob/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@
<suppress files="com.azure.storage.blob.implementation.util.ModelHelper.java" checks="com.azure.tools.checkstyle.checks.JavadocThrowsChecks" />
<suppress files="com.azure.storage.blob.implementation.AzureBlobStorageImplBuilder.java" checks="com.azure.tools.checkstyle.checks.ServiceClientBuilderCheck" />
<suppress files="com.azure.storage.blob.BlobClient.java" checks="com.azure.tools.checkstyle.checks.ServiceClientCheck" />
<suppress files="com.azure.storage.blob.specialized.BlobLeaseClient.java" checks="com.azure.tools.checkstyle.checks.ServiceClientCheck" />
<suppress files="com.azure.storage.blob.specialized.BlobLeaseAsyncClient.java" checks="com.azure.tools.checkstyle.checks.ServiceClientCheck" />
<suppress files="com.azure.storage.blob.specialized.BlobInputStream.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.specialized.BlobOutputStream.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.AppendBlobsImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.PageBlobsImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.ServicesImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.BlobsImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.BlockBlobsImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="com.azure.storage.blob.implementation.ContainersImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
</suppressions>
11 changes: 11 additions & 0 deletions sdk/storage/azure-storage-blob/spotbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<Class name="com.azure.storage.blob.implementation.util.BlobSasImplUtil" />
<Class name="com.azure.storage.blob.models.CustomerProvidedKey" />
<Class name="com.azure.storage.blob.specialized.BlobAsyncClientBase" />
<Class name="com.azure.storage.blob.specialized.BlobClientBase" />
</Or>
</Match>
<Match>
Expand Down Expand Up @@ -185,4 +186,14 @@
<Class name="com.azure.storage.blob.sas.BlobServiceSasSignatureValues" />
</Or>
</Match>
<Match>
<Bug pattern="MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR" />
<Class name="com.azure.storage.blob.specialized.BlobClientBase" />
</Match>
<!-- Return poll status as failed instead of throwing any exception -->
<Match>
<Class name="com.azure.storage.blob.specialized.BlobClientBase"/>
<Method name="onPoll"/>
<Bug pattern="REC_CATCH_EXCEPTION"/>
</Match>
</FindBugsFilter>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.azure.core.util.ProgressReporter;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.blob.implementation.models.EncryptionScope;
import com.azure.storage.blob.implementation.util.BlobConstants;
import com.azure.storage.blob.implementation.util.ModelHelper;
import com.azure.storage.blob.models.AccessTier;
import com.azure.storage.blob.models.BlobHttpHeaders;
Expand Down Expand Up @@ -85,19 +86,19 @@ public class BlobAsyncClient extends BlobAsyncClientBase {
/**
* The block size to use if none is specified in parallel operations.
*/
public static final int BLOB_DEFAULT_UPLOAD_BLOCK_SIZE = 4 * Constants.MB;
public static final int BLOB_DEFAULT_UPLOAD_BLOCK_SIZE = BlobConstants.BLOB_DEFAULT_UPLOAD_BLOCK_SIZE;

/**
* The number of buffers to use if none is specified on the buffered upload method.
*/
public static final int BLOB_DEFAULT_NUMBER_OF_BUFFERS = 8;
public static final int BLOB_DEFAULT_NUMBER_OF_BUFFERS = BlobConstants.BLOB_DEFAULT_NUMBER_OF_BUFFERS;

/**
* If a blob is known to be greater than 100MB, using a larger block size will trigger some server-side
* optimizations. If the block size is not set and the size of the blob is known to be greater than 100MB, this
* value will be used.
*/
public static final int BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE = 8 * Constants.MB;
public static final int BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE = BlobConstants.BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE;

static final long BLOB_MAX_UPLOAD_BLOCK_SIZE = 4000L * Constants.MB;

Expand All @@ -107,7 +108,7 @@ public class BlobAsyncClient extends BlobAsyncClientBase {
* and {@link BinaryData#fromFile(Path, Long, Long, int)}
* to represent the content.
*/
private static final int DEFAULT_FILE_READ_CHUNK_SIZE = 1024 * 64;
private static final int DEFAULT_FILE_READ_CHUNK_SIZE = BlobConstants.DEFAULT_FILE_READ_CHUNK_SIZE;

private static final ClientLogger LOGGER = new ClientLogger(BlobAsyncClient.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceClient;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.azure.core.util.Context;
import com.azure.core.util.FluxUtil;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.blob.implementation.models.EncryptionScope;
import com.azure.storage.blob.implementation.util.BlobConstants;
import com.azure.storage.blob.implementation.util.ModelHelper;
import com.azure.storage.blob.models.AccessTier;
import com.azure.storage.blob.models.CpkInfo;
import com.azure.storage.blob.models.CustomerProvidedKey;
import com.azure.storage.blob.options.BlobParallelUploadOptions;
import com.azure.storage.blob.models.BlobRequestConditions;
Expand All @@ -32,6 +36,8 @@

import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -61,19 +67,26 @@ public class BlobClient extends BlobClientBase {
/**
* The block size to use if none is specified in parallel operations.
*/
public static final int BLOB_DEFAULT_UPLOAD_BLOCK_SIZE = BlobAsyncClient.BLOB_DEFAULT_UPLOAD_BLOCK_SIZE;
public static final int BLOB_DEFAULT_UPLOAD_BLOCK_SIZE = BlobConstants.BLOB_DEFAULT_UPLOAD_BLOCK_SIZE;

/**
* The number of buffers to use if none is specied on the buffered upload method.
* The number of buffers to use if none is specified on the buffered upload method.
*/
public static final int BLOB_DEFAULT_NUMBER_OF_BUFFERS = BlobAsyncClient.BLOB_DEFAULT_NUMBER_OF_BUFFERS;
public static final int BLOB_DEFAULT_NUMBER_OF_BUFFERS = BlobConstants.BLOB_DEFAULT_NUMBER_OF_BUFFERS;
/**
* If a blob is known to be greater than 100MB, using a larger block size will trigger some server-side
* optimizations. If the block size is not set and the size of the blob is known to be greater than 100MB, this
* value will be used.
*/
public static final int BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE = BlobAsyncClient.BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE;
public static final int BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE = BlobConstants.BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE;

/**
* The default block size used in {@link FluxUtil#readFile(AsynchronousFileChannel)}.
* This is to make sure we're using same size when using {@link BinaryData#fromFile(Path, int)}
* and {@link BinaryData#fromFile(Path, Long, Long, int)}
* to represent the content.
*/
private static final int DEFAULT_FILE_READ_CHUNK_SIZE = BlobConstants.DEFAULT_FILE_READ_CHUNK_SIZE;
private final BlobAsyncClient client;

private BlockBlobClient blockBlobClient;
Expand All @@ -89,6 +102,31 @@ protected BlobClient(BlobAsyncClient client) {
this.client = client;
}

/**
* Protected constructor for use by {@link BlobClientBuilder}.
*
* @param client the async blob client
* @param pipeline The pipeline used to send and receive service requests.
* @param url The endpoint where to send service requests.
* @param serviceVersion The version of the service to receive requests.
* @param accountName The storage account name.
* @param containerName The container name.
* @param blobName The blob name.
* @param snapshot The snapshot identifier for the blob, pass {@code null} to interact with the blob directly.
* @param customerProvidedKey Customer provided key used during encryption of the blob's data on the server, pass
* {@code null} to allow the service to use its own encryption.
* @param encryptionScope Encryption scope used during encryption of the blob's data on the server, pass
* {@code null} to allow the service to use its own encryption.
* @param versionId The version identifier for the blob, pass {@code null} to interact with the latest blob version.
*/
protected BlobClient(BlobAsyncClient client, HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion,
String accountName, String containerName, String blobName, String snapshot, CpkInfo customerProvidedKey,
EncryptionScope encryptionScope, String versionId) {
super(client, pipeline, url, serviceVersion, accountName, containerName, blobName, snapshot, customerProvidedKey,
encryptionScope, versionId);
this.client = client;
}

/**
* Creates a new {@link BlobClient} linked to the {@code snapshot} of this blob resource.
*
Expand All @@ -97,7 +135,11 @@ protected BlobClient(BlobAsyncClient client) {
*/
@Override
public BlobClient getSnapshotClient(String snapshot) {
return new BlobClient(client.getSnapshotClient(snapshot));
BlobAsyncClient asyncClient = new BlobAsyncClient(getHttpPipeline(), getAccountUrl(), getServiceVersion(),
getAccountName(), getContainerName(), getBlobName(), snapshot, getCustomerProvidedKey(),
encryptionScope, getVersionId());
return new BlobClient(asyncClient, getHttpPipeline(), getAccountUrl(), getServiceVersion(), getAccountName(),
getContainerName(), getBlobName(), snapshot, getCustomerProvidedKey(), encryptionScope, getVersionId());
}

/**
Expand All @@ -109,7 +151,11 @@ public BlobClient getSnapshotClient(String snapshot) {
*/
@Override
public BlobClient getVersionClient(String versionId) {
return new BlobClient(client.getVersionClient(versionId));
BlobAsyncClient asyncClient = new BlobAsyncClient(getHttpPipeline(), getAccountUrl(), getServiceVersion(),
getAccountName(), getContainerName(), getBlobName(), getSnapshotId(), getCustomerProvidedKey(),
encryptionScope, versionId);
return new BlobClient(asyncClient, getHttpPipeline(), getAccountUrl(), getServiceVersion(), getAccountName(),
getContainerName(), getBlobName(), getSnapshotId(), getCustomerProvidedKey(), encryptionScope, versionId);
}

/**
Expand All @@ -120,7 +166,13 @@ public BlobClient getVersionClient(String versionId) {
*/
@Override
public BlobClient getEncryptionScopeClient(String encryptionScope) {
return new BlobClient(client.getEncryptionScopeAsyncClient(encryptionScope));
EncryptionScope finalEncryptionScope = null;
if (encryptionScope != null) {
finalEncryptionScope = new EncryptionScope().setEncryptionScope(encryptionScope);
}
return new BlobClient(this.client.getEncryptionScopeAsyncClient(encryptionScope), getHttpPipeline(),
getAccountUrl(), getServiceVersion(), getAccountName(), getContainerName(), getBlobName(), getSnapshotId(),
getCustomerProvidedKey(), finalEncryptionScope, getVersionId());
}

/**
Expand All @@ -132,7 +184,16 @@ public BlobClient getEncryptionScopeClient(String encryptionScope) {
*/
@Override
public BlobClient getCustomerProvidedKeyClient(CustomerProvidedKey customerProvidedKey) {
return new BlobClient(client.getCustomerProvidedKeyAsyncClient(customerProvidedKey));
CpkInfo finalCustomerProvidedKey = null;
if (customerProvidedKey != null) {
finalCustomerProvidedKey = new CpkInfo()
.setEncryptionKey(customerProvidedKey.getKey())
.setEncryptionKeySha256(customerProvidedKey.getKeySha256())
.setEncryptionAlgorithm(customerProvidedKey.getEncryptionAlgorithm());
}
return new BlobClient(this.client.getCustomerProvidedKeyAsyncClient(customerProvidedKey), getHttpPipeline(),
getAccountUrl(), getServiceVersion(), getAccountName(), getContainerName(), getBlobName(), getSnapshotId(),
finalCustomerProvidedKey, encryptionScope, getVersionId());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,29 @@ public BlobClientBuilder() {
* and {@link #retryOptions(RequestRetryOptions)} have been set.
*/
public BlobClient buildClient() {
return new BlobClient(buildAsyncClient());
Objects.requireNonNull(blobName, "'blobName' cannot be null.");
Objects.requireNonNull(endpoint, "'endpoint' cannot be null");

BuilderHelper.httpsValidation(customerProvidedKey, "customer provided key", endpoint, LOGGER);

if (Objects.nonNull(customerProvidedKey) && Objects.nonNull(encryptionScope)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException("Customer provided key and encryption "
+ "scope cannot both be set"));
}

/*
Implicit and explicit root container access are functionally equivalent, but explicit references are easier
to read and debug.
*/
String blobContainerName = CoreUtils.isNullOrEmpty(containerName) ? BlobContainerClient.ROOT_CONTAINER_NAME
: containerName;

BlobServiceVersion serviceVersion = version != null ? version : BlobServiceVersion.getLatest();

BlobAsyncClient asyncClient = buildAsyncClient();

return new BlobClient(asyncClient, asyncClient.getHttpPipeline(), endpoint, serviceVersion, accountName,
kyleknap marked this conversation as resolved.
Show resolved Hide resolved
blobContainerName, blobName, snapshot, customerProvidedKey, encryptionScope, versionId);
}

/**
Expand Down Expand Up @@ -171,15 +193,19 @@ public BlobAsyncClient buildAsyncClient() {

BlobServiceVersion serviceVersion = version != null ? version : BlobServiceVersion.getLatest();

HttpPipeline pipeline = (httpPipeline != null) ? httpPipeline : BuilderHelper.buildPipeline(
storageSharedKeyCredential, tokenCredential, azureSasCredential, sasToken,
endpoint, retryOptions, coreRetryOptions, logOptions,
clientOptions, httpClient, perCallPolicies, perRetryPolicies, configuration, audience, LOGGER);
HttpPipeline pipeline = constructPipeline();

return new BlobAsyncClient(pipeline, endpoint, serviceVersion, accountName, blobContainerName, blobName,
snapshot, customerProvidedKey, encryptionScope, versionId);
}

private HttpPipeline constructPipeline() {
return (httpPipeline != null) ? httpPipeline : BuilderHelper.buildPipeline(
storageSharedKeyCredential, tokenCredential, azureSasCredential, sasToken,
endpoint, retryOptions, coreRetryOptions, logOptions,
clientOptions, httpClient, perCallPolicies, perRetryPolicies, configuration, audience, LOGGER);
}

/**
* Sets the {@link CustomerProvidedKey customer provided key} that is used to encrypt blob contents on the server.
*
Expand Down
Loading