com.microsoft.azure.storage.blob.BlobRequestOptions Maven / Gradle / Ivy
Show all versions of azure-storage Show documentation
/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.azure.storage.blob;
import com.microsoft.azure.storage.Constants;
import com.microsoft.azure.storage.RequestOptions;
import com.microsoft.azure.storage.ServiceClient;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.core.Utility;
/**
* Represents a set of options that may be specified on a request.
*/
public final class BlobRequestOptions extends RequestOptions {
/**
* Indicates whether a conditional failure should be absorbed on a retry attempt for the request. This option
* is only used by {@link CloudAppendBlob} in upload and openWrite methods. By default, it is set to
* false
. Set this to true
only for single writer scenario.
*/
private Boolean absorbConditionalErrorsOnRetry = null;
/**
* Represents the concurrent number of simultaneous requests per operation. The default value is 1.
*/
private Integer concurrentRequestCount = null;
/**
* Specifies whether a range PUT or GET operation will use the Content-MD5 header to enforce transactional security.
* All partial blob uploads or downloads will be restricted to 4 MB. The default value is false
.
*/
private Boolean useTransactionalContentMD5 = null;
/**
* Specifies whether the blob's ContentMD5 header should be set on uploads. This field is not supported for page
* blobs. The default value is false
.
*/
private Boolean storeBlobContentMD5 = null;
/**
* Specifies whether download and {@link BlobInputStream} methods should ignore the blob's ContentMD5 header. The
* default value is false
.
*/
private Boolean disableContentMD5Validation = null;
/**
* Holds the maximum size of a blob in bytes that may be uploaded as a single blob.
*/
private Integer singleBlobPutThresholdInBytes = null;
/**
* The encryption policy to use for the request.
*/
private BlobEncryptionPolicy encryptionPolicy;
/**
* The customer-provided key wrapper for server-side encryption.
*/
private BlobCustomerProvidedKey customerProvidedKey;
/**
* The customer-provided key wrapper for server-side decryption of the source for a copy operation.
*/
// TODO uncomment when source CPK decryption is supported
//private BlobCustomerProvidedKey sourceCustomerProvidedKey;
/**
* Stores a value indicating whether to validate the presence of the encryption policy.
* Default is true.
*/
private boolean validateEncryptionPolicy = true;
/**
* WARNING: etag locking is automatically used in blob downloads to ensure the blob does not change mid-download.
* Skip this validation at your own risk.
* Default is false.
*/
private boolean skipEtagLocking = false;
/**
* A boolean
that defines the behavior for handling exceptions when reading from the
* InputStream
and using openWrite
. If true
the data that has been read from
* the stream up to the point of the exception will be flushed and a new blob will be committed with that data.
* Otherwise, the upload will be aborted and no data will be committed.
*/
private boolean commitWriteOnInputStreamException = true;
/**
* Creates an instance of the BlobRequestOptions
class.
*/
public BlobRequestOptions() {
// Empty Default Constructor.
}
/**
* Creates an instance of the BlobRequestOptions
class by copying values from another
* BlobRequestOptions
instance.
*
* @param other
* A {@link BlobRequestOptions} object which represents the blob request options to copy.
*/
public BlobRequestOptions(final BlobRequestOptions other) {
super(other);
if (other != null) {
this.setAbsorbConditionalErrorsOnRetry(other.getAbsorbConditionalErrorsOnRetry());
this.setConcurrentRequestCount(other.getConcurrentRequestCount());
this.setUseTransactionalContentMD5(other.getUseTransactionalContentMD5());
this.setStoreBlobContentMD5(other.getStoreBlobContentMD5());
this.setDisableContentMD5Validation(other.getDisableContentMD5Validation());
this.setSingleBlobPutThresholdInBytes(other.getSingleBlobPutThresholdInBytes());
this.setEncryptionPolicy(other.getEncryptionPolicy());
this.setCustomerProvidedKey(other.getCustomerProvidedKey());
// TODO uncomment when source CPK decryption is supported
//this.setSourceCustomerProvidedKey(other.getSourceCustomerProvidedKey());
this.setValidateEncryptionPolicy(other.getValidateEncryptionPolicy());
this.setSkipEtagLocking(other.getSkipEtagLocking());
this.setCommitWriteOnInputStreamException(other.getCommitWriteOnInputStreamException());
}
}
/**
* Uses the concurrent request count from the specified client if null
, sets a default value for
* everything else, and sets defaults as defined in the parent class.
*
* @param options
* The input options to copy from when applying defaults
* @param blobType
* BlobType of the current operation
* @param client
* A {@link CloudBlobClient} object that represents the service client used to set the default timeout
* interval and retry policy, if they are null
. Additionally, the default value of
* {@link #concurrentRequestCount} is 1
.
*/
protected static final BlobRequestOptions populateAndApplyDefaults(final BlobRequestOptions options,
final BlobType blobType, final CloudBlobClient client) {
return BlobRequestOptions.populateAndApplyDefaults(options, blobType, client, true);
}
/**
* Uses the concurrent request count from the specified client if null
, sets a default value for
* everything else, and sets defaults as defined in the parent class.
*
* @param options
* The input options to copy from when applying defaults
* @param blobType
* BlobType of the current operation
* @param client
* A {@link CloudBlobClient} object that represents the service client used to set the default timeout
* interval and retry policy, if they are null
. Additionally, the default value of
* {@link #concurrentRequestCount} is 1
.
* @param setStartTime
* whether to initialize the startTimeInMs field, or not
*/
protected static final BlobRequestOptions populateAndApplyDefaults(final BlobRequestOptions options,
final BlobType blobType, final CloudBlobClient client, final boolean setStartTime) {
BlobRequestOptions modifiedOptions = new BlobRequestOptions(options);
BlobRequestOptions.populateRequestOptions(modifiedOptions, client.getDefaultRequestOptions(), setStartTime);
BlobRequestOptions.applyDefaults(modifiedOptions, blobType);
return modifiedOptions;
}
/**
* Applies defaults to the options passed in.
*
* @param modifiedOptions
* The options to apply defaults to.
*/
protected static void applyDefaults(final BlobRequestOptions modifiedOptions, final BlobType blobtype) {
Utility.assertNotNull("modifiedOptions", modifiedOptions);
RequestOptions.applyBaseDefaultsInternal(modifiedOptions);
if (modifiedOptions.getAbsorbConditionalErrorsOnRetry() == null) {
modifiedOptions.setAbsorbConditionalErrorsOnRetry(false);
}
if (blobtype == BlobType.APPEND_BLOB) {
// Append blobs must be done in serial.
modifiedOptions.setConcurrentRequestCount(1);
} else if (modifiedOptions.getConcurrentRequestCount() == null) {
modifiedOptions.setConcurrentRequestCount(BlobConstants.DEFAULT_CONCURRENT_REQUEST_COUNT);
}
if (modifiedOptions.getSingleBlobPutThresholdInBytes() == null) {
modifiedOptions.setSingleBlobPutThresholdInBytes(BlobConstants.DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES);
}
if (modifiedOptions.getUseTransactionalContentMD5() == null) {
modifiedOptions.setUseTransactionalContentMD5(false);
}
if (modifiedOptions.getStoreBlobContentMD5() == null) {
if (blobtype != BlobType.UNSPECIFIED) {
modifiedOptions.setStoreBlobContentMD5(blobtype == BlobType.BLOCK_BLOB);
}
}
if (modifiedOptions.getDisableContentMD5Validation() == null) {
modifiedOptions.setDisableContentMD5Validation(false);
}
}
/**
* Populates any null fields in the first requestOptions object with values from the second requestOptions object.
*/
private static void populateRequestOptions(BlobRequestOptions modifiedOptions,
final BlobRequestOptions clientOptions, final boolean setStartTime) {
RequestOptions.populateRequestOptions(modifiedOptions, clientOptions, setStartTime);
if (modifiedOptions.getAbsorbConditionalErrorsOnRetry() == null) {
modifiedOptions.setAbsorbConditionalErrorsOnRetry(clientOptions.getAbsorbConditionalErrorsOnRetry());
}
if (modifiedOptions.getConcurrentRequestCount() == null) {
modifiedOptions.setConcurrentRequestCount(clientOptions.getConcurrentRequestCount());
}
if (modifiedOptions.getSingleBlobPutThresholdInBytes() == null) {
modifiedOptions.setSingleBlobPutThresholdInBytes(clientOptions.getSingleBlobPutThresholdInBytes());
}
if (modifiedOptions.getUseTransactionalContentMD5() == null) {
modifiedOptions.setUseTransactionalContentMD5(clientOptions.getUseTransactionalContentMD5());
}
if (modifiedOptions.getStoreBlobContentMD5() == null) {
modifiedOptions.setStoreBlobContentMD5(clientOptions.getStoreBlobContentMD5());
}
if (modifiedOptions.getDisableContentMD5Validation() == null) {
modifiedOptions.setDisableContentMD5Validation(clientOptions.getDisableContentMD5Validation());
}
if (modifiedOptions.getEncryptionPolicy() == null) {
modifiedOptions.setEncryptionPolicy(clientOptions.getEncryptionPolicy());
}
if (modifiedOptions.getCustomerProvidedKey() == null) {
modifiedOptions.setCustomerProvidedKey(clientOptions.getCustomerProvidedKey());
}
// TODO uncomment when source CPK decryption is supported
/*if (modifiedOptions.getSourceCustomerProvidedKey() == null) {
modifiedOptions.setSourceCustomerProvidedKey(clientOptions.getSourceCustomerProvidedKey());
}*/
}
/**
* Indicates whether a conditional failure should be absorbed on a retry attempt for the request. For more
* information about absorb conditinal errors on retry defaults, see {@link #setAbsorbConditionalErrorsOnRetry(Boolean)}.
*
* @return the absorbConditionalErrorsOnRetry
*/
public Boolean getAbsorbConditionalErrorsOnRetry() {
return this.absorbConditionalErrorsOnRetry;
}
/**
* Gets the concurrent number of simultaneous requests per operation. For more information about concurrent request
* count defaults, see {@link #setConcurrentRequestCount(Integer)}.
*
* @return the concurrentRequestCount
*/
public Integer getConcurrentRequestCount() {
return this.concurrentRequestCount;
}
/**
* Gets whether a range PUT or GET operation will use the Content-MD5 header to enforce transactional security.
* All partial blob uploads or downloads will be restricted to 4 MB. For more information about transactional
* content MD5 defaults, see {@link #setUseTransactionalContentMD5(Boolean)}.
*
* @return the useTransactionalContentMD5
*/
public Boolean getUseTransactionalContentMD5() {
return this.useTransactionalContentMD5;
}
/**
* Gets whether the blob's ContentMD5 header should be set on uploads. This field is not supported for page
* blobs. For more information about storing blob content MD5 defaults, see {@link #setStoreBlobContentMD5(Boolean)}
* .
*
* @return the storeBlobContentMD5
*/
public Boolean getStoreBlobContentMD5() {
return this.storeBlobContentMD5;
}
/**
* Gets whether download and {@link BlobInputStream} methods should ignore the blob's ContentMD5 header. For more
* information about disabling content MD5 validation defaults, see {@link #setDisableContentMD5Validation(Boolean)}
* .
*
* @return the disableContentMD5Validation
*/
public Boolean getDisableContentMD5Validation() {
return this.disableContentMD5Validation;
}
/**
* Gets the threshold size used for writing a single blob. For more information about the threshold size defaults,
* see {@link #setSingleBlobPutThresholdInBytes(Integer)}.
*
* @return The maximum size, in bytes, of a blob that may be uploaded as a single blob, ranging from 1 to 64 MB
* inclusive. If a blob size is above the threshold, it will be uploaded as blocks.
*/
public Integer getSingleBlobPutThresholdInBytes() {
return this.singleBlobPutThresholdInBytes;
}
/**
* Gets the encryption policy to use for this request. For more information about the encryption policy defaults,
* see {@link #setEncryptionPolicy(BlobEncryptionPolicy)}.
*
* @return An {@link BlobEncryptionPolicy} object that represents the current encryption policy.
*/
public BlobEncryptionPolicy getEncryptionPolicy() {
return this.encryptionPolicy;
}
/**
* Gets the customer-provided key to use for this request.
*
* @return A {@link BlobCustomerProvidedKey} object that represents the current customer-provided key.
*/
public BlobCustomerProvidedKey getCustomerProvidedKey() {
return this.customerProvidedKey;
}
/**
* Gets the customer-provided key to use on the source for a copy request.
*
* @return A {@link BlobCustomerProvidedKey} object that represents the source's customer-provided key.
*/
// TODO uncomment when source CPK decryption is supported
/*public BlobCustomerProvidedKey getSourceCustomerProvidedKey() {
return this.sourceCustomerProvidedKey;
}*/
/**
* Gets a value to indicating whether the presence of the encryption policy should validated.
*
* @return true
if validation is required; otherwise, false
.
*/
protected boolean getValidateEncryptionPolicy() {
return this.validateEncryptionPolicy;
}
/**
* WARNING: etag locking is automatically used in blob downloads to ensure the blob does not change mid-download.
* Skip this validation at your own risk.
*
* Gets whether etag locking and validation on blob downloads should be skipped.
*
* @return true
if skipping is enabled; otherwise, false
.
*/
public boolean getSkipEtagLocking() {
return this.skipEtagLocking;
}
/**
* A boolean
that defines the behavior for handling exceptions when reading from the
* InputStream
and using openWrite
. If true
the data that has been read from
* the stream up to the point of the exception will be flushed and a new blob will be committed with that data.
* Otherwise, the upload will be aborted and no data will be committed.
*
* For more information about defaults, see {@link #setCommitWriteOnInputStreamException(boolean)}.
*
* @return true
if data will be committed upon an exception; otherwise, false
.
*/
public boolean getCommitWriteOnInputStreamException() {
return this.commitWriteOnInputStreamException;
}
/**
* Sets whether a conditional failure should be absorbed on a retry attempt for the request. This option
* is only used by {@link CloudAppendBlob} in upload and openWrite methods. By default, it is set to
* false
. Set this to true
only for single writer scenario.
*
* You can change the absorbConditionalErrorsOnRetry value on this request by setting this property. You can also
* change the value on the {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests
* made via the service client will use that absorbConditionalErrorsOnRetry value.
*
* @param absorbConditionalErrorsOnRetry
* the absorbConditionalErrorsOnRetry to set
*/
public void setAbsorbConditionalErrorsOnRetry(final Boolean absorbConditionalErrorsOnRetry) {
this.absorbConditionalErrorsOnRetry = absorbConditionalErrorsOnRetry;
}
/**
* Sets the concurrent number of simultaneous requests per operation.
*
* The default concurrent request count is set in the client and is by default 1, indicating no concurrency. You can
* change the concurrent request count on this request by setting this property. You can also change the value on
* the {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests made via the
* service client will use that concurrent request count.
*
* @param concurrentRequestCount
* the concurrentRequestCount to set
*/
public void setConcurrentRequestCount(final Integer concurrentRequestCount) {
this.concurrentRequestCount = concurrentRequestCount;
}
/**
* Sets whether a range PUT or GET operation will use the Content-MD5 header to enforce transactional security.
* All partial blob uploads or downloads will be restricted to 4 MB.
*
* The default useTransactionalContentMD5 value is set in the client and is by default false
. You can
* change the useTransactionalContentMD5 value on this request by setting this property. You can also change the
* value on the {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests made via
* the service client will use that useTransactionalContentMD5 value.
*
* @param useTransactionalContentMD5
* the useTransactionalContentMD5 to set
*/
public void setUseTransactionalContentMD5(final Boolean useTransactionalContentMD5) {
this.useTransactionalContentMD5 = useTransactionalContentMD5;
}
/**
* Sets whether the blob's ContentMD5 header should be set on uploads. This field is not supported for page
* blobs.
*
* The default storeBlobContentMD5 value is set in the client and is by default true
for block blobs.
* You can change the storeBlobContentMD5 value on this request by setting this property. You can also change the
* value on the {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests made via
* the service client will use that storeBlobContentMD5 value.
*
* @param storeBlobContentMD5
* the storeBlobContentMD5 to set
*/
public void setStoreBlobContentMD5(final Boolean storeBlobContentMD5) {
this.storeBlobContentMD5 = storeBlobContentMD5;
}
/**
* Sets whether download and {@link BlobInputStream} methods should ignore the blob's ContentMD5 header.
*
* The default disableContentMD5Validation value is set in the client and is by default false
. You can
* change the disableContentMD5Validation value on this request by setting this property. You can also change the
* value on the {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests made via
* the service client will use that disableContentMD5Validation value.
*
* @param disableContentMD5Validation
* the disableContentMD5Validation to set
*/
public void setDisableContentMD5Validation(final Boolean disableContentMD5Validation) {
this.disableContentMD5Validation = disableContentMD5Validation;
}
/**
* Sets the threshold size used for writing a single blob to use.
*
* The default threshold size is set in the client and is by default 32MB. You can change the threshold size on this
* request by setting this property. You can also change the value on the
* {@link CloudBlobClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service
* client will use that threshold size.
*
* @param singleBlobPutThresholdInBytes
* The maximum size, in bytes, of a blob that may be uploaded as a single blob, ranging from 1 MB to 64
* MB inclusive. If a blob size is above the threshold, it will be uploaded as blocks.
*
* @throws IllegalArgumentException
* If minimumReadSize
is less than 1 MB or greater than 64 MB.
*/
public void setSingleBlobPutThresholdInBytes(final Integer singleBlobPutThresholdInBytes) {
if (singleBlobPutThresholdInBytes != null
&& (singleBlobPutThresholdInBytes > BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES || singleBlobPutThresholdInBytes < 1 * Constants.MB)) {
throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.ARGUMENT_OUT_OF_RANGE_ERROR,
"singleBlobPutThresholdInBytes", singleBlobPutThresholdInBytes.toString()));
}
this.singleBlobPutThresholdInBytes = singleBlobPutThresholdInBytes;
}
/**
* Sets the BlobEncryptionPolicy object to use for this request.
*
* The default BlobEncryptionPolicy is set in the client and is by default null, indicating no encryption. You can
* change the BlobEncryptionPolicy on this request by setting this property. You can also change the value on the
* {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service
* client will use that BlobEncryptionPolicy.
*
* @param encryptionPolicy
* the BlobEncryptionPolicy object to use when making service requests.
*/
public void setEncryptionPolicy(BlobEncryptionPolicy encryptionPolicy) {
this.encryptionPolicy = encryptionPolicy;
}
/**
* Sets the BlobCustomerProvidedKey object to use for this request.
* Customer-provided key encryption is supported for most upload, download, and copy requests to blob storage, as well
* as fetching of properties and metadata.
*
* @param key
* the BlobCustomerProvidedKey object to use when making service requests.
*/
public void setCustomerProvidedKey(BlobCustomerProvidedKey key) {
this.customerProvidedKey = key;
}
/**
* Sets the BlobCustomerProvidedKey object to use for a source blob.
* Customer-provided key encryption is supported for most upload, download, and copy requests to blob storage, as well
* as fetching of properties and metadata.
*
* @param key
* the BlobCustomerProvidedKey object to use when making service requests.
*/
// TODO uncomment when source CPK decryption is supported
/*public void setSourceCustomerProvidedKey(BlobCustomerProvidedKey key) {
this.sourceCustomerProvidedKey = key;
}*/
/**
* Sets a value to indicate whether the presence of the encryption policy should validated.
*
* @param validateEncryptionPolicy
* Use true
to require validation; otherwise, false
.
*/
protected void setValidateEncryptionPolicy(boolean validateEncryptionPolicy) {
this.validateEncryptionPolicy = validateEncryptionPolicy;
}
/**
* WARNING: etag locking is automatically used in blob downloads to ensure the blob does not change mid-download.
* Skip this validation at your own risk.
*
* Sets whether etag locking and validation on blob downloads should be skipped.
*
* @param skipEtagLocking
* Use true
to skip etag locking and validation; otherwise, false
.
*/
public void setSkipEtagLocking(boolean skipEtagLocking) {
this.skipEtagLocking = skipEtagLocking;
}
/**
* A boolean
that defines the behavior for handling exceptions when reading from the
* InputStream
and using openWrite
. If true
the data that has been read from
* the stream up to the point of the exception will be flushed and a new blob will be committed with that data.
* Otherwise, the upload will be aborted and no data will be committed.
*
* The default value is true
.
*
* @param commitWriteOnInputStreamException
* Use true
if data will be committed upon an exception; otherwise, false
.
*/
public void setCommitWriteOnInputStreamException(boolean commitWriteOnInputStreamException) {
this.commitWriteOnInputStreamException = commitWriteOnInputStreamException;
}
/**
* Assert that if validation is on, an encryption policy is not specified.
*/
protected void assertNoEncryptionPolicyOrStrictMode()
{
// Throw if an encryption policy is set and encryption validation is on
if (this.getEncryptionPolicy() != null && this.getValidateEncryptionPolicy())
{
throw new IllegalArgumentException(SR.ENCRYPTION_NOT_SUPPORTED_FOR_OPERATION);
}
this.assertPolicyIfRequired();
}
/**
* Assert that if strict mode is on, an encryption policy is specified.
*/
protected void assertPolicyIfRequired()
{
if (this.requireEncryption() != null && this.requireEncryption() && this.getEncryptionPolicy() == null)
{
throw new IllegalArgumentException(SR.ENCRYPTION_POLICY_MISSING_IN_STRICT_MODE);
}
}
}