All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.azure.storage.blob.BlobRequestOptions Maven / Gradle / Ivy

There is a newer version: 8.6.6
Show newest version
/**
 * 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); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy